Merge from 2.5 r20991 through r21037
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 173 KiB After Width: | Height: | Size: 172 KiB |
286
release/io/export_ply.py
Normal file
286
release/io/export_ply.py
Normal file
@@ -0,0 +1,286 @@
|
||||
import bpy
|
||||
|
||||
__author__ = "Bruce Merry"
|
||||
__version__ = "0.93"
|
||||
__bpydoc__ = """\
|
||||
This script exports Stanford PLY files from Blender. It supports normals,
|
||||
colours, and texture coordinates per face or per vertex.
|
||||
Only one mesh can be exported at a time.
|
||||
"""
|
||||
|
||||
# Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za
|
||||
#
|
||||
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
# Vector rounding se we can use as keys
|
||||
#
|
||||
# Updated on Aug 11, 2008 by Campbell Barton
|
||||
# - added 'comment' prefix to comments - Needed to comply with the PLY spec.
|
||||
#
|
||||
# Updated on Jan 1, 2007 by Gabe Ghearing
|
||||
# - fixed normals so they are correctly smooth/flat
|
||||
# - fixed crash when the model doesn't have uv coords or vertex colors
|
||||
# - fixed crash when the model has vertex colors but doesn't have uv coords
|
||||
# - changed float32 to float and uint8 to uchar for compatibility
|
||||
# Errata/Notes as of Jan 1, 2007
|
||||
# - script exports texture coords if they exist even if TexFace isn't selected (not a big deal to me)
|
||||
# - ST(R) should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
|
||||
#
|
||||
# Updated on Jan 3, 2007 by Gabe Ghearing
|
||||
# - fixed "sticky" vertex UV exporting
|
||||
# - added pupmenu to enable/disable exporting normals, uv coords, and colors
|
||||
# Errata/Notes as of Jan 3, 2007
|
||||
# - ST(R) coords should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
|
||||
# - edges should be exported since PLY files support them
|
||||
# - code is getting spaghettish, it should be refactored...
|
||||
#
|
||||
|
||||
|
||||
def rvec3d(v): return round(v[0], 6), round(v[1], 6), round(v[2], 6)
|
||||
def rvec2d(v): return round(v[0], 6), round(v[1], 6)
|
||||
|
||||
def write(filename, scene, ob, \
|
||||
EXPORT_APPLY_MODIFIERS= True,\
|
||||
EXPORT_NORMALS= True,\
|
||||
EXPORT_UV= True,\
|
||||
EXPORT_COLORS= True\
|
||||
):
|
||||
|
||||
if not filename.lower().endswith('.ply'):
|
||||
filename += '.ply'
|
||||
|
||||
if not ob:
|
||||
raise Exception("Error, Select 1 active object")
|
||||
return
|
||||
|
||||
file = open(filename, 'wb')
|
||||
|
||||
|
||||
#EXPORT_EDGES = Draw.Create(0)
|
||||
"""
|
||||
is_editmode = Blender.Window.EditMode()
|
||||
if is_editmode:
|
||||
Blender.Window.EditMode(0, '', 0)
|
||||
|
||||
Window.WaitCursor(1)
|
||||
"""
|
||||
|
||||
#mesh = BPyMesh.getMeshFromObject(ob, None, EXPORT_APPLY_MODIFIERS, False, scn) # XXX
|
||||
if EXPORT_APPLY_MODIFIERS:
|
||||
mesh = ob.create_render_mesh(scene)
|
||||
else:
|
||||
mesh = ob.data
|
||||
|
||||
if not mesh:
|
||||
raise ("Error, could not get mesh data from active object")
|
||||
return
|
||||
|
||||
# mesh.transform(ob.matrixWorld) # XXX
|
||||
|
||||
faceUV = len(mesh.uv_layers) > 0
|
||||
vertexUV = len(mesh.sticky) > 0
|
||||
vertexColors = len(mesh.vcol_layers) > 0
|
||||
|
||||
if (not faceUV) and (not vertexUV): EXPORT_UV = False
|
||||
if not vertexColors: EXPORT_COLORS = False
|
||||
|
||||
if not EXPORT_UV: faceUV = vertexUV = False
|
||||
if not EXPORT_COLORS: vertexColors = False
|
||||
|
||||
if faceUV:
|
||||
active_uv_layer = None
|
||||
for lay in mesh.uv_layers:
|
||||
if lay.active:
|
||||
active_uv_layer= lay.data
|
||||
break
|
||||
if not active_uv_layer:
|
||||
EXPORT_UV = False
|
||||
faceUV = None
|
||||
|
||||
if vertexColors:
|
||||
active_col_layer = None
|
||||
for lay in mesh.vcol_layers:
|
||||
if lay.active:
|
||||
active_col_layer= lay.data
|
||||
if not active_col_layer:
|
||||
EXPORT_COLORS = False
|
||||
vertexColors = None
|
||||
|
||||
# incase
|
||||
color = uvcoord = uvcoord_key = normal = normal_key = None
|
||||
|
||||
mesh_verts = mesh.verts # save a lookup
|
||||
ply_verts = [] # list of dictionaries
|
||||
# vdict = {} # (index, normal, uv) -> new index
|
||||
vdict = [{} for i in xrange(len(mesh_verts))]
|
||||
ply_faces = [[] for f in xrange(len(mesh.faces))]
|
||||
vert_count = 0
|
||||
for i, f in enumerate(mesh.faces):
|
||||
|
||||
|
||||
smooth = f.smooth
|
||||
# XXX need face normals
|
||||
"""
|
||||
if not smooth:
|
||||
normal = tuple(f.no)
|
||||
normal_key = rvec3d(normal)
|
||||
"""
|
||||
if faceUV:
|
||||
uv = active_uv_layer[i]
|
||||
uv = uv.uv1, uv.uv2, uv.uv3, uv.uv4 # XXX - crufty :/
|
||||
if vertexColors:
|
||||
col = active_col_layer[i]
|
||||
col = col.color1, col.color2, col.color3, col.color4
|
||||
|
||||
f_verts= list(f.verts)
|
||||
if not f_verts[3]: f_verts.pop() # XXX face length should be 3/4, not always 4
|
||||
|
||||
pf= ply_faces[i]
|
||||
for j, vidx in enumerate(f_verts):
|
||||
v = mesh_verts[vidx]
|
||||
"""
|
||||
if smooth:
|
||||
normal= tuple(v.no)
|
||||
normal_key = rvec3d(normal)
|
||||
"""
|
||||
normal_key = None # XXX
|
||||
|
||||
if faceUV:
|
||||
uvcoord= uv[j][0], 1.0-uv[j][1]
|
||||
uvcoord_key = rvec2d(uvcoord)
|
||||
elif vertexUV:
|
||||
uvcoord= v.uvco[0], 1.0-v.uvco[1]
|
||||
uvcoord_key = rvec2d(uvcoord)
|
||||
|
||||
if vertexColors:
|
||||
color= col[j]
|
||||
color= int(color[0]*255.0), int(color[1]*255.0), int(color[2]*255.0)
|
||||
|
||||
|
||||
key = normal_key, uvcoord_key, color
|
||||
|
||||
vdict_local = vdict[vidx]
|
||||
pf_vidx = vdict_local.get(key) # Will be None initially
|
||||
|
||||
if pf_vidx == None: # same as vdict_local.has_key(key)
|
||||
pf_vidx = vdict_local[key] = vert_count;
|
||||
ply_verts.append((vidx, normal, uvcoord, color))
|
||||
vert_count += 1
|
||||
|
||||
pf.append(pf_vidx)
|
||||
|
||||
file.write('ply\n')
|
||||
file.write('format ascii 1.0\n')
|
||||
version = "2.5" # Blender.Get('version')
|
||||
file.write('comment Created by Blender3D %s - www.blender.org, source file: %s\n' % (version, bpy.data.filename.split('/')[-1].split('\\')[-1] ))
|
||||
|
||||
file.write('element vertex %d\n' % len(ply_verts))
|
||||
|
||||
file.write('property float x\n')
|
||||
file.write('property float y\n')
|
||||
file.write('property float z\n')
|
||||
|
||||
# XXX
|
||||
"""
|
||||
if EXPORT_NORMALS:
|
||||
file.write('property float nx\n')
|
||||
file.write('property float ny\n')
|
||||
file.write('property float nz\n')
|
||||
"""
|
||||
if EXPORT_UV:
|
||||
file.write('property float s\n')
|
||||
file.write('property float t\n')
|
||||
if EXPORT_COLORS:
|
||||
file.write('property uchar red\n')
|
||||
file.write('property uchar green\n')
|
||||
file.write('property uchar blue\n')
|
||||
|
||||
file.write('element face %d\n' % len(mesh.faces))
|
||||
file.write('property list uchar uint vertex_indices\n')
|
||||
file.write('end_header\n')
|
||||
|
||||
for i, v in enumerate(ply_verts):
|
||||
file.write('%.6f %.6f %.6f ' % tuple(mesh_verts[v[0]].co)) # co
|
||||
"""
|
||||
if EXPORT_NORMALS:
|
||||
file.write('%.6f %.6f %.6f ' % v[1]) # no
|
||||
"""
|
||||
if EXPORT_UV: file.write('%.6f %.6f ' % v[2]) # uv
|
||||
if EXPORT_COLORS: file.write('%u %u %u' % v[3]) # col
|
||||
file.write('\n')
|
||||
|
||||
for pf in ply_faces:
|
||||
if len(pf)==3: file.write('3 %d %d %d\n' % tuple(pf))
|
||||
else: file.write('4 %d %d %d %d\n' % tuple(pf))
|
||||
|
||||
file.close()
|
||||
print("writing", filename, "done")
|
||||
|
||||
if EXPORT_APPLY_MODIFIERS:
|
||||
bpy.data.remove_mesh(mesh)
|
||||
|
||||
# XXX
|
||||
"""
|
||||
if is_editmode:
|
||||
Blender.Window.EditMode(1, '', 0)
|
||||
"""
|
||||
|
||||
class EXPORT_OT_ply(bpy.types.Operator):
|
||||
'''
|
||||
Operator documentatuon text, will be used for the operator tooltip and python docs.
|
||||
'''
|
||||
__label__ = "Export PLY"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
__props__ = [
|
||||
bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the PLY file", maxlen= 1024, default= ""),
|
||||
bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True),
|
||||
bpy.props.BoolProperty(attr="use_normals", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True),
|
||||
bpy.props.BoolProperty(attr="use_uvs", name="Export UVs", description="Exort the active UV layer", default= True),
|
||||
bpy.props.BoolProperty(attr="use_colors", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
|
||||
]
|
||||
|
||||
def poll(self, context):
|
||||
print("Poll")
|
||||
return context.active_object != None
|
||||
|
||||
def execute(self, context):
|
||||
# print("Selected: " + context.active_object.name)
|
||||
|
||||
if not self.filename:
|
||||
raise Exception("filename not set")
|
||||
|
||||
write(self.filename, context.scene, context.active_object,\
|
||||
EXPORT_APPLY_MODIFIERS = self.use_modifiers,
|
||||
EXPORT_NORMALS = self.use_normals,
|
||||
EXPORT_UV = self.use_uvs,
|
||||
EXPORT_COLORS = self.use_colors,
|
||||
)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self.__operator__)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
|
||||
bpy.ops.add(EXPORT_OT_ply)
|
||||
|
||||
if __name__ == "__main__":
|
||||
bpy.ops.EXPORT_OT_ply(filename="/tmp/test.ply")
|
||||
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
#!BPY
|
||||
|
||||
"""
|
||||
Name: 'Stanford PLY (*.ply)...'
|
||||
Blender: 241
|
||||
Group: 'Export'
|
||||
Tooltip: 'Export active object to Stanford PLY format'
|
||||
"""
|
||||
|
||||
import bpy
|
||||
import Blender
|
||||
from Blender import Mesh, Scene, Window, sys, Image, Draw
|
||||
import BPyMesh
|
||||
|
||||
__author__ = "Bruce Merry"
|
||||
__version__ = "0.93"
|
||||
__bpydoc__ = """\
|
||||
This script exports Stanford PLY files from Blender. It supports normals,
|
||||
colours, and texture coordinates per face or per vertex.
|
||||
Only one mesh can be exported at a time.
|
||||
"""
|
||||
|
||||
# Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za
|
||||
#
|
||||
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
# Vector rounding se we can use as keys
|
||||
#
|
||||
# Updated on Aug 11, 2008 by Campbell Barton
|
||||
# - added 'comment' prefix to comments - Needed to comply with the PLY spec.
|
||||
#
|
||||
# Updated on Jan 1, 2007 by Gabe Ghearing
|
||||
# - fixed normals so they are correctly smooth/flat
|
||||
# - fixed crash when the model doesn't have uv coords or vertex colors
|
||||
# - fixed crash when the model has vertex colors but doesn't have uv coords
|
||||
# - changed float32 to float and uint8 to uchar for compatibility
|
||||
# Errata/Notes as of Jan 1, 2007
|
||||
# - script exports texture coords if they exist even if TexFace isn't selected (not a big deal to me)
|
||||
# - ST(R) should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
|
||||
#
|
||||
# Updated on Jan 3, 2007 by Gabe Ghearing
|
||||
# - fixed "sticky" vertex UV exporting
|
||||
# - added pupmenu to enable/disable exporting normals, uv coords, and colors
|
||||
# Errata/Notes as of Jan 3, 2007
|
||||
# - ST(R) coords should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
|
||||
# - edges should be exported since PLY files support them
|
||||
# - code is getting spaghettish, it should be refactored...
|
||||
#
|
||||
|
||||
|
||||
def rvec3d(v): return round(v[0], 6), round(v[1], 6), round(v[2], 6)
|
||||
def rvec2d(v): return round(v[0], 6), round(v[1], 6)
|
||||
|
||||
def file_callback(filename):
|
||||
|
||||
if not filename.lower().endswith('.ply'):
|
||||
filename += '.ply'
|
||||
|
||||
scn= bpy.data.scenes.active
|
||||
ob= scn.objects.active
|
||||
if not ob:
|
||||
Blender.Draw.PupMenu('Error%t|Select 1 active object')
|
||||
return
|
||||
|
||||
file = open(filename, 'wb')
|
||||
|
||||
EXPORT_APPLY_MODIFIERS = Draw.Create(1)
|
||||
EXPORT_NORMALS = Draw.Create(1)
|
||||
EXPORT_UV = Draw.Create(1)
|
||||
EXPORT_COLORS = Draw.Create(1)
|
||||
#EXPORT_EDGES = Draw.Create(0)
|
||||
|
||||
pup_block = [\
|
||||
('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data.'),\
|
||||
('Normals', EXPORT_NORMALS, 'Export vertex normal data.'),\
|
||||
('UVs', EXPORT_UV, 'Export texface UV coords.'),\
|
||||
('Colors', EXPORT_COLORS, 'Export vertex Colors.'),\
|
||||
#('Edges', EXPORT_EDGES, 'Edges not connected to faces.'),\
|
||||
]
|
||||
|
||||
if not Draw.PupBlock('Export...', pup_block):
|
||||
return
|
||||
|
||||
is_editmode = Blender.Window.EditMode()
|
||||
if is_editmode:
|
||||
Blender.Window.EditMode(0, '', 0)
|
||||
|
||||
Window.WaitCursor(1)
|
||||
|
||||
EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val
|
||||
EXPORT_NORMALS = EXPORT_NORMALS.val
|
||||
EXPORT_UV = EXPORT_UV.val
|
||||
EXPORT_COLORS = EXPORT_COLORS.val
|
||||
#EXPORT_EDGES = EXPORT_EDGES.val
|
||||
|
||||
mesh = BPyMesh.getMeshFromObject(ob, None, EXPORT_APPLY_MODIFIERS, False, scn)
|
||||
|
||||
if not mesh:
|
||||
Blender.Draw.PupMenu('Error%t|Could not get mesh data from active object')
|
||||
return
|
||||
|
||||
mesh.transform(ob.matrixWorld)
|
||||
|
||||
faceUV = mesh.faceUV
|
||||
vertexUV = mesh.vertexUV
|
||||
vertexColors = mesh.vertexColors
|
||||
|
||||
if (not faceUV) and (not vertexUV): EXPORT_UV = False
|
||||
if not vertexColors: EXPORT_COLORS = False
|
||||
|
||||
if not EXPORT_UV: faceUV = vertexUV = False
|
||||
if not EXPORT_COLORS: vertexColors = False
|
||||
|
||||
# incase
|
||||
color = uvcoord = uvcoord_key = normal = normal_key = None
|
||||
|
||||
verts = [] # list of dictionaries
|
||||
# vdict = {} # (index, normal, uv) -> new index
|
||||
vdict = [{} for i in xrange(len(mesh.verts))]
|
||||
vert_count = 0
|
||||
for i, f in enumerate(mesh.faces):
|
||||
smooth = f.smooth
|
||||
if not smooth:
|
||||
normal = tuple(f.no)
|
||||
normal_key = rvec3d(normal)
|
||||
|
||||
if faceUV: uv = f.uv
|
||||
if vertexColors: col = f.col
|
||||
for j, v in enumerate(f):
|
||||
if smooth:
|
||||
normal= tuple(v.no)
|
||||
normal_key = rvec3d(normal)
|
||||
|
||||
if faceUV:
|
||||
uvcoord= uv[j][0], 1.0-uv[j][1]
|
||||
uvcoord_key = rvec2d(uvcoord)
|
||||
elif vertexUV:
|
||||
uvcoord= v.uvco[0], 1.0-v.uvco[1]
|
||||
uvcoord_key = rvec2d(uvcoord)
|
||||
|
||||
if vertexColors: color= col[j].r, col[j].g, col[j].b
|
||||
|
||||
|
||||
key = normal_key, uvcoord_key, color
|
||||
|
||||
vdict_local = vdict[v.index]
|
||||
|
||||
if (not vdict_local) or (not vdict_local.has_key(key)):
|
||||
vdict_local[key] = vert_count;
|
||||
verts.append( (tuple(v.co), normal, uvcoord, color) )
|
||||
vert_count += 1
|
||||
|
||||
|
||||
file.write('ply\n')
|
||||
file.write('format ascii 1.0\n')
|
||||
file.write('comment Created by Blender3D %s - www.blender.org, source file: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] ))
|
||||
|
||||
file.write('element vertex %d\n' % len(verts))
|
||||
|
||||
file.write('property float x\n')
|
||||
file.write('property float y\n')
|
||||
file.write('property float z\n')
|
||||
if EXPORT_NORMALS:
|
||||
file.write('property float nx\n')
|
||||
file.write('property float ny\n')
|
||||
file.write('property float nz\n')
|
||||
|
||||
if EXPORT_UV:
|
||||
file.write('property float s\n')
|
||||
file.write('property float t\n')
|
||||
if EXPORT_COLORS:
|
||||
file.write('property uchar red\n')
|
||||
file.write('property uchar green\n')
|
||||
file.write('property uchar blue\n')
|
||||
|
||||
file.write('element face %d\n' % len(mesh.faces))
|
||||
file.write('property list uchar uint vertex_indices\n')
|
||||
file.write('end_header\n')
|
||||
|
||||
for i, v in enumerate(verts):
|
||||
file.write('%.6f %.6f %.6f ' % v[0]) # co
|
||||
if EXPORT_NORMALS:
|
||||
file.write('%.6f %.6f %.6f ' % v[1]) # no
|
||||
|
||||
if EXPORT_UV:
|
||||
file.write('%.6f %.6f ' % v[2]) # uv
|
||||
if EXPORT_COLORS:
|
||||
file.write('%u %u %u' % v[3]) # col
|
||||
file.write('\n')
|
||||
|
||||
for (i, f) in enumerate(mesh.faces):
|
||||
file.write('%d ' % len(f))
|
||||
smooth = f.smooth
|
||||
if not smooth: no = rvec3d(f.no)
|
||||
|
||||
if faceUV: uv = f.uv
|
||||
if vertexColors: col = f.col
|
||||
for j, v in enumerate(f):
|
||||
if f.smooth: normal= rvec3d(v.no)
|
||||
else: normal= no
|
||||
if faceUV: uvcoord= rvec2d((uv[j][0], 1.0-uv[j][1]))
|
||||
elif vertexUV: uvcoord= rvec2d((v.uvco[0], 1.0-v.uvco[1]))
|
||||
if vertexColors: color= col[j].r, col[j].g, col[j].b
|
||||
|
||||
file.write('%d ' % vdict[v.index][normal, uvcoord, color])
|
||||
|
||||
file.write('\n')
|
||||
file.close()
|
||||
|
||||
if is_editmode:
|
||||
Blender.Window.EditMode(1, '', 0)
|
||||
|
||||
def main():
|
||||
Blender.Window.FileSelector(file_callback, 'PLY Export', Blender.sys.makename(ext='.ply'))
|
||||
|
||||
if __name__=='__main__':
|
||||
main()
|
||||
@@ -7,7 +7,7 @@ class BoneButtonsPanel(bpy.types.Panel):
|
||||
__context__ = "bone"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.bone != None)
|
||||
return (context.bone or context.edit_bone)
|
||||
|
||||
class BONE_PT_bone(BoneButtonsPanel):
|
||||
__idname__ = "BONE_PT_bone"
|
||||
@@ -16,6 +16,8 @@ class BONE_PT_bone(BoneButtonsPanel):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
bone = context.bone
|
||||
if not bone:
|
||||
bone = context.edit_bone
|
||||
|
||||
split = layout.split()
|
||||
|
||||
@@ -40,8 +42,7 @@ class BONE_PT_bone(BoneButtonsPanel):
|
||||
|
||||
sub.itemL(text="Display:")
|
||||
sub.itemR(bone, "draw_wire", text="Wireframe")
|
||||
sub.itemR(bone, "editmode_hidden", text="Hide (EditMode)")
|
||||
sub.itemR(bone, "pose_channel_hidden", text="Hide (PoseMode)")
|
||||
sub.itemR(bone, "hidden", text="Hide")
|
||||
|
||||
sub.itemL(text="Curved Bones:")
|
||||
sub.itemR(bone, "bbone_segments", text="Segments")
|
||||
@@ -50,4 +51,4 @@ class BONE_PT_bone(BoneButtonsPanel):
|
||||
|
||||
sub.itemR(bone, "cyclic_offset")
|
||||
|
||||
bpy.types.register(BONE_PT_bone)
|
||||
bpy.types.register(BONE_PT_bone)
|
||||
|
||||
@@ -207,6 +207,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
||||
layout.itemR(md, "texture")
|
||||
layout.itemR(md, "midlevel")
|
||||
layout.itemR(md, "strength")
|
||||
layout.itemR(md, "direction")
|
||||
layout.itemR(md, "texture_coordinates")
|
||||
if md.texture_coordinates == 'OBJECT':
|
||||
layout.itemR(md, "texture_coordinate_object", text="Object")
|
||||
|
||||
@@ -35,7 +35,7 @@ class OBJECT_PT_groups(ObjectButtonsPanel):
|
||||
# layout.itemO("OBJECT_OT_add_group");
|
||||
|
||||
for group in bpy.data.groups:
|
||||
if ob in group.objects:
|
||||
if ob.name in group.objects:
|
||||
col = layout.column(align=True)
|
||||
|
||||
row = col.box().row()
|
||||
|
||||
80
release/ui/space_logic.py
Normal file
80
release/ui/space_logic.py
Normal file
@@ -0,0 +1,80 @@
|
||||
import bpy
|
||||
|
||||
class LOGIC_PT_physics(bpy.types.Panel):
|
||||
__space_type__ = "LOGIC_EDITOR"
|
||||
__region_type__ = "UI"
|
||||
__label__ = "Physics"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ob = context.active_object
|
||||
|
||||
game = ob.game
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.active = True
|
||||
flow.itemR(game, "physics_type")
|
||||
flow.itemR(game, "actor")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(game, "ghost")
|
||||
row.itemR(ob, "restrict_render", text="Invisible") # out of place but useful
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(game, "mass")
|
||||
flow.itemR(game, "radius")
|
||||
flow.itemR(game, "no_sleeping")
|
||||
flow.itemR(game, "damping")
|
||||
flow.itemR(game, "rotation_damping")
|
||||
flow.itemR(game, "minimum_velocity")
|
||||
flow.itemR(game, "maximum_velocity")
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(game, "do_fh")
|
||||
row.itemR(game, "rotation_fh")
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.itemR(game, "form_factor")
|
||||
flow.itemR(game, "anisotropic_friction")
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.active = game.anisotropic_friction
|
||||
flow.itemR(game, "friction_coefficients")
|
||||
|
||||
split = layout.split()
|
||||
sub = split.column()
|
||||
sub.itemR(game, "lock_x_axis")
|
||||
sub.itemR(game, "lock_y_axis")
|
||||
sub.itemR(game, "lock_z_axis")
|
||||
sub = split.column()
|
||||
sub.itemR(game, "lock_x_rot_axis")
|
||||
sub.itemR(game, "lock_y_rot_axis")
|
||||
sub.itemR(game, "lock_z_rot_axis")
|
||||
|
||||
|
||||
class LOGIC_PT_collision_bounds(bpy.types.Panel):
|
||||
__space_type__ = "LOGIC_EDITOR"
|
||||
__region_type__ = "UI"
|
||||
__label__ = "Collision Bounds"
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
ob = context.active_object
|
||||
game = ob.game
|
||||
|
||||
layout.itemR(game, "use_collision_bounds", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.scene.objects[0]
|
||||
game = ob.game
|
||||
|
||||
flow = layout.column_flow()
|
||||
flow.active = game.use_collision_bounds
|
||||
flow.itemR(game, "collision_bounds")
|
||||
flow.itemR(game, "collision_compound")
|
||||
flow.itemR(game, "collision_margin")
|
||||
|
||||
bpy.types.register(LOGIC_PT_physics)
|
||||
bpy.types.register(LOGIC_PT_collision_bounds)
|
||||
@@ -146,18 +146,20 @@ void blf_font_draw(FontBLF *font, char *str)
|
||||
|
||||
if (FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta) == 0) {
|
||||
pen_x += delta.x >> 6;
|
||||
|
||||
/*
|
||||
if (pen_x < old_pen_x)
|
||||
pen_x= old_pen_x;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (font->flags & BLF_USER_KERNING) {
|
||||
old_pen_x= pen_x;
|
||||
pen_x += font->kerning;
|
||||
|
||||
/*
|
||||
if (pen_x < old_pen_x)
|
||||
pen_x= old_pen_x;
|
||||
*/
|
||||
}
|
||||
|
||||
/* do not return this loop if clipped, we want every character tested */
|
||||
@@ -226,18 +228,20 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box)
|
||||
|
||||
if (FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta) == 0) {
|
||||
pen_x += delta.x >> 6;
|
||||
|
||||
/*
|
||||
if (pen_x < old_pen_x)
|
||||
old_pen_x= pen_x;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (font->flags & BLF_USER_KERNING) {
|
||||
old_pen_x= pen_x;
|
||||
pen_x += font->kerning;
|
||||
|
||||
/*
|
||||
if (pen_x < old_pen_x)
|
||||
old_pen_x= pen_x;
|
||||
*/
|
||||
}
|
||||
|
||||
gbox.xmin= g->box.xmin + pen_x;
|
||||
|
||||
@@ -137,7 +137,7 @@ void framechange_poses_clear_unkeyed(void);
|
||||
void what_does_obaction(struct Scene *scene, struct Object *ob, struct Object *workob, struct bPose *pose, struct bAction *act, char groupname[], float cframe);
|
||||
|
||||
/* exported for game engine */
|
||||
void blend_poses(struct bPose *dst, struct bPose *src, float srcweight, short mode);
|
||||
void game_blend_poses(struct bPose *dst, struct bPose *src, float srcweight/*, short mode*/); /* was blend_poses */
|
||||
void extract_pose_from_pose(struct bPose *pose, const struct bPose *src);
|
||||
|
||||
/* for proxy */
|
||||
|
||||
@@ -126,12 +126,14 @@ void CTX_wm_menu_set(bContext *C, struct ARegion *menu);
|
||||
|
||||
/* Data Context
|
||||
|
||||
- note: listbases consist of LinkData items and must be
|
||||
freed with BLI_freelistN! */
|
||||
- listbases consist of CollectionPointerLink items and must be
|
||||
freed with BLI_freelistN!
|
||||
- the dir listbase consits of LinkData items */
|
||||
|
||||
PointerRNA CTX_data_pointer_get(bContext *C, const char *member);
|
||||
ListBase CTX_data_collection_get(bContext *C, const char *member);
|
||||
void CTX_data_get(bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb);
|
||||
PointerRNA CTX_data_pointer_get(const bContext *C, const char *member);
|
||||
ListBase CTX_data_collection_get(const bContext *C, const char *member);
|
||||
ListBase CTX_data_dir_get(const bContext *C);
|
||||
void CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb);
|
||||
|
||||
void CTX_data_id_pointer_set(bContextDataResult *result, struct ID *id);
|
||||
void CTX_data_pointer_set(bContextDataResult *result, struct ID *id, StructRNA *type, void *data);
|
||||
@@ -139,7 +141,10 @@ void CTX_data_pointer_set(bContextDataResult *result, struct ID *id, StructRNA *
|
||||
void CTX_data_id_list_add(bContextDataResult *result, struct ID *id);
|
||||
void CTX_data_list_add(bContextDataResult *result, struct ID *id, StructRNA *type, void *data);
|
||||
|
||||
void CTX_data_dir_set(bContextDataResult *result, const char **member);
|
||||
|
||||
int CTX_data_equals(const char *member, const char *str);
|
||||
int CTX_data_dir(const char *member);
|
||||
|
||||
/*void CTX_data_pointer_set(bContextDataResult *result, void *data);
|
||||
void CTX_data_list_add(bContextDataResult *result, void *data);*/
|
||||
|
||||
@@ -36,6 +36,7 @@ struct Scene;
|
||||
struct DagNodeQueue;
|
||||
struct DagForest;
|
||||
struct DagNode;
|
||||
struct GHash;
|
||||
|
||||
/* **** DAG relation types *** */
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ typedef struct DagNode
|
||||
void * first_ancestor;
|
||||
int ancestor_count;
|
||||
int lay; // accumulated layers of its relations + itself
|
||||
int scelay; // layers due to being in scene
|
||||
int lasttime; // if lasttime != DagForest->time, this node was not evaluated yet for flushing
|
||||
int BFS_dist; // BFS distance
|
||||
int DFS_dist; // DFS distance
|
||||
@@ -93,6 +94,7 @@ typedef struct DagNodeQueue
|
||||
typedef struct DagForest
|
||||
{
|
||||
ListBase DagNode;
|
||||
struct GHash *nodeHash;
|
||||
int numNodes;
|
||||
int is_acyclic;
|
||||
int time; // for flushing/tagging, compare with node->lasttime
|
||||
|
||||
@@ -581,6 +581,77 @@ void game_copy_pose(bPose **dst, bPose *src)
|
||||
*dst=out;
|
||||
}
|
||||
|
||||
|
||||
/* Only allowed for Poses with identical channels */
|
||||
void game_blend_poses(bPose *dst, bPose *src, float srcweight/*, short mode*/)
|
||||
{
|
||||
short mode= ACTSTRIPMODE_BLEND;
|
||||
|
||||
bPoseChannel *dchan;
|
||||
const bPoseChannel *schan;
|
||||
bConstraint *dcon, *scon;
|
||||
float dstweight;
|
||||
int i;
|
||||
|
||||
switch (mode){
|
||||
case ACTSTRIPMODE_BLEND:
|
||||
dstweight = 1.0F - srcweight;
|
||||
break;
|
||||
case ACTSTRIPMODE_ADD:
|
||||
dstweight = 1.0F;
|
||||
break;
|
||||
default :
|
||||
dstweight = 1.0F;
|
||||
}
|
||||
|
||||
schan= src->chanbase.first;
|
||||
for (dchan = dst->chanbase.first; dchan; dchan=dchan->next, schan= schan->next){
|
||||
if (schan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) {
|
||||
/* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */
|
||||
|
||||
/* Do the transformation blend */
|
||||
if (schan->flag & POSE_ROT) {
|
||||
/* quat interpolation done separate */
|
||||
if (schan->rotmode == PCHAN_ROT_QUAT) {
|
||||
float dquat[4], squat[4];
|
||||
|
||||
QUATCOPY(dquat, dchan->quat);
|
||||
QUATCOPY(squat, schan->quat);
|
||||
if (mode==ACTSTRIPMODE_BLEND)
|
||||
QuatInterpol(dchan->quat, dquat, squat, srcweight);
|
||||
else {
|
||||
QuatMulFac(squat, srcweight);
|
||||
QuatMul(dchan->quat, dquat, squat);
|
||||
}
|
||||
|
||||
NormalQuat(dchan->quat);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<3; i++) {
|
||||
/* blending for loc and scale are pretty self-explanatory... */
|
||||
if (schan->flag & POSE_LOC)
|
||||
dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight);
|
||||
if (schan->flag & POSE_SIZE)
|
||||
dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight);
|
||||
|
||||
/* euler-rotation interpolation done here instead... */
|
||||
// FIXME: are these results decent?
|
||||
if ((schan->flag & POSE_ROT) && (schan->rotmode))
|
||||
dchan->eul[i] = (dchan->eul[i]*dstweight) + (schan->eul[i]*srcweight);
|
||||
}
|
||||
dchan->flag |= schan->flag;
|
||||
}
|
||||
for(dcon= dchan->constraints.first, scon= schan->constraints.first; dcon && scon; dcon= dcon->next, scon= scon->next) {
|
||||
/* no 'add' option for constraint blending */
|
||||
dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight;
|
||||
}
|
||||
}
|
||||
|
||||
/* this pose is now in src time */
|
||||
dst->ctime= src->ctime;
|
||||
}
|
||||
|
||||
void game_free_pose(bPose *pose)
|
||||
{
|
||||
if (pose) {
|
||||
@@ -1039,75 +1110,6 @@ static void blend_pose_offset_bone(bActionStrip *strip, bPose *dst, bPose *src,
|
||||
VecAddf(dst->cyclic_offset, dst->cyclic_offset, src->cyclic_offset);
|
||||
}
|
||||
|
||||
|
||||
/* Only allowed for Poses with identical channels */
|
||||
void blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
|
||||
{
|
||||
bPoseChannel *dchan;
|
||||
const bPoseChannel *schan;
|
||||
bConstraint *dcon, *scon;
|
||||
float dstweight;
|
||||
int i;
|
||||
|
||||
switch (mode){
|
||||
case ACTSTRIPMODE_BLEND:
|
||||
dstweight = 1.0F - srcweight;
|
||||
break;
|
||||
case ACTSTRIPMODE_ADD:
|
||||
dstweight = 1.0F;
|
||||
break;
|
||||
default :
|
||||
dstweight = 1.0F;
|
||||
}
|
||||
|
||||
schan= src->chanbase.first;
|
||||
for (dchan = dst->chanbase.first; dchan; dchan=dchan->next, schan= schan->next){
|
||||
if (schan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) {
|
||||
/* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */
|
||||
|
||||
/* Do the transformation blend */
|
||||
if (schan->flag & POSE_ROT) {
|
||||
/* quat interpolation done separate */
|
||||
if (schan->rotmode == PCHAN_ROT_QUAT) {
|
||||
float dquat[4], squat[4];
|
||||
|
||||
QUATCOPY(dquat, dchan->quat);
|
||||
QUATCOPY(squat, schan->quat);
|
||||
if (mode==ACTSTRIPMODE_BLEND)
|
||||
QuatInterpol(dchan->quat, dquat, squat, srcweight);
|
||||
else {
|
||||
QuatMulFac(squat, srcweight);
|
||||
QuatMul(dchan->quat, dquat, squat);
|
||||
}
|
||||
|
||||
NormalQuat(dchan->quat);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<3; i++) {
|
||||
/* blending for loc and scale are pretty self-explanatory... */
|
||||
if (schan->flag & POSE_LOC)
|
||||
dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight);
|
||||
if (schan->flag & POSE_SIZE)
|
||||
dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight);
|
||||
|
||||
/* euler-rotation interpolation done here instead... */
|
||||
// FIXME: are these results decent?
|
||||
if ((schan->flag & POSE_ROT) && (schan->rotmode))
|
||||
dchan->eul[i] = (dchan->eul[i]*dstweight) + (schan->eul[i]*srcweight);
|
||||
}
|
||||
dchan->flag |= schan->flag;
|
||||
}
|
||||
for(dcon= dchan->constraints.first, scon= schan->constraints.first; dcon && scon; dcon= dcon->next, scon= scon->next) {
|
||||
/* no 'add' option for constraint blending */
|
||||
dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight;
|
||||
}
|
||||
}
|
||||
|
||||
/* this pose is now in src time */
|
||||
dst->ctime= src->ctime;
|
||||
}
|
||||
|
||||
typedef struct NlaIpoChannel {
|
||||
struct NlaIpoChannel *next, *prev;
|
||||
float val;
|
||||
|
||||
@@ -280,6 +280,7 @@ void CTX_wm_menu_set(bContext *C, ARegion *menu)
|
||||
struct bContextDataResult {
|
||||
PointerRNA ptr;
|
||||
ListBase list;
|
||||
const char **dir;
|
||||
};
|
||||
|
||||
static int ctx_data_get(bContext *C, const char *member, bContextDataResult *result)
|
||||
@@ -360,7 +361,7 @@ static int ctx_data_collection_get(const bContext *C, const char *member, ListBa
|
||||
return 0;
|
||||
}
|
||||
|
||||
PointerRNA CTX_data_pointer_get(bContext *C, const char *member)
|
||||
PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
|
||||
{
|
||||
bContextDataResult result;
|
||||
|
||||
@@ -375,7 +376,7 @@ PointerRNA CTX_data_pointer_get(bContext *C, const char *member)
|
||||
|
||||
}
|
||||
|
||||
ListBase CTX_data_collection_get(bContext *C, const char *member)
|
||||
ListBase CTX_data_collection_get(const bContext *C, const char *member)
|
||||
{
|
||||
bContextDataResult result;
|
||||
|
||||
@@ -389,7 +390,7 @@ ListBase CTX_data_collection_get(bContext *C, const char *member)
|
||||
}
|
||||
}
|
||||
|
||||
void CTX_data_get(bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb)
|
||||
void CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb)
|
||||
{
|
||||
bContextDataResult result;
|
||||
|
||||
@@ -403,11 +404,75 @@ void CTX_data_get(bContext *C, const char *member, PointerRNA *r_ptr, ListBase *
|
||||
}
|
||||
}
|
||||
|
||||
static void data_dir_add(ListBase *lb, const char *member)
|
||||
{
|
||||
LinkData *link;
|
||||
|
||||
if(strcmp(member, "scene") == 0) /* exception */
|
||||
return;
|
||||
|
||||
for(link=lb->first; link; link=link->next)
|
||||
if(strcmp(link->data, member) == 0)
|
||||
return;
|
||||
|
||||
link= MEM_callocN(sizeof(LinkData), "LinkData");
|
||||
link->data= (void*)member;
|
||||
BLI_addtail(lb, link);
|
||||
}
|
||||
|
||||
ListBase CTX_data_dir_get(const bContext *C)
|
||||
{
|
||||
bContextDataResult result;
|
||||
ListBase lb;
|
||||
int a;
|
||||
|
||||
memset(&lb, 0, sizeof(lb));
|
||||
|
||||
if(C->wm.store) {
|
||||
bContextStoreEntry *entry;
|
||||
|
||||
for(entry=C->wm.store->entries.first; entry; entry=entry->next)
|
||||
data_dir_add(&lb, entry->name);
|
||||
}
|
||||
if(C->wm.region && C->wm.region->type && C->wm.region->type->context) {
|
||||
memset(&result, 0, sizeof(result));
|
||||
C->wm.region->type->context(C, "", &result);
|
||||
|
||||
if(result.dir)
|
||||
for(a=0; result.dir[a]; a++)
|
||||
data_dir_add(&lb, result.dir[a]);
|
||||
}
|
||||
if(C->wm.area && C->wm.area->type && C->wm.area->type->context) {
|
||||
memset(&result, 0, sizeof(result));
|
||||
C->wm.area->type->context(C, "", &result);
|
||||
|
||||
if(result.dir)
|
||||
for(a=0; result.dir[a]; a++)
|
||||
data_dir_add(&lb, result.dir[a]);
|
||||
}
|
||||
if(C->wm.screen && C->wm.screen->context) {
|
||||
bContextDataCallback cb= C->wm.screen->context;
|
||||
memset(&result, 0, sizeof(result));
|
||||
cb(C, "", &result);
|
||||
|
||||
if(result.dir)
|
||||
for(a=0; result.dir[a]; a++)
|
||||
data_dir_add(&lb, result.dir[a]);
|
||||
}
|
||||
|
||||
return lb;
|
||||
}
|
||||
|
||||
int CTX_data_equals(const char *member, const char *str)
|
||||
{
|
||||
return (strcmp(member, str) == 0);
|
||||
}
|
||||
|
||||
int CTX_data_dir(const char *member)
|
||||
{
|
||||
return (strcmp(member, "") == 0);
|
||||
}
|
||||
|
||||
void CTX_data_id_pointer_set(bContextDataResult *result, ID *id)
|
||||
{
|
||||
RNA_id_pointer_create(id, &result->ptr);
|
||||
@@ -451,6 +516,11 @@ int ctx_data_list_count(const bContext *C, int (*func)(const bContext*, ListBase
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CTX_data_dir_set(bContextDataResult *result, const char **dir)
|
||||
{
|
||||
result->dir= dir;
|
||||
}
|
||||
|
||||
/* data context */
|
||||
|
||||
Main *CTX_data_main(const bContext *C)
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
#include "DNA_view2d_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_effect.h"
|
||||
#include "BKE_global.h"
|
||||
@@ -754,6 +756,9 @@ void free_forest(DagForest *Dag)
|
||||
itN = itN->next;
|
||||
MEM_freeN(tempN);
|
||||
}
|
||||
|
||||
BLI_ghash_free(Dag->nodeHash, NULL, NULL);
|
||||
Dag->nodeHash= NULL;
|
||||
Dag->DagNode.first = NULL;
|
||||
Dag->DagNode.last = NULL;
|
||||
Dag->numNodes = 0;
|
||||
@@ -762,13 +767,9 @@ void free_forest(DagForest *Dag)
|
||||
|
||||
DagNode * dag_find_node (DagForest *forest,void * fob)
|
||||
{
|
||||
DagNode *node = forest->DagNode.first;
|
||||
|
||||
while (node) {
|
||||
if (node->ob == fob)
|
||||
return node;
|
||||
node = node->next;
|
||||
}
|
||||
if(forest->nodeHash)
|
||||
return BLI_ghash_lookup(forest->nodeHash, fob);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -794,7 +795,12 @@ DagNode * dag_add_node (DagForest *forest, void * fob)
|
||||
forest->DagNode.first = node;
|
||||
forest->numNodes = 1;
|
||||
}
|
||||
|
||||
if(!forest->nodeHash)
|
||||
forest->nodeHash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
|
||||
BLI_ghash_insert(forest->nodeHash, fob, node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1805,17 +1811,10 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
|
||||
/* node was checked to have lasttime != curtime , and is of type ID_OB */
|
||||
static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime)
|
||||
{
|
||||
Base *base;
|
||||
DagAdjList *itA;
|
||||
|
||||
node->lasttime= curtime;
|
||||
node->lay= 0;
|
||||
for(base= sce->base.first; base; base= base->next) {
|
||||
if(node->ob == base->object) {
|
||||
node->lay= ((Object *)node->ob)->lay;
|
||||
break;
|
||||
}
|
||||
}
|
||||
node->lay= node->scelay;
|
||||
|
||||
for(itA = node->child; itA; itA= itA->next) {
|
||||
if(itA->node->type==ID_OB) {
|
||||
@@ -1860,9 +1859,10 @@ static void flush_pointcache_reset(DagNode *node, int curtime, int reset)
|
||||
/* flushes all recalc flags in objects down the dependency tree */
|
||||
void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time)
|
||||
{
|
||||
DagNode *firstnode;
|
||||
DagNode *firstnode, *node;
|
||||
DagAdjList *itA;
|
||||
Object *ob;
|
||||
Base *base;
|
||||
int lasttime;
|
||||
|
||||
if(sce->theDag==NULL) {
|
||||
@@ -1879,6 +1879,15 @@ void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time)
|
||||
sce->theDag->time++; // so we know which nodes were accessed
|
||||
lasttime= sce->theDag->time;
|
||||
|
||||
|
||||
for(base= sce->base.first; base; base= base->next) {
|
||||
node= dag_get_node(sce->theDag, base->object);
|
||||
if(node)
|
||||
node->scelay= base->object->lay;
|
||||
else
|
||||
node->scelay= 0;
|
||||
}
|
||||
|
||||
for(itA = firstnode->child; itA; itA= itA->next)
|
||||
if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB)
|
||||
flush_layer_node(sce, itA->node, lasttime);
|
||||
|
||||
@@ -235,17 +235,15 @@ static char *ob_adrcodes_to_paths (int adrcode, int *array_index)
|
||||
*array_index= 1; return "delta_scale";
|
||||
case OB_DSIZE_Z:
|
||||
*array_index= 2; return "delta_scale";
|
||||
|
||||
#if 0
|
||||
case OB_COL_R:
|
||||
poin= &(ob->col[0]); break;
|
||||
case OB_COL_R:
|
||||
*array_index= 0; return "color";
|
||||
case OB_COL_G:
|
||||
poin= &(ob->col[1]); break;
|
||||
*array_index= 1; return "color";
|
||||
case OB_COL_B:
|
||||
poin= &(ob->col[2]); break;
|
||||
*array_index= 2; return "color";
|
||||
case OB_COL_A:
|
||||
poin= &(ob->col[3]); break;
|
||||
|
||||
*array_index= 3; return "color";
|
||||
#if 0
|
||||
case OB_PD_FSTR:
|
||||
if (ob->pd) poin= &(ob->pd->f_strength);
|
||||
break;
|
||||
@@ -1515,14 +1513,7 @@ void do_versions_ipos_to_animato(Main *main)
|
||||
/* Add AnimData block */
|
||||
adt= BKE_id_add_animdata(id);
|
||||
|
||||
/* IPO first */
|
||||
if (ob->ipo) {
|
||||
ipo_to_animdata(id, ob->ipo, NULL, NULL);
|
||||
ob->ipo->id.us--;
|
||||
ob->ipo= NULL;
|
||||
}
|
||||
|
||||
/* now Action */
|
||||
/* Action first - so that Action name get conserved */
|
||||
if (ob->action) {
|
||||
action_to_animdata(id, ob->action);
|
||||
|
||||
@@ -1533,6 +1524,13 @@ void do_versions_ipos_to_animato(Main *main)
|
||||
}
|
||||
}
|
||||
|
||||
/* IPO second... */
|
||||
if (ob->ipo) {
|
||||
ipo_to_animdata(id, ob->ipo, NULL, NULL);
|
||||
ob->ipo->id.us--;
|
||||
ob->ipo= NULL;
|
||||
}
|
||||
|
||||
/* finally NLA */
|
||||
// XXX todo... for now, new NLA code not hooked up yet, so keep old stuff (but not for too long!)
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ void BLI_dynstr_vappendf(DynStr *ds, const char *format, va_list args)
|
||||
if(len == sizeof(fixedmessage))
|
||||
message= fixedmessage;
|
||||
else
|
||||
message= MEM_callocN(sizeof(char)*len+1, "BLI_dynstr_appendf");
|
||||
message= MEM_callocN(sizeof(char)*(len+1), "BLI_dynstr_appendf");
|
||||
|
||||
retval= vsnprintf(message, len, format, args);
|
||||
|
||||
@@ -132,10 +132,54 @@ void BLI_dynstr_vappendf(DynStr *ds, const char *format, va_list args)
|
||||
void BLI_dynstr_appendf(DynStr *ds, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *message, fixedmessage[256];
|
||||
int len= 256, maxlen= 65536, retval;
|
||||
|
||||
va_start(args, format);
|
||||
BLI_dynstr_vappendf(ds, format, args);
|
||||
va_end(args);
|
||||
/* note that it's tempting to just call BLI_dynstr_vappendf here
|
||||
* and avoid code duplication, that crashes on some system because
|
||||
* va_start/va_end have to be called for each vsnprintf call */
|
||||
|
||||
while(1) {
|
||||
if(len == sizeof(fixedmessage))
|
||||
message= fixedmessage;
|
||||
else
|
||||
message= MEM_callocN(sizeof(char)*(len+1), "BLI_dynstr_appendf");
|
||||
|
||||
va_start(args, format);
|
||||
retval= vsnprintf(message, len, format, args);
|
||||
va_end(args);
|
||||
|
||||
if(retval == -1) {
|
||||
/* -1 means not enough space, but on windows it may also mean
|
||||
* there is a formatting error, so we impose a maximum length */
|
||||
if(message != fixedmessage)
|
||||
MEM_freeN(message);
|
||||
message= NULL;
|
||||
|
||||
len *= 2;
|
||||
if(len > maxlen) {
|
||||
fprintf(stderr, "BLI_dynstr_append text too long or format error.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(retval > len) {
|
||||
/* in C99 the actual length required is returned */
|
||||
if(message != fixedmessage)
|
||||
MEM_freeN(message);
|
||||
message= NULL;
|
||||
|
||||
len= retval;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if(message) {
|
||||
BLI_dynstr_append(ds, message);
|
||||
|
||||
if(message != fixedmessage)
|
||||
MEM_freeN(message);
|
||||
}
|
||||
}
|
||||
|
||||
int BLI_dynstr_get_len(DynStr *ds) {
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
#define PNL_WAS_ACTIVE 4
|
||||
#define PNL_ANIM_ALIGN 8
|
||||
#define PNL_NEW_ADDED 16
|
||||
#define PNL_FIRST 32
|
||||
|
||||
typedef enum uiHandlePanelState {
|
||||
PANEL_STATE_DRAG,
|
||||
@@ -528,7 +529,7 @@ static void rectf_scale(rctf *rect, float scale)
|
||||
/* panel integrated in buttonswindow, tool/property lists etc */
|
||||
void ui_draw_aligned_panel(ARegion *ar, uiStyle *style, uiBlock *block, rcti *rect)
|
||||
{
|
||||
Panel *panel= block->panel, *prev;
|
||||
Panel *panel= block->panel;
|
||||
rcti headrect;
|
||||
rctf itemrect;
|
||||
int ofsx;
|
||||
@@ -541,14 +542,7 @@ void ui_draw_aligned_panel(ARegion *ar, uiStyle *style, uiBlock *block, rcti *re
|
||||
headrect.ymin= headrect.ymax;
|
||||
headrect.ymax= headrect.ymin + floor(PNL_HEADER/block->aspect + 0.001f);
|
||||
|
||||
/* divider only when there's a previous panel */
|
||||
prev= panel->prev;
|
||||
while(prev) {
|
||||
if(prev->runtime_flag & PNL_ACTIVE) break;
|
||||
prev= prev->prev;
|
||||
}
|
||||
|
||||
if(panel->sortorder != 0) {
|
||||
if(!(panel->runtime_flag & PNL_FIRST)) {
|
||||
float minx= rect->xmin+5.0f/block->aspect;
|
||||
float maxx= rect->xmax-5.0f/block->aspect;
|
||||
float y= headrect.ymax;
|
||||
@@ -848,7 +842,7 @@ void uiEndPanels(const bContext *C, ARegion *ar)
|
||||
{
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
uiBlock *block;
|
||||
Panel *panot, *panew, *patest, *pa;
|
||||
Panel *panot, *panew, *patest, *pa, *firstpa;
|
||||
|
||||
/* offset contents */
|
||||
for(block= ar->uiblocks.first; block; block= block->next)
|
||||
@@ -888,6 +882,16 @@ void uiEndPanels(const bContext *C, ARegion *ar)
|
||||
uiAlignPanelStep(sa, ar, 1.0, 0);
|
||||
}
|
||||
|
||||
/* tag first panel */
|
||||
firstpa= NULL;
|
||||
for(block= ar->uiblocks.first; block; block=block->next)
|
||||
if(block->active && block->panel)
|
||||
if(!firstpa || block->panel->sortorder < firstpa->sortorder)
|
||||
firstpa= block->panel;
|
||||
|
||||
if(firstpa)
|
||||
firstpa->runtime_flag |= PNL_FIRST;
|
||||
|
||||
/* draw panels, selected on top */
|
||||
for(block= ar->uiblocks.first; block; block=block->next) {
|
||||
if(block->active && block->panel && !(block->panel->flag & PNL_SELECT)) {
|
||||
|
||||
@@ -1876,7 +1876,9 @@ static void widget_disabled(rcti *rect)
|
||||
/* can't use theme TH_BACK or TH_PANEL... undefined */
|
||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, col);
|
||||
glColor4f(col[0], col[1], col[2], 0.5f);
|
||||
glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
|
||||
/* need -1 and +1 to make it work right for aligned buttons,
|
||||
* but problem may be somewhere else? */
|
||||
glRectf(rect->xmin-1, rect->ymin, rect->xmax, rect->ymax+1);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,15 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
|
||||
Scene *scene= sc->scene;
|
||||
Base *base;
|
||||
|
||||
if(CTX_data_equals(member, "scene")) {
|
||||
if(CTX_data_dir(member)) {
|
||||
static const char *dir[] = {
|
||||
"scene", "selected_objects", "selected_bases", "active_base",
|
||||
"active_object", "edit_object", NULL};
|
||||
|
||||
CTX_data_dir_set(result, dir);
|
||||
return 1;
|
||||
}
|
||||
else if(CTX_data_equals(member, "scene")) {
|
||||
CTX_data_id_pointer_set(result, &scene->id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -234,6 +234,9 @@ static char brush_size(Sculpt *sd)
|
||||
special multiplier found experimentally to scale the strength factor. */
|
||||
static float brush_strength(Sculpt *sd, StrokeCache *cache)
|
||||
{
|
||||
/* Primary strength input; square it to make lower values more sensitive */
|
||||
float alpha = sd->brush->alpha * sd->brush->alpha;
|
||||
|
||||
float dir= sd->brush->flag & BRUSH_DIR_IN ? -1 : 1;
|
||||
float pressure= 1;
|
||||
float flip= cache->flip ? -1:1;
|
||||
@@ -244,18 +247,17 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache)
|
||||
|
||||
switch(sd->brush->sculpt_tool){
|
||||
case SCULPT_TOOL_DRAW:
|
||||
case SCULPT_TOOL_LAYER:
|
||||
return sd->brush->alpha / 50.0f * dir * pressure * flip * anchored; /*XXX: not sure why? multiplied by G.vd->grid */;
|
||||
case SCULPT_TOOL_INFLATE:
|
||||
return alpha * dir * pressure * flip; /*XXX: not sure why? was multiplied by G.vd->grid */;
|
||||
case SCULPT_TOOL_FLATTEN:
|
||||
case SCULPT_TOOL_SMOOTH:
|
||||
return sd->brush->alpha / .5 * pressure * anchored;
|
||||
return alpha * 4 * pressure;
|
||||
case SCULPT_TOOL_PINCH:
|
||||
return sd->brush->alpha / 10.0f * dir * pressure * flip * anchored;
|
||||
return alpha / 2 * dir * pressure * flip;
|
||||
case SCULPT_TOOL_GRAB:
|
||||
return 1;
|
||||
case SCULPT_TOOL_INFLATE:
|
||||
return sd->brush->alpha / 50.0f * dir * pressure * flip * anchored;
|
||||
case SCULPT_TOOL_FLATTEN:
|
||||
return sd->brush->alpha / 5.0f * pressure * anchored;
|
||||
case SCULPT_TOOL_LAYER:
|
||||
return sd->brush->alpha / 50.0f * dir * pressure * flip * anchored; /*XXX: not sure why? multiplied by G.vd->grid */;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -354,10 +356,10 @@ static void do_draw_brush(Sculpt *sd, SculptSession *ss, const ListBase* active_
|
||||
|
||||
while(node){
|
||||
float *co= ss->mvert[node->Index].co;
|
||||
|
||||
const float val[3]= {co[0]+area_normal[0]*node->Fade*ss->cache->scale[0],
|
||||
co[1]+area_normal[1]*node->Fade*ss->cache->scale[1],
|
||||
co[2]+area_normal[2]*node->Fade*ss->cache->scale[2]};
|
||||
|
||||
const float val[3]= {co[0]+area_normal[0]*ss->cache->radius*node->Fade*ss->cache->scale[0],
|
||||
co[1]+area_normal[1]*ss->cache->radius*node->Fade*ss->cache->scale[1],
|
||||
co[2]+area_normal[2]*ss->cache->radius*node->Fade*ss->cache->scale[2]};
|
||||
|
||||
sculpt_clip(ss->cache, co, val);
|
||||
|
||||
@@ -412,18 +414,21 @@ static void neighbor_average(SculptSession *ss, float avg[3], const int vert)
|
||||
static void do_smooth_brush(SculptSession *ss, const ListBase* active_verts)
|
||||
{
|
||||
ActiveData *node= active_verts->first;
|
||||
|
||||
while(node){
|
||||
float *co= ss->mvert[node->Index].co;
|
||||
float avg[3], val[3];
|
||||
|
||||
neighbor_average(ss, avg, node->Index);
|
||||
val[0] = co[0]+(avg[0]-co[0])*node->Fade;
|
||||
val[1] = co[1]+(avg[1]-co[1])*node->Fade;
|
||||
val[2] = co[2]+(avg[2]-co[2])*node->Fade;
|
||||
|
||||
sculpt_clip(ss->cache, co, val);
|
||||
node= node->next;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 2; ++i) {
|
||||
while(node){
|
||||
float *co= ss->mvert[node->Index].co;
|
||||
float avg[3], val[3];
|
||||
|
||||
neighbor_average(ss, avg, node->Index);
|
||||
val[0] = co[0]+(avg[0]-co[0])*node->Fade;
|
||||
val[1] = co[1]+(avg[1]-co[1])*node->Fade;
|
||||
val[2] = co[2]+(avg[2]-co[2])*node->Fade;
|
||||
|
||||
sculpt_clip(ss->cache, co, val);
|
||||
node= node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,33 +472,33 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active
|
||||
{
|
||||
float area_normal[3];
|
||||
ActiveData *node= active_verts->first;
|
||||
const float bstr= brush_strength(sd, ss->cache);
|
||||
float lim= brush_strength(sd, ss->cache);
|
||||
|
||||
if(sd->brush->flag & BRUSH_DIR_IN)
|
||||
lim = -lim;
|
||||
|
||||
calc_area_normal(sd, area_normal, active_verts);
|
||||
|
||||
while(node){
|
||||
float *disp= &ss->cache->layer_disps[node->Index];
|
||||
|
||||
if((bstr > 0 && *disp < bstr) ||
|
||||
(bstr < 0 && *disp > bstr)) {
|
||||
if((lim > 0 && *disp < lim) ||
|
||||
(lim < 0 && *disp > lim)) {
|
||||
float *co= ss->mvert[node->Index].co;
|
||||
float val[3];
|
||||
|
||||
*disp+= node->Fade;
|
||||
|
||||
if(bstr < 0) {
|
||||
if(*disp < bstr)
|
||||
*disp = bstr;
|
||||
} else {
|
||||
if(*disp > bstr)
|
||||
*disp = bstr;
|
||||
}
|
||||
if(lim < 0 && *disp < lim)
|
||||
*disp = lim;
|
||||
else if(lim > 0 && *disp > lim)
|
||||
*disp = lim;
|
||||
|
||||
{
|
||||
const float val[3]= {ss->cache->mesh_store[node->Index][0]+area_normal[0] * *disp*ss->cache->scale[0],
|
||||
ss->cache->mesh_store[node->Index][1]+area_normal[1] * *disp*ss->cache->scale[1],
|
||||
ss->cache->mesh_store[node->Index][2]+area_normal[2] * *disp*ss->cache->scale[2]};
|
||||
sculpt_clip(ss->cache, co, val);
|
||||
}
|
||||
val[0] = ss->cache->mesh_store[node->Index][0]+area_normal[0] * *disp*ss->cache->scale[0];
|
||||
val[1] = ss->cache->mesh_store[node->Index][1]+area_normal[1] * *disp*ss->cache->scale[1];
|
||||
val[2] = ss->cache->mesh_store[node->Index][2]+area_normal[2] * *disp*ss->cache->scale[2];
|
||||
//VecMulf(val, ss->cache->radius);
|
||||
sculpt_clip(ss->cache, co, val);
|
||||
}
|
||||
|
||||
node= node->next;
|
||||
@@ -512,7 +517,7 @@ static void do_inflate_brush(SculptSession *ss, const ListBase *active_verts)
|
||||
add[0]= no[0]/ 32767.0f;
|
||||
add[1]= no[1]/ 32767.0f;
|
||||
add[2]= no[2]/ 32767.0f;
|
||||
VecMulf(add, node->Fade);
|
||||
VecMulf(add, node->Fade * ss->cache->radius);
|
||||
add[0]*= ss->cache->scale[0];
|
||||
add[1]*= ss->cache->scale[1];
|
||||
add[2]*= ss->cache->scale[2];
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "ED_armature.h"
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
@@ -249,16 +250,29 @@ static int buttons_context_path_bone(ButsContextPath *path)
|
||||
{
|
||||
bArmature *arm;
|
||||
Bone *bone;
|
||||
EditBone *edbo;
|
||||
|
||||
/* if we have an armature, get the active bone */
|
||||
if(buttons_context_path_data(path, OB_ARMATURE)) {
|
||||
arm= path->ptr[path->len-1].data;
|
||||
bone= find_active_bone(arm->bonebase.first);
|
||||
|
||||
if(bone) {
|
||||
RNA_pointer_create(&arm->id, &RNA_Bone, bone, &path->ptr[path->len]);
|
||||
path->len++;
|
||||
return 1;
|
||||
if(arm->edbo) {
|
||||
for(edbo=arm->edbo->first; edbo; edbo=edbo->next) {
|
||||
if(edbo->flag & BONE_ACTIVE) {
|
||||
RNA_pointer_create(&arm->id, &RNA_EditBone, edbo, &path->ptr[path->len]);
|
||||
path->len++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
bone= find_active_bone(arm->bonebase.first);
|
||||
|
||||
if(bone) {
|
||||
RNA_pointer_create(&arm->id, &RNA_Bone, bone, &path->ptr[path->len]);
|
||||
path->len++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,8 +492,17 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
|
||||
return 0;
|
||||
|
||||
/* here we handle context, getting data from precomputed path */
|
||||
if(CTX_data_dir(member)) {
|
||||
static const char *dir[] = {
|
||||
"world", "object", "meshe", "armature", "lattice", "curve",
|
||||
"meta_ball", "lamp", "camera", "material", "material_slot",
|
||||
"texture", "texture_slot", "bone", "edit_bone", "particle_system",
|
||||
"cloth", "soft_body", "fluid", NULL};
|
||||
|
||||
if(CTX_data_equals(member, "world")) {
|
||||
CTX_data_dir_set(result, dir);
|
||||
return 1;
|
||||
}
|
||||
else if(CTX_data_equals(member, "world")) {
|
||||
set_pointer_type(path, result, &RNA_World);
|
||||
return 1;
|
||||
}
|
||||
@@ -569,6 +592,10 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
|
||||
set_pointer_type(path, result, &RNA_Bone);
|
||||
return 1;
|
||||
}
|
||||
else if(CTX_data_equals(member, "edit_bone")) {
|
||||
set_pointer_type(path, result, &RNA_EditBone);
|
||||
return 1;
|
||||
}
|
||||
else if(CTX_data_equals(member, "particle_system")) {
|
||||
set_pointer_type(path, result, &RNA_ParticleSystem);
|
||||
return 1;
|
||||
|
||||
@@ -301,7 +301,11 @@ static int image_context(const bContext *C, const char *member, bContextDataResu
|
||||
{
|
||||
SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
|
||||
|
||||
if(CTX_data_equals(member, "edit_image")) {
|
||||
if(CTX_data_dir(member)) {
|
||||
static const char *dir[] = {"edit_image", NULL};
|
||||
CTX_data_dir_set(result, dir);
|
||||
}
|
||||
else if(CTX_data_equals(member, "edit_image")) {
|
||||
CTX_data_id_pointer_set(result, (ID*)ED_space_image(sima));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -283,7 +283,12 @@ static int node_context(const bContext *C, const char *member, bContextDataResul
|
||||
{
|
||||
SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C);
|
||||
|
||||
if(CTX_data_equals(member, "selected_nodes")) {
|
||||
if(CTX_data_dir(member)) {
|
||||
static const char *dir[] = {"selected_nodes", NULL};
|
||||
CTX_data_dir_set(result, dir);
|
||||
return 1;
|
||||
}
|
||||
else if(CTX_data_equals(member, "selected_nodes")) {
|
||||
bNode *node;
|
||||
|
||||
for(next_node(snode->edittree); (node=next_node(NULL));) {
|
||||
|
||||
@@ -293,7 +293,12 @@ static int text_context(const bContext *C, const char *member, bContextDataResul
|
||||
{
|
||||
SpaceText *st= CTX_wm_space_text(C);
|
||||
|
||||
if(CTX_data_equals(member, "edit_text")) {
|
||||
if(CTX_data_dir(member)) {
|
||||
static const char *dir[] = {"edit_text", NULL};
|
||||
CTX_data_dir_set(result, dir);
|
||||
return 1;
|
||||
}
|
||||
else if(CTX_data_equals(member, "edit_text")) {
|
||||
CTX_data_id_pointer_set(result, &st->text->id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -565,7 +565,17 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
|
||||
|
||||
if(v3d==NULL) return 0;
|
||||
|
||||
if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
|
||||
if(CTX_data_dir(member)) {
|
||||
static const char *dir[] = {
|
||||
"selected_objects", "selected_bases" "selected_editable_objects",
|
||||
"selected_editable_bases" "visible_objects", "visible_bases",
|
||||
"active_base", "active_object", "visible_bones", "editable_bones",
|
||||
"selected_bones", "selected_editable_bones" "visible_pchans",
|
||||
"selected_pchans", "active_bone", "active_pchan", NULL};
|
||||
|
||||
CTX_data_dir_set(result, dir);
|
||||
}
|
||||
else if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
|
||||
int selected_objects= CTX_data_equals(member, "selected_objects");
|
||||
|
||||
for(base=scene->base.first; base; base=base->next) {
|
||||
|
||||
@@ -164,6 +164,7 @@ extern StructRNA RNA_DomainFluidSettings;
|
||||
extern StructRNA RNA_Driver;
|
||||
extern StructRNA RNA_DriverTarget;
|
||||
extern StructRNA RNA_EdgeSplitModifier;
|
||||
extern StructRNA RNA_EditBone;
|
||||
extern StructRNA RNA_EffectSequence;
|
||||
extern StructRNA RNA_EnumProperty;
|
||||
extern StructRNA RNA_EnumPropertyItem;
|
||||
|
||||
@@ -42,6 +42,8 @@ extern "C" {
|
||||
BlenderRNA *RNA_create(void);
|
||||
void RNA_define_free(BlenderRNA *brna);
|
||||
void RNA_free(BlenderRNA *brna);
|
||||
|
||||
void RNA_init(void);
|
||||
void RNA_exit(void);
|
||||
|
||||
/* Struct */
|
||||
|
||||
@@ -702,8 +702,10 @@ static char *rna_def_property_begin_func(FILE *f, StructRNA *srna, PropertyRNA *
|
||||
else {
|
||||
if(manualfunc)
|
||||
fprintf(f, "\n %s(iter, ptr);\n", manualfunc);
|
||||
else
|
||||
else if(dp->dnapointerlevel == 0)
|
||||
fprintf(f, "\n rna_iterator_listbase_begin(iter, &data->%s, NULL);\n", dp->dnaname);
|
||||
else
|
||||
fprintf(f, "\n rna_iterator_listbase_begin(iter, data->%s, NULL);\n", dp->dnaname);
|
||||
}
|
||||
|
||||
getfunc= rna_alloc_function_name(srna->identifier, prop->identifier, "get");
|
||||
@@ -1486,8 +1488,8 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
|
||||
if(nest != NULL) {
|
||||
len= strlen(nest);
|
||||
|
||||
strnest= MEM_mallocN(sizeof(char)*(len+1), "rna_generate_property -> strnest");
|
||||
errnest= MEM_mallocN(sizeof(char)*(len+1), "rna_generate_property -> errnest");
|
||||
strnest= MEM_mallocN(sizeof(char)*(len+2), "rna_generate_property -> strnest");
|
||||
errnest= MEM_mallocN(sizeof(char)*(len+2), "rna_generate_property -> errnest");
|
||||
|
||||
strcpy(strnest, "_"); strcat(strnest, nest);
|
||||
strcpy(errnest, "."); strcat(errnest, nest);
|
||||
@@ -1711,6 +1713,8 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
|
||||
if(func->cont.prev) fprintf(f, "(FunctionRNA*)&rna_%s_%s_func,\n", srna->identifier, ((FunctionRNA*)func->cont.prev)->identifier);
|
||||
else fprintf(f, "NULL,\n");
|
||||
|
||||
fprintf(f, "\tNULL,\n");
|
||||
|
||||
parm= func->cont.properties.first;
|
||||
if(parm) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s_%s, ", srna->identifier, func->identifier, parm->identifier);
|
||||
else fprintf(f, "\t{NULL, ");
|
||||
@@ -1742,6 +1746,8 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
|
||||
if(srna->cont.prev) fprintf(f, "(ContainerRNA *)&RNA_%s,\n", ((StructRNA*)srna->cont.prev)->identifier);
|
||||
else fprintf(f, "NULL,\n");
|
||||
|
||||
fprintf(f, "\tNULL,\n");
|
||||
|
||||
prop= srna->cont.properties.first;
|
||||
if(prop) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s, ", srna->identifier, prop->identifier);
|
||||
else fprintf(f, "\t{NULL, ");
|
||||
|
||||
@@ -218,7 +218,6 @@ static void rna_def_ID(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
FunctionRNA *func;
|
||||
|
||||
srna= RNA_def_struct(brna, "ID", NULL);
|
||||
RNA_def_struct_ui_text(srna, "ID", "Base type for datablocks, defining a unique name, linking from other libraries and garbage collection.");
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_dynstr.h"
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_idprop.h"
|
||||
@@ -46,10 +47,35 @@
|
||||
|
||||
#include "rna_internal.h"
|
||||
|
||||
/* Exit */
|
||||
/* Init/Exit */
|
||||
|
||||
void RNA_init()
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
|
||||
if(!srna->cont.prophash) {
|
||||
srna->cont.prophash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
|
||||
|
||||
for(prop=srna->cont.properties.first; prop; prop=prop->next)
|
||||
if(!(prop->flag & PROP_BUILTIN))
|
||||
BLI_ghash_insert(srna->cont.prophash, (void*)prop->identifier, prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RNA_exit()
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
|
||||
if(srna->cont.prophash) {
|
||||
BLI_ghash_free(srna->cont.prophash, NULL, NULL);
|
||||
srna->cont.prophash= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
RNA_free(&BLENDER_RNA);
|
||||
}
|
||||
|
||||
@@ -388,24 +414,13 @@ int RNA_struct_is_a(StructRNA *type, StructRNA *srna)
|
||||
|
||||
PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
|
||||
{
|
||||
CollectionPropertyIterator iter;
|
||||
PropertyRNA *iterprop, *prop;
|
||||
int i = 0;
|
||||
PropertyRNA *iterprop= RNA_struct_iterator_property(ptr->type);
|
||||
PointerRNA propptr;
|
||||
|
||||
iterprop= RNA_struct_iterator_property(ptr->type);
|
||||
RNA_property_collection_begin(ptr, iterprop, &iter);
|
||||
prop= NULL;
|
||||
|
||||
for(; iter.valid; RNA_property_collection_next(&iter), i++) {
|
||||
if(strcmp(identifier, RNA_property_identifier(iter.ptr.data)) == 0) {
|
||||
prop= iter.ptr.data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RNA_property_collection_end(&iter);
|
||||
|
||||
return prop;
|
||||
if(RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr))
|
||||
return propptr.data;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the property which uses the given nested struct */
|
||||
@@ -1500,7 +1515,7 @@ void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb,
|
||||
ListBaseIterator *internal;
|
||||
|
||||
internal= MEM_callocN(sizeof(ListBaseIterator), "ListBaseIterator");
|
||||
internal->link= lb->first;
|
||||
internal->link= (lb)? lb->first: NULL;
|
||||
internal->skip= skip;
|
||||
|
||||
iter->internal= internal;
|
||||
@@ -1643,12 +1658,18 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int
|
||||
buf= MEM_callocN(sizeof(char)*(len+1), "rna_path_token");
|
||||
|
||||
/* copy string, taking into account escaped ] */
|
||||
for(p=*path, i=0, j=0; i<len; i++, p++) {
|
||||
if(*p == '\\' && *(p+1) == ']');
|
||||
else buf[j++]= *p;
|
||||
}
|
||||
if(bracket) {
|
||||
for(p=*path, i=0, j=0; i<len; i++, p++) {
|
||||
if(*p == '\\' && *(p+1) == ']');
|
||||
else buf[j++]= *p;
|
||||
}
|
||||
|
||||
buf[j]= 0;
|
||||
buf[j]= 0;
|
||||
}
|
||||
else {
|
||||
memcpy(buf, *path, sizeof(char)*len);
|
||||
buf[len]= '\0';
|
||||
}
|
||||
|
||||
/* set path to start of next token */
|
||||
if(*p == ']') p++;
|
||||
@@ -1660,8 +1681,7 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int
|
||||
|
||||
int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
|
||||
{
|
||||
CollectionPropertyIterator iter;
|
||||
PropertyRNA *prop, *iterprop;
|
||||
PropertyRNA *prop;
|
||||
PointerRNA curptr, nextptr;
|
||||
char fixedbuf[256], *token;
|
||||
int len, intkey;
|
||||
@@ -1676,18 +1696,7 @@ int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, Prope
|
||||
if(!token)
|
||||
return 0;
|
||||
|
||||
iterprop= RNA_struct_iterator_property(curptr.type);
|
||||
RNA_property_collection_begin(&curptr, iterprop, &iter);
|
||||
prop= NULL;
|
||||
|
||||
for(; iter.valid; RNA_property_collection_next(&iter)) {
|
||||
if(strcmp(token, RNA_property_identifier(iter.ptr.data)) == 0) {
|
||||
prop= iter.ptr.data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RNA_property_collection_end(&iter);
|
||||
prop= RNA_struct_find_property(&curptr, token);
|
||||
|
||||
if(token != fixedbuf)
|
||||
MEM_freeN(token);
|
||||
|
||||
@@ -36,25 +36,32 @@
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
static void rna_Bone_layer_set(PointerRNA *ptr, const int *values)
|
||||
#include "ED_armature.h"
|
||||
|
||||
static void rna_bone_layer_set(short *layer, const int *values)
|
||||
{
|
||||
Bone *bone= (Bone*)ptr->data;
|
||||
int i, tot= 0;
|
||||
|
||||
/* ensure we always have some layer selected */
|
||||
for(i=0; i<20; i++)
|
||||
for(i=0; i<16; i++)
|
||||
if(values[i])
|
||||
tot++;
|
||||
|
||||
if(tot==0)
|
||||
return;
|
||||
|
||||
for(i=0; i<20; i++) {
|
||||
if(values[i]) bone->layer |= (1<<i);
|
||||
else bone->layer &= ~(1<<i);
|
||||
for(i=0; i<16; i++) {
|
||||
if(values[i]) *layer |= (1<<i);
|
||||
else *layer &= ~(1<<i);
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_Bone_layer_set(PointerRNA *ptr, const int *values)
|
||||
{
|
||||
Bone *bone= (Bone*)ptr->data;
|
||||
rna_bone_layer_set(&bone->layer, values);
|
||||
}
|
||||
|
||||
static void rna_Armature_layer_set(PointerRNA *ptr, const int *values)
|
||||
{
|
||||
bArmature *arm= (bArmature*)ptr->data;
|
||||
@@ -102,8 +109,449 @@ static void rna_Armature_path_end_frame_set(PointerRNA *ptr, int value)
|
||||
data->pathef= value;
|
||||
}
|
||||
|
||||
PointerRNA rna_EditBone_rna_type_get(PointerRNA *ptr)
|
||||
{
|
||||
return rna_builtin_type_get(ptr);
|
||||
}
|
||||
|
||||
void rna_EditBone_name_get(PointerRNA *ptr, char *value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
BLI_strncpy(value, data->name, sizeof(data->name));
|
||||
}
|
||||
|
||||
int rna_EditBone_name_length(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return strlen(data->name);
|
||||
}
|
||||
|
||||
int rna_EditBone_active_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (((data->flag) & BONE_ACTIVE) != 0);
|
||||
}
|
||||
|
||||
void rna_EditBone_active_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
if(value) data->flag |= BONE_ACTIVE;
|
||||
else data->flag &= ~BONE_ACTIVE;
|
||||
}
|
||||
|
||||
float rna_EditBone_bbone_in_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (float)(data->ease1);
|
||||
}
|
||||
|
||||
void rna_EditBone_bbone_in_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
data->ease1= CLAMPIS(value, 0.0f, 2.0f);
|
||||
}
|
||||
|
||||
float rna_EditBone_bbone_out_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (float)(data->ease2);
|
||||
}
|
||||
|
||||
void rna_EditBone_bbone_out_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
data->ease2= CLAMPIS(value, 0.0f, 2.0f);
|
||||
}
|
||||
|
||||
int rna_EditBone_bbone_segments_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (int)(data->segments);
|
||||
}
|
||||
|
||||
void rna_EditBone_bbone_segments_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
data->segments= CLAMPIS(value, 1, 32);
|
||||
}
|
||||
|
||||
void rna_EditBone_layer_get(PointerRNA *ptr, int values[16])
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
values[0]= ((data->layer & (1<<0)) != 0);
|
||||
values[1]= ((data->layer & (1<<1)) != 0);
|
||||
values[2]= ((data->layer & (1<<2)) != 0);
|
||||
values[3]= ((data->layer & (1<<3)) != 0);
|
||||
values[4]= ((data->layer & (1<<4)) != 0);
|
||||
values[5]= ((data->layer & (1<<5)) != 0);
|
||||
values[6]= ((data->layer & (1<<6)) != 0);
|
||||
values[7]= ((data->layer & (1<<7)) != 0);
|
||||
values[8]= ((data->layer & (1<<8)) != 0);
|
||||
values[9]= ((data->layer & (1<<9)) != 0);
|
||||
values[10]= ((data->layer & (1<<10)) != 0);
|
||||
values[11]= ((data->layer & (1<<11)) != 0);
|
||||
values[12]= ((data->layer & (1<<12)) != 0);
|
||||
values[13]= ((data->layer & (1<<13)) != 0);
|
||||
values[14]= ((data->layer & (1<<14)) != 0);
|
||||
values[15]= ((data->layer & (1<<15)) != 0);
|
||||
}
|
||||
|
||||
void rna_EditBone_layer_set(PointerRNA *ptr, const int values[16])
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
rna_bone_layer_set(&data->layer, values);
|
||||
}
|
||||
|
||||
int rna_EditBone_connected_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (((data->flag) & BONE_CONNECTED) != 0);
|
||||
}
|
||||
|
||||
void rna_EditBone_connected_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
if(value) data->flag |= BONE_CONNECTED;
|
||||
else data->flag &= ~BONE_CONNECTED;
|
||||
}
|
||||
|
||||
int rna_EditBone_cyclic_offset_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (!((data->flag) & BONE_NO_CYCLICOFFSET) != 0);
|
||||
}
|
||||
|
||||
void rna_EditBone_cyclic_offset_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
if(!value) data->flag |= BONE_NO_CYCLICOFFSET;
|
||||
else data->flag &= ~BONE_NO_CYCLICOFFSET;
|
||||
}
|
||||
|
||||
int rna_EditBone_deform_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (!((data->flag) & BONE_NO_DEFORM) != 0);
|
||||
}
|
||||
|
||||
void rna_EditBone_deform_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
if(!value) data->flag |= BONE_NO_DEFORM;
|
||||
else data->flag &= ~BONE_NO_DEFORM;
|
||||
}
|
||||
|
||||
int rna_EditBone_draw_wire_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (((data->flag) & BONE_DRAWWIRE) != 0);
|
||||
}
|
||||
|
||||
void rna_EditBone_draw_wire_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
if(value) data->flag |= BONE_DRAWWIRE;
|
||||
else data->flag &= ~BONE_DRAWWIRE;
|
||||
}
|
||||
|
||||
float rna_EditBone_envelope_distance_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (float)(data->dist);
|
||||
}
|
||||
|
||||
void rna_EditBone_envelope_distance_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
data->dist= CLAMPIS(value, 0.0f, 1000.0f);
|
||||
}
|
||||
|
||||
float rna_EditBone_envelope_weight_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (float)(data->weight);
|
||||
}
|
||||
|
||||
void rna_EditBone_envelope_weight_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
data->weight= CLAMPIS(value, 0.0f, 1000.0f);
|
||||
}
|
||||
|
||||
float rna_EditBone_radius_head_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (float)(data->rad_head);
|
||||
}
|
||||
|
||||
void rna_EditBone_radius_head_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
data->rad_head= value;
|
||||
}
|
||||
|
||||
float rna_EditBone_radius_tail_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (float)(data->rad_tail);
|
||||
}
|
||||
|
||||
void rna_EditBone_radius_tail_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
data->rad_tail= value;
|
||||
}
|
||||
|
||||
void rna_EditBone_head_get(PointerRNA *ptr, float values[3])
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
values[0]= (float)(((float*)data->head)[0]);
|
||||
values[1]= (float)(((float*)data->head)[1]);
|
||||
values[2]= (float)(((float*)data->head)[2]);
|
||||
}
|
||||
|
||||
void rna_EditBone_head_set(PointerRNA *ptr, const float values[3])
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
((float*)data->head)[0]= values[0];
|
||||
((float*)data->head)[1]= values[1];
|
||||
((float*)data->head)[2]= values[2];
|
||||
}
|
||||
|
||||
int rna_EditBone_head_selected_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (((data->flag) & BONE_ROOTSEL) != 0);
|
||||
}
|
||||
|
||||
void rna_EditBone_head_selected_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
if(value) data->flag |= BONE_ROOTSEL;
|
||||
else data->flag &= ~BONE_ROOTSEL;
|
||||
}
|
||||
|
||||
int rna_EditBone_hidden_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (((data->flag) & BONE_HIDDEN_A) != 0);
|
||||
}
|
||||
|
||||
void rna_EditBone_hidden_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
if(value) data->flag |= BONE_HIDDEN_A;
|
||||
else data->flag &= ~BONE_HIDDEN_A;
|
||||
}
|
||||
|
||||
int rna_EditBone_hinge_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (!((data->flag) & BONE_HINGE) != 0);
|
||||
}
|
||||
|
||||
void rna_EditBone_hinge_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
if(!value) data->flag |= BONE_HINGE;
|
||||
else data->flag &= ~BONE_HINGE;
|
||||
}
|
||||
|
||||
int rna_EditBone_inherit_scale_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (!((data->flag) & BONE_NO_SCALE) != 0);
|
||||
}
|
||||
|
||||
void rna_EditBone_inherit_scale_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
if(!value) data->flag |= BONE_NO_SCALE;
|
||||
else data->flag &= ~BONE_NO_SCALE;
|
||||
}
|
||||
|
||||
int rna_EditBone_locked_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (((data->flag) & BONE_EDITMODE_LOCKED) != 0);
|
||||
}
|
||||
|
||||
void rna_EditBone_locked_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
if(value) data->flag |= BONE_EDITMODE_LOCKED;
|
||||
else data->flag &= ~BONE_EDITMODE_LOCKED;
|
||||
}
|
||||
|
||||
int rna_EditBone_multiply_vertexgroup_with_envelope_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (((data->flag) & BONE_MULT_VG_ENV) != 0);
|
||||
}
|
||||
|
||||
void rna_EditBone_multiply_vertexgroup_with_envelope_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
if(value) data->flag |= BONE_MULT_VG_ENV;
|
||||
else data->flag &= ~BONE_MULT_VG_ENV;
|
||||
}
|
||||
|
||||
PointerRNA rna_EditBone_parent_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_EditBone, data->parent);
|
||||
}
|
||||
|
||||
float rna_EditBone_roll_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (float)(data->roll);
|
||||
}
|
||||
|
||||
void rna_EditBone_roll_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
data->roll= value;
|
||||
}
|
||||
|
||||
void rna_EditBone_tail_get(PointerRNA *ptr, float values[3])
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
values[0]= (float)(((float*)data->tail)[0]);
|
||||
values[1]= (float)(((float*)data->tail)[1]);
|
||||
values[2]= (float)(((float*)data->tail)[2]);
|
||||
}
|
||||
|
||||
void rna_EditBone_tail_set(PointerRNA *ptr, const float values[3])
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
((float*)data->tail)[0]= values[0];
|
||||
((float*)data->tail)[1]= values[1];
|
||||
((float*)data->tail)[2]= values[2];
|
||||
}
|
||||
|
||||
int rna_EditBone_tail_selected_get(PointerRNA *ptr)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
return (((data->flag) & BONE_TIPSEL) != 0);
|
||||
}
|
||||
|
||||
void rna_EditBone_tail_selected_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
EditBone *data= (EditBone*)(ptr->data);
|
||||
if(value) data->flag |= BONE_TIPSEL;
|
||||
else data->flag &= ~BONE_TIPSEL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void rna_def_bone_common(StructRNA *srna, int editbone)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* strings */
|
||||
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* must be unique */
|
||||
RNA_def_property_ui_text(prop, "Name", "");
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
if(editbone) RNA_def_property_string_funcs(prop, "rna_EditBone_name_get", "rna_EditBone_name_length", "rna_EditBone_name_set");
|
||||
|
||||
/* flags */
|
||||
prop= RNA_def_property(srna, "layer", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_array(prop, 16);
|
||||
RNA_def_property_ui_text(prop, "Bone Layers", "Layers bone exists in");
|
||||
if(editbone) RNA_def_property_boolean_funcs(prop, "rna_EditBone_layer_get", "rna_EditBone_layer_set");
|
||||
else {
|
||||
RNA_def_property_boolean_funcs(prop, NULL, "rna_Bone_layer_set");
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "layer", 1);
|
||||
}
|
||||
|
||||
prop= RNA_def_property(srna, "connected", PROP_BOOLEAN, PROP_NONE);
|
||||
if(editbone) RNA_def_property_boolean_funcs(prop, "rna_EditBone_connected_get", "rna_EditBone_connected_set");
|
||||
else RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_CONNECTED);
|
||||
RNA_def_property_ui_text(prop, "Connected", "When bone has a parent, bone's head is struck to the parent's tail.");
|
||||
|
||||
prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
|
||||
if(editbone) RNA_def_property_boolean_funcs(prop, "rna_EditBone_active_get", "rna_EditBone_active_set");
|
||||
else RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_ACTIVE);
|
||||
RNA_def_property_ui_text(prop, "Active", "Bone was the last bone clicked on (most operations are applied to only this bone)");
|
||||
|
||||
prop= RNA_def_property(srna, "hinge", PROP_BOOLEAN, PROP_NONE);
|
||||
if(editbone) RNA_def_property_boolean_funcs(prop, "rna_EditBone_hinge_get", "rna_EditBone_hinge_set");
|
||||
else RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_HINGE);
|
||||
RNA_def_property_ui_text(prop, "Inherit Rotation", "Bone doesn't inherit rotation or scale from parent bone.");
|
||||
|
||||
prop= RNA_def_property(srna, "multiply_vertexgroup_with_envelope", PROP_BOOLEAN, PROP_NONE);
|
||||
if(editbone) RNA_def_property_boolean_funcs(prop, "rna_EditBone_multiply_vertexgroup_with_envelope_get", "rna_EditBone_multiply_vertexgroup_with_envelope_set");
|
||||
else RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_MULT_VG_ENV);
|
||||
RNA_def_property_ui_text(prop, "Multiply Vertex Group with Envelope", "When deforming bone, multiply effects of Vertex Group weights with Envelope influence.");
|
||||
|
||||
prop= RNA_def_property(srna, "deform", PROP_BOOLEAN, PROP_NONE);
|
||||
if(editbone) RNA_def_property_boolean_funcs(prop, "rna_EditBone_deform_get", "rna_EditBone_deform_set");
|
||||
else RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_DEFORM);
|
||||
RNA_def_property_ui_text(prop, "Deform", "Bone does not deform any geometry.");
|
||||
|
||||
prop= RNA_def_property(srna, "inherit_scale", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Inherit Scale", "Bone inherits scaling from parent bone.");
|
||||
if(editbone) RNA_def_property_boolean_funcs(prop, "rna_EditBone_inherit_scale_get", "rna_EditBone_inherit_scale_set");
|
||||
else RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_SCALE);
|
||||
|
||||
prop= RNA_def_property(srna, "draw_wire", PROP_BOOLEAN, PROP_NONE);
|
||||
if(editbone) RNA_def_property_boolean_funcs(prop, "rna_EditBone_draw_wire_get", "rna_EditBone_draw_wire_set");
|
||||
else RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_DRAWWIRE);
|
||||
RNA_def_property_ui_text(prop, "Draw Wire", "Bone is always drawn as Wireframe regardless of viewport draw mode. Useful for non-obstructive custom bone shapes.");
|
||||
|
||||
prop= RNA_def_property(srna, "cyclic_offset", PROP_BOOLEAN, PROP_NONE);
|
||||
if(editbone) RNA_def_property_boolean_funcs(prop, "rna_EditBone_cyclic_offset_get", "rna_EditBone_cyclic_offset_set");
|
||||
else RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_CYCLICOFFSET);
|
||||
RNA_def_property_ui_text(prop, "Cyclic Offset", "When bone doesn't have a parent, it receives cyclic offset effects.");
|
||||
|
||||
/* Number values */
|
||||
/* envelope deform settings */
|
||||
prop= RNA_def_property(srna, "envelope_distance", PROP_FLOAT, PROP_NONE);
|
||||
if(editbone) RNA_def_property_float_funcs(prop, "rna_EditBone_envelope_distance_get", "rna_EditBone_envelope_distance_set", NULL);
|
||||
else RNA_def_property_float_sdna(prop, NULL, "dist");
|
||||
RNA_def_property_range(prop, 0.0f, 1000.0f);
|
||||
RNA_def_property_ui_text(prop, "Envelope Deform Distance", "Bone deformation distance (for Envelope deform only).");
|
||||
|
||||
prop= RNA_def_property(srna, "envelope_weight", PROP_FLOAT, PROP_NONE);
|
||||
if(editbone) RNA_def_property_float_funcs(prop, "rna_EditBone_envelope_weight_get", "rna_EditBone_envelope_weight_set", NULL);
|
||||
else RNA_def_property_float_sdna(prop, NULL, "weight");
|
||||
RNA_def_property_range(prop, 0.0f, 1000.0f);
|
||||
RNA_def_property_ui_text(prop, "Envelope Deform Weight", "Bone deformation weight (for Envelope deform only).");
|
||||
|
||||
prop= RNA_def_property(srna, "radius_head", PROP_FLOAT, PROP_NONE);
|
||||
if(editbone) RNA_def_property_float_funcs(prop, "rna_EditBone_radius_head_get", "rna_EditBone_radius_head_set", NULL);
|
||||
else RNA_def_property_float_sdna(prop, NULL, "rad_head");
|
||||
//RNA_def_property_range(prop, 0, 1000); // XXX range is 0 to lim, where lim= 10000.0f*MAX2(1.0, view3d->grid);
|
||||
RNA_def_property_ui_text(prop, "Envelope Radius Head", "Radius of head of bone (for Envelope deform only).");
|
||||
|
||||
prop= RNA_def_property(srna, "radius_tail", PROP_FLOAT, PROP_NONE);
|
||||
if(editbone) RNA_def_property_float_funcs(prop, "rna_EditBone_radius_tail_get", "rna_EditBone_radius_tail_set", NULL);
|
||||
else RNA_def_property_float_sdna(prop, NULL, "rad_tail");
|
||||
//RNA_def_property_range(prop, 0, 1000); // XXX range is 0 to lim, where lim= 10000.0f*MAX2(1.0, view3d->grid);
|
||||
RNA_def_property_ui_text(prop, "Envelope Radius Tail", "Radius of tail of bone (for Envelope deform only).");
|
||||
|
||||
/* b-bones deform settings */
|
||||
prop= RNA_def_property(srna, "bbone_segments", PROP_INT, PROP_NONE);
|
||||
if(editbone) RNA_def_property_int_funcs(prop, "rna_EditBone_bbone_segments_get", "rna_EditBone_bbone_segments_set", NULL);
|
||||
else RNA_def_property_int_sdna(prop, NULL, "segments");
|
||||
RNA_def_property_range(prop, 1, 32);
|
||||
RNA_def_property_ui_text(prop, "B-Bone Segments", "Number of subdivisions of bone (for B-Bones only).");
|
||||
|
||||
prop= RNA_def_property(srna, "bbone_in", PROP_FLOAT, PROP_NONE);
|
||||
if(editbone) RNA_def_property_float_funcs(prop, "rna_EditBone_bbone_in_get", "rna_EditBone_bbone_in_set", NULL);
|
||||
else RNA_def_property_float_sdna(prop, NULL, "ease1");
|
||||
RNA_def_property_range(prop, 0.0f, 2.0f);
|
||||
RNA_def_property_ui_text(prop, "B-Bone Ease In", "Length of first Bezier Handle (for B-Bones only).");
|
||||
|
||||
prop= RNA_def_property(srna, "bbone_out", PROP_FLOAT, PROP_NONE);
|
||||
if(editbone) RNA_def_property_float_funcs(prop, "rna_EditBone_bbone_out_get", "rna_EditBone_bbone_out_set", NULL);
|
||||
else RNA_def_property_float_sdna(prop, NULL, "ease2");
|
||||
RNA_def_property_range(prop, 0.0f, 2.0f);
|
||||
RNA_def_property_ui_text(prop, "B-Bone Ease Out", "Length of second Bezier Handle (for B-Bones only).");
|
||||
}
|
||||
|
||||
// err... bones should not be directly edited (only editbones should be...)
|
||||
static void rna_def_bone(BlenderRNA *brna)
|
||||
{
|
||||
@@ -126,128 +574,64 @@ static void rna_def_bone(BlenderRNA *brna)
|
||||
RNA_def_property_collection_sdna(prop, NULL, "childbase", NULL);
|
||||
RNA_def_property_struct_type(prop, "Bone");
|
||||
RNA_def_property_ui_text(prop, "Children", "Bones which are children of this bone");
|
||||
|
||||
/* strings */
|
||||
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* must be unique */
|
||||
RNA_def_property_ui_text(prop, "Name", "");
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
|
||||
/* flags */
|
||||
/* layer */
|
||||
prop= RNA_def_property(srna, "layer", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "layer", 1);
|
||||
RNA_def_property_array(prop, 16);
|
||||
RNA_def_property_ui_text(prop, "Bone Layers", "Layers bone exists in");
|
||||
RNA_def_property_boolean_funcs(prop, NULL, "rna_Bone_layer_set");
|
||||
|
||||
/* flag */
|
||||
rna_def_bone_common(srna, 0);
|
||||
|
||||
// XXX should we define this in PoseChannel wrapping code instead? but PoseChannels directly get some of their flags from here...
|
||||
prop= RNA_def_property(srna, "hidden", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_HIDDEN_P);
|
||||
RNA_def_property_ui_text(prop, "Hidden", "Bone is not visible when it is not in Edit Mode (i.e. in Object or Pose Modes).");
|
||||
|
||||
prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_SELECTED);
|
||||
RNA_def_property_ui_text(prop, "Selected", "");
|
||||
}
|
||||
|
||||
static void rna_def_edit_bone(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna= RNA_def_struct(brna, "EditBone", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Edit Bone", "Editmode bone in an Armature datablock.");
|
||||
RNA_def_struct_ui_icon(srna, ICON_BONE_DATA);
|
||||
|
||||
prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "EditBone");
|
||||
RNA_def_property_pointer_funcs(prop, "rna_EditBone_parent_get", NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Parent", "Parent edit bone (in same Armature).");
|
||||
|
||||
prop= RNA_def_property(srna, "roll", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_funcs(prop, "rna_EditBone_roll_get", "rna_EditBone_roll_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "Roll", "Bone rotation around head-tail axis.");
|
||||
|
||||
prop= RNA_def_property(srna, "head", PROP_FLOAT, PROP_VECTOR);
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_float_funcs(prop, "rna_EditBone_head_get", "rna_EditBone_head_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "Head", "Location of head end of the bone.");
|
||||
|
||||
prop= RNA_def_property(srna, "tail", PROP_FLOAT, PROP_VECTOR);
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_float_funcs(prop, "rna_EditBone_tail_get", "rna_EditBone_tail_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "Tail", "Location of tail end of the bone.");
|
||||
|
||||
rna_def_bone_common(srna, 1);
|
||||
|
||||
prop= RNA_def_property(srna, "hidden", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_EditBone_hidden_get", "rna_EditBone_hidden_set");
|
||||
RNA_def_property_ui_text(prop, "Hidden", "Bone is not visible when in Edit Mode");
|
||||
|
||||
prop= RNA_def_property(srna, "locked", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_EditBone_locked_get", "rna_EditBone_locked_set");
|
||||
RNA_def_property_ui_text(prop, "Locked", "Bone is not able to be transformed when in Edit Mode.");
|
||||
|
||||
prop= RNA_def_property(srna, "head_selected", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_ROOTSEL);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_EditBone_head_selected_get", "rna_EditBone_head_selected_set");
|
||||
RNA_def_property_ui_text(prop, "Head Selected", "");
|
||||
|
||||
prop= RNA_def_property(srna, "tail_selected", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_TIPSEL);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_EditBone_tail_selected_get", "rna_EditBone_tail_selected_set");
|
||||
RNA_def_property_ui_text(prop, "Tail Selected", "");
|
||||
|
||||
prop= RNA_def_property(srna, "connected", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_CONNECTED);
|
||||
RNA_def_property_ui_text(prop, "Connected", "When bone has a parent, bone's head is struck to the parent's tail.");
|
||||
|
||||
// XXX should we define this in PoseChannel wrapping code instead? but PoseChannels directly get some of their flags from here...
|
||||
prop= RNA_def_property(srna, "pose_channel_hidden", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_HIDDEN_P);
|
||||
RNA_def_property_ui_text(prop, "Pose Channel Hidden", "Bone is not visible when it is not in Edit Mode (i.e. in Object or Pose Modes).");
|
||||
|
||||
prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_ACTIVE);
|
||||
RNA_def_property_ui_text(prop, "Active", "Bone was the last bone clicked on (most operations are applied to only this bone)");
|
||||
|
||||
prop= RNA_def_property(srna, "hinge", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_HINGE);
|
||||
RNA_def_property_ui_text(prop, "Inherit Rotation", "Bone doesn't inherit rotation or scale from parent bone.");
|
||||
|
||||
prop= RNA_def_property(srna, "editmode_hidden", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_HIDDEN_A);
|
||||
RNA_def_property_ui_text(prop, "Edit Mode Hidden", "Bone is not visible when in Edit Mode");
|
||||
|
||||
prop= RNA_def_property(srna, "multiply_vertexgroup_with_envelope", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_MULT_VG_ENV);
|
||||
RNA_def_property_ui_text(prop, "Multiply Vertex Group with Envelope", "When deforming bone, multiply effects of Vertex Group weights with Envelope influence.");
|
||||
|
||||
prop= RNA_def_property(srna, "deform", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_DEFORM);
|
||||
RNA_def_property_ui_text(prop, "Deform", "Bone does not deform any geometry.");
|
||||
|
||||
prop= RNA_def_property(srna, "inherit_scale", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_SCALE);
|
||||
RNA_def_property_ui_text(prop, "Inherit Scale", "Bone inherits scaling from parent bone.");
|
||||
|
||||
prop= RNA_def_property(srna, "draw_wire", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_DRAWWIRE);
|
||||
RNA_def_property_ui_text(prop, "Draw Wire", "Bone is always drawn as Wireframe regardless of viewport draw mode. Useful for non-obstructive custom bone shapes.");
|
||||
|
||||
prop= RNA_def_property(srna, "cyclic_offset", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_CYCLICOFFSET);
|
||||
RNA_def_property_ui_text(prop, "Cyclic Offset", "When bone doesn't have a parent, it receives cyclic offset effects.");
|
||||
|
||||
prop= RNA_def_property(srna, "editmode_locked", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_EDITMODE_LOCKED);
|
||||
RNA_def_property_ui_text(prop, "Edit Mode Locked", "Bone is not able to be transformed when in Edit Mode.");
|
||||
|
||||
/* Number values */
|
||||
/* envelope deform settings */
|
||||
prop= RNA_def_property(srna, "envelope_distance", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "dist");
|
||||
RNA_def_property_range(prop, 0.0f, 1000.0f);
|
||||
RNA_def_property_ui_text(prop, "Envelope Deform Distance", "Bone deformation distance (for Envelope deform only).");
|
||||
|
||||
prop= RNA_def_property(srna, "envelope_weight", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "weight");
|
||||
RNA_def_property_range(prop, 0.0f, 1000.0f);
|
||||
RNA_def_property_ui_text(prop, "Envelope Deform Weight", "Bone deformation weight (for Envelope deform only).");
|
||||
|
||||
prop= RNA_def_property(srna, "radius_head", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "rad_head");
|
||||
//RNA_def_property_range(prop, 0, 1000); // XXX range is 0 to lim, where lim= 10000.0f*MAX2(1.0, view3d->grid);
|
||||
RNA_def_property_ui_text(prop, "Envelope Radius Head", "Radius of head of bone (for Envelope deform only).");
|
||||
|
||||
prop= RNA_def_property(srna, "radius_tail", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "rad_tail");
|
||||
//RNA_def_property_range(prop, 0, 1000); // XXX range is 0 to lim, where lim= 10000.0f*MAX2(1.0, view3d->grid);
|
||||
RNA_def_property_ui_text(prop, "Envelope Radius Tail", "Radius of tail of bone (for Envelope deform only).");
|
||||
|
||||
/* b-bones deform settings */
|
||||
prop= RNA_def_property(srna, "bbone_segments", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "segments");
|
||||
RNA_def_property_range(prop, 1, 32);
|
||||
RNA_def_property_ui_text(prop, "B-Bone Segments", "Number of subdivisions of bone (for B-Bones only).");
|
||||
|
||||
prop= RNA_def_property(srna, "bbone_in", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "ease1");
|
||||
RNA_def_property_range(prop, 0.0f, 2.0f);
|
||||
RNA_def_property_ui_text(prop, "B-Bone Ease In", "Length of first Bezier Handle (for B-Bones only).");
|
||||
|
||||
prop= RNA_def_property(srna, "bbone_out", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "ease2");
|
||||
RNA_def_property_range(prop, 0.0f, 2.0f);
|
||||
RNA_def_property_ui_text(prop, "B-Bone Ease Out", "Length of second Bezier Handle (for B-Bones only).");
|
||||
|
||||
/* editmode bone coordinates */
|
||||
// XXX not sure if we want to wrap these here... besides, changing these requires changing the matrix?
|
||||
prop= RNA_def_property(srna, "head", PROP_FLOAT, PROP_VECTOR);
|
||||
RNA_def_property_ui_text(prop, "Bone Head Location", "In Edit Mode, the location of the 'head' of the bone.");
|
||||
|
||||
prop= RNA_def_property(srna, "tail", PROP_FLOAT, PROP_VECTOR);
|
||||
RNA_def_property_ui_text(prop, "Bone Tail Location", "In Edit Mode, the location of the 'head' of the bone.");
|
||||
|
||||
prop= RNA_def_property(srna, "roll", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0.0f, 2.0f);
|
||||
RNA_def_property_ui_text(prop, "Bone Roll", "In Edit Mode, the 'roll' (i.e. rotation around the bone vector, equivalent to local Y-axis rotation).");
|
||||
}
|
||||
|
||||
void rna_def_armature(BlenderRNA *brna)
|
||||
@@ -278,6 +662,11 @@ void rna_def_armature(BlenderRNA *brna)
|
||||
RNA_def_property_collection_sdna(prop, NULL, "bonebase", NULL);
|
||||
RNA_def_property_struct_type(prop, "Bone");
|
||||
RNA_def_property_ui_text(prop, "Bones", "");
|
||||
|
||||
prop= RNA_def_property(srna, "edit_bones", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "edbo", NULL);
|
||||
RNA_def_property_struct_type(prop, "EditBone");
|
||||
RNA_def_property_ui_text(prop, "Edit Bones", "");
|
||||
|
||||
/* Enum values */
|
||||
prop= RNA_def_property(srna, "drawtype", PROP_ENUM, PROP_NONE);
|
||||
@@ -436,6 +825,7 @@ void RNA_def_armature(BlenderRNA *brna)
|
||||
{
|
||||
rna_def_armature(brna);
|
||||
rna_def_bone(brna);
|
||||
rna_def_edit_bone(brna);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_types.h"
|
||||
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
#include "rna_internal.h"
|
||||
|
||||
/* Global used during defining */
|
||||
@@ -557,6 +559,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
|
||||
/* copy from struct to derive stuff, a bit clumsy since we can't
|
||||
* use MEM_dupallocN, data structs may not be alloced but builtin */
|
||||
memcpy(srna, srnafrom, sizeof(StructRNA));
|
||||
srna->cont.prophash= NULL;
|
||||
srna->cont.properties.first= srna->cont.properties.last= NULL;
|
||||
srna->functions.first= srna->functions.last= NULL;
|
||||
srna->py_type= NULL;
|
||||
@@ -604,7 +607,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
|
||||
|
||||
if(DefRNA.preprocess) {
|
||||
RNA_def_property_struct_type(prop, "Property");
|
||||
RNA_def_property_collection_funcs(prop, "rna_builtin_properties_begin", "rna_builtin_properties_next", "rna_iterator_listbase_end", "rna_builtin_properties_get", 0, 0, 0, 0, 0);
|
||||
RNA_def_property_collection_funcs(prop, "rna_builtin_properties_begin", "rna_builtin_properties_next", "rna_iterator_listbase_end", "rna_builtin_properties_get", 0, 0, "rna_builtin_properties_lookup_string", 0, 0);
|
||||
}
|
||||
else {
|
||||
#ifdef RNA_RUNTIME
|
||||
@@ -923,8 +926,13 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
prop->flag |= PROP_IDPROPERTY|PROP_RUNTIME;
|
||||
#ifdef RNA_RUNTIME
|
||||
if(cont->prophash)
|
||||
BLI_ghash_insert(cont->prophash, (void*)prop->identifier, prop);
|
||||
#endif
|
||||
}
|
||||
|
||||
rna_addtail(&cont->properties, prop);
|
||||
|
||||
|
||||
@@ -217,6 +217,7 @@ void rna_builtin_properties_begin(struct CollectionPropertyIterator *iter, struc
|
||||
void rna_builtin_properties_next(struct CollectionPropertyIterator *iter);
|
||||
PointerRNA rna_builtin_properties_get(struct CollectionPropertyIterator *iter);
|
||||
PointerRNA rna_builtin_type_get(struct PointerRNA *ptr);
|
||||
PointerRNA rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key);
|
||||
|
||||
/* Iterators */
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ struct ReportList;
|
||||
struct CollectionPropertyIterator;
|
||||
struct bContext;
|
||||
struct IDProperty;
|
||||
struct GHash;
|
||||
|
||||
#define RNA_MAX_ARRAY 32
|
||||
|
||||
@@ -83,6 +84,7 @@ typedef PointerRNA (*PropCollectionLookupStringFunc)(struct PointerRNA *ptr, con
|
||||
typedef struct ContainerRNA {
|
||||
void *next, *prev;
|
||||
|
||||
struct GHash *prophash;
|
||||
ListBase properties;
|
||||
} ContainerRNA;
|
||||
|
||||
|
||||
@@ -38,11 +38,14 @@
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
/*static float rna_MeshVertex_no_get(PointerRNA *ptr, int index)
|
||||
static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value)
|
||||
{
|
||||
MVert *mvert= (MVert*)ptr->data;
|
||||
return mvert->no[index]/32767.0f;
|
||||
}*/
|
||||
|
||||
value[0]= mvert->no[0]/32767.0f;
|
||||
value[1]= mvert->no[1]/32767.0f;
|
||||
value[2]= mvert->no[2]/32767.0f;
|
||||
}
|
||||
|
||||
static float rna_MeshVertex_bevel_weight_get(PointerRNA *ptr)
|
||||
{
|
||||
@@ -80,76 +83,77 @@ static void rna_MEdge_crease_set(PointerRNA *ptr, float value)
|
||||
medge->crease= (char)(CLAMPIS(value*255.0f, 0, 255));
|
||||
}
|
||||
|
||||
/* notice red and blue are swapped */
|
||||
static void rna_MeshColor_color1_get(PointerRNA *ptr, float *values)
|
||||
{
|
||||
MCol *mcol= (MCol*)ptr->data;
|
||||
|
||||
values[0]= (&mcol[0].r)[0]/255.0f;
|
||||
values[2]= (&mcol[0].r)[0]/255.0f;
|
||||
values[1]= (&mcol[0].r)[1]/255.0f;
|
||||
values[2]= (&mcol[0].r)[2]/255.0f;
|
||||
values[0]= (&mcol[0].r)[2]/255.0f;
|
||||
}
|
||||
|
||||
static void rna_MeshColor_color1_set(PointerRNA *ptr, const float *values)
|
||||
{
|
||||
MCol *mcol= (MCol*)ptr->data;
|
||||
|
||||
(&mcol[0].r)[0]= (char)(CLAMPIS(values[0]*255.0f, 0, 255));
|
||||
(&mcol[0].r)[2]= (char)(CLAMPIS(values[0]*255.0f, 0, 255));
|
||||
(&mcol[0].r)[1]= (char)(CLAMPIS(values[1]*255.0f, 0, 255));
|
||||
(&mcol[0].r)[2]= (char)(CLAMPIS(values[2]*255.0f, 0, 255));
|
||||
(&mcol[0].r)[0]= (char)(CLAMPIS(values[2]*255.0f, 0, 255));
|
||||
}
|
||||
|
||||
static void rna_MeshColor_color2_get(PointerRNA *ptr, float *values)
|
||||
{
|
||||
MCol *mcol= (MCol*)ptr->data;
|
||||
|
||||
values[0]= (&mcol[1].r)[0]/255.0f;
|
||||
values[2]= (&mcol[1].r)[0]/255.0f;
|
||||
values[1]= (&mcol[1].r)[1]/255.0f;
|
||||
values[2]= (&mcol[1].r)[2]/255.0f;
|
||||
values[0]= (&mcol[1].r)[2]/255.0f;
|
||||
}
|
||||
|
||||
static void rna_MeshColor_color2_set(PointerRNA *ptr, const float *values)
|
||||
{
|
||||
MCol *mcol= (MCol*)ptr->data;
|
||||
|
||||
(&mcol[1].r)[0]= (char)(CLAMPIS(values[0]*255.0f, 0, 255));
|
||||
(&mcol[1].r)[2]= (char)(CLAMPIS(values[0]*255.0f, 0, 255));
|
||||
(&mcol[1].r)[1]= (char)(CLAMPIS(values[1]*255.0f, 0, 255));
|
||||
(&mcol[1].r)[2]= (char)(CLAMPIS(values[2]*255.0f, 0, 255));
|
||||
(&mcol[1].r)[0]= (char)(CLAMPIS(values[2]*255.0f, 0, 255));
|
||||
}
|
||||
|
||||
static void rna_MeshColor_color3_get(PointerRNA *ptr, float *values)
|
||||
{
|
||||
MCol *mcol= (MCol*)ptr->data;
|
||||
|
||||
values[0]= (&mcol[2].r)[0]/255.0f;
|
||||
values[2]= (&mcol[2].r)[0]/255.0f;
|
||||
values[1]= (&mcol[2].r)[1]/255.0f;
|
||||
values[2]= (&mcol[2].r)[2]/255.0f;
|
||||
values[0]= (&mcol[2].r)[2]/255.0f;
|
||||
}
|
||||
|
||||
static void rna_MeshColor_color3_set(PointerRNA *ptr, const float *values)
|
||||
{
|
||||
MCol *mcol= (MCol*)ptr->data;
|
||||
|
||||
(&mcol[2].r)[0]= (char)(CLAMPIS(values[0]*255.0f, 0, 255));
|
||||
(&mcol[2].r)[2]= (char)(CLAMPIS(values[0]*255.0f, 0, 255));
|
||||
(&mcol[2].r)[1]= (char)(CLAMPIS(values[1]*255.0f, 0, 255));
|
||||
(&mcol[2].r)[2]= (char)(CLAMPIS(values[2]*255.0f, 0, 255));
|
||||
(&mcol[2].r)[0]= (char)(CLAMPIS(values[2]*255.0f, 0, 255));
|
||||
}
|
||||
|
||||
static void rna_MeshColor_color4_get(PointerRNA *ptr, float *values)
|
||||
{
|
||||
MCol *mcol= (MCol*)ptr->data;
|
||||
|
||||
values[0]= (&mcol[3].r)[0]/255.0f;
|
||||
values[2]= (&mcol[3].r)[0]/255.0f;
|
||||
values[1]= (&mcol[3].r)[1]/255.0f;
|
||||
values[2]= (&mcol[3].r)[2]/255.0f;
|
||||
values[0]= (&mcol[3].r)[2]/255.0f;
|
||||
}
|
||||
|
||||
static void rna_MeshColor_color4_set(PointerRNA *ptr, const float *values)
|
||||
{
|
||||
MCol *mcol= (MCol*)ptr->data;
|
||||
|
||||
(&mcol[3].r)[0]= (char)(CLAMPIS(values[0]*255.0f, 0, 255));
|
||||
(&mcol[3].r)[2]= (char)(CLAMPIS(values[0]*255.0f, 0, 255));
|
||||
(&mcol[3].r)[1]= (char)(CLAMPIS(values[1]*255.0f, 0, 255));
|
||||
(&mcol[3].r)[2]= (char)(CLAMPIS(values[2]*255.0f, 0, 255));
|
||||
(&mcol[3].r)[0]= (char)(CLAMPIS(values[2]*255.0f, 0, 255));
|
||||
}
|
||||
|
||||
static int rna_Mesh_texspace_editable(PointerRNA *ptr)
|
||||
@@ -628,10 +632,11 @@ static void rna_def_mvert(BlenderRNA *brna)
|
||||
prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_VECTOR);
|
||||
RNA_def_property_ui_text(prop, "Location", "");
|
||||
|
||||
/*prop= RNA_def_property(srna, "no", PROP_FLOAT, PROP_VECTOR);
|
||||
RNA_def_property_float_funcs(prop, "rna_MeshVertex_no_get", NULL, NULL);
|
||||
prop= RNA_def_property(srna, "normal", PROP_FLOAT, PROP_VECTOR);
|
||||
RNA_def_property_float_sdna(prop, NULL, "no");
|
||||
RNA_def_property_float_funcs(prop, "rna_MeshVertex_normal_get", NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Normal", "Vertex Normal");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);*/
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
|
||||
prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
|
||||
@@ -907,21 +912,25 @@ static void rna_def_mcol(BlenderRNA *brna)
|
||||
|
||||
prop= RNA_def_property(srna, "color1", PROP_FLOAT, PROP_COLOR);
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_float_funcs(prop, "rna_MeshColor_color1_get", "rna_MeshColor_color1_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "Color 1", "");
|
||||
|
||||
prop= RNA_def_property(srna, "color2", PROP_FLOAT, PROP_COLOR);
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_float_funcs(prop, "rna_MeshColor_color2_get", "rna_MeshColor_color2_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "Color 2", "");
|
||||
|
||||
prop= RNA_def_property(srna, "color3", PROP_FLOAT, PROP_COLOR);
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_float_funcs(prop, "rna_MeshColor_color3_get", "rna_MeshColor_color3_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "Color 3", "");
|
||||
|
||||
prop= RNA_def_property(srna, "color4", PROP_FLOAT, PROP_COLOR);
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_float_funcs(prop, "rna_MeshColor_color4_get", "rna_MeshColor_color4_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "Color 4", "");
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value)
|
||||
ob->data= id;
|
||||
test_object_materials(id);
|
||||
|
||||
if(GS(id->name)==ID_CU )
|
||||
if(GS(id->name)==ID_CU)
|
||||
test_curve_type(ob);
|
||||
else if(ob->type==OB_ARMATURE)
|
||||
armature_rebuild_pose(ob, ob->data);
|
||||
@@ -522,6 +522,49 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_ui_text(prop, "Rotation Damping", "General rotation damping.");
|
||||
|
||||
prop= RNA_def_property(srna, "minimum_velocity", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "min_vel");
|
||||
RNA_def_property_range(prop, 0.0, 1000.0);
|
||||
RNA_def_property_ui_text(prop, "Velocity Min", "Clamp velocity to this minimum speed (except when totally still).");
|
||||
|
||||
prop= RNA_def_property(srna, "maximum_velocity", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "max_vel");
|
||||
RNA_def_property_range(prop, 0.0, 1000.0);
|
||||
RNA_def_property_ui_text(prop, "Velocity Max", "Clamp velocity to this maximum speed.");
|
||||
|
||||
/* lock position */
|
||||
prop= RNA_def_property(srna, "lock_x_axis", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "gameflag2", OB_LOCK_RIGID_BODY_X_AXIS);
|
||||
RNA_def_property_ui_text(prop, "Lock X Axis", "Disable simulation of linear motion along the X axis.");
|
||||
|
||||
prop= RNA_def_property(srna, "lock_y_axis", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "gameflag2", OB_LOCK_RIGID_BODY_Y_AXIS);
|
||||
RNA_def_property_ui_text(prop, "Lock Y Axis", "Disable simulation of linear motion along the Y axis.");
|
||||
|
||||
prop= RNA_def_property(srna, "lock_z_axis", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "gameflag2", OB_LOCK_RIGID_BODY_Z_AXIS);
|
||||
RNA_def_property_ui_text(prop, "Lock Z Axis", "Disable simulation of linear motion along the Z axis.");
|
||||
|
||||
|
||||
/* lock rotation */
|
||||
prop= RNA_def_property(srna, "lock_x_rot_axis", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "gameflag2", OB_LOCK_RIGID_BODY_X_ROT_AXIS);
|
||||
RNA_def_property_ui_text(prop, "Lock X Rotation Axis", "Disable simulation of angular motion along the X axis.");
|
||||
|
||||
prop= RNA_def_property(srna, "lock_y_rot_axis", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "gameflag2", OB_LOCK_RIGID_BODY_Y_ROT_AXIS);
|
||||
RNA_def_property_ui_text(prop, "Lock Y Rotation Axis", "Disable simulation of angular motion along the Y axis.");
|
||||
|
||||
prop= RNA_def_property(srna, "lock_z_rot_axis", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "gameflag2", OB_LOCK_RIGID_BODY_Z_ROT_AXIS);
|
||||
RNA_def_property_ui_text(prop, "Lock Z Rotation Axis", "Disable simulation of angular motion along the Z axis.");
|
||||
|
||||
/* is this used anywhere ? */
|
||||
prop= RNA_def_property(srna, "use_activity_culling", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflag2", OB_NEVER_DO_ACTIVITY_CULLING);
|
||||
RNA_def_property_ui_text(prop, "Lock Z Rotation Axis", "Disable simulation of angular motion along the Z axis.");
|
||||
|
||||
|
||||
prop= RNA_def_property(srna, "do_fh", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "gameflag", OB_DO_FH);
|
||||
RNA_def_property_ui_text(prop, "Do Fh", "Use Fh settings in materials.");
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
/* Struct */
|
||||
|
||||
static void rna_Struct_identifier_get(PointerRNA *ptr, char *value)
|
||||
@@ -277,6 +279,51 @@ PointerRNA rna_builtin_properties_get(CollectionPropertyIterator *iter)
|
||||
return rna_Struct_properties_get(iter);
|
||||
}
|
||||
|
||||
PointerRNA rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
IDProperty *group, *idp;
|
||||
PointerRNA propptr;
|
||||
|
||||
memset(&propptr, 0, sizeof(propptr));
|
||||
srna= ptr->type;
|
||||
|
||||
do {
|
||||
if(srna->cont.prophash) {
|
||||
prop= BLI_ghash_lookup(srna->cont.prophash, (void*)key);
|
||||
|
||||
if(prop) {
|
||||
propptr.type= &RNA_Property;
|
||||
propptr.data= prop;
|
||||
return propptr;
|
||||
}
|
||||
}
|
||||
|
||||
for(prop=srna->cont.properties.first; prop; prop=prop->next) {
|
||||
if(!(prop->flag & PROP_BUILTIN) && strcmp(prop->identifier, key)==0) {
|
||||
propptr.type= &RNA_Property;
|
||||
propptr.data= prop;
|
||||
return propptr;
|
||||
}
|
||||
}
|
||||
} while((srna=srna->base));
|
||||
|
||||
group= RNA_struct_idproperties(ptr, 0);
|
||||
|
||||
if(group) {
|
||||
for(idp=group->data.group.first; idp; idp=idp->next) {
|
||||
if(strcmp(idp->name, key) == 0) {
|
||||
propptr.type= &RNA_Property;
|
||||
propptr.data= idp;
|
||||
return propptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return propptr;
|
||||
}
|
||||
|
||||
PointerRNA rna_builtin_type_get(PointerRNA *ptr)
|
||||
{
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_Struct, ptr->type);
|
||||
|
||||
@@ -62,7 +62,7 @@ EnumPropertyItem space_type_items[] = {
|
||||
#define DC_ALPHA {SI_SHOW_ALPHA, "ALPHA", ICON_IMAGE_ALPHA, "Alpha", "Draw alpha transparency channel."}
|
||||
#define DC_Z {SI_SHOW_ZBUF, "Z_BUFFER", ICON_IMAGE_ZDEPTH, "Z-Buffer", "Draw Z-buffer associated with image (mapped from camera clip start to end)."}
|
||||
#ifdef WITH_LCMS
|
||||
#define DC_LCMS SI_COLOR_CORRECTION, "COLOR_CORRECTED", ICON_IMAGE_ALPHA, "Color Corrected", "Display color corrected image."}
|
||||
#define DC_LCMS {SI_COLOR_CORRECTION, "COLOR_CORRECTED", ICON_IMAGE_ALPHA, "Color Corrected", "Display color corrected image."}
|
||||
#else
|
||||
#define DC_LCMS {0, NULL, 0, NULL, NULL}
|
||||
#endif
|
||||
|
||||
@@ -36,65 +36,53 @@
|
||||
|
||||
//-------------------------DOC STRINGS ---------------------------
|
||||
static char M_Mathutils_doc[] = "The Blender Mathutils module\n\n";
|
||||
static char M_Mathutils_Vector_doc[] = "() - create a new vector object from a list of floats";
|
||||
static char M_Mathutils_Matrix_doc[] = "() - create a new matrix object from a list of floats";
|
||||
static char M_Mathutils_Quaternion_doc[] = "() - create a quaternion from a list or an axis of rotation and an angle";
|
||||
static char M_Mathutils_Euler_doc[] = "() - create and return a new euler object";
|
||||
static char M_Mathutils_Rand_doc[] = "() - return a random number";
|
||||
static char M_Mathutils_CrossVecs_doc[] = "() - returns a vector perpedicular to the 2 vectors crossed";
|
||||
static char M_Mathutils_CopyVec_doc[] = "() - create a copy of vector";
|
||||
static char M_Mathutils_DotVecs_doc[] = "() - return the dot product of two vectors";
|
||||
static char M_Mathutils_AngleBetweenVecs_doc[] = "() - returns the angle between two vectors in degrees";
|
||||
static char M_Mathutils_MidpointVecs_doc[] = "() - return the vector to the midpoint between two vectors";
|
||||
static char M_Mathutils_MatMultVec_doc[] = "() - multiplies a matrix by a column vector";
|
||||
static char M_Mathutils_VecMultMat_doc[] = "() - multiplies a row vector by a matrix";
|
||||
static char M_Mathutils_ProjectVecs_doc[] = "() - returns the projection vector from the projection of vecA onto vecB";
|
||||
static char M_Mathutils_RotationMatrix_doc[] = "() - construct a rotation matrix from an angle and axis of rotation";
|
||||
static char M_Mathutils_ScaleMatrix_doc[] = "() - construct a scaling matrix from a scaling factor";
|
||||
static char M_Mathutils_OrthoProjectionMatrix_doc[] = "() - construct a orthographic projection matrix from a selected plane";
|
||||
static char M_Mathutils_ShearMatrix_doc[] = "() - construct a shearing matrix from a plane of shear and a shear factor";
|
||||
static char M_Mathutils_CopyMat_doc[] = "() - create a copy of a matrix";
|
||||
static char M_Mathutils_TranslationMatrix_doc[] = "(vec) - create a translation matrix from a vector";
|
||||
static char M_Mathutils_CopyQuat_doc[] = "() - copy quatB to quatA";
|
||||
static char M_Mathutils_CopyEuler_doc[] = "() - copy eulB to eultA";
|
||||
static char M_Mathutils_CrossQuats_doc[] = "() - return the mutliplication of two quaternions";
|
||||
static char M_Mathutils_DotQuats_doc[] = "() - return the dot product of two quaternions";
|
||||
static char M_Mathutils_Slerp_doc[] = "() - returns the interpolation between two quaternions";
|
||||
static char M_Mathutils_DifferenceQuats_doc[] = "() - return the angular displacment difference between two quats";
|
||||
static char M_Mathutils_RotateEuler_doc[] = "() - rotate euler by an axis and angle";
|
||||
static char M_Mathutils_Intersect_doc[] = "(v1, v2, v3, ray, orig, clip=1) - returns the intersection between a ray and a triangle, if possible, returns None otherwise";
|
||||
static char M_Mathutils_TriangleArea_doc[] = "(v1, v2, v3) - returns the area size of the 2D or 3D triangle defined";
|
||||
static char M_Mathutils_TriangleNormal_doc[] = "(v1, v2, v3) - returns the normal of the 3D triangle defined";
|
||||
static char M_Mathutils_QuadNormal_doc[] = "(v1, v2, v3, v4) - returns the normal of the 3D quad defined";
|
||||
static char M_Mathutils_LineIntersect_doc[] = "(v1, v2, v3, v4) - returns a tuple with the points on each line respectively closest to the other";
|
||||
//-----------------------METHOD DEFINITIONS ----------------------
|
||||
|
||||
static PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args);
|
||||
static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args);
|
||||
static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args);
|
||||
static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args);
|
||||
static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args);
|
||||
static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * value);
|
||||
static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args);
|
||||
static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args);
|
||||
static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args);
|
||||
static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args);
|
||||
static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args);
|
||||
static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args );
|
||||
static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args );
|
||||
static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args );
|
||||
static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args );
|
||||
static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args );
|
||||
|
||||
struct PyMethodDef M_Mathutils_methods[] = {
|
||||
{"Rand", (PyCFunction) M_Mathutils_Rand, METH_VARARGS, M_Mathutils_Rand_doc},
|
||||
{"Vector", (PyCFunction) M_Mathutils_Vector, METH_VARARGS, M_Mathutils_Vector_doc},
|
||||
{"CrossVecs", (PyCFunction) M_Mathutils_CrossVecs, METH_VARARGS, M_Mathutils_CrossVecs_doc},
|
||||
{"DotVecs", (PyCFunction) M_Mathutils_DotVecs, METH_VARARGS, M_Mathutils_DotVecs_doc},
|
||||
{"AngleBetweenVecs", (PyCFunction) M_Mathutils_AngleBetweenVecs, METH_VARARGS, M_Mathutils_AngleBetweenVecs_doc},
|
||||
{"MidpointVecs", (PyCFunction) M_Mathutils_MidpointVecs, METH_VARARGS, M_Mathutils_MidpointVecs_doc},
|
||||
{"VecMultMat", (PyCFunction) M_Mathutils_VecMultMat, METH_VARARGS, M_Mathutils_VecMultMat_doc},
|
||||
{"ProjectVecs", (PyCFunction) M_Mathutils_ProjectVecs, METH_VARARGS, M_Mathutils_ProjectVecs_doc},
|
||||
{"CopyVec", (PyCFunction) M_Mathutils_CopyVec, METH_VARARGS, M_Mathutils_CopyVec_doc},
|
||||
{"Matrix", (PyCFunction) M_Mathutils_Matrix, METH_VARARGS, M_Mathutils_Matrix_doc},
|
||||
{"RotationMatrix", (PyCFunction) M_Mathutils_RotationMatrix, METH_VARARGS, M_Mathutils_RotationMatrix_doc},
|
||||
{"ScaleMatrix", (PyCFunction) M_Mathutils_ScaleMatrix, METH_VARARGS, M_Mathutils_ScaleMatrix_doc},
|
||||
{"ShearMatrix", (PyCFunction) M_Mathutils_ShearMatrix, METH_VARARGS, M_Mathutils_ShearMatrix_doc},
|
||||
{"TranslationMatrix", (PyCFunction) M_Mathutils_TranslationMatrix, METH_O, M_Mathutils_TranslationMatrix_doc},
|
||||
{"CopyMat", (PyCFunction) M_Mathutils_CopyMat, METH_VARARGS, M_Mathutils_CopyMat_doc},
|
||||
{"OrthoProjectionMatrix", (PyCFunction) M_Mathutils_OrthoProjectionMatrix, METH_VARARGS, M_Mathutils_OrthoProjectionMatrix_doc},
|
||||
{"MatMultVec", (PyCFunction) M_Mathutils_MatMultVec, METH_VARARGS, M_Mathutils_MatMultVec_doc},
|
||||
{"Quaternion", (PyCFunction) M_Mathutils_Quaternion, METH_VARARGS, M_Mathutils_Quaternion_doc},
|
||||
{"CopyQuat", (PyCFunction) M_Mathutils_CopyQuat, METH_VARARGS, M_Mathutils_CopyQuat_doc},
|
||||
{"CrossQuats", (PyCFunction) M_Mathutils_CrossQuats, METH_VARARGS, M_Mathutils_CrossQuats_doc},
|
||||
{"DotQuats", (PyCFunction) M_Mathutils_DotQuats, METH_VARARGS, M_Mathutils_DotQuats_doc},
|
||||
{"DifferenceQuats", (PyCFunction) M_Mathutils_DifferenceQuats, METH_VARARGS,M_Mathutils_DifferenceQuats_doc},
|
||||
{"Slerp", (PyCFunction) M_Mathutils_Slerp, METH_VARARGS, M_Mathutils_Slerp_doc},
|
||||
{"Euler", (PyCFunction) M_Mathutils_Euler, METH_VARARGS, M_Mathutils_Euler_doc},
|
||||
{"CopyEuler", (PyCFunction) M_Mathutils_CopyEuler, METH_VARARGS, M_Mathutils_CopyEuler_doc},
|
||||
{"RotateEuler", (PyCFunction) M_Mathutils_RotateEuler, METH_VARARGS, M_Mathutils_RotateEuler_doc},
|
||||
{"Intersect", ( PyCFunction ) M_Mathutils_Intersect, METH_VARARGS, M_Mathutils_Intersect_doc},
|
||||
{"TriangleArea", ( PyCFunction ) M_Mathutils_TriangleArea, METH_VARARGS, M_Mathutils_TriangleArea_doc},
|
||||
{"TriangleNormal", ( PyCFunction ) M_Mathutils_TriangleNormal, METH_VARARGS, M_Mathutils_TriangleNormal_doc},
|
||||
@@ -102,6 +90,7 @@ struct PyMethodDef M_Mathutils_methods[] = {
|
||||
{"LineIntersect", ( PyCFunction ) M_Mathutils_LineIntersect, METH_VARARGS, M_Mathutils_LineIntersect_doc},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
/*----------------------------MODULE INIT-------------------------*/
|
||||
/* from can be Blender.Mathutils or GameLogic.Mathutils for the BGE */
|
||||
|
||||
@@ -142,6 +131,12 @@ PyObject *Mathutils_Init(const char *from)
|
||||
submodule = Py_InitModule3(from, M_Mathutils_methods, M_Mathutils_doc);
|
||||
#endif
|
||||
|
||||
/* each type has its own new() function */
|
||||
PyModule_AddObject( submodule, "Vector", (PyObject *)&vector_Type );
|
||||
PyModule_AddObject( submodule, "Matrix", (PyObject *)&matrix_Type );
|
||||
PyModule_AddObject( submodule, "Euler", (PyObject *)&euler_Type );
|
||||
PyModule_AddObject( submodule, "Quaternion", (PyObject *)&quaternion_Type );
|
||||
|
||||
return (submodule);
|
||||
}
|
||||
|
||||
@@ -272,7 +267,7 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2)
|
||||
|
||||
//----------------------------------Mathutils.Rand() --------------------
|
||||
//returns a random number between a high and low value
|
||||
PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args)
|
||||
{
|
||||
float high, low, range;
|
||||
double drand;
|
||||
@@ -300,108 +295,9 @@ PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args)
|
||||
return PyFloat_FromDouble(drand);
|
||||
}
|
||||
//----------------------------------VECTOR FUNCTIONS---------------------
|
||||
//----------------------------------Mathutils.Vector() ------------------
|
||||
// Supports 2D, 3D, and 4D vector objects both int and float values
|
||||
// accepted. Mixed float and int values accepted. Ints are parsed to float
|
||||
PyObject *M_Mathutils_Vector(PyObject * self, PyObject * args)
|
||||
{
|
||||
PyObject *listObject = NULL;
|
||||
int size, i;
|
||||
float vec[4], f;
|
||||
PyObject *v;
|
||||
|
||||
size = PySequence_Length(args);
|
||||
if (size == 1) {
|
||||
listObject = PySequence_GetItem(args, 0);
|
||||
if (PySequence_Check(listObject)) {
|
||||
size = PySequence_Length(listObject);
|
||||
} else { // Single argument was not a sequence
|
||||
Py_XDECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
||||
return NULL;
|
||||
}
|
||||
} else if (size == 0) {
|
||||
//returns a new empty 3d vector
|
||||
return newVectorObject(NULL, 3, Py_NEW);
|
||||
} else {
|
||||
Py_INCREF(args);
|
||||
listObject = args;
|
||||
}
|
||||
|
||||
if (size<2 || size>4) { // Invalid vector size
|
||||
Py_XDECREF(listObject);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
v=PySequence_GetItem(listObject, i);
|
||||
if (v==NULL) { // Failed to read sequence
|
||||
Py_XDECREF(listObject);
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f= PyFloat_AsDouble(v);
|
||||
if(f==-1 && PyErr_Occurred()) { // parsed item not a number
|
||||
Py_DECREF(v);
|
||||
Py_XDECREF(listObject);
|
||||
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);
|
||||
}
|
||||
Py_DECREF(listObject);
|
||||
return newVectorObject(vec, size, Py_NEW);
|
||||
}
|
||||
//----------------------------------Mathutils.CrossVecs() ---------------
|
||||
//finds perpendicular vector - only 3D is supported
|
||||
PyObject *M_Mathutils_CrossVecs(PyObject * self, PyObject * args)
|
||||
{
|
||||
PyObject *vecCross = NULL;
|
||||
VectorObject *vec1 = NULL, *vec2 = NULL;
|
||||
|
||||
if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.CrossVecs(): expects (2) 3D vector objects\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(vec1->size != 3 || vec2->size != 3) {
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.CrossVecs(): expects (2) 3D vector objects\n");
|
||||
return NULL;
|
||||
}
|
||||
vecCross = newVectorObject(NULL, 3, Py_NEW);
|
||||
Crossf(((VectorObject*)vecCross)->vec, vec1->vec, vec2->vec);
|
||||
return vecCross;
|
||||
}
|
||||
//----------------------------------Mathutils.DotVec() -------------------
|
||||
//calculates the dot product of two vectors
|
||||
PyObject *M_Mathutils_DotVecs(PyObject * self, PyObject * args)
|
||||
{
|
||||
VectorObject *vec1 = NULL, *vec2 = NULL;
|
||||
double dot = 0.0f;
|
||||
int x;
|
||||
|
||||
if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.DotVecs(): expects (2) vector objects of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(vec1->size != vec2->size) {
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.DotVecs(): expects (2) vector objects of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(x = 0; x < vec1->size; x++) {
|
||||
dot += vec1->vec[x] * vec2->vec[x];
|
||||
}
|
||||
return PyFloat_FromDouble(dot);
|
||||
}
|
||||
//----------------------------------Mathutils.AngleBetweenVecs() ---------
|
||||
//calculates the angle between 2 vectors
|
||||
PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args)
|
||||
{
|
||||
VectorObject *vec1 = NULL, *vec2 = NULL;
|
||||
double dot = 0.0f, angleRads, test_v1 = 0.0f, test_v2 = 0.0f;
|
||||
@@ -443,7 +339,7 @@ AttributeError2:
|
||||
}
|
||||
//----------------------------------Mathutils.MidpointVecs() -------------
|
||||
//calculates the midpoint between 2 vectors
|
||||
PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args)
|
||||
{
|
||||
VectorObject *vec1 = NULL, *vec2 = NULL;
|
||||
float vec[4];
|
||||
@@ -465,7 +361,7 @@ PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args)
|
||||
}
|
||||
//----------------------------------Mathutils.ProjectVecs() -------------
|
||||
//projects vector 1 onto vector 2
|
||||
PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args)
|
||||
{
|
||||
VectorObject *vec1 = NULL, *vec2 = NULL;
|
||||
float vec[4];
|
||||
@@ -497,94 +393,10 @@ PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args)
|
||||
return newVectorObject(vec, size, Py_NEW);
|
||||
}
|
||||
//----------------------------------MATRIX FUNCTIONS--------------------
|
||||
//----------------------------------Mathutils.Matrix() -----------------
|
||||
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
|
||||
//create a new matrix type
|
||||
PyObject *M_Mathutils_Matrix(PyObject * self, PyObject * args)
|
||||
{
|
||||
PyObject *listObject = NULL;
|
||||
PyObject *argObject, *m, *s, *f;
|
||||
MatrixObject *mat;
|
||||
int argSize, seqSize = 0, i, j;
|
||||
float matrix[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
argSize = PySequence_Length(args);
|
||||
if(argSize > 4){ //bad arg nums
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
} else if (argSize == 0) { //return empty 4D matrix
|
||||
return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW);
|
||||
}else if (argSize == 1){
|
||||
//copy constructor for matrix objects
|
||||
argObject = PySequence_GetItem(args, 0);
|
||||
if(MatrixObject_Check(argObject)){
|
||||
mat = (MatrixObject*)argObject;
|
||||
|
||||
argSize = mat->rowSize; //rows
|
||||
seqSize = mat->colSize; //col
|
||||
for(i = 0; i < (seqSize * argSize); i++){
|
||||
matrix[i] = mat->contigPtr[i];
|
||||
}
|
||||
}
|
||||
Py_DECREF(argObject);
|
||||
}else{ //2-4 arguments (all seqs? all same size?)
|
||||
for(i =0; i < argSize; i++){
|
||||
argObject = PySequence_GetItem(args, i);
|
||||
if (PySequence_Check(argObject)) { //seq?
|
||||
if(seqSize){ //0 at first
|
||||
if(PySequence_Length(argObject) != seqSize){ //seq size not same
|
||||
Py_DECREF(argObject);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
seqSize = PySequence_Length(argObject);
|
||||
}else{ //arg not a sequence
|
||||
Py_XDECREF(argObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(argObject);
|
||||
}
|
||||
//all is well... let's continue parsing
|
||||
listObject = args;
|
||||
for (i = 0; i < argSize; i++){
|
||||
m = PySequence_GetItem(listObject, i);
|
||||
if (m == NULL) { // Failed to read sequence
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (j = 0; j < seqSize; j++) {
|
||||
s = PySequence_GetItem(m, j);
|
||||
if (s == NULL) { // Failed to read sequence
|
||||
Py_DECREF(m);
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f = PyNumber_Float(s);
|
||||
if(f == NULL) { // parsed item is not a number
|
||||
Py_DECREF(m);
|
||||
Py_DECREF(s);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
matrix[(seqSize*i)+j]=(float)PyFloat_AS_DOUBLE(f);
|
||||
Py_DECREF(f);
|
||||
Py_DECREF(s);
|
||||
}
|
||||
Py_DECREF(m);
|
||||
}
|
||||
}
|
||||
return newMatrixObject(matrix, argSize, seqSize, Py_NEW);
|
||||
}
|
||||
//----------------------------------Mathutils.RotationMatrix() ----------
|
||||
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
|
||||
//creates a rotation matrix
|
||||
PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
|
||||
{
|
||||
VectorObject *vec = NULL;
|
||||
char *axis = NULL;
|
||||
@@ -713,7 +525,7 @@ PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
|
||||
}
|
||||
//----------------------------------Mathutils.TranslationMatrix() -------
|
||||
//creates a translation matrix
|
||||
PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * vec)
|
||||
static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * vec)
|
||||
{
|
||||
float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
|
||||
@@ -737,7 +549,7 @@ PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * vec)
|
||||
//----------------------------------Mathutils.ScaleMatrix() -------------
|
||||
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
|
||||
//creates a scaling matrix
|
||||
PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args)
|
||||
{
|
||||
VectorObject *vec = NULL;
|
||||
float norm = 0.0f, factor;
|
||||
@@ -811,7 +623,7 @@ PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args)
|
||||
//----------------------------------Mathutils.OrthoProjectionMatrix() ---
|
||||
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
|
||||
//creates an ortho projection matrix
|
||||
PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args)
|
||||
{
|
||||
VectorObject *vec = NULL;
|
||||
char *plane;
|
||||
@@ -909,7 +721,7 @@ PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args)
|
||||
}
|
||||
//----------------------------------Mathutils.ShearMatrix() -------------
|
||||
//creates a shear matrix
|
||||
PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args)
|
||||
{
|
||||
int matSize;
|
||||
char *plane;
|
||||
@@ -975,167 +787,10 @@ PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args)
|
||||
return newMatrixObject(mat, matSize, matSize, Py_NEW);
|
||||
}
|
||||
//----------------------------------QUATERNION FUNCTIONS-----------------
|
||||
//----------------------------------Mathutils.Quaternion() --------------
|
||||
PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args)
|
||||
{
|
||||
PyObject *listObject = NULL, *n, *q, *f;
|
||||
int size, i;
|
||||
float quat[4];
|
||||
double norm = 0.0f, angle = 0.0f;
|
||||
|
||||
size = PySequence_Length(args);
|
||||
if (size == 1 || size == 2) { //seq?
|
||||
listObject = PySequence_GetItem(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
|
||||
Py_DECREF(listObject);
|
||||
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
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
angle = PyFloat_AsDouble(n);
|
||||
Py_DECREF(n);
|
||||
|
||||
if (angle==-1 && PyErr_Occurred()) {
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
Py_DECREF(listObject); /* assume the list is teh second arg */
|
||||
listObject = PySequence_GetItem(args, 1);
|
||||
if (size>1 && PySequence_Check(listObject)) {
|
||||
size = PySequence_Length(listObject);
|
||||
if (size != 3) {
|
||||
// invalid args/size
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
n = PySequence_GetItem(args, 0);
|
||||
if(n == NULL) { // parsed item not a number or getItem fail
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
angle = PyFloat_AsDouble(n);
|
||||
Py_DECREF(n);
|
||||
|
||||
if (angle==-1 && PyErr_Occurred()) {
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
} else { // argument was not a sequence
|
||||
Py_XDECREF(listObject);
|
||||
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);
|
||||
} else {
|
||||
Py_INCREF(args);
|
||||
listObject = args;
|
||||
}
|
||||
|
||||
if (size == 3) { // invalid quat size
|
||||
if(PySequence_Length(args) != 2){
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
}else{
|
||||
if(size != 4){
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<size; i++) { //parse
|
||||
q = PySequence_GetItem(listObject, i);
|
||||
if (q == NULL) { // Failed to read sequence
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f = PyNumber_Float(q);
|
||||
if(f == NULL) { // parsed item not a number
|
||||
Py_DECREF(q);
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
quat[i] = (float)PyFloat_AS_DOUBLE(f);
|
||||
Py_DECREF(f);
|
||||
Py_DECREF(q);
|
||||
}
|
||||
if(size == 3){ //calculate the quat based on axis/angle
|
||||
norm = sqrt(quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2]);
|
||||
quat[0] /= (float)norm;
|
||||
quat[1] /= (float)norm;
|
||||
quat[2] /= (float)norm;
|
||||
|
||||
angle = angle * (Py_PI / 180);
|
||||
quat[3] =(float) (sin(angle/ 2.0f)) * quat[2];
|
||||
quat[2] =(float) (sin(angle/ 2.0f)) * quat[1];
|
||||
quat[1] =(float) (sin(angle/ 2.0f)) * quat[0];
|
||||
quat[0] =(float) (cos(angle/ 2.0f));
|
||||
}
|
||||
|
||||
Py_DECREF(listObject);
|
||||
return newQuaternionObject(quat, Py_NEW);
|
||||
}
|
||||
//----------------------------------Mathutils.CrossQuats() ----------------
|
||||
//quaternion multiplication - associate not commutative
|
||||
PyObject *M_Mathutils_CrossQuats(PyObject * self, PyObject * args)
|
||||
{
|
||||
QuaternionObject *quatU = NULL, *quatV = NULL;
|
||||
float quat[4];
|
||||
|
||||
if(!PyArg_ParseTuple(args, "O!O!", &quaternion_Type, &quatU, &quaternion_Type, &quatV)) {
|
||||
PyErr_SetString(PyExc_TypeError,"Mathutils.CrossQuats(): expected Quaternion types");
|
||||
return NULL;
|
||||
}
|
||||
QuatMul(quat, quatU->quat, quatV->quat);
|
||||
|
||||
return newQuaternionObject(quat, Py_NEW);
|
||||
}
|
||||
//----------------------------------Mathutils.DotQuats() ----------------
|
||||
//returns the dot product of 2 quaternions
|
||||
PyObject *M_Mathutils_DotQuats(PyObject * self, PyObject * args)
|
||||
{
|
||||
QuaternionObject *quatU = NULL, *quatV = NULL;
|
||||
double dot = 0.0f;
|
||||
int x;
|
||||
|
||||
if(!PyArg_ParseTuple(args, "O!O!", &quaternion_Type, &quatU, &quaternion_Type, &quatV)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.DotQuats(): expected Quaternion types");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(x = 0; x < 4; x++) {
|
||||
dot += quatU->quat[x] * quatV->quat[x];
|
||||
}
|
||||
return PyFloat_FromDouble(dot);
|
||||
}
|
||||
//----------------------------------Mathutils.DifferenceQuats() ---------
|
||||
//returns the difference between 2 quaternions
|
||||
PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args)
|
||||
{
|
||||
QuaternionObject *quatU = NULL, *quatV = NULL;
|
||||
float quat[4], tempQuat[4];
|
||||
@@ -1162,7 +817,7 @@ PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args)
|
||||
}
|
||||
//----------------------------------Mathutils.Slerp() ------------------
|
||||
//attemps to interpolate 2 quaternions and return the result
|
||||
PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args)
|
||||
static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args)
|
||||
{
|
||||
QuaternionObject *quatU = NULL, *quatV = NULL;
|
||||
float quat[4], quat_u[4], quat_v[4], param;
|
||||
@@ -1218,67 +873,9 @@ PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args)
|
||||
return newQuaternionObject(quat, Py_NEW);
|
||||
}
|
||||
//----------------------------------EULER FUNCTIONS----------------------
|
||||
//----------------------------------Mathutils.Euler() -------------------
|
||||
//makes a new euler for you to play with
|
||||
PyObject *M_Mathutils_Euler(PyObject * self, PyObject * args)
|
||||
{
|
||||
|
||||
PyObject *listObject = NULL;
|
||||
int size, i;
|
||||
float eul[3];
|
||||
PyObject *e, *f;
|
||||
|
||||
size = PySequence_Length(args);
|
||||
if (size == 1) {
|
||||
listObject = PySequence_GetItem(args, 0);
|
||||
if (PySequence_Check(listObject)) {
|
||||
size = PySequence_Length(listObject);
|
||||
} else { // Single argument was not a sequence
|
||||
Py_DECREF(listObject);
|
||||
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, Py_NEW);
|
||||
} else {
|
||||
Py_INCREF(args);
|
||||
listObject = args;
|
||||
}
|
||||
|
||||
if (size != 3) { // Invalid euler size
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f = PyNumber_Float(e);
|
||||
if(f == NULL) { // parsed item not a number
|
||||
Py_DECREF(e);
|
||||
Py_DECREF(listObject);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
eul[i]=(float)PyFloat_AS_DOUBLE(f);
|
||||
Py_DECREF(f);
|
||||
Py_DECREF(e);
|
||||
}
|
||||
Py_DECREF(listObject);
|
||||
return newEulerObject(eul, Py_NEW);
|
||||
}
|
||||
|
||||
//---------------------------------INTERSECTION FUNCTIONS--------------------
|
||||
//----------------------------------Mathutils.Intersect() -------------------
|
||||
PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args )
|
||||
static PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args )
|
||||
{
|
||||
VectorObject *ray, *ray_off, *vec1, *vec2, *vec3;
|
||||
float dir[3], orig[3], v1[3], v2[3], v3[3], e1[3], e2[3], pvec[3], tvec[3], qvec[3];
|
||||
@@ -1348,7 +945,7 @@ PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args )
|
||||
}
|
||||
//----------------------------------Mathutils.LineIntersect() -------------------
|
||||
/* Line-Line intersection using algorithm from mathworld.wolfram.com */
|
||||
PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
|
||||
static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
|
||||
{
|
||||
PyObject * tuple;
|
||||
VectorObject *vec1, *vec2, *vec3, *vec4;
|
||||
@@ -1412,7 +1009,7 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
|
||||
|
||||
//---------------------------------NORMALS FUNCTIONS--------------------
|
||||
//----------------------------------Mathutils.QuadNormal() -------------------
|
||||
PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args )
|
||||
static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args )
|
||||
{
|
||||
VectorObject *vec1;
|
||||
VectorObject *vec2;
|
||||
@@ -1459,7 +1056,7 @@ PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args )
|
||||
}
|
||||
|
||||
//----------------------------Mathutils.TriangleNormal() -------------------
|
||||
PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args )
|
||||
static PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args )
|
||||
{
|
||||
VectorObject *vec1, *vec2, *vec3;
|
||||
float v1[3], v2[3], v3[3], e1[3], e2[3], n[3];
|
||||
@@ -1493,7 +1090,7 @@ PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args )
|
||||
|
||||
//--------------------------------- AREA FUNCTIONS--------------------
|
||||
//----------------------------------Mathutils.TriangleArea() -------------------
|
||||
PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args )
|
||||
static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args )
|
||||
{
|
||||
VectorObject *vec1, *vec2, *vec3;
|
||||
float v1[3], v2[3], v3[3];
|
||||
@@ -1533,145 +1130,6 @@ PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args )
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
//#############################DEPRECATED################################
|
||||
//#######################################################################
|
||||
//----------------------------------Mathutils.CopyMat() -----------------
|
||||
//copies a matrix into a new matrix
|
||||
PyObject *M_Mathutils_CopyMat(PyObject * self, PyObject * args)
|
||||
{
|
||||
PyObject *matrix = NULL;
|
||||
static char warning = 1;
|
||||
|
||||
if( warning ) {
|
||||
printf("Mathutils.CopyMat(): deprecated :use Mathutils.Matrix() to copy matrices\n");
|
||||
--warning;
|
||||
}
|
||||
|
||||
matrix = M_Mathutils_Matrix(self, args);
|
||||
if(matrix == NULL)
|
||||
return NULL; //error string already set if we get here
|
||||
else
|
||||
return matrix;
|
||||
}
|
||||
//----------------------------------Mathutils.CopyVec() -----------------
|
||||
//makes a new vector that is a copy of the input
|
||||
PyObject *M_Mathutils_CopyVec(PyObject * self, PyObject * args)
|
||||
{
|
||||
PyObject *vec = NULL;
|
||||
static char warning = 1;
|
||||
|
||||
if( warning ) {
|
||||
printf("Mathutils.CopyVec(): Deprecated: use Mathutils.Vector() to copy vectors\n");
|
||||
--warning;
|
||||
}
|
||||
|
||||
vec = M_Mathutils_Vector(self, args);
|
||||
if(vec == NULL)
|
||||
return NULL; //error string already set if we get here
|
||||
else
|
||||
return vec;
|
||||
}
|
||||
//----------------------------------Mathutils.CopyQuat() --------------
|
||||
//Copies a quaternion to a new quat
|
||||
PyObject *M_Mathutils_CopyQuat(PyObject * self, PyObject * args)
|
||||
{
|
||||
PyObject *quat = NULL;
|
||||
static char warning = 1;
|
||||
|
||||
if( warning ) {
|
||||
printf("Mathutils.CopyQuat(): Deprecated: use Mathutils.Quaternion() to copy vectors\n");
|
||||
--warning;
|
||||
}
|
||||
|
||||
quat = M_Mathutils_Quaternion(self, args);
|
||||
if(quat == NULL)
|
||||
return NULL; //error string already set if we get here
|
||||
else
|
||||
return quat;
|
||||
}
|
||||
//----------------------------------Mathutils.CopyEuler() ---------------
|
||||
//copies a euler to a new euler
|
||||
PyObject *M_Mathutils_CopyEuler(PyObject * self, PyObject * args)
|
||||
{
|
||||
PyObject *eul = NULL;
|
||||
static char warning = 1;
|
||||
|
||||
if( warning ) {
|
||||
printf("Mathutils.CopyEuler(): deprecated:use Mathutils.Euler() to copy vectors\n");
|
||||
--warning;
|
||||
}
|
||||
|
||||
eul = M_Mathutils_Euler(self, args);
|
||||
if(eul == NULL)
|
||||
return NULL; //error string already set if we get here
|
||||
else
|
||||
return eul;
|
||||
}
|
||||
//----------------------------------Mathutils.RotateEuler() ------------
|
||||
//rotates a euler a certain amount and returns the result
|
||||
//should return a unique euler rotation (i.e. no 720 degree pitches :)
|
||||
PyObject *M_Mathutils_RotateEuler(PyObject * self, PyObject * args)
|
||||
{
|
||||
EulerObject *Eul = NULL;
|
||||
float angle;
|
||||
char *axis;
|
||||
static char warning = 1;
|
||||
|
||||
if( warning ) {
|
||||
printf("Mathutils.RotateEuler(): Deprecated:use Euler.rotate() to rotate a euler\n");
|
||||
--warning;
|
||||
}
|
||||
|
||||
if(!PyArg_ParseTuple(args, "O!fs", &euler_Type, &Eul, &angle, &axis)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.RotateEuler(): expected euler type & float & string");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Euler_Rotate(Eul, Py_BuildValue("fs", angle, axis));
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
//----------------------------------Mathutils.MatMultVec() --------------
|
||||
//COLUMN VECTOR Multiplication (Matrix X Vector)
|
||||
PyObject *M_Mathutils_MatMultVec(PyObject * self, PyObject * args)
|
||||
{
|
||||
MatrixObject *mat = NULL;
|
||||
VectorObject *vec = NULL;
|
||||
static char warning = 1;
|
||||
|
||||
if( warning ) {
|
||||
printf("Mathutils.MatMultVec(): Deprecated: use matrix * vec to perform column vector multiplication\n");
|
||||
--warning;
|
||||
}
|
||||
|
||||
//get pyObjects
|
||||
if(!PyArg_ParseTuple(args, "O!O!", &matrix_Type, &mat, &vector_Type, &vec)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.MatMultVec(): MatMultVec() expects a matrix and a vector object - in that order\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return column_vector_multiplication(mat, vec);
|
||||
}
|
||||
//----------------------------------Mathutils.VecMultMat() ---------------
|
||||
//ROW VECTOR Multiplication - Vector X Matrix
|
||||
PyObject *M_Mathutils_VecMultMat(PyObject * self, PyObject * args)
|
||||
{
|
||||
MatrixObject *mat = NULL;
|
||||
VectorObject *vec = NULL;
|
||||
static char warning = 1;
|
||||
|
||||
if( warning ) {
|
||||
printf("Mathutils.VecMultMat(): Deprecated: use vec * matrix to perform row vector multiplication\n");
|
||||
--warning;
|
||||
}
|
||||
|
||||
//get pyObjects
|
||||
if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec, &matrix_Type, &mat)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.VecMultMat(): VecMultMat() expects a vector and matrix object - in that order\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return row_vector_multiplication(vec, mat);
|
||||
}
|
||||
|
||||
/* Utility functions */
|
||||
|
||||
|
||||
@@ -44,39 +44,6 @@ PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat);
|
||||
PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec);
|
||||
PyObject *quat_rotation(PyObject *arg1, PyObject *arg2);
|
||||
|
||||
PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_Vector(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_Matrix(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * value);
|
||||
PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_Quaternion(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_Euler(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args );
|
||||
PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args );
|
||||
PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args );
|
||||
PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args );
|
||||
PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args );
|
||||
//DEPRECATED
|
||||
PyObject *M_Mathutils_CopyMat(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_CopyVec(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_CopyQuat(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_CopyEuler(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_RotateEuler(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_MatMultVec(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_VecMultMat(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_CrossVecs(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_DotVecs(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_CrossQuats(PyObject * self, PyObject * args);
|
||||
PyObject *M_Mathutils_DotQuats(PyObject * self, PyObject * args);
|
||||
|
||||
int EXPP_FloatsAreEqual(float A, float B, int floatSteps);
|
||||
int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps);
|
||||
|
||||
|
||||
@@ -34,15 +34,24 @@
|
||||
|
||||
|
||||
//-------------------------DOC STRINGS ---------------------------
|
||||
char Euler_Zero_doc[] = "() - set all values in the euler to 0";
|
||||
char Euler_Unique_doc[] ="() - sets the euler rotation a unique shortest arc rotation - tests for gimbal lock";
|
||||
char Euler_ToMatrix_doc[] = "() - returns a rotation matrix representing the euler rotation";
|
||||
char Euler_ToQuat_doc[] = "() - returns a quaternion representing the euler rotation";
|
||||
char Euler_Rotate_doc[] = "() - rotate a euler by certain amount around an axis of rotation";
|
||||
char Euler_copy_doc[] = "() - returns a copy of the euler.";
|
||||
char Euler_MakeCompatible_doc[] = "(euler) - Make this user compatible with another (no axis flipping).";
|
||||
static char Euler_Zero_doc[] = "() - set all values in the euler to 0";
|
||||
static char Euler_Unique_doc[] ="() - sets the euler rotation a unique shortest arc rotation - tests for gimbal lock";
|
||||
static char Euler_ToMatrix_doc[] = "() - returns a rotation matrix representing the euler rotation";
|
||||
static char Euler_ToQuat_doc[] = "() - returns a quaternion representing the euler rotation";
|
||||
static char Euler_Rotate_doc[] = "() - rotate a euler by certain amount around an axis of rotation";
|
||||
static char Euler_copy_doc[] = "() - returns a copy of the euler.";
|
||||
static char Euler_MakeCompatible_doc[] = "(euler) - Make this user compatible with another (no axis flipping).";
|
||||
|
||||
static PyObject *Euler_Zero( EulerObject * self );
|
||||
static PyObject *Euler_Unique( EulerObject * self );
|
||||
static PyObject *Euler_ToMatrix( EulerObject * self );
|
||||
static PyObject *Euler_ToQuat( EulerObject * self );
|
||||
static PyObject *Euler_Rotate( EulerObject * self, PyObject *args );
|
||||
static PyObject *Euler_MakeCompatible( EulerObject * self, EulerObject *value );
|
||||
static PyObject *Euler_copy( EulerObject * self, PyObject *args );
|
||||
|
||||
//-----------------------METHOD DEFINITIONS ----------------------
|
||||
struct PyMethodDef Euler_methods[] = {
|
||||
static struct PyMethodDef Euler_methods[] = {
|
||||
{"zero", (PyCFunction) Euler_Zero, METH_NOARGS, Euler_Zero_doc},
|
||||
{"unique", (PyCFunction) Euler_Unique, METH_NOARGS, Euler_Unique_doc},
|
||||
{"toMatrix", (PyCFunction) Euler_ToMatrix, METH_NOARGS, Euler_ToMatrix_doc},
|
||||
@@ -53,10 +62,63 @@ struct PyMethodDef Euler_methods[] = {
|
||||
{"copy", (PyCFunction) Euler_copy, METH_VARARGS, Euler_copy_doc},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
//----------------------------------Mathutils.Euler() -------------------
|
||||
//makes a new euler for you to play with
|
||||
static PyObject *Euler_new(PyObject * self, PyObject * args)
|
||||
{
|
||||
|
||||
PyObject *listObject = NULL;
|
||||
int size, i;
|
||||
float eul[3], scalar;
|
||||
PyObject *e;
|
||||
|
||||
size = PyTuple_GET_SIZE(args);
|
||||
if (size == 1) {
|
||||
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, Py_NEW);
|
||||
} else {
|
||||
listObject = args;
|
||||
}
|
||||
|
||||
if (size != 3) { // Invalid euler size
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scalar= (float)PyFloat_AsDouble(e);
|
||||
Py_DECREF(e);
|
||||
|
||||
if(scalar==-1 && PyErr_Occurred()) { // parsed item is not a number
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Euler(): 3d numeric sequence expected\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
eul[i]= scalar;
|
||||
}
|
||||
return newEulerObject(eul, Py_NEW);
|
||||
}
|
||||
|
||||
//-----------------------------METHODS----------------------------
|
||||
//----------------------------Euler.toQuat()----------------------
|
||||
//return a quaternion representation of the euler
|
||||
PyObject *Euler_ToQuat(EulerObject * self)
|
||||
static PyObject *Euler_ToQuat(EulerObject * self)
|
||||
{
|
||||
float eul[3], quat[4];
|
||||
int x;
|
||||
@@ -69,7 +131,7 @@ PyObject *Euler_ToQuat(EulerObject * self)
|
||||
}
|
||||
//----------------------------Euler.toMatrix()---------------------
|
||||
//return a matrix representation of the euler
|
||||
PyObject *Euler_ToMatrix(EulerObject * self)
|
||||
static PyObject *Euler_ToMatrix(EulerObject * self)
|
||||
{
|
||||
float eul[3];
|
||||
float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
|
||||
@@ -83,7 +145,7 @@ PyObject *Euler_ToMatrix(EulerObject * self)
|
||||
}
|
||||
//----------------------------Euler.unique()-----------------------
|
||||
//sets the x,y,z values to a unique euler rotation
|
||||
PyObject *Euler_Unique(EulerObject * self)
|
||||
static PyObject *Euler_Unique(EulerObject * self)
|
||||
{
|
||||
double heading, pitch, bank;
|
||||
double pi2 = Py_PI * 2.0f;
|
||||
@@ -134,7 +196,7 @@ PyObject *Euler_Unique(EulerObject * self)
|
||||
}
|
||||
//----------------------------Euler.zero()-------------------------
|
||||
//sets the euler to 0,0,0
|
||||
PyObject *Euler_Zero(EulerObject * self)
|
||||
static PyObject *Euler_Zero(EulerObject * self)
|
||||
{
|
||||
self->eul[0] = 0.0;
|
||||
self->eul[1] = 0.0;
|
||||
@@ -146,7 +208,7 @@ PyObject *Euler_Zero(EulerObject * self)
|
||||
//----------------------------Euler.rotate()-----------------------
|
||||
//rotates a euler a certain amount and returns the result
|
||||
//should return a unique euler rotation (i.e. no 720 degree pitches :)
|
||||
PyObject *Euler_Rotate(EulerObject * self, PyObject *args)
|
||||
static PyObject *Euler_Rotate(EulerObject * self, PyObject *args)
|
||||
{
|
||||
float angle = 0.0f;
|
||||
char *axis;
|
||||
@@ -176,7 +238,7 @@ PyObject *Euler_Rotate(EulerObject * self, PyObject *args)
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
|
||||
static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
|
||||
{
|
||||
float eul_from_rad[3];
|
||||
int x;
|
||||
@@ -203,7 +265,7 @@ PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
|
||||
|
||||
//----------------------------Euler.rotate()-----------------------
|
||||
// return a copy of the euler
|
||||
PyObject *Euler_copy(EulerObject * self, PyObject *args)
|
||||
static PyObject *Euler_copy(EulerObject * self, PyObject *args)
|
||||
{
|
||||
return newEulerObject(self->eul, Py_NEW);
|
||||
}
|
||||
@@ -509,7 +571,7 @@ PyTypeObject euler_Type = {
|
||||
0, //tp_dictoffset
|
||||
0, //tp_init
|
||||
0, //tp_alloc
|
||||
0, //tp_new
|
||||
Euler_new, //tp_new
|
||||
0, //tp_free
|
||||
0, //tp_is_gc
|
||||
0, //tp_bases
|
||||
|
||||
@@ -54,13 +54,6 @@ be stored in py_data) or be a wrapper for data allocated through
|
||||
blender (stored in blend_data). This is an either/or struct not both*/
|
||||
|
||||
//prototypes
|
||||
PyObject *Euler_Zero( EulerObject * self );
|
||||
PyObject *Euler_Unique( EulerObject * self );
|
||||
PyObject *Euler_ToMatrix( EulerObject * self );
|
||||
PyObject *Euler_ToQuat( EulerObject * self );
|
||||
PyObject *Euler_Rotate( EulerObject * self, PyObject *args );
|
||||
PyObject *Euler_MakeCompatible( EulerObject * self, EulerObject *value );
|
||||
PyObject *Euler_copy( EulerObject * self, PyObject *args );
|
||||
PyObject *newEulerObject( float *eul, int type );
|
||||
|
||||
#endif /* EXPP_euler_h */
|
||||
|
||||
@@ -32,20 +32,34 @@
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
/*-------------------------DOC STRINGS ---------------------------*/
|
||||
char Matrix_Zero_doc[] = "() - set all values in the matrix to 0";
|
||||
char Matrix_Identity_doc[] = "() - set the square matrix to it's identity matrix";
|
||||
char Matrix_Transpose_doc[] = "() - set the matrix to it's transpose";
|
||||
char Matrix_Determinant_doc[] = "() - return the determinant of the matrix";
|
||||
char Matrix_Invert_doc[] = "() - set the matrix to it's inverse if an inverse is possible";
|
||||
char Matrix_TranslationPart_doc[] = "() - return a vector encompassing the translation of the matrix";
|
||||
char Matrix_RotationPart_doc[] = "() - return a vector encompassing the rotation of the matrix";
|
||||
char Matrix_scalePart_doc[] = "() - convert matrix to a 3D vector";
|
||||
char Matrix_Resize4x4_doc[] = "() - resize the matrix to a 4x4 square matrix";
|
||||
char Matrix_toEuler_doc[] = "(eul_compat) - convert matrix to a euler angle rotation, optional euler argument that the new euler will be made compatible with.";
|
||||
char Matrix_toQuat_doc[] = "() - convert matrix to a quaternion rotation";
|
||||
char Matrix_copy_doc[] = "() - return a copy of the matrix";
|
||||
static char Matrix_Zero_doc[] = "() - set all values in the matrix to 0";
|
||||
static char Matrix_Identity_doc[] = "() - set the square matrix to it's identity matrix";
|
||||
static char Matrix_Transpose_doc[] = "() - set the matrix to it's transpose";
|
||||
static char Matrix_Determinant_doc[] = "() - return the determinant of the matrix";
|
||||
static char Matrix_Invert_doc[] = "() - set the matrix to it's inverse if an inverse is possible";
|
||||
static char Matrix_TranslationPart_doc[] = "() - return a vector encompassing the translation of the matrix";
|
||||
static char Matrix_RotationPart_doc[] = "() - return a vector encompassing the rotation of the matrix";
|
||||
static char Matrix_scalePart_doc[] = "() - convert matrix to a 3D vector";
|
||||
static char Matrix_Resize4x4_doc[] = "() - resize the matrix to a 4x4 square matrix";
|
||||
static char Matrix_toEuler_doc[] = "(eul_compat) - convert matrix to a euler angle rotation, optional euler argument that the new euler will be made compatible with.";
|
||||
static char Matrix_toQuat_doc[] = "() - convert matrix to a quaternion rotation";
|
||||
static char Matrix_copy_doc[] = "() - return a copy of the matrix";
|
||||
|
||||
static PyObject *Matrix_Zero( MatrixObject * self );
|
||||
static PyObject *Matrix_Identity( MatrixObject * self );
|
||||
static PyObject *Matrix_Transpose( MatrixObject * self );
|
||||
static PyObject *Matrix_Determinant( MatrixObject * self );
|
||||
static PyObject *Matrix_Invert( MatrixObject * self );
|
||||
static PyObject *Matrix_TranslationPart( MatrixObject * self );
|
||||
static PyObject *Matrix_RotationPart( MatrixObject * self );
|
||||
static PyObject *Matrix_scalePart( MatrixObject * self );
|
||||
static PyObject *Matrix_Resize4x4( MatrixObject * self );
|
||||
static PyObject *Matrix_toEuler( MatrixObject * self, PyObject *args );
|
||||
static PyObject *Matrix_toQuat( MatrixObject * self );
|
||||
static PyObject *Matrix_copy( MatrixObject * self );
|
||||
|
||||
/*-----------------------METHOD DEFINITIONS ----------------------*/
|
||||
struct PyMethodDef Matrix_methods[] = {
|
||||
static struct PyMethodDef Matrix_methods[] = {
|
||||
{"zero", (PyCFunction) Matrix_Zero, METH_NOARGS, Matrix_Zero_doc},
|
||||
{"identity", (PyCFunction) Matrix_Identity, METH_NOARGS, Matrix_Identity_doc},
|
||||
{"transpose", (PyCFunction) Matrix_Transpose, METH_NOARGS, Matrix_Transpose_doc},
|
||||
@@ -61,9 +75,86 @@ struct PyMethodDef Matrix_methods[] = {
|
||||
{"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
//----------------------------------Mathutils.Matrix() -----------------
|
||||
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
|
||||
//create a new matrix type
|
||||
static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *argObject, *m, *s;
|
||||
MatrixObject *mat;
|
||||
int argSize, seqSize = 0, i, j;
|
||||
float matrix[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
|
||||
float scalar;
|
||||
|
||||
argSize = PyTuple_GET_SIZE(args);
|
||||
if(argSize > 4){ //bad arg nums
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
} else if (argSize == 0) { //return empty 4D matrix
|
||||
return (PyObject *) newMatrixObject(NULL, 4, 4, Py_NEW);
|
||||
}else if (argSize == 1){
|
||||
//copy constructor for matrix objects
|
||||
argObject = PyTuple_GET_ITEM(args, 0);
|
||||
if(MatrixObject_Check(argObject)){
|
||||
mat = (MatrixObject*)argObject;
|
||||
|
||||
argSize = mat->rowSize; //rows
|
||||
seqSize = mat->colSize; //col
|
||||
for(i = 0; i < (seqSize * argSize); i++){
|
||||
matrix[i] = mat->contigPtr[i];
|
||||
}
|
||||
}
|
||||
}else{ //2-4 arguments (all seqs? all same size?)
|
||||
for(i =0; i < argSize; i++){
|
||||
argObject = PyTuple_GET_ITEM(args, i);
|
||||
if (PySequence_Check(argObject)) { //seq?
|
||||
if(seqSize){ //0 at first
|
||||
if(PySequence_Length(argObject) != seqSize){ //seq size not same
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
seqSize = PySequence_Length(argObject);
|
||||
}else{ //arg not a sequence
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
//all is well... let's continue parsing
|
||||
for (i = 0; i < argSize; i++){
|
||||
m = PyTuple_GET_ITEM(args, i);
|
||||
if (m == NULL) { // Failed to read sequence
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (j = 0; j < seqSize; j++) {
|
||||
s = PySequence_GetItem(m, j);
|
||||
if (s == NULL) { // Failed to read sequence
|
||||
PyErr_SetString(PyExc_RuntimeError, "Mathutils.Matrix(): failed to parse arguments...\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scalar= (float)PyFloat_AsDouble(s);
|
||||
Py_DECREF(s);
|
||||
|
||||
if(scalar==-1 && PyErr_Occurred()) { // parsed item is not a number
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Matrix(): expects 0-4 numeric sequences of the same size\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
matrix[(seqSize*i)+j]= scalar;
|
||||
}
|
||||
}
|
||||
}
|
||||
return newMatrixObject(matrix, argSize, seqSize, Py_NEW);
|
||||
}
|
||||
|
||||
/*-----------------------------METHODS----------------------------*/
|
||||
/*---------------------------Matrix.toQuat() ---------------------*/
|
||||
PyObject *Matrix_toQuat(MatrixObject * self)
|
||||
static PyObject *Matrix_toQuat(MatrixObject * self)
|
||||
{
|
||||
float quat[4];
|
||||
|
||||
@@ -387,7 +478,6 @@ PyObject *Matrix_copy(MatrixObject * self)
|
||||
/*free the py_object*/
|
||||
static void Matrix_dealloc(MatrixObject * self)
|
||||
{
|
||||
Py_XDECREF(self->coerced_object);
|
||||
PyMem_Free(self->matrix);
|
||||
/*only free py_data*/
|
||||
if(self->data.py_data){
|
||||
@@ -395,35 +485,7 @@ static void Matrix_dealloc(MatrixObject * self)
|
||||
}
|
||||
PyObject_DEL(self);
|
||||
}
|
||||
/*----------------------------getattr()(internal) ----------------*/
|
||||
/*object.attribute access (get)*/
|
||||
static PyObject *Matrix_getattr(MatrixObject * self, char *name)
|
||||
{
|
||||
if(STREQ(name, "rowSize")) {
|
||||
return PyLong_FromLong((long) self->rowSize);
|
||||
} else if(STREQ(name, "colSize")) {
|
||||
return PyLong_FromLong((long) self->colSize);
|
||||
}
|
||||
if(STREQ(name, "wrapped")){
|
||||
if(self->wrapped == Py_WRAP)
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
#if 0 //XXX
|
||||
return Py_FindMethod(Matrix_methods, (PyObject *) self, name);
|
||||
#else
|
||||
PyErr_SetString(PyExc_AttributeError, "blender 2.5 is not finished yet");
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
/*----------------------------setattr()(internal) ----------------*/
|
||||
/*object.attribute access (set)*/
|
||||
static int Matrix_setattr(MatrixObject * self, char *name, PyObject * v)
|
||||
{
|
||||
/* This is not supported. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*----------------------------print object (internal)-------------*/
|
||||
/*print the object to screen*/
|
||||
static PyObject *Matrix_repr(MatrixObject * self)
|
||||
@@ -672,7 +734,7 @@ static PyObject *Matrix_add(PyObject * m1, PyObject * m2)
|
||||
mat1 = (MatrixObject*)m1;
|
||||
mat2 = (MatrixObject*)m2;
|
||||
|
||||
if(mat1->coerced_object || mat2->coerced_object){
|
||||
if(!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) {
|
||||
PyErr_SetString(PyExc_AttributeError, "Matrix addition: arguments not valid for this operation....");
|
||||
return NULL;
|
||||
}
|
||||
@@ -701,7 +763,7 @@ static PyObject *Matrix_sub(PyObject * m1, PyObject * m2)
|
||||
mat1 = (MatrixObject*)m1;
|
||||
mat2 = (MatrixObject*)m2;
|
||||
|
||||
if(mat1->coerced_object || mat2->coerced_object){
|
||||
if(!MatrixObject_Check(m1) || !MatrixObject_Check(m2)) {
|
||||
PyErr_SetString(PyExc_AttributeError, "Matrix addition: arguments not valid for this operation....");
|
||||
return NULL;
|
||||
}
|
||||
@@ -728,22 +790,31 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
|
||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
|
||||
double dot = 0.0f;
|
||||
MatrixObject *mat1 = NULL, *mat2 = NULL;
|
||||
PyObject *f = NULL;
|
||||
|
||||
mat1 = (MatrixObject*)m1;
|
||||
mat2 = (MatrixObject*)m2;
|
||||
if(MatrixObject_Check(m1)) mat1 = (MatrixObject*)m1;
|
||||
if(MatrixObject_Check(m2)) mat2 = (MatrixObject*)m2;
|
||||
|
||||
if(mat1->coerced_object){
|
||||
if (PyFloat_Check(mat1->coerced_object) ||
|
||||
PyLong_Check(mat1->coerced_object)){ /*FLOAT/INT * MATRIX*/
|
||||
f = PyNumber_Float(mat1->coerced_object);
|
||||
if(f == NULL) { /*parsed item not a number*/
|
||||
PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation");
|
||||
return NULL;
|
||||
if(mat1 && mat2) { /*MATRIX * MATRIX*/
|
||||
if(mat1->colSize != mat2->rowSize){
|
||||
PyErr_SetString(PyExc_AttributeError,"Matrix multiplication: matrix A rowsize must equal matrix B colsize");
|
||||
return NULL;
|
||||
}
|
||||
for(x = 0; x < mat1->rowSize; x++) {
|
||||
for(y = 0; y < mat2->colSize; y++) {
|
||||
for(z = 0; z < mat1->colSize; z++) {
|
||||
dot += (mat1->matrix[x][z] * mat2->matrix[z][y]);
|
||||
}
|
||||
mat[((x * mat1->rowSize) + y)] = (float)dot;
|
||||
dot = 0.0f;
|
||||
}
|
||||
|
||||
scalar = (float)PyFloat_AS_DOUBLE(f);
|
||||
Py_DECREF(f);
|
||||
}
|
||||
|
||||
return newMatrixObject(mat, mat1->rowSize, mat2->colSize, Py_NEW);
|
||||
}
|
||||
|
||||
if(mat1==NULL){
|
||||
scalar=PyFloat_AsDouble(m1); // may not be a float...
|
||||
if ((scalar == -1.0 && PyErr_Occurred())==0) { /*FLOAT/INT * MATRIX, this line annoys theeth, lets see if he finds it */
|
||||
for(x = 0; x < mat2->rowSize; x++) {
|
||||
for(y = 0; y < mat2->colSize; y++) {
|
||||
mat[((x * mat2->colSize) + y)] = scalar * mat2->matrix[x][y];
|
||||
@@ -751,22 +822,18 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
|
||||
}
|
||||
return newMatrixObject(mat, mat2->rowSize, mat2->colSize, Py_NEW);
|
||||
}
|
||||
}else{
|
||||
if(mat2->coerced_object){
|
||||
/* MATRIX * VECTOR operation is now being done by vector */
|
||||
/*if(VectorObject_Check(mat2->coerced_object)){
|
||||
vec = (VectorObject*)mat2->coerced_object;
|
||||
return column_vector_multiplication(mat1, vec);
|
||||
}else */
|
||||
if (PyFloat_Check(mat2->coerced_object) || PyLong_Check(mat2->coerced_object)){ /*MATRIX * FLOAT/INT*/
|
||||
f = PyNumber_Float(mat2->coerced_object);
|
||||
if(f == NULL) { /*parsed item not a number*/
|
||||
PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scalar = (float)PyFloat_AS_DOUBLE(f);
|
||||
Py_DECREF(f);
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation");
|
||||
return NULL;
|
||||
}
|
||||
else /* if(mat1) { */ {
|
||||
|
||||
if(VectorObject_Check(m2)) { /* MATRIX*VECTOR */
|
||||
return column_vector_multiplication(mat1, (VectorObject *)m2);
|
||||
}
|
||||
else {
|
||||
scalar= PyFloat_AsDouble(m2);
|
||||
if ((scalar == -1.0 && PyErr_Occurred())==0) { /* MATRIX*FLOAT/INT */
|
||||
for(x = 0; x < mat1->rowSize; x++) {
|
||||
for(y = 0; y < mat1->colSize; y++) {
|
||||
mat[((x * mat1->colSize) + y)] = scalar * mat1->matrix[x][y];
|
||||
@@ -774,22 +841,9 @@ static PyObject *Matrix_mul(PyObject * m1, PyObject * m2)
|
||||
}
|
||||
return newMatrixObject(mat, mat1->rowSize, mat1->colSize, Py_NEW);
|
||||
}
|
||||
}else{ /*MATRIX * MATRIX*/
|
||||
if(mat1->colSize != mat2->rowSize){
|
||||
PyErr_SetString(PyExc_AttributeError,"Matrix multiplication: matrix A rowsize must equal matrix B colsize");
|
||||
return NULL;
|
||||
}
|
||||
for(x = 0; x < mat1->rowSize; x++) {
|
||||
for(y = 0; y < mat2->colSize; y++) {
|
||||
for(z = 0; z < mat1->colSize; z++) {
|
||||
dot += (mat1->matrix[x][z] * mat2->matrix[z][y]);
|
||||
}
|
||||
mat[((x * mat1->rowSize) + y)] = (float)dot;
|
||||
dot = 0.0f;
|
||||
}
|
||||
}
|
||||
return newMatrixObject(mat, mat1->rowSize, mat2->colSize, Py_NEW);
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Matrix multiplication: arguments not acceptable for this operation\n");
|
||||
@@ -799,29 +853,7 @@ static PyObject* Matrix_inv(MatrixObject *self)
|
||||
{
|
||||
return Matrix_Invert(self);
|
||||
}
|
||||
/*------------------------coerce(obj, obj)-----------------------
|
||||
coercion of unknown types to type MatrixObject for numeric protocols.
|
||||
|
||||
Coercion() is called whenever a math operation has 2 operands that
|
||||
it doesn't understand how to evaluate. 2+Matrix for example. We want to
|
||||
evaluate some of these operations like: (vector * 2), however, for math
|
||||
to proceed, the unknown operand must be cast to a type that python math will
|
||||
understand. (e.g. in the case above case, 2 must be cast to a vector and
|
||||
then call vector.multiply(vector, scalar_cast_as_vector)*/
|
||||
static int Matrix_coerce(PyObject ** m1, PyObject ** m2)
|
||||
{
|
||||
if(VectorObject_Check(*m2) || PyFloat_Check(*m2) || PyLong_Check(*m2)) {
|
||||
PyObject *coerced = (PyObject *)(*m2);
|
||||
Py_INCREF(coerced);
|
||||
*m2 = newMatrixObject(NULL,3,3,Py_NEW);
|
||||
((MatrixObject*)*m2)->coerced_object = coerced;
|
||||
Py_INCREF (*m1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "matrix.coerce(): unknown operand - can't coerce for numeric protocols");
|
||||
return -1;
|
||||
}
|
||||
/*-----------------PROTOCOL DECLARATIONS--------------------------*/
|
||||
static PySequenceMethods Matrix_SeqMethods = {
|
||||
(inquiry) Matrix_len, /* sq_length */
|
||||
@@ -850,17 +882,42 @@ static PyNumberMethods Matrix_NumMethods = {
|
||||
(binaryfunc) 0, /* __and__ */
|
||||
(binaryfunc) 0, /* __xor__ */
|
||||
(binaryfunc) 0, /* __or__ */
|
||||
#if 0 // XXX 2.5
|
||||
(coercion) Matrix_coerce, /* __coerce__ */
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
/*(coercion)*/ 0, /* __coerce__ */
|
||||
(unaryfunc) 0, /* __int__ */
|
||||
(unaryfunc) 0, /* __long__ */
|
||||
(unaryfunc) 0, /* __float__ */
|
||||
(unaryfunc) 0, /* __oct__ */
|
||||
(unaryfunc) 0, /* __hex__ */
|
||||
};
|
||||
|
||||
static PyObject *Matrix_getRowSize( MatrixObject * self, void *type )
|
||||
{
|
||||
return PyLong_FromLong((long) self->rowSize);
|
||||
}
|
||||
|
||||
static PyObject *Matrix_getColSize( MatrixObject * self, void *type )
|
||||
{
|
||||
return PyLong_FromLong((long) self->colSize);
|
||||
}
|
||||
|
||||
static PyObject *Matrix_getWrapped( MatrixObject * self, void *type )
|
||||
{
|
||||
if (self->wrapped == Py_WRAP)
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Python attributes get/set structure: */
|
||||
/*****************************************************************************/
|
||||
static PyGetSetDef Matrix_getseters[] = {
|
||||
{"rowSize", (getter)Matrix_getRowSize, (setter)NULL, "", NULL},
|
||||
{"colSize", (getter)Matrix_getColSize, (setter)NULL, "", NULL},
|
||||
{"wrapped", (getter)Matrix_getWrapped, (setter)NULL, "", NULL},
|
||||
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
/*------------------PY_OBECT DEFINITION--------------------------*/
|
||||
PyTypeObject matrix_Type = {
|
||||
#if (PY_VERSION_HEX >= 0x02060000)
|
||||
@@ -875,8 +932,8 @@ PyTypeObject matrix_Type = {
|
||||
0, /*tp_itemsize*/
|
||||
(destructor)Matrix_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
(getattrfunc)Matrix_getattr, /*tp_getattr*/
|
||||
(setattrfunc) Matrix_setattr, /*tp_setattr*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
(reprfunc) Matrix_repr, /*tp_repr*/
|
||||
&Matrix_NumMethods, /*tp_as_number*/
|
||||
@@ -896,9 +953,9 @@ PyTypeObject matrix_Type = {
|
||||
0, /*tp_weaklistoffset*/
|
||||
0, /*tp_iter*/
|
||||
0, /*tp_iternext*/
|
||||
0, /*tp_methods*/
|
||||
Matrix_methods, /*tp_methods*/
|
||||
0, /*tp_members*/
|
||||
0, /*tp_getset*/
|
||||
Matrix_getseters, /*tp_getset*/
|
||||
0, /*tp_base*/
|
||||
0, /*tp_dict*/
|
||||
0, /*tp_descr_get*/
|
||||
@@ -906,7 +963,7 @@ PyTypeObject matrix_Type = {
|
||||
0, /*tp_dictoffset*/
|
||||
0, /*tp_init*/
|
||||
0, /*tp_alloc*/
|
||||
0, /*tp_new*/
|
||||
Matrix_new, /*tp_new*/
|
||||
0, /*tp_free*/
|
||||
0, /*tp_is_gc*/
|
||||
0, /*tp_bases*/
|
||||
@@ -949,7 +1006,6 @@ PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type)
|
||||
self->data.py_data = NULL;
|
||||
self->rowSize = rowSize;
|
||||
self->colSize = colSize;
|
||||
self->coerced_object = NULL;
|
||||
|
||||
if(type == Py_WRAP){
|
||||
self->data.blend_data = mat;
|
||||
|
||||
@@ -48,11 +48,7 @@ typedef struct _Matrix {
|
||||
int rowSize;
|
||||
int colSize;
|
||||
int wrapped; /*is wrapped data?*/
|
||||
PyObject *coerced_object;
|
||||
} MatrixObject;
|
||||
/*coerced_object is a pointer to the object that it was
|
||||
coerced from when a dummy vector needs to be created from
|
||||
the coerce() function for numeric protocol operations*/
|
||||
|
||||
/*struct data contains a pointer to the actual data that the
|
||||
object uses. It can use either PyMem allocated data (which will
|
||||
@@ -60,18 +56,6 @@ be stored in py_data) or be a wrapper for data allocated through
|
||||
blender (stored in blend_data). This is an either/or struct not both*/
|
||||
|
||||
/*prototypes*/
|
||||
PyObject *Matrix_Zero( MatrixObject * self );
|
||||
PyObject *Matrix_Identity( MatrixObject * self );
|
||||
PyObject *Matrix_Transpose( MatrixObject * self );
|
||||
PyObject *Matrix_Determinant( MatrixObject * self );
|
||||
PyObject *Matrix_Invert( MatrixObject * self );
|
||||
PyObject *Matrix_TranslationPart( MatrixObject * self );
|
||||
PyObject *Matrix_RotationPart( MatrixObject * self );
|
||||
PyObject *Matrix_scalePart( MatrixObject * self );
|
||||
PyObject *Matrix_Resize4x4( MatrixObject * self );
|
||||
PyObject *Matrix_toEuler( MatrixObject * self, PyObject *args );
|
||||
PyObject *Matrix_toQuat( MatrixObject * self );
|
||||
PyObject *Matrix_copy( MatrixObject * self );
|
||||
PyObject *newMatrixObject(float *mat, int rowSize, int colSize, int type);
|
||||
|
||||
#endif /* EXPP_matrix_H */
|
||||
|
||||
@@ -34,18 +34,30 @@
|
||||
|
||||
|
||||
//-------------------------DOC STRINGS ---------------------------
|
||||
char Quaternion_Identity_doc[] = "() - set the quaternion to it's identity (1, vector)";
|
||||
char Quaternion_Negate_doc[] = "() - set all values in the quaternion to their negative";
|
||||
char Quaternion_Conjugate_doc[] = "() - set the quaternion to it's conjugate";
|
||||
char Quaternion_Inverse_doc[] = "() - set the quaternion to it's inverse";
|
||||
char Quaternion_Normalize_doc[] = "() - normalize the vector portion of the quaternion";
|
||||
char Quaternion_ToEuler_doc[] = "(eul_compat) - return a euler rotation representing the quaternion, optional euler argument that the new euler will be made compatible with.";
|
||||
char Quaternion_ToMatrix_doc[] = "() - return a rotation matrix representing the quaternion";
|
||||
char Quaternion_Cross_doc[] = "(other) - return the cross product between this quaternion and another";
|
||||
char Quaternion_Dot_doc[] = "(other) - return the dot product between this quaternion and another";
|
||||
char Quaternion_copy_doc[] = "() - return a copy of the quat";
|
||||
static char Quaternion_Identity_doc[] = "() - set the quaternion to it's identity (1, vector)";
|
||||
static char Quaternion_Negate_doc[] = "() - set all values in the quaternion to their negative";
|
||||
static char Quaternion_Conjugate_doc[] = "() - set the quaternion to it's conjugate";
|
||||
static char Quaternion_Inverse_doc[] = "() - set the quaternion to it's inverse";
|
||||
static char Quaternion_Normalize_doc[] = "() - normalize the vector portion of the quaternion";
|
||||
static char Quaternion_ToEuler_doc[] = "(eul_compat) - return a euler rotation representing the quaternion, optional euler argument that the new euler will be made compatible with.";
|
||||
static char Quaternion_ToMatrix_doc[] = "() - return a rotation matrix representing the quaternion";
|
||||
static char Quaternion_Cross_doc[] = "(other) - return the cross product between this quaternion and another";
|
||||
static char Quaternion_Dot_doc[] = "(other) - return the dot product between this quaternion and another";
|
||||
static char Quaternion_copy_doc[] = "() - return a copy of the quat";
|
||||
|
||||
static PyObject *Quaternion_Identity( QuaternionObject * self );
|
||||
static PyObject *Quaternion_Negate( QuaternionObject * self );
|
||||
static PyObject *Quaternion_Conjugate( QuaternionObject * self );
|
||||
static PyObject *Quaternion_Inverse( QuaternionObject * self );
|
||||
static PyObject *Quaternion_Normalize( QuaternionObject * self );
|
||||
static PyObject *Quaternion_ToEuler( QuaternionObject * self, PyObject *args );
|
||||
static PyObject *Quaternion_ToMatrix( QuaternionObject * self );
|
||||
static PyObject *Quaternion_Cross( QuaternionObject * self, QuaternionObject * value );
|
||||
static PyObject *Quaternion_Dot( QuaternionObject * self, QuaternionObject * value );
|
||||
static PyObject *Quaternion_copy( QuaternionObject * self );
|
||||
|
||||
//-----------------------METHOD DEFINITIONS ----------------------
|
||||
struct PyMethodDef Quaternion_methods[] = {
|
||||
static struct PyMethodDef Quaternion_methods[] = {
|
||||
{"identity", (PyCFunction) Quaternion_Identity, METH_NOARGS, Quaternion_Identity_doc},
|
||||
{"negate", (PyCFunction) Quaternion_Negate, METH_NOARGS, Quaternion_Negate_doc},
|
||||
{"conjugate", (PyCFunction) Quaternion_Conjugate, METH_NOARGS, Quaternion_Conjugate_doc},
|
||||
@@ -59,10 +71,117 @@ struct PyMethodDef Quaternion_methods[] = {
|
||||
{"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
//----------------------------------Mathutils.Quaternion() --------------
|
||||
static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *listObject = NULL, *n, *q, *f;
|
||||
int size, i;
|
||||
float quat[4], scalar;
|
||||
double norm = 0.0f, angle = 0.0f;
|
||||
|
||||
size = PyTuple_GET_SIZE(args);
|
||||
if (size == 1 || size == 2) { //seq?
|
||||
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);
|
||||
Py_DECREF(n);
|
||||
|
||||
if (angle==-1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
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);
|
||||
} 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;
|
||||
}
|
||||
}else{
|
||||
if(size != 4){
|
||||
PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
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;
|
||||
}
|
||||
|
||||
scalar = PyFloat_AsDouble(q);
|
||||
if (scalar==-1 && PyErr_Occurred()) {
|
||||
Py_DECREF(q);
|
||||
PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
quat[i] = scalar;
|
||||
Py_DECREF(f);
|
||||
Py_DECREF(q);
|
||||
}
|
||||
if(size == 3){ //calculate the quat based on axis/angle
|
||||
norm = sqrt(quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2]);
|
||||
quat[0] /= (float)norm;
|
||||
quat[1] /= (float)norm;
|
||||
quat[2] /= (float)norm;
|
||||
|
||||
angle = angle * (Py_PI / 180);
|
||||
quat[3] =(float) (sin(angle/ 2.0f)) * quat[2];
|
||||
quat[2] =(float) (sin(angle/ 2.0f)) * quat[1];
|
||||
quat[1] =(float) (sin(angle/ 2.0f)) * quat[0];
|
||||
quat[0] =(float) (cos(angle/ 2.0f));
|
||||
}
|
||||
|
||||
return newQuaternionObject(quat, Py_NEW);
|
||||
}
|
||||
|
||||
//-----------------------------METHODS------------------------------
|
||||
//----------------------------Quaternion.toEuler()------------------
|
||||
//return the quat as a euler
|
||||
PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
|
||||
static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
|
||||
{
|
||||
float eul[3];
|
||||
EulerObject *eul_compat = NULL;
|
||||
@@ -93,7 +212,7 @@ PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
|
||||
}
|
||||
//----------------------------Quaternion.toMatrix()------------------
|
||||
//return the quat as a matrix
|
||||
PyObject *Quaternion_ToMatrix(QuaternionObject * self)
|
||||
static PyObject *Quaternion_ToMatrix(QuaternionObject * self)
|
||||
{
|
||||
float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
|
||||
QuatToMat3(self->quat, (float (*)[3]) mat);
|
||||
@@ -103,7 +222,7 @@ PyObject *Quaternion_ToMatrix(QuaternionObject * self)
|
||||
|
||||
//----------------------------Quaternion.cross(other)------------------
|
||||
//return the cross quat
|
||||
PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * value)
|
||||
static PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * value)
|
||||
{
|
||||
float quat[4];
|
||||
|
||||
@@ -118,7 +237,7 @@ PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * value)
|
||||
|
||||
//----------------------------Quaternion.dot(other)------------------
|
||||
//return the dot quat
|
||||
PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value)
|
||||
static PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value)
|
||||
{
|
||||
int x;
|
||||
double dot = 0.0;
|
||||
@@ -136,7 +255,7 @@ PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value)
|
||||
|
||||
//----------------------------Quaternion.normalize()----------------
|
||||
//normalize the axis of rotation of [theta,vector]
|
||||
PyObject *Quaternion_Normalize(QuaternionObject * self)
|
||||
static PyObject *Quaternion_Normalize(QuaternionObject * self)
|
||||
{
|
||||
NormalQuat(self->quat);
|
||||
Py_INCREF(self);
|
||||
@@ -144,7 +263,7 @@ PyObject *Quaternion_Normalize(QuaternionObject * self)
|
||||
}
|
||||
//----------------------------Quaternion.inverse()------------------
|
||||
//invert the quat
|
||||
PyObject *Quaternion_Inverse(QuaternionObject * self)
|
||||
static PyObject *Quaternion_Inverse(QuaternionObject * self)
|
||||
{
|
||||
double mag = 0.0f;
|
||||
int x;
|
||||
@@ -165,7 +284,7 @@ PyObject *Quaternion_Inverse(QuaternionObject * self)
|
||||
}
|
||||
//----------------------------Quaternion.identity()-----------------
|
||||
//generate the identity quaternion
|
||||
PyObject *Quaternion_Identity(QuaternionObject * self)
|
||||
static PyObject *Quaternion_Identity(QuaternionObject * self)
|
||||
{
|
||||
self->quat[0] = 1.0;
|
||||
self->quat[1] = 0.0;
|
||||
@@ -177,7 +296,7 @@ PyObject *Quaternion_Identity(QuaternionObject * self)
|
||||
}
|
||||
//----------------------------Quaternion.negate()-------------------
|
||||
//negate the quat
|
||||
PyObject *Quaternion_Negate(QuaternionObject * self)
|
||||
static PyObject *Quaternion_Negate(QuaternionObject * self)
|
||||
{
|
||||
int x;
|
||||
for(x = 0; x < 4; x++) {
|
||||
@@ -188,7 +307,7 @@ PyObject *Quaternion_Negate(QuaternionObject * self)
|
||||
}
|
||||
//----------------------------Quaternion.conjugate()----------------
|
||||
//negate the vector part
|
||||
PyObject *Quaternion_Conjugate(QuaternionObject * self)
|
||||
static PyObject *Quaternion_Conjugate(QuaternionObject * self)
|
||||
{
|
||||
int x;
|
||||
for(x = 1; x < 4; x++) {
|
||||
@@ -199,7 +318,7 @@ PyObject *Quaternion_Conjugate(QuaternionObject * self)
|
||||
}
|
||||
//----------------------------Quaternion.copy()----------------
|
||||
//return a copy of the quat
|
||||
PyObject *Quaternion_copy(QuaternionObject * self)
|
||||
static PyObject *Quaternion_copy(QuaternionObject * self)
|
||||
{
|
||||
return newQuaternionObject(self->quat, Py_NEW);
|
||||
}
|
||||
@@ -208,7 +327,6 @@ PyObject *Quaternion_copy(QuaternionObject * self)
|
||||
//free the py_object
|
||||
static void Quaternion_dealloc(QuaternionObject * self)
|
||||
{
|
||||
Py_XDECREF(self->coerced_object);
|
||||
//only free py_data
|
||||
if(self->data.py_data){
|
||||
PyMem_Free(self->data.py_data);
|
||||
@@ -377,13 +495,14 @@ static PyObject *Quaternion_add(PyObject * q1, PyObject * q2)
|
||||
float quat[4];
|
||||
QuaternionObject *quat1 = NULL, *quat2 = NULL;
|
||||
|
||||
quat1 = (QuaternionObject*)q1;
|
||||
quat2 = (QuaternionObject*)q2;
|
||||
|
||||
if(quat1->coerced_object || quat2->coerced_object){
|
||||
if(!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) {
|
||||
PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation....\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
quat1 = (QuaternionObject*)q1;
|
||||
quat2 = (QuaternionObject*)q2;
|
||||
|
||||
for(x = 0; x < 4; x++) {
|
||||
quat[x] = quat1->quat[x] + quat2->quat[x];
|
||||
}
|
||||
@@ -398,13 +517,14 @@ static PyObject *Quaternion_sub(PyObject * q1, PyObject * q2)
|
||||
float quat[4];
|
||||
QuaternionObject *quat1 = NULL, *quat2 = NULL;
|
||||
|
||||
quat1 = (QuaternionObject*)q1;
|
||||
quat2 = (QuaternionObject*)q2;
|
||||
|
||||
if(quat1->coerced_object || quat2->coerced_object){
|
||||
if(!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) {
|
||||
PyErr_SetString(PyExc_AttributeError, "Quaternion addition: arguments not valid for this operation....\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
quat1 = (QuaternionObject*)q1;
|
||||
quat2 = (QuaternionObject*)q2;
|
||||
|
||||
for(x = 0; x < 4; x++) {
|
||||
quat[x] = quat1->quat[x] - quat2->quat[x];
|
||||
}
|
||||
@@ -419,86 +539,53 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
|
||||
float quat[4], scalar;
|
||||
double dot = 0.0f;
|
||||
QuaternionObject *quat1 = NULL, *quat2 = NULL;
|
||||
PyObject *f = NULL;
|
||||
VectorObject *vec = NULL;
|
||||
|
||||
quat1 = (QuaternionObject*)q1;
|
||||
quat2 = (QuaternionObject*)q2;
|
||||
|
||||
if(quat1->coerced_object){
|
||||
if (PyFloat_Check(quat1->coerced_object) ||
|
||||
PyLong_Check(quat1->coerced_object)){ // FLOAT/INT * QUAT
|
||||
f = PyNumber_Float(quat1->coerced_object);
|
||||
if(f == NULL) { // parsed item not a number
|
||||
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: arguments not acceptable for this operation\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scalar = (float)PyFloat_AS_DOUBLE(f);
|
||||
Py_DECREF(f);
|
||||
if(QuaternionObject_Check(q1) && QuaternionObject_Check(q2)) { /* QUAT*QUAT (dot product) */
|
||||
for(x = 0; x < 4; x++) {
|
||||
dot += quat1->quat[x] * quat1->quat[x];
|
||||
}
|
||||
return PyFloat_FromDouble(dot);
|
||||
}
|
||||
|
||||
/* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */
|
||||
if(!QuaternionObject_Check(q1)) {
|
||||
scalar= PyFloat_AsDouble(q1);
|
||||
if ((scalar == -1.0 && PyErr_Occurred())==0) { /* FLOAT*QUAT */
|
||||
for(x = 0; x < 4; x++) {
|
||||
quat[x] = quat2->quat[x] * scalar;
|
||||
}
|
||||
return newQuaternionObject(quat, Py_NEW);
|
||||
}
|
||||
}else{
|
||||
if(quat2->coerced_object){
|
||||
if (PyFloat_Check(quat2->coerced_object) ||
|
||||
PyLong_Check(quat2->coerced_object)){ // QUAT * FLOAT/INT
|
||||
f = PyNumber_Float(quat2->coerced_object);
|
||||
if(f == NULL) { // parsed item not a number
|
||||
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: arguments not acceptable for this operation\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scalar = (float)PyFloat_AS_DOUBLE(f);
|
||||
Py_DECREF(f);
|
||||
for(x = 0; x < 4; x++) {
|
||||
quat[x] = quat1->quat[x] * scalar;
|
||||
}
|
||||
return newQuaternionObject(quat, Py_NEW);
|
||||
}else if(VectorObject_Check(quat2->coerced_object)){ //QUAT * VEC
|
||||
vec = (VectorObject*)quat2->coerced_object;
|
||||
if(vec->size != 3){
|
||||
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: only 3D vector rotations currently supported\n");
|
||||
return NULL;
|
||||
}
|
||||
return quat_rotation((PyObject*)quat1, (PyObject*)vec);
|
||||
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: val * quat, val is not an acceptable type");
|
||||
return NULL;
|
||||
}
|
||||
else { /* QUAT*SOMETHING */
|
||||
if(VectorObject_Check(q2)){ /* QUAT*VEC */
|
||||
vec = (VectorObject*)q2;
|
||||
if(vec->size != 3){
|
||||
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: only 3D vector rotations currently supported\n");
|
||||
return NULL;
|
||||
}
|
||||
}else{ //QUAT * QUAT (dot product)
|
||||
return quat_rotation((PyObject*)quat1, (PyObject*)vec);
|
||||
}
|
||||
|
||||
scalar= PyFloat_AsDouble(q2);
|
||||
if ((scalar == -1.0 && PyErr_Occurred())==0) { /* QUAT*FLOAT */
|
||||
for(x = 0; x < 4; x++) {
|
||||
dot += quat1->quat[x] * quat1->quat[x];
|
||||
quat[x] = quat1->quat[x] * scalar;
|
||||
}
|
||||
return PyFloat_FromDouble(dot);
|
||||
return newQuaternionObject(quat, Py_NEW);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: arguments not acceptable for this operation\n");
|
||||
return NULL;
|
||||
}
|
||||
//------------------------coerce(obj, obj)-----------------------
|
||||
//coercion of unknown types to type QuaternionObject for numeric protocols
|
||||
/*Coercion() is called whenever a math operation has 2 operands that
|
||||
it doesn't understand how to evaluate. 2+Matrix for example. We want to
|
||||
evaluate some of these operations like: (vector * 2), however, for math
|
||||
to proceed, the unknown operand must be cast to a type that python math will
|
||||
understand. (e.g. in the case above case, 2 must be cast to a vector and
|
||||
then call vector.multiply(vector, scalar_cast_as_vector)*/
|
||||
static int Quaternion_coerce(PyObject ** q1, PyObject ** q2)
|
||||
{
|
||||
if(VectorObject_Check(*q2) || PyFloat_Check(*q2) || PyLong_Check(*q2)) {
|
||||
PyObject *coerced = (PyObject *)(*q2);
|
||||
Py_INCREF(coerced);
|
||||
|
||||
*q2 = newQuaternionObject(NULL,Py_NEW);
|
||||
((QuaternionObject*)*q2)->coerced_object = coerced;
|
||||
Py_INCREF (*q1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "quaternion.coerce(): unknown operand - can't coerce for numeric protocols");
|
||||
return -1;
|
||||
}
|
||||
//-----------------PROTOCOL DECLARATIONS--------------------------
|
||||
static PySequenceMethods Quaternion_SeqMethods = {
|
||||
(inquiry) Quaternion_len, /* sq_length */
|
||||
@@ -527,11 +614,7 @@ static PyNumberMethods Quaternion_NumMethods = {
|
||||
(binaryfunc) 0, /* __and__ */
|
||||
(binaryfunc) 0, /* __xor__ */
|
||||
(binaryfunc) 0, /* __or__ */
|
||||
#if 0 //XXX 2.5
|
||||
(coercion) Quaternion_coerce, /* __coerce__ */
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
/*(coercion)*/ 0, /* __coerce__ */
|
||||
(unaryfunc) 0, /* __int__ */
|
||||
(unaryfunc) 0, /* __long__ */
|
||||
(unaryfunc) 0, /* __float__ */
|
||||
@@ -716,7 +799,7 @@ PyTypeObject quaternion_Type = {
|
||||
0, //tp_dictoffset
|
||||
0, //tp_init
|
||||
0, //tp_alloc
|
||||
0, //tp_new
|
||||
Quaternion_new, //tp_new
|
||||
0, //tp_free
|
||||
0, //tp_is_gc
|
||||
0, //tp_bases
|
||||
@@ -740,7 +823,6 @@ PyObject *newQuaternionObject(float *quat, int type)
|
||||
self = PyObject_NEW(QuaternionObject, &quaternion_Type);
|
||||
self->data.blend_data = NULL;
|
||||
self->data.py_data = NULL;
|
||||
self->coerced_object = NULL;
|
||||
|
||||
if(type == Py_WRAP){
|
||||
self->data.blend_data = quat;
|
||||
|
||||
@@ -46,11 +46,7 @@ typedef struct {
|
||||
}data;
|
||||
float *quat; //1D array of data (alias)
|
||||
int wrapped; //is wrapped data?
|
||||
PyObject *coerced_object;
|
||||
} QuaternionObject;
|
||||
/*coerced_object is a pointer to the object that it was
|
||||
coerced from when a dummy vector needs to be created from
|
||||
the coerce() function for numeric protocol operations*/
|
||||
|
||||
/*struct data contains a pointer to the actual data that the
|
||||
object uses. It can use either PyMem allocated data (which will
|
||||
@@ -58,16 +54,6 @@ be stored in py_data) or be a wrapper for data allocated through
|
||||
blender (stored in blend_data). This is an either/or struct not both*/
|
||||
|
||||
//prototypes
|
||||
PyObject *Quaternion_Identity( QuaternionObject * self );
|
||||
PyObject *Quaternion_Negate( QuaternionObject * self );
|
||||
PyObject *Quaternion_Conjugate( QuaternionObject * self );
|
||||
PyObject *Quaternion_Inverse( QuaternionObject * self );
|
||||
PyObject *Quaternion_Normalize( QuaternionObject * self );
|
||||
PyObject *Quaternion_ToEuler( QuaternionObject * self, PyObject *args );
|
||||
PyObject *Quaternion_ToMatrix( QuaternionObject * self );
|
||||
PyObject *Quaternion_Cross( QuaternionObject * self, QuaternionObject * value );
|
||||
PyObject *Quaternion_Dot( QuaternionObject * self, QuaternionObject * value );
|
||||
PyObject *Quaternion_copy( QuaternionObject * self );
|
||||
PyObject *newQuaternionObject( float *quat, int type );
|
||||
|
||||
#endif /* EXPP_quat_h */
|
||||
|
||||
@@ -40,20 +40,32 @@
|
||||
#define SWIZZLE_AXIS 0x3
|
||||
|
||||
/*-------------------------DOC STRINGS ---------------------------*/
|
||||
char Vector_Zero_doc[] = "() - set all values in the vector to 0";
|
||||
char Vector_Normalize_doc[] = "() - normalize the vector";
|
||||
char Vector_Negate_doc[] = "() - changes vector to it's additive inverse";
|
||||
char Vector_Resize2D_doc[] = "() - resize a vector to [x,y]";
|
||||
char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]";
|
||||
char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]";
|
||||
char Vector_ToTrackQuat_doc[] = "(track, up) - extract a quaternion from the vector and the track and up axis";
|
||||
char Vector_Reflect_doc[] = "(mirror) - return a vector reflected on the mirror normal";
|
||||
char Vector_Cross_doc[] = "(other) - return the cross product between this vector and another";
|
||||
char Vector_Dot_doc[] = "(other) - return the dot product between this vector and another";
|
||||
char Vector_copy_doc[] = "() - return a copy of the vector";
|
||||
char Vector_swizzle_doc[] = "Swizzle: Get or set axes in specified order";
|
||||
static char Vector_Zero_doc[] = "() - set all values in the vector to 0";
|
||||
static char Vector_Normalize_doc[] = "() - normalize the vector";
|
||||
static char Vector_Negate_doc[] = "() - changes vector to it's additive inverse";
|
||||
static char Vector_Resize2D_doc[] = "() - resize a vector to [x,y]";
|
||||
static char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]";
|
||||
static char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]";
|
||||
static char Vector_ToTrackQuat_doc[] = "(track, up) - extract a quaternion from the vector and the track and up axis";
|
||||
static char Vector_Reflect_doc[] = "(mirror) - return a vector reflected on the mirror normal";
|
||||
static char Vector_Cross_doc[] = "(other) - return the cross product between this vector and another";
|
||||
static char Vector_Dot_doc[] = "(other) - return the dot product between this vector and another";
|
||||
static char Vector_copy_doc[] = "() - return a copy of the vector";
|
||||
static char Vector_swizzle_doc[] = "Swizzle: Get or set axes in specified order";
|
||||
/*-----------------------METHOD DEFINITIONS ----------------------*/
|
||||
struct PyMethodDef Vector_methods[] = {
|
||||
static PyObject *Vector_Zero( VectorObject * self );
|
||||
static PyObject *Vector_Normalize( VectorObject * self );
|
||||
static PyObject *Vector_Negate( VectorObject * self );
|
||||
static PyObject *Vector_Resize2D( VectorObject * self );
|
||||
static PyObject *Vector_Resize3D( VectorObject * self );
|
||||
static PyObject *Vector_Resize4D( VectorObject * self );
|
||||
static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args );
|
||||
static PyObject *Vector_Reflect( VectorObject * self, PyObject * value );
|
||||
static PyObject *Vector_Cross( VectorObject * self, VectorObject * value );
|
||||
static PyObject *Vector_Dot( VectorObject * self, VectorObject * value );
|
||||
static PyObject *Vector_copy( VectorObject * self );
|
||||
|
||||
static struct PyMethodDef Vector_methods[] = {
|
||||
{"zero", (PyCFunction) Vector_Zero, METH_NOARGS, Vector_Zero_doc},
|
||||
{"normalize", (PyCFunction) Vector_Normalize, METH_NOARGS, Vector_Normalize_doc},
|
||||
{"negate", (PyCFunction) Vector_Negate, METH_NOARGS, Vector_Negate_doc},
|
||||
@@ -69,10 +81,61 @@ struct PyMethodDef Vector_methods[] = {
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
//----------------------------------Mathutils.Vector() ------------------
|
||||
// Supports 2D, 3D, and 4D vector objects both int and float values
|
||||
// accepted. Mixed float and int values accepted. Ints are parsed to float
|
||||
static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *listObject = NULL;
|
||||
int size, i;
|
||||
float vec[4], f;
|
||||
PyObject *v;
|
||||
|
||||
size = PyTuple_GET_SIZE(args); /* we know its a tuple because its an arg */
|
||||
if (size == 1) {
|
||||
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.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
||||
return NULL;
|
||||
}
|
||||
} else if (size == 0) {
|
||||
//returns a new empty 3d vector
|
||||
return newVectorObject(NULL, 3, Py_NEW);
|
||||
} 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
f= PyFloat_AsDouble(v);
|
||||
if(f==-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);
|
||||
}
|
||||
|
||||
/*-----------------------------METHODS---------------------------- */
|
||||
/*----------------------------Vector.zero() ----------------------
|
||||
set the vector data to 0,0,0 */
|
||||
PyObject *Vector_Zero(VectorObject * self)
|
||||
static PyObject *Vector_Zero(VectorObject * self)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < self->size; i++) {
|
||||
@@ -83,7 +146,7 @@ PyObject *Vector_Zero(VectorObject * self)
|
||||
}
|
||||
/*----------------------------Vector.normalize() -----------------
|
||||
normalize the vector data to a unit vector */
|
||||
PyObject *Vector_Normalize(VectorObject * self)
|
||||
static PyObject *Vector_Normalize(VectorObject * self)
|
||||
{
|
||||
int i;
|
||||
float norm = 0.0f;
|
||||
@@ -102,7 +165,7 @@ PyObject *Vector_Normalize(VectorObject * self)
|
||||
|
||||
/*----------------------------Vector.resize2D() ------------------
|
||||
resize the vector to x,y */
|
||||
PyObject *Vector_Resize2D(VectorObject * self)
|
||||
static PyObject *Vector_Resize2D(VectorObject * self)
|
||||
{
|
||||
if(self->wrapped==Py_WRAP) {
|
||||
PyErr_SetString(PyExc_TypeError, "vector.resize2d(): cannot resize wrapped data - only python vectors\n");
|
||||
@@ -120,7 +183,7 @@ PyObject *Vector_Resize2D(VectorObject * self)
|
||||
}
|
||||
/*----------------------------Vector.resize3D() ------------------
|
||||
resize the vector to x,y,z */
|
||||
PyObject *Vector_Resize3D(VectorObject * self)
|
||||
static PyObject *Vector_Resize3D(VectorObject * self)
|
||||
{
|
||||
if (self->wrapped==Py_WRAP) {
|
||||
PyErr_SetString(PyExc_TypeError, "vector.resize3d(): cannot resize wrapped data - only python vectors\n");
|
||||
@@ -141,7 +204,7 @@ PyObject *Vector_Resize3D(VectorObject * self)
|
||||
}
|
||||
/*----------------------------Vector.resize4D() ------------------
|
||||
resize the vector to x,y,z,w */
|
||||
PyObject *Vector_Resize4D(VectorObject * self)
|
||||
static PyObject *Vector_Resize4D(VectorObject * self)
|
||||
{
|
||||
if(self->wrapped==Py_WRAP) {
|
||||
PyErr_SetString(PyExc_TypeError, "vector.resize4d(): cannot resize wrapped data - only python vectors");
|
||||
@@ -164,7 +227,7 @@ PyObject *Vector_Resize4D(VectorObject * self)
|
||||
}
|
||||
/*----------------------------Vector.toTrackQuat(track, up) ----------------------
|
||||
extract a quaternion from the vector and the track and up axis */
|
||||
PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
|
||||
static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
|
||||
{
|
||||
float vec[3], quat[4];
|
||||
char *strack, *sup;
|
||||
@@ -279,7 +342,7 @@ PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
|
||||
return a reflected vector on the mirror normal
|
||||
((2 * DotVecs(vec, mirror)) * mirror) - vec
|
||||
using arithb.c would be nice here */
|
||||
PyObject *Vector_Reflect( VectorObject * self, PyObject * value )
|
||||
static PyObject *Vector_Reflect( VectorObject * self, PyObject * value )
|
||||
{
|
||||
VectorObject *mirrvec;
|
||||
float mirror[3];
|
||||
@@ -326,7 +389,7 @@ PyObject *Vector_Reflect( VectorObject * self, PyObject * value )
|
||||
return newVectorObject(reflect, self->size, Py_NEW);
|
||||
}
|
||||
|
||||
PyObject *Vector_Cross( VectorObject * self, VectorObject * value )
|
||||
static PyObject *Vector_Cross( VectorObject * self, VectorObject * value )
|
||||
{
|
||||
VectorObject *vecCross = NULL;
|
||||
|
||||
@@ -345,7 +408,7 @@ PyObject *Vector_Cross( VectorObject * self, VectorObject * value )
|
||||
return (PyObject *)vecCross;
|
||||
}
|
||||
|
||||
PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
|
||||
static PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
|
||||
{
|
||||
double dot = 0.0;
|
||||
int x;
|
||||
@@ -368,7 +431,7 @@ PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
|
||||
|
||||
/*----------------------------Vector.copy() --------------------------------------
|
||||
return a copy of the vector */
|
||||
PyObject *Vector_copy(VectorObject * self)
|
||||
static PyObject *Vector_copy(VectorObject * self)
|
||||
{
|
||||
return newVectorObject(self->vec, self->size, Py_NEW);
|
||||
}
|
||||
@@ -428,8 +491,8 @@ static PyObject *Vector_item(VectorObject * self, int i)
|
||||
sequence accessor (set)*/
|
||||
static int Vector_ass_item(VectorObject * self, int i, PyObject * ob)
|
||||
{
|
||||
|
||||
if(!(PyNumber_Check(ob))) { /* parsed item not a number */
|
||||
float scalar= (float)PyFloat_AsDouble(ob);
|
||||
if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
|
||||
PyErr_SetString(PyExc_TypeError, "vector[index] = x: index argument not a number\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -438,7 +501,7 @@ static int Vector_ass_item(VectorObject * self, int i, PyObject * ob)
|
||||
PyErr_SetString(PyExc_IndexError, "vector[index] = x: assignment index out of range\n");
|
||||
return -1;
|
||||
}
|
||||
self->vec[i] = (float)PyFloat_AsDouble(ob);
|
||||
self->vec[i] = scalar;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -468,7 +531,7 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end,
|
||||
PyObject * seq)
|
||||
{
|
||||
int i, y, size = 0;
|
||||
float vec[4];
|
||||
float vec[4], scalar;
|
||||
PyObject *v;
|
||||
|
||||
CLAMP(begin, 0, self->size);
|
||||
@@ -489,13 +552,14 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!PyNumber_Check(v)) { /* parsed item not a number */
|
||||
scalar= (float)PyFloat_AsDouble(v);
|
||||
if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
|
||||
Py_DECREF(v);
|
||||
PyErr_SetString(PyExc_TypeError, "vector[begin:end] = []: sequence argument not a number\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
vec[i] = (float)PyFloat_AsDouble(v);
|
||||
vec[i] = scalar;
|
||||
Py_DECREF(v);
|
||||
}
|
||||
/*parsed well - now set in vector*/
|
||||
@@ -628,6 +692,7 @@ static PyObject *Vector_isub(PyObject * v1, PyObject * v2)
|
||||
static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
|
||||
{
|
||||
VectorObject *vec1 = NULL, *vec2 = NULL;
|
||||
float scalar;
|
||||
|
||||
if VectorObject_Check(v1)
|
||||
vec1= (VectorObject *)v1;
|
||||
@@ -658,23 +723,9 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
|
||||
v2= v1;
|
||||
}
|
||||
|
||||
if (PyNumber_Check(v2)) {
|
||||
/* VEC * NUM */
|
||||
int i;
|
||||
float vec[4];
|
||||
float scalar = (float)PyFloat_AsDouble( v2 );
|
||||
|
||||
for(i = 0; i < vec1->size; i++) {
|
||||
vec[i] = vec1->vec[i] * scalar;
|
||||
}
|
||||
return newVectorObject(vec, vec1->size, Py_NEW);
|
||||
|
||||
} else if (MatrixObject_Check(v2)) {
|
||||
if (MatrixObject_Check(v2)) {
|
||||
/* VEC * MATRIX */
|
||||
if (v1==v2) /* mat*vec, we have swapped the order */
|
||||
return column_vector_multiplication((MatrixObject*)v2, vec1);
|
||||
else /* vec*mat */
|
||||
return row_vector_multiplication(vec1, (MatrixObject*)v2);
|
||||
return row_vector_multiplication(vec1, (MatrixObject*)v2);
|
||||
} else if (QuaternionObject_Check(v2)) {
|
||||
QuaternionObject *quat = (QuaternionObject*)v2;
|
||||
if(vec1->size != 3) {
|
||||
@@ -683,6 +734,16 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
|
||||
}
|
||||
return quat_rotation((PyObject*)vec1, (PyObject*)quat);
|
||||
}
|
||||
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */
|
||||
int i;
|
||||
float vec[4];
|
||||
|
||||
for(i = 0; i < vec1->size; i++) {
|
||||
vec[i] = vec1->vec[i] * scalar;
|
||||
}
|
||||
return newVectorObject(vec, vec1->size, Py_NEW);
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n");
|
||||
return NULL;
|
||||
@@ -694,21 +755,11 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
|
||||
{
|
||||
VectorObject *vec = (VectorObject *)v1;
|
||||
int i;
|
||||
float scalar;
|
||||
|
||||
/* only support vec*=float and vec*=mat
|
||||
vec*=vec result is a float so that wont work */
|
||||
if (PyNumber_Check(v2)) {
|
||||
/* VEC * NUM */
|
||||
float scalar = (float)PyFloat_AsDouble( v2 );
|
||||
|
||||
for(i = 0; i < vec->size; i++) {
|
||||
vec->vec[i] *= scalar;
|
||||
}
|
||||
|
||||
Py_INCREF( v1 );
|
||||
return v1;
|
||||
|
||||
} else if (MatrixObject_Check(v2)) {
|
||||
if (MatrixObject_Check(v2)) {
|
||||
float vecCopy[4];
|
||||
int x,y, size = vec->size;
|
||||
MatrixObject *mat= (MatrixObject*)v2;
|
||||
@@ -739,6 +790,17 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
|
||||
Py_INCREF( v1 );
|
||||
return v1;
|
||||
}
|
||||
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*=FLOAT */
|
||||
|
||||
for(i = 0; i < vec->size; i++) {
|
||||
vec->vec[i] *= scalar;
|
||||
}
|
||||
|
||||
Py_INCREF( v1 );
|
||||
return v1;
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Vector multiplication: arguments not acceptable for this operation\n");
|
||||
return NULL;
|
||||
}
|
||||
@@ -747,7 +809,7 @@ static PyObject *Vector_imul(PyObject * v1, PyObject * v2)
|
||||
divide*/
|
||||
static PyObject *Vector_div(PyObject * v1, PyObject * v2)
|
||||
{
|
||||
int i, size;
|
||||
int i;
|
||||
float vec[4], scalar;
|
||||
VectorObject *vec1 = NULL;
|
||||
|
||||
@@ -757,28 +819,28 @@ static PyObject *Vector_div(PyObject * v1, PyObject * v2)
|
||||
}
|
||||
vec1 = (VectorObject*)v1; /* vector */
|
||||
|
||||
if(!PyNumber_Check(v2)) { /* parsed item not a number */
|
||||
scalar = (float)PyFloat_AsDouble(v2);
|
||||
if(scalar== -1.0f && PyErr_Occurred()) { /* parsed item not a number */
|
||||
PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n");
|
||||
return NULL;
|
||||
}
|
||||
scalar = (float)PyFloat_AsDouble(v2);
|
||||
|
||||
if(scalar==0.0) { /* not a vector */
|
||||
PyErr_SetString(PyExc_ZeroDivisionError, "Vector division: divide by zero error.\n");
|
||||
return NULL;
|
||||
}
|
||||
size = vec1->size;
|
||||
for(i = 0; i < size; i++) {
|
||||
|
||||
for(i = 0; i < vec1->size; i++) {
|
||||
vec[i] = vec1->vec[i] / scalar;
|
||||
}
|
||||
return newVectorObject(vec, size, Py_NEW);
|
||||
return newVectorObject(vec, vec1->size, Py_NEW);
|
||||
}
|
||||
|
||||
/*------------------------obj / obj------------------------------
|
||||
/*------------------------obj /= obj------------------------------
|
||||
divide*/
|
||||
static PyObject *Vector_idiv(PyObject * v1, PyObject * v2)
|
||||
{
|
||||
int i, size;
|
||||
int i;
|
||||
float scalar;
|
||||
VectorObject *vec1 = NULL;
|
||||
|
||||
@@ -788,20 +850,18 @@ static PyObject *Vector_idiv(PyObject * v1, PyObject * v2)
|
||||
}*/
|
||||
|
||||
vec1 = (VectorObject*)v1; /* vector */
|
||||
|
||||
if(!PyNumber_Check(v2)) { /* parsed item not a number */
|
||||
|
||||
scalar = (float)PyFloat_AsDouble(v2);
|
||||
if(scalar==-1.0f && PyErr_Occurred()) { /* parsed item not a number */
|
||||
PyErr_SetString(PyExc_TypeError, "Vector division: Vector must be divided by a float\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scalar = (float)PyFloat_AsDouble(v2);
|
||||
|
||||
if(scalar==0.0) { /* not a vector */
|
||||
PyErr_SetString(PyExc_ZeroDivisionError, "Vector division: divide by zero error.\n");
|
||||
return NULL;
|
||||
}
|
||||
size = vec1->size;
|
||||
for(i = 0; i < size; i++) {
|
||||
for(i = 0; i < vec1->size; i++) {
|
||||
vec1->vec[i] /= scalar;
|
||||
}
|
||||
Py_INCREF( v1 );
|
||||
@@ -820,24 +880,6 @@ static PyObject *Vector_neg(VectorObject *self)
|
||||
|
||||
return newVectorObject(vec, self->size, Py_NEW);
|
||||
}
|
||||
/*------------------------coerce(obj, obj)-----------------------
|
||||
coercion of unknown types to type VectorObject for numeric protocols
|
||||
Coercion() is called whenever a math operation has 2 operands that
|
||||
it doesn't understand how to evaluate. 2+Matrix for example. We want to
|
||||
evaluate some of these operations like: (vector * 2), however, for math
|
||||
to proceed, the unknown operand must be cast to a type that python math will
|
||||
understand. (e.g. in the case above case, 2 must be cast to a vector and
|
||||
then call vector.multiply(vector, scalar_cast_as_vector)*/
|
||||
|
||||
|
||||
static int Vector_coerce(PyObject ** v1, PyObject ** v2)
|
||||
{
|
||||
/* Just incref, each functon must raise errors for bad types */
|
||||
Py_INCREF (*v1);
|
||||
Py_INCREF (*v2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------tp_doc*/
|
||||
static char VectorObject_doc[] = "This is a wrapper for vector objects.";
|
||||
@@ -860,7 +902,7 @@ static double vec_magnitude_nosqrt(float *data, int size)
|
||||
|
||||
/*------------------------tp_richcmpr
|
||||
returns -1 execption, 0 false, 1 true */
|
||||
PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
|
||||
static PyObject* Vector_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
|
||||
{
|
||||
VectorObject *vecA = NULL, *vecB = NULL;
|
||||
int result = 0;
|
||||
@@ -949,15 +991,6 @@ static PySequenceMethods Vector_SeqMethods = {
|
||||
(ssizeobjargproc) Vector_ass_item, /* sq_ass_item */
|
||||
(ssizessizeobjargproc) Vector_ass_slice, /* sq_ass_slice */
|
||||
};
|
||||
|
||||
|
||||
/* For numbers without flag bit Py_TPFLAGS_CHECKTYPES set, all
|
||||
arguments are guaranteed to be of the object's type (modulo
|
||||
coercion hacks -- i.e. if the type's coercion function
|
||||
returns other types, then these are allowed as well). Numbers that
|
||||
have the Py_TPFLAGS_CHECKTYPES flag bit set should check *both*
|
||||
arguments for proper type and implement the necessary conversions
|
||||
in the slot functions themselves. */
|
||||
|
||||
static PyNumberMethods Vector_NumMethods = {
|
||||
(binaryfunc) Vector_add, /* __add__ */
|
||||
@@ -977,11 +1010,7 @@ static PyNumberMethods Vector_NumMethods = {
|
||||
(binaryfunc) NULL, /* __and__ */
|
||||
(binaryfunc) NULL, /* __xor__ */
|
||||
(binaryfunc) NULL, /* __or__ */
|
||||
#if 0 //XXX 2.5
|
||||
(coercion) Vector_coerce, /* __coerce__ */
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
/*(coercion)*/ NULL, /* __coerce__ */
|
||||
(unaryfunc) NULL, /* __int__ */
|
||||
(unaryfunc) NULL, /* __long__ */
|
||||
(unaryfunc) NULL, /* __float__ */
|
||||
@@ -1095,11 +1124,11 @@ static int Vector_setLength( VectorObject * self, PyObject * value )
|
||||
double dot = 0.0f, param;
|
||||
int i;
|
||||
|
||||
if (!PyNumber_Check(value)) {
|
||||
PyErr_SetString( PyExc_TypeError, "expected a number for the vector axis" );
|
||||
param= PyFloat_AsDouble( value );
|
||||
if(param==-1.0 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "length must be set to a number");
|
||||
return -1;
|
||||
}
|
||||
param= PyFloat_AsDouble( value );
|
||||
|
||||
if (param < 0) {
|
||||
PyErr_SetString( PyExc_TypeError, "cannot set a vectors length to a negative value" );
|
||||
@@ -1229,12 +1258,13 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
|
||||
while (swizzleClosure & SWIZZLE_VALID_AXIS && axisB < listLen)
|
||||
{
|
||||
item = PyList_GetItem(value, axisB);
|
||||
if (!PyNumber_Check(item))
|
||||
{
|
||||
scalarVal = (float)PyFloat_AsDouble(item);
|
||||
|
||||
if (scalarVal==-1.0 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis.\n");
|
||||
return -1;
|
||||
}
|
||||
scalarVal = (float)PyFloat_AsDouble(item);
|
||||
|
||||
|
||||
axisA = swizzleClosure & SWIZZLE_AXIS;
|
||||
vecTemp[axisA] = scalarVal;
|
||||
@@ -1245,10 +1275,9 @@ static int Vector_setSwizzle(VectorObject * self, PyObject * value, void *closur
|
||||
memcpy(self->vec, vecTemp, axisB * sizeof(float));
|
||||
return 0;
|
||||
}
|
||||
else if (PyNumber_Check(value))
|
||||
else if (((scalarVal = (float)PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred())==0)
|
||||
{
|
||||
/* Assign the same value to each axis. */
|
||||
scalarVal = (float)PyFloat_AsDouble(value);
|
||||
swizzleClosure = (unsigned int) closure;
|
||||
while (swizzleClosure & SWIZZLE_VALID_AXIS)
|
||||
{
|
||||
@@ -1729,12 +1758,7 @@ PyTypeObject vector_Type = {
|
||||
NULL, /* PyBufferProcs *tp_as_buffer; */
|
||||
|
||||
/*** Flags to define presence of optional/expanded features ***/
|
||||
#if 0 //XXX 2.5
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* long tp_flags; */
|
||||
#else
|
||||
Py_TPFLAGS_DEFAULT,
|
||||
#endif
|
||||
|
||||
VectorObject_doc, /* char *tp_doc; Documentation string */
|
||||
/*** Assigned meaning in release 2.0 ***/
|
||||
/* call function for all accessible objects */
|
||||
@@ -1766,7 +1790,7 @@ PyTypeObject vector_Type = {
|
||||
0, /* long tp_dictoffset; */
|
||||
NULL, /* initproc tp_init; */
|
||||
NULL, /* allocfunc tp_alloc; */
|
||||
NULL, /* newfunc tp_new; */
|
||||
Vector_new, /* newfunc tp_new; */
|
||||
/* Low-level free-memory routine */
|
||||
NULL, /* freefunc tp_free; */
|
||||
/* For PyObject_IS_GC */
|
||||
@@ -1824,7 +1848,7 @@ PyObject *newVectorObject(float *vec, int size, int type)
|
||||
#######################################################################
|
||||
----------------------------Vector.negate() --------------------
|
||||
set the vector to it's negative -x, -y, -z */
|
||||
PyObject *Vector_Negate(VectorObject * self)
|
||||
static PyObject *Vector_Negate(VectorObject * self)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < self->size; i++) {
|
||||
|
||||
@@ -45,17 +45,6 @@ typedef struct {
|
||||
} VectorObject;
|
||||
|
||||
/*prototypes*/
|
||||
PyObject *Vector_Zero( VectorObject * self );
|
||||
PyObject *Vector_Normalize( VectorObject * self );
|
||||
PyObject *Vector_Negate( VectorObject * self );
|
||||
PyObject *Vector_Resize2D( VectorObject * self );
|
||||
PyObject *Vector_Resize3D( VectorObject * self );
|
||||
PyObject *Vector_Resize4D( VectorObject * self );
|
||||
PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args );
|
||||
PyObject *Vector_Reflect( VectorObject * self, PyObject * value );
|
||||
PyObject *Vector_Cross( VectorObject * self, VectorObject * value );
|
||||
PyObject *Vector_Dot( VectorObject * self, VectorObject * value );
|
||||
PyObject *Vector_copy( VectorObject * self );
|
||||
PyObject *newVectorObject(float *vec, int size, int type);
|
||||
|
||||
#endif /* EXPP_vector_h */
|
||||
|
||||
@@ -771,12 +771,12 @@ static int pyrna_prop_contains(BPy_PropertyRNA * self, PyObject *value)
|
||||
char *keyname = _PyUnicode_AsString(value);
|
||||
|
||||
if(keyname==NULL) {
|
||||
PyErr_SetString(PyExc_SystemError, "PropertyRNA - key in prop, key must be a string type");
|
||||
PyErr_SetString(PyExc_TypeError, "PropertyRNA - key in prop, key must be a string type");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (RNA_property_type(self->prop) != PROP_COLLECTION) {
|
||||
PyErr_SetString(PyExc_SystemError, "PropertyRNA - key in prop, is only valid for collection types");
|
||||
PyErr_SetString(PyExc_TypeError, "PropertyRNA - key in prop, is only valid for collection types");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -875,6 +875,19 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA * self)
|
||||
|
||||
RNA_property_collection_end(&iter);
|
||||
}
|
||||
|
||||
if(self->ptr.type == &RNA_Context) {
|
||||
ListBase lb = CTX_data_dir_get(self->ptr.data);
|
||||
LinkData *link;
|
||||
|
||||
for(link=lb.first; link; link=link->next) {
|
||||
pystring = PyUnicode_FromString(link->data);
|
||||
PyList_Append(ret, pystring);
|
||||
Py_DECREF(pystring);
|
||||
}
|
||||
|
||||
BLI_freelistN(&lb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1011,22 +1024,30 @@ PyObject *pyrna_prop_items(BPy_PropertyRNA *self)
|
||||
CollectionPropertyIterator iter;
|
||||
PropertyRNA *nameprop;
|
||||
char name[256], *nameptr;
|
||||
int i= 0;
|
||||
|
||||
ret = PyList_New(0);
|
||||
|
||||
RNA_property_collection_begin(&self->ptr, self->prop, &iter);
|
||||
for(; iter.valid; RNA_property_collection_next(&iter)) {
|
||||
if(iter.ptr.data && (nameprop = RNA_struct_name_property(iter.ptr.type))) {
|
||||
nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
|
||||
|
||||
if(iter.ptr.data) {
|
||||
/* add to python list */
|
||||
item = Py_BuildValue("(NN)", PyUnicode_FromString( nameptr ), pyrna_struct_CreatePyObject(&iter.ptr));
|
||||
item= PyTuple_New(2);
|
||||
if(nameprop = RNA_struct_name_property(iter.ptr.type)) {
|
||||
nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
|
||||
PyTuple_SET_ITEM(item, 0, PyUnicode_FromString( nameptr ));
|
||||
if ((char *)&name != nameptr)
|
||||
MEM_freeN(nameptr);
|
||||
}
|
||||
else {
|
||||
PyTuple_SET_ITEM(item, 0, PyLong_FromSsize_t(i)); /* a bit strange but better then returning an empty list */
|
||||
}
|
||||
PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&iter.ptr));
|
||||
|
||||
PyList_Append(ret, item);
|
||||
Py_DECREF(item);
|
||||
/* done */
|
||||
|
||||
if ((char *)&name != nameptr)
|
||||
MEM_freeN(nameptr);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
RNA_property_collection_end(&iter);
|
||||
@@ -1039,23 +1060,22 @@ PyObject *pyrna_prop_items(BPy_PropertyRNA *self)
|
||||
PyObject *pyrna_prop_values(BPy_PropertyRNA *self)
|
||||
{
|
||||
PyObject *ret;
|
||||
|
||||
if (RNA_property_type(self->prop) != PROP_COLLECTION) {
|
||||
PyErr_SetString( PyExc_TypeError, "values() is only valid for collection types" );
|
||||
ret = NULL;
|
||||
} else {
|
||||
PyObject *item;
|
||||
CollectionPropertyIterator iter;
|
||||
PropertyRNA *nameprop;
|
||||
|
||||
PropertyRNA *iterprop;
|
||||
ret = PyList_New(0);
|
||||
|
||||
//iterprop= RNA_struct_iterator_property(self->ptr.type);
|
||||
RNA_property_collection_begin(&self->ptr, self->prop, &iter);
|
||||
for(; iter.valid; RNA_property_collection_next(&iter)) {
|
||||
if(iter.ptr.data && (nameprop = RNA_struct_name_property(iter.ptr.type))) {
|
||||
item = pyrna_struct_CreatePyObject(&iter.ptr);
|
||||
PyList_Append(ret, item);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
item = pyrna_struct_CreatePyObject(&iter.ptr);
|
||||
PyList_Append(ret, item);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
RNA_property_collection_end(&iter);
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ static struct PyMethodDef ui_methods[] = {
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
static struct PyModuleDef ui_module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"bpyui",
|
||||
"bpy.ui",
|
||||
"",
|
||||
-1,/* multiple "initialization" just copies the module dict. */
|
||||
ui_methods,
|
||||
|
||||
@@ -77,6 +77,8 @@
|
||||
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_extensions.h"
|
||||
|
||||
@@ -310,11 +312,13 @@ int main(int argc, char **argv)
|
||||
|
||||
BLI_where_am_i(bprogname, argv[0]);
|
||||
|
||||
RNA_init();
|
||||
|
||||
/* Hack - force inclusion of the plugin api functions,
|
||||
* see blenpluginapi:pluginapi.c
|
||||
*/
|
||||
pluginapi_force_ref();
|
||||
|
||||
|
||||
init_nodesystem();
|
||||
|
||||
initglobals(); /* blender.c */
|
||||
|
||||
@@ -409,7 +409,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
|
||||
|
||||
/* Find percentages */
|
||||
newweight = (m_blendframe/(float)m_blendin);
|
||||
// XXX blend_poses(m_pose, m_blendpose, 1.0 - newweight, ACTSTRIPMODE_BLEND);
|
||||
game_blend_poses(m_pose, m_blendpose, 1.0 - newweight);
|
||||
|
||||
/* Increment current blending percentage */
|
||||
m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
|
||||
|
||||
@@ -43,6 +43,9 @@ float BL_ScalarInterpolator::GetValue(float currentTime) const {
|
||||
}
|
||||
|
||||
BL_InterpolatorList::BL_InterpolatorList(struct AnimData *adt) {
|
||||
if(adt->action==NULL)
|
||||
return;
|
||||
|
||||
for(FCurve *fcu= (FCurve *)adt->action->curves.first; fcu; fcu= (FCurve *)fcu->next) {
|
||||
if(fcu->rna_path) {
|
||||
BL_ScalarInterpolator *new_ipo = new BL_ScalarInterpolator(fcu);
|
||||
|
||||
@@ -18,9 +18,10 @@
|
||||
#include "StringValue.h"
|
||||
#include "VoidValue.h"
|
||||
#include <algorithm>
|
||||
#include <stdint.h>
|
||||
#include "BoolValue.h"
|
||||
|
||||
#include "BLO_sys_types.h" /* for intptr_t support */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
@@ -3,7 +3,7 @@ Import ('env')
|
||||
|
||||
sources = env.Glob('*.cpp')
|
||||
|
||||
incs ='. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/SceneGraph'
|
||||
incs ='. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/SceneGraph #source/blender/blenloader'
|
||||
incs += ' ' + env['BF_PYTHON_INC']
|
||||
|
||||
cxxflags = []
|
||||
|
||||
@@ -51,6 +51,7 @@ SET(INC
|
||||
../../../../source/blender
|
||||
../../../../source/blender/include
|
||||
../../../../source/blender/makesdna
|
||||
../../../../source/blender/makesrna
|
||||
../../../../source/gameengine/Rasterizer
|
||||
../../../../source/gameengine/GameLogic
|
||||
../../../../source/gameengine/Expressions
|
||||
|
||||
@@ -86,6 +86,8 @@ extern "C"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#ifdef NDEBUG
|
||||
@@ -344,6 +346,8 @@ int main(int argc, char** argv)
|
||||
*/
|
||||
#endif // __APPLE__
|
||||
|
||||
RNA_init();
|
||||
|
||||
init_nodesystem();
|
||||
|
||||
initglobals();
|
||||
|
||||
@@ -68,6 +68,7 @@ CPPFLAGS += -I../../../blender/blenlib
|
||||
CPPFLAGS += -I../../../blender/blenloader
|
||||
CPPFLAGS += -I../../../blender/imbuf
|
||||
CPPFLAGS += -I../../../blender/makesdna
|
||||
CPPFLAGS += -I../../../blender/makesrna
|
||||
CPPFLAGS += -I../../../blender/readblenfile
|
||||
CPPFLAGS += -I../../../blender/gpu
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ incs = ['.',
|
||||
'#source/blender',
|
||||
'#source/blender/include',
|
||||
'#source/blender/makesdna',
|
||||
'#source/blender/makesrna',
|
||||
'#source/gameengine/BlenderRoutines',
|
||||
'#source/gameengine/Rasterizer',
|
||||
'#source/gameengine/GameLogic',
|
||||
|
||||
Reference in New Issue
Block a user