Merge from 2.5 r20991 through r21037
authorArystanbek Dyussenov <arystan.d@gmail.com>
Sat, 20 Jun 2009 16:48:58 +0000 (16:48 +0000)
committerArystanbek Dyussenov <arystan.d@gmail.com>
Sat, 20 Jun 2009 16:48:58 +0000 (16:48 +0000)
60 files changed:
release/datafiles/blenderbuttons
release/io/export_ply.py [new file with mode: 0644]
release/scripts/ply_export.py [deleted file]
release/ui/buttons_data_bone.py
release/ui/buttons_data_modifier.py
release/ui/buttons_objects.py
release/ui/space_logic.py [new file with mode: 0644]
source/blender/blenfont/intern/blf_font.c
source/blender/blenkernel/BKE_action.h
source/blender/blenkernel/BKE_context.h
source/blender/blenkernel/BKE_depsgraph.h
source/blender/blenkernel/depsgraph_private.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/context.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/ipo.c
source/blender/blenlib/intern/BLI_dynstr.c
source/blender/editors/interface/interface_panel.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/screen/screen_context.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_node/space_node.c
source/blender/editors/space_text/space_text.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_define.h
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_ID.c
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_armature.c
source/blender/makesrna/intern/rna_define.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_internal_types.h
source/blender/makesrna/intern/rna_mesh.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_rna.c
source/blender/makesrna/intern/rna_space.c
source/blender/python/generic/Mathutils.c
source/blender/python/generic/Mathutils.h
source/blender/python/generic/euler.c
source/blender/python/generic/euler.h
source/blender/python/generic/matrix.c
source/blender/python/generic/matrix.h
source/blender/python/generic/quat.c
source/blender/python/generic/quat.h
source/blender/python/generic/vector.c
source/blender/python/generic/vector.h
source/blender/python/intern/bpy_rna.c
source/blender/python/intern/bpy_ui.c
source/creator/creator.c
source/gameengine/Converter/BL_ActionActuator.cpp
source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp
source/gameengine/Expressions/ListValue.cpp
source/gameengine/Expressions/SConscript
source/gameengine/GamePlayer/ghost/CMakeLists.txt
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/GamePlayer/ghost/Makefile
source/gameengine/GamePlayer/ghost/SConscript

index 467e79f024a53f18223567e2fc60ae044e617463..963c76fcfa9d9bea03ff3d8d41c2f0e4e4e5203a 100644 (file)
Binary files a/release/datafiles/blenderbuttons and b/release/datafiles/blenderbuttons differ
diff --git a/release/io/export_ply.py b/release/io/export_ply.py
new file mode 100644 (file)
index 0000000..ed983c2
--- /dev/null
@@ -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")
+
+
diff --git a/release/scripts/ply_export.py b/release/scripts/ply_export.py
deleted file mode 100644 (file)
index 46d0805..0000000
+++ /dev/null
@@ -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()
index 2abe76b93c162e24f0503cd4dd57c76b264d0ca1..044f7b93806f6dbd91b88208583d68003c53c6f5 100644 (file)
@@ -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)
\ No newline at end of file
+bpy.types.register(BONE_PT_bone)
index adc448b20b5e929b566c4e975a04333a07e1548c..ecb0590f8e59338fbe6ccaefb2d799f87d395e50 100644 (file)
@@ -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")
index 48ab0d2d755e0fadd07c6e0487a285ec69cfd8be..3138f447ad2f078f7e47c94a81d428e5d4c2b36c 100644 (file)
@@ -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()
diff --git a/release/ui/space_logic.py b/release/ui/space_logic.py
new file mode 100644 (file)
index 0000000..71d94c8
--- /dev/null
@@ -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)
index 921f5cac67c3b724a733c1f68127adba0796820c..ee4ba0ee71a6d3b9ce63488bec8d840cf67239fb 100644 (file)
@@ -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;
index 67eb2ed58bf2cc972850cf16865c8498fc5d1fc9..f0796697670a86ed8ce7f584f4aeb9806b616285 100644 (file)
@@ -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 */
index 6a43f4ca25c99b0e91efb8e205bc4e3328aeeee1..898b84ecdc3cab9560e8631f8eeabd1e9000a503 100644 (file)
@@ -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);*/
index b86a58780dc92dd8f548e50028453e154963c8d1..70b6c1d13f4862e834e9795b1b901a2fb368a1c9 100644 (file)
@@ -36,6 +36,7 @@ struct Scene;
 struct DagNodeQueue;
 struct DagForest;
 struct DagNode;
+struct GHash;
 
 /* **** DAG relation types *** */
 
index 78717393bafd4c5b0b030e8a4728fecdfbba7d34..47e33c0e81e9eecaa6685c02b42c634ca4d140d9 100644 (file)
@@ -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
index fb1b2e9cf70d75b82e0805c6519ad75ed8fbbcd6..f7e15cef4c4137ab158f2198c75f1f60dc3807ab 100644 (file)
@@ -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;
index ae541365b1ebd5a384e529da08240724a0629a48..12deec838a8bd9ce6bf757a7e2c0d164592df2a5 100644 (file)
@@ -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)
index dfe3b7ea27943f5d2ca8301c4290a21f683c7709..8bb34bde12210802cad4ec89d84844e49281e232 100644 (file)
@@ -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);
index e4c366dd3d7ed42af42de0cd33a5801ac759df51..54618813a0bcd105273a7620f6b90e498451c15e 100644 (file)
@@ -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!)
                }
index 04388ea946fda81c58a62d352b3e79bc2e6f23dd..dd10d898a7f34ece492238600ec365d0c2df4211 100644 (file)
@@ -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;
+
+       /* 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 */
 
-       va_start(args, format);
-       BLI_dynstr_vappendf(ds, format, args);
-       va_end(args);
+       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) {
index 06582762fdb65a5414ed69c82d8d71b31acc4cdb..72076175ad5707a5833d4e4cc2744ab8f19036f4 100644 (file)
@@ -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)) {
index 119fd8a3fe59b941f00187e5d1ccf493b4b4139a..14df9026078d012ba8008449b7d767dde37dfd3f 100644 (file)
@@ -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);
 }
index 11d1d019005a641824f720212903c9703b5b5650..1ea6f8baceb05e1e4a2b48989541b39fd0d21fff 100644 (file)
@@ -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;
        }
index 2dba08b4601faa0f02af43873041aabcb7b0ae0e..7703dc0c303275513a2958d17853afb16e3b60b4 100644 (file)
@@ -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];
index 42180e7902f409a2dff8ad01e9dab155c498bd78..d97b4acdb96540797e0a1beb6e74e3c790de92f0 100644 (file)
@@ -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_equals(member, "world")) {
+       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};
+
+               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;
index e12f3bfe3578ef914043258021637cd64c47fa48..49f950fe67b8ebee18cb4680ab0e45e4c2cfdca1 100644 (file)
@@ -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;
        }
index 775f46b8e04f9e338023b38502039a4377e034d4..ac3a884c5f822aa54f326cd7d9b80ac3100f06bb 100644 (file)
@@ -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));) {
index d3c3b78cc504f6e46476e20592d4779fb71cdb48..8759fd00f74481e9c197471f218e735584bd3285 100644 (file)
@@ -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;
        }
index 6e33b1dcaabdef06ca1df958d9303841ae5abd02..2d6a57d5a34673d6c098ec1a8f1aa085fa0827e6 100644 (file)
@@ -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) {
index 1907b2cedb4b78edd7ad81169570fafdb09a5688..9b653bd924a57522750bc723646820047701bdb8 100644 (file)
@@ -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;
index dfe072c4b8e1f250e0cd3afb7b01e8087fc7c06b..b620a31508532134d936ef4dc8843fd7d43820a2 100644 (file)
@@ -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 */
index a8fe025fd4614e7f268f6abb58b58741006929f6..75293d83346228ddc4c63e3a860c7c0692c84952 100644 (file)
@@ -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, ");
index 52680e26afe432fdfd79c2919da3bb4cb6b6f8ff..7d8bab8bee8dd8d8f6dd553eafcfba77075189d1 100644 (file)
@@ -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.");
index cfddb1daf10730a6534528a7ffb5b9e2c2cdedb9..ba893319ce98f0ffb3029de71d40dc74c4ef25ca 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "BLI_blenlib.h"
 #include "BLI_dynstr.h"
+#include "BLI_ghash.h"
 
 #include "BKE_context.h"
 #include "BKE_idprop.h"
 
 #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;
-
-       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);
+       PropertyRNA *iterprop= RNA_struct_iterator_property(ptr->type);
+       PointerRNA propptr;
 
-       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);
index 631550964d6eac960b67f32481308f68a64f5aef..0f437f8f1a8c4c908d0dcd4965c000bc19a7c917 100644 (file)
 
 #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,152 +109,529 @@ 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
 
-// err... bones should not be directly edited (only editbones should be...)
-static void rna_def_bone(BlenderRNA *brna)
+static void rna_def_bone_common(StructRNA *srna, int editbone)
 {
-       StructRNA *srna;
        PropertyRNA *prop;
-       
-       srna= RNA_def_struct(brna, "Bone", NULL);
-       RNA_def_struct_ui_text(srna, "Bone", "Bone in an Armature datablock.");
-       RNA_def_struct_ui_icon(srna, ICON_BONE_DATA);
-       
-       /* pointers/collections */
-               /* parent (pointer) */
-       prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
-       RNA_def_property_struct_type(prop, "Bone");
-       RNA_def_property_pointer_sdna(prop, NULL, "parent");
-       RNA_def_property_ui_text(prop, "Parent", "Parent bone (in same Armature).");
-       
-               /* children (collection) */
-       prop= RNA_def_property(srna, "children", PROP_COLLECTION, PROP_NONE);
-       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);
-       
+       if(editbone) RNA_def_property_string_funcs(prop, "rna_EditBone_name_get", "rna_EditBone_name_length", "rna_EditBone_name_set");
+
        /* 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");
+       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);
+       }
 
-               /* flag */
-       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", "");
-       
-       prop= RNA_def_property(srna, "head_selected", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_ROOTSEL);
-       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_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);
+       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.");
        
-               // 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);
+       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);
-       RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_HINGE);
+       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, "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);
+       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);
-       RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_DEFORM);
+       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_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_SCALE);
        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);
-       RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_DRAWWIRE);
+       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);
-       RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_CYCLICOFFSET);
+       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.");
-       
-       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");
+       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);
-       RNA_def_property_float_sdna(prop, NULL, "weight");
+       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);
-       RNA_def_property_float_sdna(prop, NULL, "rad_head");
+       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);
-       RNA_def_property_float_sdna(prop, NULL, "rad_tail");
+       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);
-       RNA_def_property_int_sdna(prop, NULL, "segments");
+       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);
-       RNA_def_property_float_sdna(prop, NULL, "ease1");
+       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);
-       RNA_def_property_float_sdna(prop, NULL, "ease2");
+       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)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
        
-               /* 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.");
+       srna= RNA_def_struct(brna, "Bone", NULL);
+       RNA_def_struct_ui_text(srna, "Bone", "Bone in an Armature datablock.");
+       RNA_def_struct_ui_icon(srna, ICON_BONE_DATA);
        
-       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.");
+       /* pointers/collections */
+               /* parent (pointer) */
+       prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
+       RNA_def_property_struct_type(prop, "Bone");
+       RNA_def_property_pointer_sdna(prop, NULL, "parent");
+       RNA_def_property_ui_text(prop, "Parent", "Parent bone (in same Armature).");
+       
+               /* children (collection) */
+       prop= RNA_def_property(srna, "children", PROP_COLLECTION, PROP_NONE);
+       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");
+
+       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_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).");
+       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_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_funcs(prop, "rna_EditBone_tail_selected_get", "rna_EditBone_tail_selected_set");
+       RNA_def_property_ui_text(prop, "Tail Selected", "");
 }
 
 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
index d91f538d412f91965def0accb35f4e213b09c8f2..51c1818eed98c0e43c53f79de1b8aed3ee9b5602 100644 (file)
@@ -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);
 
index 61cde5a01a3a18c377eb27036a7c3c57e83ac981..362217e31230cc7b2237f4296d6efd2b2077a6b3 100644 (file)
@@ -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 */
 
index d93e6f4d7cfbb63a1f49354163b98a1727a9a1bd..8bae21cca2b1f622e7492b1433d86f341499c7e9 100644 (file)
@@ -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;
 
index 653f9d61fa5154a33b9617129f4e5c23a12e4f2c..da90b9f4c76dd153d500302cc2fffad2da84a13d 100644 (file)
 
 #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", "");
 }
index 36e2ba2d8aa30c788505429f3d0cdc7050175202..159362ef7e7482ba9ac301edadca7ee5d8ea3ce8 100644 (file)
@@ -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.");
index bd3a8ae55807eb32c11d46afa7fc2d51257a5b08..6fa275cec910f5ba70e6c45d749fbe07566f57fe 100644 (file)
@@ -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);
index 3b8b88beaff0ac78faf9ee297cbe5fe238d27687..41acc458cd95c036017931a4fa57a84a84e8a56e 100644 (file)
@@ -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
index 1e2e59edbafd26eeb8a17b8f94d776cc9f671523..3c34a369baf8708988925b470e18dd65f7a7e698 100644 (file)
 
 //-------------------------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 */
 
index 173922fe09af699e14abb43076756e32d43d4429..e8882c3dac2abf7913e7786d1377218b5a9d4f1c 100644 (file)
@@ -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);
 
index 82131b107101a8ad46a7ca24899ebea18b3cae32..a65feb7e9496d7c6cb91add4da337db6454bde55 100644 (file)
 
 
 //-------------------------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
index 773b024f1744f67dc7a3bad55ab8647d4097c1b1..3206668ffa08ebc912a571bd15c6cd90870184e0 100644 (file)
@@ -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 */
index 16c72d69dde06f1589e1fd061f5fbed05835eb92..e2ab1c3c653f45ef452f4d14cef6766d0213f3fb 100644 (file)
 #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;
index fd51d99c455b8b4800e76076892d972fd4a0fbd1..ef82263fe00b1615fcfbd34a598b92798b922fee 100644 (file)
@@ -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 */
index ca703f12907e033a241604a47bd4b22347946ff8..4ad5d07b3b884353754502182d0099a0211cec34 100644 (file)
 
 
 //-------------------------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;
index 8a4602c1d8ef45b6dadf5ba37eb759e8ec1b3bb3..cfb50e4dbe1dcfd02b1a109a3012c39c747f7f7e 100644 (file)
@@ -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 */
index 86ce5c21217b7ae16c27e0b82737a057c10029a8..562413c69672a5f5806aa0efbacc239d4808460d 100644 (file)
 #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++) {
index 930e987fcc7d26345cfcf173463c94e16454ba5f..d2eb826ef10eff9e155d5101ff8676b79c834801 100644 (file)
@@ -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 */
index 57a4de21443d2cf91b2fd7fbb0fb99a0baa54863..f28f00e9c0254397eeac3ee10ef7aab366012cee 100644 (file)
@@ -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);
        }
index c15315ca350ce9f54d6b9e022eab473438744779..088fe436c69d2ebb44d67ffc6f4dbe74f8c7bc21 100644 (file)
@@ -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,
index a19e5d0718cee6eb725c57ebffd3b9736263b5b1..9bf09a464617a7f765ba8968040faae602c3659f 100644 (file)
@@ -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 */
index 131d48aed4f3ba8781eb0a2b3b9c19bd2af63e25..c0d28d28bda4323071f4cb0a2d5b98f25410d23c 100644 (file)
@@ -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();
index 20829524558ec8e180b594d186b243b66fbea22e..c3264a2bc37403667483772f57ffd9d1a0ba4ec4 100644 (file)
@@ -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); 
index d3df36fbff0b5c4b90daaab6605b22982f120679..59344ddb7b7f42bf9f9dc53c8ae6faac28eae6f5 100644 (file)
 #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
index b5c69eafe6bac6bbbb437fdc4358ff5558edb80d..07cab62c02090587977994841b7b982f55173d89 100644 (file)
@@ -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 = []
index 71961f273397de37811849ebda1ba786d9c64fc0..0d4abf1e1fea885dfb5115ff5d1716f60b0b070c 100644 (file)
@@ -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
index b69188e54765533b1e490a4e70b53b98a5d58707..2433c58717965813e687635915d0ca3700af0a68 100644 (file)
@@ -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();
index c82edca0d455e21bb2a858a40a61d684250bf7a8..49ad9457ee30e3390710d77beb187996347b6fb3 100644 (file)
@@ -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
 
index 1cb7c9f2457eaa795cb1fafda765c320c14fe3dd..390b6f5e089903956698f33d22eb2f39fdd574d1 100644 (file)
@@ -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',