Mathutils refactor & include in sphinx generated docs, (TODO, include getset'ers...
authorCampbell Barton <ideasman42@gmail.com>
Mon, 25 Jan 2010 09:44:04 +0000 (09:44 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 25 Jan 2010 09:44:04 +0000 (09:44 +0000)
 - Mathutils.MidpointVecs --> vector.lerp(other, fac)
 - Mathutils.AngleBetweenVecs --> vector.angle(other)
 - Mathutils.ProjectVecs --> vector.project(other)
 - Mathutils.DifferenceQuats --> quat.difference(other)
 - Mathutils.Slerp --> quat.slerp(other, fac)
 - Mathutils.Rand: removed, use pythons random module
 - Mathutils.RotationMatrix(angle, size, axis_flag, axis) --> Mathutils.RotationMatrix(angle, size, axis); merge axis & axis_flag args
 - Matrix.scalePart --> Matrix.scale_part
 - Matrix.translationPart --> Matrix.translation_part
 - Matrix.rotationPart --> Matrix.rotation_part
 - toMatrix --> to_matrix
 - toEuler --> to_euler
 - toQuat --> to_quat
 - Vector.toTrackQuat --> Vector.to_track_quat

26 files changed:
release/scripts/io/engine_render_pov.py
release/scripts/io/export_3ds.py
release/scripts/io/export_fbx.py
release/scripts/io/export_x3d.py
release/scripts/io/import_anim_bvh.py
release/scripts/modules/bpy_types.py
release/scripts/modules/retopo.py
release/scripts/modules/rigify/delta.py
release/scripts/modules/rigify/leg_quadruped.py
release/scripts/modules/rigify/mouth.py
release/scripts/modules/rigify/palm_curl.py
release/scripts/modules/rigify/shape_key_rotdiff.py
release/scripts/modules/rigify_utils.py
release/scripts/op/mesh.py
release/scripts/op/mesh_skin.py
release/scripts/op/uvcalc_smart_project.py
release/scripts/templates/gamelogic.py
source/blender/python/doc/epy/Geometry.py
source/blender/python/doc/epy/Mathutils.py
source/blender/python/generic/Geometry.c
source/blender/python/generic/Mathutils.c
source/blender/python/generic/euler.c
source/blender/python/generic/matrix.c
source/blender/python/generic/quat.c
source/blender/python/generic/vector.c
source/blender/python/sphinx_doc_gen.py

index 5275574d903930a26146f3dce85f78c02f0e6b7e..7abb0c19cd7debf236b55e88e216a85977e91957 100644 (file)
@@ -146,7 +146,7 @@ def write_pov(filename, scene=None, info_callback=None):
         file.write('\tup <0, 1, 0>\n')
         file.write('\tangle  %f \n' % (360.0 * atan(16.0 / camera.data.lens) / pi))
 
-        file.write('\trotate  <%.6f, %.6f, %.6f>\n' % tuple([degrees(e) for e in matrix.rotationPart().toEuler()]))
+        file.write('\trotate  <%.6f, %.6f, %.6f>\n' % tuple([degrees(e) for e in matrix.rotation_part().to_euler()]))
         file.write('\ttranslate <%.6f, %.6f, %.6f>\n' % (matrix[3][0], matrix[3][1], matrix[3][2]))
         file.write('}\n')
 
index 979c53c581d744bf1fb0398ee7f786ebcbc4665c..f898a4b5f9ea344121d7f873763a2189efa31881 100644 (file)
@@ -839,7 +839,7 @@ def make_track_chunk(ID, obj):
             track_chunk.add_variable("position", _3ds_point_3d(obj.getLocation()))
         elif ID==ROT_TRACK_TAG:
             # rotation (quaternion, angle first, followed by axis):
-            q = obj.getEuler().toQuat()
+            q = obj.getEuler().to_quat()
             track_chunk.add_variable("rotation", _3ds_point_4d((q.angle, q.axis[0], q.axis[1], q.axis[2])))
         elif ID==SCL_TRACK_TAG:
             # scale vector:
index 7a69659d16438b319693c47aef232c88396bd71a..dcf109e24e1e8e8a7ce0920e15c717df916a792c 100644 (file)
@@ -146,7 +146,7 @@ def eulerRadToDeg(eul):
 mtx4_identity = Mathutils.Matrix()
 
 # testing
-mtx_x90                = Mathutils.RotationMatrix( math.pi/2, 3, 'x') # used
+mtx_x90                = Mathutils.RotationMatrix( math.pi/2, 3, 'X') # used
 #mtx_x90n      = RotationMatrix(-90, 3, 'x')
 #mtx_y90       = RotationMatrix( 90, 3, 'y')
 #mtx_y90n      = RotationMatrix(-90, 3, 'y')
@@ -154,11 +154,11 @@ mtx_x90           = Mathutils.RotationMatrix( math.pi/2, 3, 'x') # used
 #mtx_z90n      = RotationMatrix(-90, 3, 'z')
 
 #mtx4_x90      = RotationMatrix( 90, 4, 'x')
-mtx4_x90n      = Mathutils.RotationMatrix(-math.pi/2, 4, 'x') # used
+mtx4_x90n      = Mathutils.RotationMatrix(-math.pi/2, 4, 'X') # used
 #mtx4_y90      = RotationMatrix( 90, 4, 'y')
-mtx4_y90n      = Mathutils.RotationMatrix(-math.pi/2, 4, 'y') # used
-mtx4_z90       = Mathutils.RotationMatrix( math.pi/2, 4, 'z') # used
-mtx4_z90n      = Mathutils.RotationMatrix(-math.pi/2, 4, 'z') # used
+mtx4_y90n      = Mathutils.RotationMatrix(-math.pi/2, 4, 'Y') # used
+mtx4_z90       = Mathutils.RotationMatrix( math.pi/2, 4, 'Z') # used
+mtx4_z90n      = Mathutils.RotationMatrix(-math.pi/2, 4, 'Z') # used
 
 # def strip_path(p):
 #      return p.split('\\')[-1].split('/')[-1]
@@ -590,9 +590,9 @@ def write(filename, batch_objects = None, \
         def getAnimParRelMatrixRot(self, frame):
             type = self.blenObject.type
             if self.fbxParent:
-                matrix_rot = (((self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert())).rotationPart()
+                matrix_rot = (((self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert())).rotation_part()
             else:
-                matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotationPart()
+                matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotation_part()
 
             # Lamps need to be rotated
             if type =='LAMP':
@@ -600,7 +600,7 @@ def write(filename, batch_objects = None, \
             elif type =='CAMERA':
 #                      elif ob and type =='Camera':
                 y = Mathutils.Vector(0,1,0) * matrix_rot
-                matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y)
+                matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, y)
 
             return matrix_rot
 
@@ -676,11 +676,11 @@ def write(filename, batch_objects = None, \
 #                              par_matrix = mtx4_z90 * parent.matrix['ARMATURESPACE'] # dont apply armature matrix anymore
                 matrix = matrix * par_matrix.copy().invert()
 
-            matrix_rot =       matrix.rotationPart()
+            matrix_rot =       matrix.rotation_part()
 
-            loc =                      tuple(matrix.translationPart())
-            scale =                    tuple(matrix.scalePart())
-            rot =                      tuple(matrix_rot.toEuler())
+            loc =                      tuple(matrix.translation_part())
+            scale =                    tuple(matrix.scale_part())
+            rot =                      tuple(matrix_rot.to_euler())
 
         else:
             # This is bad because we need the parent relative matrix from the fbx parent (if we have one), dont use anymore
@@ -692,20 +692,20 @@ def write(filename, batch_objects = None, \
             #  matrix = matrix_scale * matrix
 
             if matrix:
-                loc = tuple(matrix.translationPart())
-                scale = tuple(matrix.scalePart())
+                loc = tuple(matrix.translation_part())
+                scale = tuple(matrix.scale_part())
 
-                matrix_rot = matrix.rotationPart()
+                matrix_rot = matrix.rotation_part()
                 # Lamps need to be rotated
                 if ob and ob.type =='Lamp':
                     matrix_rot = mtx_x90 * matrix_rot
-                    rot = tuple(matrix_rot.toEuler())
+                    rot = tuple(matrix_rot.to_euler())
                 elif ob and ob.type =='Camera':
                     y = Mathutils.Vector(0,1,0) * matrix_rot
-                    matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, 'r', y)
-                    rot = tuple(matrix_rot.toEuler())
+                    matrix_rot = matrix_rot * Mathutils.RotationMatrix(math.pi/2, 3, y)
+                    rot = tuple(matrix_rot.to_euler())
                 else:
-                    rot = tuple(matrix_rot.toEuler())
+                    rot = tuple(matrix_rot.to_euler())
             else:
                 if not loc:
                     loc = 0,0,0
@@ -1131,7 +1131,7 @@ def write(filename, batch_objects = None, \
         else:
             do_light = 1
 
-        scale = abs(GLOBAL_MATRIX.scalePart()[0]) # scale is always uniform in this case
+        scale = abs(GLOBAL_MATRIX.scale_part()[0]) # scale is always uniform in this case
 
         file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
         file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1')
@@ -2866,18 +2866,18 @@ Takes:  {''')
                         # ----------------
                         for TX_LAYER, TX_CHAN in enumerate('TRS'): # transform, rotate, scale
 
-                            if         TX_CHAN=='T':   context_bone_anim_vecs = [mtx[0].translationPart()      for mtx in context_bone_anim_mats]
-                            elif       TX_CHAN=='S':   context_bone_anim_vecs = [mtx[0].scalePart()            for mtx in context_bone_anim_mats]
+                            if         TX_CHAN=='T':   context_bone_anim_vecs = [mtx[0].translation_part()     for mtx in context_bone_anim_mats]
+                            elif       TX_CHAN=='S':   context_bone_anim_vecs = [mtx[0].scale_part()           for mtx in context_bone_anim_mats]
                             elif       TX_CHAN=='R':
                                 # Was....
-                                # elif         TX_CHAN=='R':   context_bone_anim_vecs = [mtx[1].toEuler()                      for mtx in context_bone_anim_mats]
+                                # elif         TX_CHAN=='R':   context_bone_anim_vecs = [mtx[1].to_euler()                     for mtx in context_bone_anim_mats]
                                 #
                                 # ...but we need to use the previous euler for compatible conversion.
                                 context_bone_anim_vecs = []
                                 prev_eul = None
                                 for mtx in context_bone_anim_mats:
-                                    if prev_eul:       prev_eul = mtx[1].toEuler(prev_eul)
-                                    else:                      prev_eul = mtx[1].toEuler()
+                                    if prev_eul:       prev_eul = mtx[1].to_euler(prev_eul)
+                                    else:                      prev_eul = mtx[1].to_euler()
                                     context_bone_anim_vecs.append(eulerRadToDeg(prev_eul))
 #                                                                      context_bone_anim_vecs.append(prev_eul)
 
index 44032a0c733da7303c5eb5896b2b2b0def0c0f15..0875abf1de1cec37baaf6ecd1fb349a6b0c88247 100644 (file)
@@ -81,7 +81,7 @@ from export_3ds import create_derived_objects, free_derived_objects
 
 #
 DEG2RAD=0.017453292519943295
-MATWORLD= Mathutils.RotationMatrix(-90, 4, 'x')
+MATWORLD= Mathutils.RotationMatrix(-90, 4, 'X')
 
 ####################################
 # Global Variables
@@ -239,8 +239,8 @@ class x3d_class:
         # get the camera location, subtract 90 degress from X to orient like X3D does
         # mat = ob.matrixWorld - mat is now passed!
 
-        loc = self.rotatePointForVRML(mat.translationPart())
-        rot = mat.toEuler()
+        loc = self.rotatePointForVRML(mat.translation_part())
+        rot = mat.to_euler()
         rot = (((rot[0]-90)), rot[1], rot[2])
         # rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD)
         nRot = self.rotatePointForVRML( rot )
@@ -300,8 +300,8 @@ class x3d_class:
         # note -dz seems to equal om[3][1]
         # note  dy seems to equal om[3][2]
 
-        #location=(ob.matrixWorld*MATWORLD).translationPart() # now passed
-        location=(mtx*MATWORLD).translationPart()
+        #location=(ob.matrixWorld*MATWORLD).translation_part() # now passed
+        location=(mtx*MATWORLD).translation_part()
 
         radius = lamp.distance*math.cos(beamWidth)
         # radius = lamp.dist*math.cos(beamWidth)
@@ -346,8 +346,8 @@ class x3d_class:
             ambi = 0
             ambientIntensity = 0
 
-        # location=(ob.matrixWorld*MATWORLD).translationPart() # now passed
-        location= (mtx*MATWORLD).translationPart()
+        # location=(ob.matrixWorld*MATWORLD).translation_part() # now passed
+        location= (mtx*MATWORLD).translation_part()
 
         self.file.write("<PointLight DEF=\"%s\" " % safeName)
         self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
@@ -364,8 +364,8 @@ class x3d_class:
             return
         else:
             dx,dy,dz = self.computeDirection(mtx)
-            # location=(ob.matrixWorld*MATWORLD).translationPart()
-            location=(mtx*MATWORLD).translationPart()
+            # location=(ob.matrixWorld*MATWORLD).translation_part()
+            location=(mtx*MATWORLD).translation_part()
             self.writeIndented("<%s\n" % obname,1)
             self.writeIndented("direction=\"%s %s %s\"\n" % (round(dx,3),round(dy,3),round(dz,3)))
             self.writeIndented("location=\"%s %s %s\"\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
@@ -448,9 +448,9 @@ class x3d_class:
         # mtx = ob.matrixWorld * MATWORLD # mtx is now passed
         mtx = mtx * MATWORLD
 
-        loc= mtx.translationPart()
-        sca= mtx.scalePart()
-        quat = mtx.toQuat()
+        loc= mtx.translation_part()
+        sca= mtx.scale_part()
+        quat = mtx.to_quat()
         rot= quat.axis
 
         self.writeIndented('<Transform DEF="%s" translation="%.6f %.6f %.6f" scale="%.6f %.6f %.6f" rotation="%.6f %.6f %.6f %.6f">\n' % \
@@ -1048,7 +1048,7 @@ class x3d_class:
     def computeDirection(self, mtx):
         x,y,z=(0,-1.0,0) # point down
 
-        ax,ay,az = (mtx*MATWORLD).toEuler()
+        ax,ay,az = (mtx*MATWORLD).to_euler()
 
         # ax *= DEG2RAD
         # ay *= DEG2RAD
index 2afd2db3cb2e847af3db03315aef4b89691b75f3..f6626e8fb1eef3a0e91f3868cfde4ef2a8150e88 100644 (file)
@@ -89,13 +89,13 @@ MATRIX_IDENTITY_4x4 = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1])
 def eulerRotate(x,y,z, rot_order):
 
     # Clamp all values between 0 and 360, values outside this raise an error.
-    mats=[RotationMatrix(math.radians(x%360),3,'x'), RotationMatrix(math.radians(y%360),3,'y'), RotationMatrix(math.radians(z%360),3,'z')]
+    mats=[RotationMatrix(math.radians(x % 360), 3, 'X'), RotationMatrix(math.radians(y % 360),3,'Y'), RotationMatrix(math.radians(z % 360), 3, 'Z')]
     # print rot_order
     # Standard BVH multiplication order, apply the rotation in the order Z,X,Y
 
     #XXX, order changes???
-    #eul = (mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))).toEuler()
-    eul = (MATRIX_IDENTITY_3x3*mats[rot_order[0]]*(mats[rot_order[1]]* (mats[rot_order[2]]))).toEuler()
+    #eul = (mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))).to_euler()
+    eul = (MATRIX_IDENTITY_3x3*mats[rot_order[0]]*(mats[rot_order[1]]* (mats[rot_order[2]]))).to_euler()
 
     eul = math.degrees(eul.x), math.degrees(eul.y), math.degrees(eul.z)
 
@@ -534,8 +534,8 @@ def bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOO
         bone_name= bvh_node.temp # may not be the same name as the bvh_node, could have been shortened.
         pose_bone= pose_bones[bone_name]
         rest_bone= arm_data.bones[bone_name]
-#XXX           bone_rest_matrix = rest_bone.matrix['ARMATURESPACE'].rotationPart()
-        bone_rest_matrix = rest_bone.matrix.rotationPart()
+#XXX           bone_rest_matrix = rest_bone.matrix['ARMATURESPACE'].rotation_part()
+        bone_rest_matrix = rest_bone.matrix.rotation_part()
 
 
         bone_rest_matrix_inv= Matrix(bone_rest_matrix)
@@ -575,31 +575,31 @@ def bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOO
 
                 if ROT_STYLE=='QUAT':
                     # Set the rotation, not so simple
-                    bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).toMatrix()
+                    bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).to_matrix()
 
                     bone_rotation_matrix.resize4x4()
                     #XXX ORDER CHANGE???
-                    #pose_bone.rotation_quaternion= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat() # ORIGINAL
-                    # pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix).toQuat()
-                    # pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix).toQuat() # BAD
-                    # pose_bone.rotation_quaternion= bone_rotation_matrix.toQuat() # NOT GOOD
-                    # pose_bone.rotation_quaternion= bone_rotation_matrix.toQuat() # NOT GOOD
+                    #pose_bone.rotation_quaternion= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).to_quat() # ORIGINAL
+                    # pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix).to_quat()
+                    # pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix).to_quat() # BAD
+                    # pose_bone.rotation_quaternion= bone_rotation_matrix.to_quat() # NOT GOOD
+                    # pose_bone.rotation_quaternion= bone_rotation_matrix.to_quat() # NOT GOOD
 
-                    #pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix_inv * bone_rest_matrix).toQuat()
-                    #pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rest_matrix * bone_rotation_matrix).toQuat()
-                    #pose_bone.rotation_quaternion= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat()
+                    #pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix_inv * bone_rest_matrix).to_quat()
+                    #pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rest_matrix * bone_rotation_matrix).to_quat()
+                    #pose_bone.rotation_quaternion= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).to_quat()
 
-                    #pose_bone.rotation_quaternion= ( bone_rest_matrix* bone_rest_matrix_inv * bone_rotation_matrix).toQuat()
-                    #pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix  * bone_rest_matrix_inv).toQuat()
-                    #pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix  * bone_rest_matrix ).toQuat()
+                    #pose_bone.rotation_quaternion= ( bone_rest_matrix* bone_rest_matrix_inv * bone_rotation_matrix).to_quat()
+                    #pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix  * bone_rest_matrix_inv).to_quat()
+                    #pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix  * bone_rest_matrix ).to_quat()
 
-                    pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix).toQuat()
+                    pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix).to_quat()
 
                 else:
-                    bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).toMatrix()
+                    bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).to_matrix()
                     bone_rotation_matrix.resize4x4()
 
-                    eul= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toEuler()
+                    eul= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).to_euler()
 
                     #pose_bone.rotation_euler = math.radians(rx), math.radians(ry), math.radians(rz)
                     pose_bone.rotation_euler = eul
@@ -610,8 +610,8 @@ def bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOO
                 # Set the Location, simple too
 
                 #XXX ORDER CHANGE
-                # pose_bone.location= (TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local ) * bone_rest_matrix_inv).translationPart() # WHY * 10? - just how pose works
-                # pose_bone.location= (bone_rest_matrix_inv * TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local )).translationPart()
+                # pose_bone.location= (TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local ) * bone_rest_matrix_inv).translation_part() # WHY * 10? - just how pose works
+                # pose_bone.location= (bone_rest_matrix_inv * TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local )).translation_part()
                 # pose_bone.location= lx, ly, lz
                 pose_bone.location= Vector(lx, ly, lz) - bvh_node.rest_head_local
 
@@ -714,12 +714,12 @@ def bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOO
 
 
         def pose_rot(anim_data):
-            bone_rotation_matrix= Euler(anim_data[3], anim_data[4], anim_data[5]).toMatrix()
+            bone_rotation_matrix= Euler(anim_data[3], anim_data[4], anim_data[5]).to_matrix()
             bone_rotation_matrix.resize4x4()
-            return tuple((bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat()) # qw,qx,qy,qz
+            return tuple((bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).to_quat()) # qw,qx,qy,qz
 
         def pose_loc(anim_data):
-            return tuple((TranslationMatrix(Vector(anim_data[0], anim_data[1], anim_data[2])) * bone_rest_matrix_inv).translationPart())
+            return tuple((TranslationMatrix(Vector(anim_data[0], anim_data[1], anim_data[2])) * bone_rest_matrix_inv).translation_part())
 
 
         last_frame= len(bvh_node.anim_data)+IMPORT_START_FRAME-1
index a1278f4f7cda89161ef846b81029e252c283cc6c..668951980e8ac3c3ed7b3fe5f301d9ad0512789c 100644 (file)
@@ -94,19 +94,19 @@ class _GenericBone:
     def x_axis(self):
         """ Vector pointing down the x-axis of the bone.
         """
-        return self.matrix.rotationPart() * Vector(1,0,0)
+        return self.matrix.rotation_part() * Vector(1,0,0)
     
     @property
     def y_axis(self):
         """ Vector pointing down the x-axis of the bone.
         """
-        return self.matrix.rotationPart() * Vector(0,1,0)
+        return self.matrix.rotation_part() * Vector(0,1,0)
     
     @property
     def z_axis(self):
         """ Vector pointing down the x-axis of the bone.
         """
-        return self.matrix.rotationPart() * Vector(0,0,1)
+        return self.matrix.rotation_part() * Vector(0,0,1)
 
     @property
     def basename(self):
@@ -236,7 +236,7 @@ class EditBone(StructRNA, _GenericBone):
         Expects a 4x4 or 3x3 matrix.
         """
         from Mathutils import Vector
-        z_vec = self.matrix.rotationPart() * Vector(0.0, 0.0, 1.0)
+        z_vec = self.matrix.rotation_part() * Vector(0.0, 0.0, 1.0)
         self.tail = matrix * self.tail
         self.head = matrix * self.head
         scalar = matrix.median_scale
@@ -421,8 +421,8 @@ class OrderedMeta(type):
 
 
 # Only defined so operators members can be used by accessing self.order
-class Operator(StructRNA, metaclass=OrderedMeta):
-    __slots__ = ()
+#class Operator(StructRNA, metaclass=OrderedMeta):
+#    __slots__ = ()
 
 
 class Macro(StructRNA, metaclass=OrderedMeta):
index 6fba34b7b58cd71477f8c08bda823aac20cc6e34..e10589d17d00adfac04f8c1c20f9c3f1e2b08631 100644 (file)
@@ -30,14 +30,14 @@ def get_hub(co, _hubs, EPS_SPLINE):
             if (hub.co - co).length < EPS_SPLINE:
                 return hub
 
-        key = co.toTuple(3)
+        key = co.to_tuple(3)
         hub = _hubs[key] = Hub(co, key, len(_hubs))
         return hub
     else:
         pass
 
         '''
-        key = co.toTuple(3)
+        key = co.to_tuple(3)
         try:
             return _hubs[key]
         except:
@@ -274,9 +274,7 @@ def get_splines(gp):
 
 
 def xsect_spline(sp_a, sp_b, _hubs):
-    from Mathutils import LineIntersect
-    from Mathutils import MidpointVecs
-    from Geometry import ClosestPointOnLine
+    from Geometry import ClosestPointOnLine, LineIntersect
     pt_a_prev = pt_b_prev = None
     EPS_SPLINE = (sp_a.length + sp_b.length) / (EPS_SPLINE_DIV * 2)
     pt_a_prev = sp_a.points[0]
@@ -296,7 +294,7 @@ def xsect_spline(sp_a, sp_b, _hubs):
                         # if f >= 0.0-EPS_SPLINE and f <= 1.0+EPS_SPLINE:
                         if f >= 0.0 and f <= 1.0:
                             # This wont happen often
-                            co = MidpointVecs(xsect[0], xsect[1])
+                            co = xsect[0].lerp(xsect[1], 0.5)
                             hub = get_hub(co, _hubs, EPS_SPLINE)
 
                             sp_a.hubs.append((a, hub))
@@ -309,7 +307,6 @@ def xsect_spline(sp_a, sp_b, _hubs):
 
 def connect_splines(splines):
     HASH_PREC = 8
-    from Mathutils import AngleBetweenVecs
     from math import radians
     ANG_LIMIT = radians(ANGLE_JOIN_LIMIT)
     def sort_pair(a, b):
@@ -341,7 +338,7 @@ def connect_splines(splines):
         v1 = p1a - p1b
         v2 = p2b - p2a
         
-        if AngleBetweenVecs(v1, v2) > ANG_LIMIT:
+        if v1.angle(v2) > ANG_LIMIT:
             return False
 
         # print("joining!")
@@ -354,8 +351,8 @@ def connect_splines(splines):
     while do_join:
         do_join = False
         for i, s1 in enumerate(splines):
-            key1a = s1.points[0].toTuple(HASH_PREC)
-            key1b = s1.points[-1].toTuple(HASH_PREC)
+            key1a = s1.points[0].to_tuple(HASH_PREC)
+            key1b = s1.points[-1].to_tuple(HASH_PREC)
             
             for j, s2 in enumerate(splines):
                 if s1 is s2:
@@ -363,8 +360,8 @@ def connect_splines(splines):
 
                 length_average = min(s1.length, s2.length)
 
-                key2a = s2.points[0].toTuple(HASH_PREC)
-                key2b = s2.points[-1].toTuple(HASH_PREC)
+                key2a = s2.points[0].to_tuple(HASH_PREC)
+                key2b = s2.points[-1].to_tuple(HASH_PREC)
                 
                 # there are 4 ways this may be joined
                 key_pair = sort_pair(key1a, key2a)
index 475c64ab31771b0255a9fd58b87c5a0b54a617b9..3376348c0af97aa7fc54b7ad9b651f283d60f2de 100644 (file)
@@ -127,8 +127,8 @@ def main(obj, bone_definition, base_names, options):
 
     delta_pbone.rotation_mode = 'XYZ'
 
-    rot = delta_pmatrix.invert().rotationPart() * child_pmatrix.rotationPart()
-    rot = rot.invert().toEuler()
+    rot = delta_pmatrix.invert().rotation_part() * child_pmatrix.rotation_part()
+    rot = rot.invert().to_euler()
 
     fcurve_drivers = delta_pbone.driver_add("rotation_euler", -1)
     for i, fcurve_driver in enumerate(fcurve_drivers):
@@ -141,7 +141,7 @@ def main(obj, bone_definition, base_names, options):
         mod.coefficients[1] = 0.0
 
     # tricky, find the transform to drive the bone to this location.
-    delta_head_offset = child_pmatrix.rotationPart() * (delta_phead - child_phead)
+    delta_head_offset = child_pmatrix.rotation_part() * (delta_phead - child_phead)
 
     fcurve_drivers = delta_pbone.driver_add("location", -1)
     for i, fcurve_driver in enumerate(fcurve_drivers):
index d1f74ca28bfe259359007140e5fa68b6c93a1f76..524450d0d24256fba7e6bab8b6670fc35076b3a8 100644 (file)
@@ -157,7 +157,7 @@ def ik(obj, bone_definition, base_names, options):
     ik.foot_roll_e.parent = ik_chain.foot_e
     ik.foot_roll_e.head -= mt_chain.toe_e.vector.normalize() * mt_chain.foot_e.length
     ik.foot_roll_e.tail = ik.foot_roll_e.head - (mt_chain.foot_e.vector.normalize() * mt_chain.toe_e.length)
-    ik.foot_roll_e.align_roll(mt_chain.foot_e.matrix.rotationPart() * Vector(0.0, 0.0, -1.0))
+    ik.foot_roll_e.align_roll(mt_chain.foot_e.matrix.rotation_part() * Vector(0.0, 0.0, -1.0))
 
     # MCH-foot
     ik.foot_roll_01_e = copy_bone_simple(arm, mt_chain.foot, "MCH-" + base_names[mt_chain.foot])
index e2ca1ab4d0c7d1f0aec141a892cde8d25d1787d4..77545bc09fd5bc75917a20cdca71eb27533176d7 100644 (file)
@@ -255,8 +255,8 @@ def deform(obj, definitions, base_names, options):
     bpy.ops.object.mode_set(mode='EDIT')
     
     # Calculate the rotation difference between the bones
-    rotdiff_r = acos(eb[lip1].matrix.toQuat() * eb[lip8].matrix.toQuat()) * 2
-    rotdiff_l = acos(eb[lip4].matrix.toQuat() * eb[lip5].matrix.toQuat()) * 2
+    rotdiff_r = acos(eb[lip1].matrix.to_quat() * eb[lip8].matrix.to_quat()) * 2
+    rotdiff_l = acos(eb[lip4].matrix.to_quat() * eb[lip5].matrix.to_quat()) * 2
     
     print (rotdiff_l)
     
index b231919823b9446662dc469138864cb6f9f01c0c..82010552ea7442f30260d38b43c8938a47e5d974 100644 (file)
@@ -249,15 +249,15 @@ def main(obj, bone_definition, base_names, options):
         # NOTE: the direction of the Z rotation depends on which side the palm is on.
         # we could do a simple side-of-x test but better to work out the direction
         # the hand is facing.
-        from Mathutils import Vector, AngleBetweenVecs
+        from Mathutils import Vector
         from math import degrees
         child_pbone_01 = obj.pose.bones[children[0]].bone
         child_pbone_02 = obj.pose.bones[children[1]].bone
 
         rel_vec = child_pbone_01.head - child_pbone_02.head
-        x_vec = child_pbone_01.matrix.rotationPart() * Vector(1.0, 0.0, 0.0)
+        x_vec = child_pbone_01.matrix.rotation_part() * Vector(1.0, 0.0, 0.0)
 
-        return degrees(AngleBetweenVecs(rel_vec, x_vec)) > 90.0
+        return degrees(rel_vec.angle(x_vec)) > 90.0
 
     if x_direction(): # flip
         driver.expression = "-(%s)" % driver.expression
index 98ab1bd16b72857ca2c6a65693b5fa7bd62c2bc8..265a2fe368a07fc55c1779e61c36983c02a925b8 100644 (file)
@@ -111,7 +111,7 @@ def deform(obj, definitions, base_names, options):
         
     
     # Calculate the rotation difference between the bones
-    rotdiff = (eb[bone_from].matrix.toQuat() * eb[bone_to].matrix.toQuat()) * 2
+    rotdiff = (eb[bone_from].matrix.to_quat() * eb[bone_to].matrix.to_quat()) * 2
     
     bpy.ops.object.mode_set(mode='OBJECT')
     
index e45f0dbc63af175d09fb114c598613f660638a8d..289489686ec0519b192273a53b7bba9e4ae92a0f 100644 (file)
@@ -205,8 +205,8 @@ def add_pole_target_bone(obj, base_bone_name, name, mode='CROSS'):
         offset.length = distance
     elif mode == 'ZAVERAGE':
         # between both bones Z axis
-        z_axis_a = base_ebone.matrix.copy().rotationPart() * Vector(0.0, 0.0, -1.0)
-        z_axis_b = parent_ebone.matrix.copy().rotationPart() * Vector(0.0, 0.0, -1.0)
+        z_axis_a = base_ebone.matrix.copy().rotation_part() * Vector(0.0, 0.0, -1.0)
+        z_axis_b = parent_ebone.matrix.copy().rotation_part() * Vector(0.0, 0.0, -1.0)
         offset = (z_axis_a + z_axis_b).normalize() * distance
     else:
         # preset axis
@@ -274,8 +274,8 @@ def write_meta_rig(obj, func_name="metarig_template"):
     for bone_name in bones:
         bone = arm.edit_bones[bone_name]
         code.append("    bone = arm.edit_bones.new('%s')" % bone.name)
-        code.append("    bone.head[:] = %.4f, %.4f, %.4f" % bone.head.toTuple(4))
-        code.append("    bone.tail[:] = %.4f, %.4f, %.4f" % bone.tail.toTuple(4))
+        code.append("    bone.head[:] = %.4f, %.4f, %.4f" % bone.head.to_tuple(4))
+        code.append("    bone.tail[:] = %.4f, %.4f, %.4f" % bone.tail.to_tuple(4))
         code.append("    bone.roll = %.4f" % bone.roll)
         code.append("    bone.connected = %s" % str(bone.connected))
         if bone.parent:
index f9b0b4d75b82bdac584aea6e953913c04db0f53e..88b70509dee83532dee91f8c0213248a5a372193 100644 (file)
@@ -90,7 +90,7 @@ class MeshMirrorUV(bpy.types.Operator):
         mirror_gt = {}
         mirror_lt = {}
 
-        vcos = [v.co.toTuple(5) for v in mesh.verts]
+        vcos = [v.co.to_tuple(5) for v in mesh.verts]
 
         for i, co in enumerate(vcos):
             if co[0] > 0.0:
index 6f62924ec024c2865b71d0ace159f154071a31f2..15bf22d38b937f2d833bccea39de5688aa829575 100644 (file)
@@ -22,8 +22,7 @@
 import time, functools
 import bpy
 # from Blender import Window
-from Mathutils import MidpointVecs, Vector
-from Mathutils import AngleBetweenVecs as _AngleBetweenVecs_
+from Mathutils import Vector
 # import BPyMessages
 
 # from Blender.Draw import PupMenu
@@ -36,7 +35,7 @@ CULL_METHOD = 0
 def AngleBetweenVecs(a1,a2):
     import math
     try:
-        return math.degrees(_AngleBetweenVecs_(a1,a2))
+        return math.degrees(a1.angle(a2))
     except:
         return 180.0
 
@@ -54,7 +53,7 @@ class edge(object):
         self.removed = 0       # Have we been culled from the eloop
         self.match = None      # The other edge were making a face with
 
-        self.cent= MidpointVecs(co1, co2)
+        self.cent= co1.lerp(co2, 0.5)
         self.angle= 0.0
         self.fake= False
 
index 0cf2a650973ba15a70c051a2d76e16a16750a7da..5efbbf25c3227218319aefa0e09457729f4f88ae 100644 (file)
@@ -936,7 +936,7 @@ def main(context, island_margin, projection_limit):
         # Initialize projectVecs
         if USER_VIEW_INIT:
             # Generate Projection
-            projectVecs = [Vector(Window.GetViewVector()) * ob.matrixWorld.copy().invert().rotationPart()] # We add to this allong the way
+            projectVecs = [Vector(Window.GetViewVector()) * ob.matrixWorld.copy().invert().rotation_part()] # We add to this allong the way
         else:
             projectVecs = []
 
index 0d1bc7fa29df385e9b7a908682420899ff7d0de3..b4eac81b4925355d2d4a00732087115042ba6fef 100644 (file)
@@ -6,7 +6,7 @@
 # for keyboard event comparison
 # import GameKeys
 
-# support for Vector(), Matrix() types and advanced functions like AngleBetweenVecs(v1,v2) and RotationMatrix(...)
+# support for Vector(), Matrix() types and advanced functions like ScaleMatrix(...) and RotationMatrix(...)
 # import Mathutils
 
 # for functions like getWindowWidth(), getWindowHeight()
index da5ce045b44e1daa53a2e58e1898289999b0c762..237cd8c3443d877061cdf72c78c6f68bc8afc3ce 100644 (file)
@@ -10,6 +10,83 @@ Geometry
 This new module provides access to a geometry function.
 """
 
+def Intersect(vec1, vec2, vec3, ray, orig, clip=1):
+  """
+  Return the intersection between a ray and a triangle, if possible, return None otherwise.
+  @type vec1: Vector object.
+  @param vec1: A 3d vector, one corner of the triangle.
+  @type vec2: Vector object.
+  @param vec2: A 3d vector, one corner of the triangle.
+  @type vec3: Vector object.
+  @param vec3: A 3d vector, one corner of the triangle.
+  @type ray: Vector object.
+  @param ray: A 3d vector, the orientation of the ray. the length of the ray is not used, only the direction.
+  @type orig: Vector object.
+  @param orig: A 3d vector, the origin of the ray.
+  @type clip: integer
+  @param clip: if 0, don't restrict the intersection to the area of the triangle, use the infinite plane defined by the triangle.
+  @rtype: Vector object
+  @return: The intersection between a ray and a triangle, if possible, None otherwise.
+  """
+
+def TriangleArea(vec1, vec2, vec3):
+  """
+  Return the area size of the 2D or 3D triangle defined.
+  @type vec1: Vector object.
+  @param vec1: A 2d or 3d vector, one corner of the triangle.
+  @type vec2: Vector object.
+  @param vec2: A 2d or 3d vector, one corner of the triangle.
+  @type vec3: Vector object.
+  @param vec3: A 2d or 3d vector, one corner of the triangle.
+  @rtype: float
+  @return: The area size of the 2D or 3D triangle defined.
+  """
+
+def TriangleNormal(vec1, vec2, vec3):
+  """
+  Return the normal of the 3D triangle defined.
+  @type vec1: Vector object.
+  @param vec1: A 3d vector, one corner of the triangle.
+  @type vec2: Vector object.
+  @param vec2: A 3d vector, one corner of the triangle.
+  @type vec3: Vector object.
+  @param vec3: A 3d vector, one corner of the triangle.
+  @rtype: float
+  @return: The normal of the 3D triangle defined.
+  """
+
+def QuadNormal(vec1, vec2, vec3, vec4):
+  """
+  Return the normal of the 3D quad defined.
+  @type vec1: Vector object.
+  @param vec1: A 3d vector, the first vertex of the quad.
+  @type vec2: Vector object.
+  @param vec2: A 3d vector, the second vertex of the quad.
+  @type vec3: Vector object.
+  @param vec3: A 3d vector, the third vertex of the quad.
+  @type vec4: Vector object.
+  @param vec4: A 3d vector, the fourth vertex of the quad.
+  @rtype: float
+  @return: The normal of the 3D quad defined.
+  """
+
+def LineIntersect(vec1, vec2, vec3, vec4):
+  """
+  Return a tuple with the points on each line respectively closest to the other
+  (when both lines intersect, both vector hold the same value).
+  The lines are evaluated as infinite lines in space, the values returned may not be between the 2 points given for each line.
+  @type vec1: Vector object.
+  @param vec1: A 3d vector, one point on the first line.
+  @type vec2: Vector object.
+  @param vec2: A 3d vector, another point on the first line.
+  @type vec3: Vector object.
+  @param vec3: A 3d vector, one point on the second line.
+  @type vec4: Vector object.
+  @param vec4: A 3d vector, another point on the second line.
+  @rtype: (Vector object, Vector object)
+  @return: A tuple with the points on each line respectively closest to the other.
+  """
+
 def PolyFill(polylines):
        """
        Takes a list of polylines and calculates triangles that would fill in the polylines.
index 5d5462de7d46f67d5c43272af3afb1a0eef4af25..8cd78920f08fef5e9f91e031e219aeeedc1de3ab 100644 (file)
@@ -22,242 +22,13 @@ Example::
   matTotal.invert()
 
   mat3 = matTotal.rotationPart
-  quat1 = mat.toQuat()
-  quat2 = mat3.toQuat()
+  quat1 = mat.to_quat()
+  quat2 = mat3.to_quat()
 
   angle = DifferenceQuats(quat1, quat2)
   print angle  
 """
 
-def Rand (low=0.0, high = 1.0):
-  """
-  Return a random number within a range.
-  low and high represent are optional parameters which represent the range
-  from which the random number must return its result.
-  @type low: float
-  @param low: The lower range.
-  @type high: float
-  @param high: The upper range.
-  """
-
-def Intersect(vec1, vec2, vec3, ray, orig, clip=1):
-  """
-  Return the intersection between a ray and a triangle, if possible, return None otherwise.
-  @type vec1: Vector object.
-  @param vec1: A 3d vector, one corner of the triangle.
-  @type vec2: Vector object.
-  @param vec2: A 3d vector, one corner of the triangle.
-  @type vec3: Vector object.
-  @param vec3: A 3d vector, one corner of the triangle.
-  @type ray: Vector object.
-  @param ray: A 3d vector, the orientation of the ray. the length of the ray is not used, only the direction.
-  @type orig: Vector object.
-  @param orig: A 3d vector, the origin of the ray.
-  @type clip: integer
-  @param clip: if 0, don't restrict the intersection to the area of the triangle, use the infinite plane defined by the triangle.
-  @rtype: Vector object
-  @return: The intersection between a ray and a triangle, if possible, None otherwise.
-  """
-
-def TriangleArea(vec1, vec2, vec3):
-  """
-  Return the area size of the 2D or 3D triangle defined.
-  @type vec1: Vector object.
-  @param vec1: A 2d or 3d vector, one corner of the triangle.
-  @type vec2: Vector object.
-  @param vec2: A 2d or 3d vector, one corner of the triangle.
-  @type vec3: Vector object.
-  @param vec3: A 2d or 3d vector, one corner of the triangle.
-  @rtype: float
-  @return: The area size of the 2D or 3D triangle defined.
-  """
-
-def TriangleNormal(vec1, vec2, vec3):
-  """
-  Return the normal of the 3D triangle defined.
-  @type vec1: Vector object.
-  @param vec1: A 3d vector, one corner of the triangle.
-  @type vec2: Vector object.
-  @param vec2: A 3d vector, one corner of the triangle.
-  @type vec3: Vector object.
-  @param vec3: A 3d vector, one corner of the triangle.
-  @rtype: float
-  @return: The normal of the 3D triangle defined.
-  """
-
-def QuadNormal(vec1, vec2, vec3, vec4):
-  """
-  Return the normal of the 3D quad defined.
-  @type vec1: Vector object.
-  @param vec1: A 3d vector, the first vertex of the quad.
-  @type vec2: Vector object.
-  @param vec2: A 3d vector, the second vertex of the quad.
-  @type vec3: Vector object.
-  @param vec3: A 3d vector, the third vertex of the quad.
-  @type vec4: Vector object.
-  @param vec4: A 3d vector, the fourth vertex of the quad.
-  @rtype: float
-  @return: The normal of the 3D quad defined.
-  """
-
-def LineIntersect(vec1, vec2, vec3, vec4):
-  """
-  Return a tuple with the points on each line respectively closest to the other
-  (when both lines intersect, both vector hold the same value).
-  The lines are evaluated as infinite lines in space, the values returned may not be between the 2 points given for each line.
-  @type vec1: Vector object.
-  @param vec1: A 3d vector, one point on the first line.
-  @type vec2: Vector object.
-  @param vec2: A 3d vector, another point on the first line.
-  @type vec3: Vector object.
-  @param vec3: A 3d vector, one point on the second line.
-  @type vec4: Vector object.
-  @param vec4: A 3d vector, another point on the second line.
-  @rtype: (Vector object, Vector object)
-  @return: A tuple with the points on each line respectively closest to the other.
-  """
-
-def AngleBetweenVecs(vec1, vec2):
-  """
-  Return the angle between two vectors. Zero length vectors raise an error.
-  @type vec1: Vector object.
-  @param vec1: A 2d or 3d vector.
-  @type vec2: Vector object.
-  @param vec2: A 2d or 3d vector.
-  @rtype: float
-  @return: The angle between the vectors in degrees.
-  @raise AttributeError: When there is a zero-length vector as an argument.
-  """
-
-def MidpointVecs(vec1, vec2):
-  """
-  Return a vector to the midpoint between two vectors.
-  @type vec1: Vector object.
-  @param vec1: A 2d,3d or 4d vector.
-  @type vec2: Vector object.
-  @param vec2: A 2d,3d or 4d vector.
-  @rtype: Vector object
-  @return: The vector to the midpoint.
-  """
-
-def ProjectVecs(vec1, vec2):
-  """  
-  Return the projection of vec1 onto vec2.
-  @type vec1: Vector object.
-  @param vec1: A 2d,3d or 4d vector.
-  @type vec2: Vector object.
-  @param vec2: A 2d,3d or 4d vector.
-  @rtype: Vector object
-  @return: The parallel projection vector.
-  """
-
-def RotationMatrix(angle, matSize, axisFlag, axis):
-  """  
-  Create a matrix representing a rotation.
-  @type angle: float
-  @param angle: The angle of rotation desired.
-  @type matSize: int
-  @param matSize: The size of the rotation matrix to construct.
-  Can be 2d, 3d, or 4d.
-  @type axisFlag: string (optional)
-  @param axisFlag: Possible values:
-       - "x - x-axis rotation"
-       - "y - y-axis rotation"
-       - "z - z-axis rotation"
-       - "r - arbitrary rotation around vector"
-  @type axis: Vector object. (optional)
-  @param axis: The arbitrary axis of rotation used with "R"
-  @rtype: Matrix object.
-  @return: A new rotation matrix.
-  """
-
-def TranslationMatrix(vector):
-  """  
-  Create a matrix representing a translation
-  @type vector: Vector object
-  @param vector: The translation vector
-  @rtype: Matrix object.
-  @return: An identity matrix with a translation.
-  """
-
-def ScaleMatrix(factor, matSize, axis):
-  """  
-  Create a matrix representing a scaling.
-  @type factor: float
-  @param factor: The factor of scaling to apply.
-  @type matSize: int
-  @param matSize: The size of the scale matrix to construct.
-  Can be 2d, 3d, or 4d.
-  @type axis: Vector object.  (optional)
-  @param axis: Direction to influence scale.
-  @rtype: Matrix object.
-  @return: A new scale matrix.
-  """
-
-def OrthoProjectionMatrix(plane, matSize, axis):
-  """  
-  Create a matrix to represent an orthographic projection
-  @type plane: string
-  @param plane: Can be any of the following:
-       - "x - x projection (2D)"
-       - "y - y projection (2D)"
-       - "xy - xy projection"
-       - "xz - xz projection"
-       - "yz - yz projection"
-       - "r - arbitrary projection plane"
-  @type matSize: int
-  @param matSize: The size of the projection matrix to construct.
-  Can be 2d, 3d, or 4d.
-  @type axis: Vector object. (optional)
-  @param axis: Arbitrary perpendicular plane vector.
-  @rtype: Matrix object.
-  @return: A new projeciton matrix.
-  """
-
-def ShearMatrix(plane, factor, matSize):
-  """  
-  Create a matrix to represent an orthographic projection
-  @type plane: string
-  @param plane: Can be any of the following:
-       - "x - x shear (2D)"
-       - "y - y shear (2D)"
-       - "xy - xy shear"
-       - "xz - xz shear"
-       - "yz - yz shear"
-  @type factor: float
-  @param factor: The factor of shear to apply.
-  @type matSize: int
-  @param matSize: The size of the projection matrix to construct.
-  Can be 2d, 3d, or 4d.
-  @rtype: Matrix object.
-  @return: A new shear matrix.
-  """
-
-def DifferenceQuats(quat1, quat2):
-  """
-  Returns a quaternion represting the rotational difference.
-  @type quat1: Quaternion object.
-  @param quat1: Quaternion.
-  @type quat2: Quaternion object.
-  @param quat2: Quaternion.
-  @rtype: Quaternion object
-  @return: Return a quaternion which which represents the rotational
-  difference between the two quat rotations.
-  """
-
-def Slerp(quat1, quat2, factor):
-  """
-  Returns the interpolation of two quaternions.
-  @type quat1: Quaternion object.
-  @param quat1: Quaternion.
-  @type quat2: Quaternion object.
-  @param quat2: Quaternion.
-  @type factor: float
-  @param factor: The interpolation value
-  @rtype: Quaternion object
-  @return: The interpolated rotation.
-  """
-
 class Vector:
   """
   The Vector object
@@ -330,100 +101,6 @@ class Vector:
         - ():     An empty 3 dimensional vector.
     """
 
-  def copy():
-    """
-    Returns a copy of this vector
-    @return: a copy of itself
-    """
-
-  def zero():
-    """
-    Set all values to zero.
-    @return: an instance of itself
-    """
-
-  def normalize():
-    """
-    Normalize the vector, making the length of the vector always 1.0
-    @note: Normalize works for vectors of all sizes, however 4D Vectors w axis is left untouched.
-    @note: Normalizing a vector where all values are zero results in all axis having a nan value (not a number).
-    @return: an instance of itself
-    """
-
-  def negate():
-    """
-    Set all values to their negative.
-    @return: an instance of its self
-    """
-
-  def resize2D():
-    """
-    Resize the vector to 2d.
-    @return: an instance of itself
-    """
-
-  def resize3D():
-    """
-    Resize the vector to 3d. New axis will be 0.0.
-    @return: an instance of itself
-    """
-
-  def resize4D():
-    """
-    Resize the vector to 4d. New axis will be 0.0.
-    The last component will be 1.0, to make multiplying 3d vectors by 4x4 matrices easier.
-    @return: an instance of itself
-    """
-
-  def toTrackQuat(track, up):
-    """
-    Return a quaternion rotation from the vector and the track and up axis.
-    @type track: String.
-    @param track: Possible values:
-                  - "x - x-axis up"
-                  - "y - y-axis up"
-                  - "z - z-axis up"
-                  - "-x - negative x-axis up"
-                  - "-y - negative y-axis up"
-                  - "-z - negative z-axis up"
-    @type up: String.
-    @param up: Possible values:
-                  - "x - x-axis up"
-                  - "y - y-axis up"
-                  - "z - z-axis up"
-    @rtype: Quaternion
-    @return: Return a quaternion rotation from the vector and the track and up axis.
-    """
-
-  def reflect(mirror):
-    """
-    Return the reflection vector from the mirror vector argument.
-    @type mirror: Vector object
-    @param mirror: This vector could be a normal from the reflecting surface.
-    @rtype: Vector object matching the size of this vector.
-    @return: The reflected vector.
-    """
-
-  def cross(other):
-    """
-    Return the cross product of this vector and another.
-    @note: both vectors must be 3D.
-    @type other: Vector object
-    @param other: The other vector to perform the cross product with.
-    @rtype: Vector
-    @return: The cross product.
-    """
-
-  def dot(other):
-    """
-    Return the dot product of this vector and another.
-    @note: both vectors must be the same size.
-    @type other: Vector object
-    @param other: The other vector to perform the dot product with.
-    @rtype: float
-    @return: The dot product.
-    """
-
 class Euler:
   """
   The Euler object
@@ -470,43 +147,6 @@ class Euler:
     @note: Values are in degrees.
     """
 
-  def zero():
-    """
-    Set all values to zero.
-    @return: an instance of itself
-    """
-
-  def copy():
-    """
-    @return: a copy of this euler.
-    """
-
-  def unique():
-    """
-    Calculate a unique rotation for this euler. Avoids gimble lock.
-    @return: an instance of itself
-    """
-
-  def toMatrix():
-    """
-    Return a matrix representation of the euler.
-    @rtype: Matrix object
-    @return: A 3x3 roation matrix representation of the euler.
-    """
-
-  def toQuat():
-    """
-    Return a quaternion representation of the euler.
-    @rtype: Quaternion object
-    @return: Quaternion representation of the euler.
-    """
-  def makeCompatible(eul_compat):
-    """
-    Make this euler compatible with another, so interpolating between them works as expected.
-    @rtype: Euler object
-    @return: an instance of itself
-    """
-
 class Quaternion:
   """
   The Quaternion object
@@ -571,76 +211,6 @@ class Quaternion:
         - ():     An identity 4 dimensional quaternion.
     """
 
-  def identity():
-    """
-    Set the quaternion to the identity quaternion.
-    @return: an instance of itself
-    """
-
-  def copy():
-    """
-    make a copy of the quaternion.
-    @return: a copy of itself
-    """
-
-  def negate():
-    """
-    Set the quaternion to its negative.
-    @return: an instance of itself
-    """
-
-  def conjugate():
-    """
-    Set the quaternion to its conjugate.
-    @return: an instance of itself
-    """
-
-  def inverse():
-    """
-    Set the quaternion to its inverse
-    @return: an instance of itself
-    """
-
-  def normalize():
-    """
-    Normalize the quaternion.
-    @return: an instance of itself
-    """
-
-  def toEuler(eul_compat):
-    """
-    Return Euler representation of the quaternion.
-    @type eul_compat: L{Euler}
-    @param eul_compat: Optional euler argument the new euler will be made compatible with (no axis flipping between them). Useful for converting a series of matrices to animation curves.
-    @rtype: Euler object
-    @return: Euler representation of the quaternion.
-    """
-  
-  def toMatrix():
-    """
-    Return a matrix representation of the quaternion.
-    @rtype: Matrix object
-    @return: A 3x3 rotation matrix representation of the quaternion.
-    """
-
-  def cross(other):
-    """
-    Return the cross product of this quaternion and another.
-    @type other: Quaterion object
-    @param other: The other quaternion to perform the cross product with.
-    @rtype: Vector
-    @return: The cross product.
-    """
-
-  def dot(other):
-    """
-    Return the dot product of this quaternion and another.
-    @type other: Quaterion object
-    @param other: The other quaternion to perform the dot product with.
-    @rtype: float
-    @return: The dot product.
-    """
-
 class Matrix:
   """
   The Matrix Object
@@ -699,99 +269,3 @@ class Matrix:
         - (list1, etc.): Matrix object initialized with the given values;
         - ():     An empty 3 dimensional matrix.
     """
-
-  def zero():
-    """
-    Set all matrix values to 0.
-    @return: an instance of itself
-    """
-
-
-  def copy():
-    """
-    Returns a copy of this matrix
-    @return: a copy of itself
-    """
-
-  def identity():
-    """
-    Set the matrix to the identity matrix.
-    An object with zero location and rotation, a scale of 1, will have an identity matrix.
-
-    See U{http://en.wikipedia.org/wiki/Identity_matrix}
-    @return: an instance of itself
-    """
-
-  def transpose():
-    """
-    Set the matrix to its transpose.
-    
-    See U{http://en.wikipedia.org/wiki/Transpose}
-    @return: None
-    """
-
-  def determinant():
-    """
-    Return the determinant of a matrix.
-    
-    See U{http://en.wikipedia.org/wiki/Determinant}
-    @rtype: float
-    @return: Return a the determinant of a matrix.
-    """
-
-  def invert():
-    """
-    Set the matrix to its inverse.
-    
-    See U{http://en.wikipedia.org/wiki/Inverse_matrix}
-    @return: an instance of itself.
-    @raise ValueError: When matrix is singular.
-    """
-
-  def rotationPart():
-    """
-    Return the 3d submatrix corresponding to the linear term of the 
-    embedded affine transformation in 3d. This matrix represents rotation
-    and scale. Note that the (4,4) element of a matrix can be used for uniform
-    scaling, too.
-    @rtype: Matrix object.
-    @return: Return the 3d matrix for rotation and scale.
-    """
-
-  def translationPart():
-    """
-    Return a the translation part of a 4 row matrix.
-    @rtype: Vector object.
-    @return: Return a the translation of a matrix.
-    """
-
-  def scalePart():
-    """
-    Return a the scale part of a 3x3 or 4x4 matrix.
-    @note: This method does not return negative a scale on any axis because it is not possible to obtain this data from the matrix alone.
-    @rtype: Vector object.
-    @return: Return a the scale of a matrix.
-    """
-
-  def resize4x4():
-    """
-    Resize the matrix to by 4x4
-    @return: an instance of itself.
-    """
-  
-  def toEuler(eul_compat):
-    """
-    Return an Euler representation of the rotation matrix (3x3 or 4x4 matrix only).
-    @type eul_compat: L{Euler}
-    @param eul_compat: Optional euler argument the new euler will be made compatible with (no axis flipping between them). Useful for converting a series of matrices to animation curves.
-    @rtype: Euler object
-    @return: Euler representation of the rotation matrix.
-    """
-
-  def toQuat():
-    """
-    Return a quaternion representation of the rotation matrix
-    @rtype: Quaternion object
-    @return: Quaternion representation of the rotation matrix
-    """
-
index 579c9d987cf3e825ba644868353d878b721f99f6..0dfddeee3480caee65975a3cd663f4f4399f7c24 100644 (file)
 #define SWAP_FLOAT(a,b,tmp) tmp=a; a=b; b=tmp
 #define eps 0.000001
 
-/*-- forward declarations -- */
-static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq );
-static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args );
-static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args );
-static PyObject *M_Geometry_PointInTriangle2D( PyObject * self, PyObject * args );
-static PyObject *M_Geometry_PointInQuad2D( PyObject * self, PyObject * args );
-static PyObject *M_Geometry_BoxPack2D( PyObject * self, PyObject * args );
-static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args );
-static PyObject *M_Geometry_BarycentricTransform( PyObject * self, PyObject * args );
-
 
 /*-------------------------DOC STRINGS ---------------------------*/
 static char M_Geometry_doc[] = "The Blender Geometry module\n\n";
+static char M_Geometry_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_Geometry_TriangleArea_doc[] = "(v1, v2, v3) - returns the area size of the 2D or 3D triangle defined";
+static char M_Geometry_TriangleNormal_doc[] = "(v1, v2, v3) - returns the normal of the 3D triangle defined";
+static char M_Geometry_QuadNormal_doc[] = "(v1, v2, v3, v4) - returns the normal of the 3D quad defined";
+static char M_Geometry_LineIntersect_doc[] = "(v1, v2, v3, v4) - returns a tuple with the points on each line respectively closest to the other";
 static char M_Geometry_PolyFill_doc[] = "(veclist_list) - takes a list of polylines (each point a vector) and returns the point indicies for a polyline filled with triangles";
 static char M_Geometry_LineIntersect2D_doc[] = "(lineA_p1, lineA_p2, lineB_p1, lineB_p2) - takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None";
 static char M_Geometry_ClosestPointOnLine_doc[] = "(pt, line_p1, line_p2) - takes a point and a line and returns a (Vector, float) for the point on the line, and the bool so you can know if the point was between the 2 points";
@@ -67,40 +62,280 @@ static char M_Geometry_PointInTriangle2D_doc[] = "(pt, tri_p1, tri_p2, tri_p3) -
 static char M_Geometry_PointInQuad2D_doc[] = "(pt, quad_p1, quad_p2, quad_p3, quad_p4) - takes 5 vectors, one is the point and the next 4 define the quad, only the x and y are used from the vectors";
 static char M_Geometry_BoxPack2D_doc[] = "";
 static char M_Geometry_BezierInterp_doc[] = "";
-/*-----------------------METHOD DEFINITIONS ----------------------*/
-struct PyMethodDef M_Geometry_methods[] = {
-       {"PolyFill", ( PyCFunction ) M_Geometry_PolyFill, METH_O, M_Geometry_PolyFill_doc},
-       {"LineIntersect2D", ( PyCFunction ) M_Geometry_LineIntersect2D, METH_VARARGS, M_Geometry_LineIntersect2D_doc},
-       {"ClosestPointOnLine", ( PyCFunction ) M_Geometry_ClosestPointOnLine, METH_VARARGS, M_Geometry_ClosestPointOnLine_doc},
-       {"PointInTriangle2D", ( PyCFunction ) M_Geometry_PointInTriangle2D, METH_VARARGS, M_Geometry_PointInTriangle2D_doc},
-       {"PointInQuad2D", ( PyCFunction ) M_Geometry_PointInQuad2D, METH_VARARGS, M_Geometry_PointInQuad2D_doc},
-       {"BoxPack2D", ( PyCFunction ) M_Geometry_BoxPack2D, METH_O, M_Geometry_BoxPack2D_doc},
-       {"BezierInterp", ( PyCFunction ) M_Geometry_BezierInterp, METH_VARARGS, M_Geometry_BezierInterp_doc},
-       {"BarycentricTransform", ( PyCFunction ) M_Geometry_BarycentricTransform, METH_VARARGS, NULL},
-       {NULL, NULL, 0, NULL}
-};
 
-static struct PyModuleDef M_Geometry_module_def = {
-       PyModuleDef_HEAD_INIT,
-       "Geometry",  /* m_name */
-       M_Geometry_doc,  /* m_doc */
-       0,  /* m_size */
-       M_Geometry_methods,  /* m_methods */
-       0,  /* m_reload */
-       0,  /* m_traverse */
-       0,  /* m_clear */
-       0,  /* m_free */
-};
+//---------------------------------INTERSECTION FUNCTIONS--------------------
+//----------------------------------Mathutils.Intersect() -------------------
+static PyObject *M_Geometry_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];
+       float det, inv_det, u, v, t;
+       int clip = 1;
 
-/*----------------------------MODULE INIT-------------------------*/
-PyObject *Geometry_Init(void)
+       if(!PyArg_ParseTuple(args, "O!O!O!O!O!|i", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &ray, &vector_Type, &ray_off , &clip)) {
+               PyErr_SetString( PyExc_TypeError, "expected 5 vector types\n" );
+               return NULL;
+       }
+       if(vec1->size != 3 || vec2->size != 3 || vec3->size != 3 || ray->size != 3 || ray_off->size != 3) {
+               PyErr_SetString( PyExc_TypeError, "only 3D vectors for all parameters\n");
+               return NULL;
+       }
+
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(ray) || !BaseMath_ReadCallback(ray_off))
+               return NULL;
+
+       VECCOPY(v1, vec1->vec);
+       VECCOPY(v2, vec2->vec);
+       VECCOPY(v3, vec3->vec);
+
+       VECCOPY(dir, ray->vec);
+       normalize_v3(dir);
+
+       VECCOPY(orig, ray_off->vec);
+
+       /* find vectors for two edges sharing v1 */
+       sub_v3_v3v3(e1, v2, v1);
+       sub_v3_v3v3(e2, v3, v1);
+
+       /* begin calculating determinant - also used to calculated U parameter */
+       cross_v3_v3v3(pvec, dir, e2);
+
+       /* if determinant is near zero, ray lies in plane of triangle */
+       det = dot_v3v3(e1, pvec);
+
+       if (det > -0.000001 && det < 0.000001) {
+               Py_RETURN_NONE;
+       }
+
+       inv_det = 1.0f / det;
+
+       /* calculate distance from v1 to ray origin */
+       sub_v3_v3v3(tvec, orig, v1);
+
+       /* calculate U parameter and test bounds */
+       u = dot_v3v3(tvec, pvec) * inv_det;
+       if (clip && (u < 0.0f || u > 1.0f)) {
+               Py_RETURN_NONE;
+       }
+
+       /* prepare to test the V parameter */
+       cross_v3_v3v3(qvec, tvec, e1);
+
+       /* calculate V parameter and test bounds */
+       v = dot_v3v3(dir, qvec) * inv_det;
+
+       if (clip && (v < 0.0f || u + v > 1.0f)) {
+               Py_RETURN_NONE;
+       }
+
+       /* calculate t, ray intersects triangle */
+       t = dot_v3v3(e2, qvec) * inv_det;
+
+       mul_v3_fl(dir, t);
+       add_v3_v3v3(pvec, orig, dir);
+
+       return newVectorObject(pvec, 3, Py_NEW, NULL);
+}
+//----------------------------------Mathutils.LineIntersect() -------------------
+/* Line-Line intersection using algorithm from mathworld.wolfram.com */
+static PyObject *M_Geometry_LineIntersect( PyObject * self, PyObject * args )
 {
-       PyObject *submodule;
-       
-       submodule = PyModule_Create(&M_Geometry_module_def);
-       PyDict_SetItemString(PySys_GetObject("modules"), M_Geometry_module_def.m_name, submodule);
-       
-       return (submodule);
+       PyObject * tuple;
+       VectorObject *vec1, *vec2, *vec3, *vec4;
+       float v1[3], v2[3], v3[3], v4[3], i1[3], i2[3];
+
+       if( !PyArg_ParseTuple( args, "O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4 ) ) {
+               PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" );
+               return NULL;
+       }
+       if( vec1->size != vec2->size || vec1->size != vec3->size || vec3->size != vec2->size) {
+               PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" );
+               return NULL;
+       }
+
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
+               return NULL;
+
+       if( vec1->size == 3 || vec1->size == 2) {
+               int result;
+
+               if (vec1->size == 3) {
+                       VECCOPY(v1, vec1->vec);
+                       VECCOPY(v2, vec2->vec);
+                       VECCOPY(v3, vec3->vec);
+                       VECCOPY(v4, vec4->vec);
+               }
+               else {
+                       v1[0] = vec1->vec[0];
+                       v1[1] = vec1->vec[1];
+                       v1[2] = 0.0f;
+
+                       v2[0] = vec2->vec[0];
+                       v2[1] = vec2->vec[1];
+                       v2[2] = 0.0f;
+
+                       v3[0] = vec3->vec[0];
+                       v3[1] = vec3->vec[1];
+                       v3[2] = 0.0f;
+
+                       v4[0] = vec4->vec[0];
+                       v4[1] = vec4->vec[1];
+                       v4[2] = 0.0f;
+               }
+
+               result = isect_line_line_v3(v1, v2, v3, v4, i1, i2);
+
+               if (result == 0) {
+                       /* colinear */
+                       Py_RETURN_NONE;
+               }
+               else {
+                       tuple = PyTuple_New( 2 );
+                       PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW, NULL) );
+                       PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW, NULL) );
+                       return tuple;
+               }
+       }
+       else {
+               PyErr_SetString( PyExc_TypeError, "2D/3D vectors only\n" );
+               return NULL;
+       }
+}
+
+
+
+//---------------------------------NORMALS FUNCTIONS--------------------
+//----------------------------------Mathutils.QuadNormal() -------------------
+static PyObject *M_Geometry_QuadNormal( PyObject * self, PyObject * args )
+{
+       VectorObject *vec1;
+       VectorObject *vec2;
+       VectorObject *vec3;
+       VectorObject *vec4;
+       float v1[3], v2[3], v3[3], v4[3], e1[3], e2[3], n1[3], n2[3];
+
+       if( !PyArg_ParseTuple( args, "O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4 ) ) {
+               PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" );
+               return NULL;
+       }
+       if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec4->size) {
+               PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" );
+               return NULL;
+       }
+       if( vec1->size != 3 ) {
+               PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" );
+               return NULL;
+       }
+
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
+               return NULL;
+
+       VECCOPY(v1, vec1->vec);
+       VECCOPY(v2, vec2->vec);
+       VECCOPY(v3, vec3->vec);
+       VECCOPY(v4, vec4->vec);
+
+       /* find vectors for two edges sharing v2 */
+       sub_v3_v3v3(e1, v1, v2);
+       sub_v3_v3v3(e2, v3, v2);
+
+       cross_v3_v3v3(n1, e2, e1);
+       normalize_v3(n1);
+
+       /* find vectors for two edges sharing v4 */
+       sub_v3_v3v3(e1, v3, v4);
+       sub_v3_v3v3(e2, v1, v4);
+
+       cross_v3_v3v3(n2, e2, e1);
+       normalize_v3(n2);
+
+       /* adding and averaging the normals of both triangles */
+       add_v3_v3v3(n1, n2, n1);
+       normalize_v3(n1);
+
+       return newVectorObject(n1, 3, Py_NEW, NULL);
+}
+
+//----------------------------Mathutils.TriangleNormal() -------------------
+static PyObject *M_Geometry_TriangleNormal( PyObject * self, PyObject * args )
+{
+       VectorObject *vec1, *vec2, *vec3;
+       float v1[3], v2[3], v3[3], e1[3], e2[3], n[3];
+
+       if( !PyArg_ParseTuple( args, "O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3 ) ) {
+               PyErr_SetString( PyExc_TypeError, "expected 3 vector types\n" );
+               return NULL;
+       }
+       if( vec1->size != vec2->size || vec1->size != vec3->size ) {
+               PyErr_SetString( PyExc_TypeError, "vectors must be of the same size\n" );
+               return NULL;
+       }
+       if( vec1->size != 3 ) {
+               PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" );
+               return NULL;
+       }
+
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
+               return NULL;
+
+       VECCOPY(v1, vec1->vec);
+       VECCOPY(v2, vec2->vec);
+       VECCOPY(v3, vec3->vec);
+
+       /* find vectors for two edges sharing v2 */
+       sub_v3_v3v3(e1, v1, v2);
+       sub_v3_v3v3(e2, v3, v2);
+
+       cross_v3_v3v3(n, e2, e1);
+       normalize_v3(n);
+
+       return newVectorObject(n, 3, Py_NEW, NULL);
+}
+
+//--------------------------------- AREA FUNCTIONS--------------------
+//----------------------------------Mathutils.TriangleArea() -------------------
+static PyObject *M_Geometry_TriangleArea( PyObject * self, PyObject * args )
+{
+       VectorObject *vec1, *vec2, *vec3;
+       float v1[3], v2[3], v3[3];
+
+       if( !PyArg_ParseTuple
+           ( args, "O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2
+               , &vector_Type, &vec3 ) ) {
+               PyErr_SetString( PyExc_TypeError, "expected 3 vector types\n");
+               return NULL;
+       }
+       if( vec1->size != vec2->size || vec1->size != vec3->size ) {
+               PyErr_SetString( PyExc_TypeError, "vectors must be of the same size\n" );
+               return NULL;
+       }
+
+       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
+               return NULL;
+
+       if (vec1->size == 3) {
+               VECCOPY(v1, vec1->vec);
+               VECCOPY(v2, vec2->vec);
+               VECCOPY(v3, vec3->vec);
+
+               return PyFloat_FromDouble( area_tri_v3(v1, v2, v3) );
+       }
+       else if (vec1->size == 2) {
+               v1[0] = vec1->vec[0];
+               v1[1] = vec1->vec[1];
+
+               v2[0] = vec2->vec[0];
+               v2[1] = vec2->vec[1];
+
+               v3[0] = vec3->vec[0];
+               v3[1] = vec3->vec[1];
+
+               return PyFloat_FromDouble( area_tri_v2(v1, v2, v3) );
+       }
+       else {
+               PyErr_SetString( PyExc_TypeError, "only 2D,3D vectors are supported\n" );
+               return NULL;
+       }
 }
 
 /*----------------------------------Geometry.PolyFill() -------------------*/
@@ -569,3 +804,43 @@ static PyObject *M_Geometry_BarycentricTransform(PyObject * self, PyObject * arg
 
        return newVectorObject(vec, 3, Py_NEW, NULL);
 }
+
+struct PyMethodDef M_Geometry_methods[] = {
+       {"Intersect", ( PyCFunction ) M_Geometry_Intersect, METH_VARARGS, M_Geometry_Intersect_doc},
+       {"TriangleArea", ( PyCFunction ) M_Geometry_TriangleArea, METH_VARARGS, M_Geometry_TriangleArea_doc},
+       {"TriangleNormal", ( PyCFunction ) M_Geometry_TriangleNormal, METH_VARARGS, M_Geometry_TriangleNormal_doc},
+       {"QuadNormal", ( PyCFunction ) M_Geometry_QuadNormal, METH_VARARGS, M_Geometry_QuadNormal_doc},
+       {"LineIntersect", ( PyCFunction ) M_Geometry_LineIntersect, METH_VARARGS, M_Geometry_LineIntersect_doc},
+       {"PolyFill", ( PyCFunction ) M_Geometry_PolyFill, METH_O, M_Geometry_PolyFill_doc},
+       {"LineIntersect2D", ( PyCFunction ) M_Geometry_LineIntersect2D, METH_VARARGS, M_Geometry_LineIntersect2D_doc},
+       {"ClosestPointOnLine", ( PyCFunction ) M_Geometry_ClosestPointOnLine, METH_VARARGS, M_Geometry_ClosestPointOnLine_doc},
+       {"PointInTriangle2D", ( PyCFunction ) M_Geometry_PointInTriangle2D, METH_VARARGS, M_Geometry_PointInTriangle2D_doc},
+       {"PointInQuad2D", ( PyCFunction ) M_Geometry_PointInQuad2D, METH_VARARGS, M_Geometry_PointInQuad2D_doc},
+       {"BoxPack2D", ( PyCFunction ) M_Geometry_BoxPack2D, METH_O, M_Geometry_BoxPack2D_doc},
+       {"BezierInterp", ( PyCFunction ) M_Geometry_BezierInterp, METH_VARARGS, M_Geometry_BezierInterp_doc},
+       {"BarycentricTransform", ( PyCFunction ) M_Geometry_BarycentricTransform, METH_VARARGS, NULL},
+       {NULL, NULL, 0, NULL}
+};
+
+static struct PyModuleDef M_Geometry_module_def = {
+       PyModuleDef_HEAD_INIT,
+       "Geometry",  /* m_name */
+       M_Geometry_doc,  /* m_doc */
+       0,  /* m_size */
+       M_Geometry_methods,  /* m_methods */
+       0,  /* m_reload */
+       0,  /* m_traverse */
+       0,  /* m_clear */
+       0,  /* m_free */
+};
+
+/*----------------------------MODULE INIT-------------------------*/
+PyObject *Geometry_Init(void)
+{
+       PyObject *submodule;
+
+       submodule = PyModule_Create(&M_Geometry_module_def);
+       PyDict_SetItemString(PySys_GetObject("modules"), M_Geometry_module_def.m_name, submodule);
+
+       return (submodule);
+}
index b44d6450145fef24bc0c460e05543942a844b6ba..2e4b6dbb490d0b89bbd5255a80631d8905373165 100644 (file)
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/* Note: Changes to Mathutils since 2.4x
+ * use radians rather then degrees
+ * - Mathutils.MidpointVecs --> vector.lerp(other, fac)
+ * - Mathutils.AngleBetweenVecs --> vector.angle(other)
+ * - Mathutils.ProjectVecs --> vector.project(other)
+ * - Mathutils.DifferenceQuats --> quat.difference(other)
+ * - Mathutils.Slerp --> quat.slerp(other, fac)
+ * - Mathutils.Rand: removed, use pythons random module
+ * - Mathutils.RotationMatrix(angle, size, axis_flag, axis) --> Mathutils.RotationMatrix(angle, size, axis); merge axis & axis_flag args
+ * - Matrix.scalePart --> Matrix.scale_part
+ * - Matrix.translationPart --> Matrix.translation_part
+ * - Matrix.rotationPart --> Matrix.rotation_part
+ * - toMatrix --> to_matrix
+ * - toEuler --> to_euler
+ * - toQuat --> to_quat
+ * - Vector.toTrackQuat --> Vector.to_track_quat
+ *
+ * Moved to Geometry module: Intersect, TriangleArea, TriangleNormal, QuadNormal, LineIntersect
+ */
+
 #include "Mathutils.h"
 
 #include "BLI_math.h"
 #include "PIL_time.h"
-#include "BLI_rand.h"
 #include "BKE_utildefines.h"
 
 //-------------------------DOC STRINGS ---------------------------
-static char M_Mathutils_doc[] = "The Blender Mathutils module\n\n";
-static char M_Mathutils_Rand_doc[] = "() - return a random number";
-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_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_TranslationMatrix_doc[] = "(vec) - create a translation matrix from a vector";
-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_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},
-       {"AngleBetweenVecs", (PyCFunction) M_Mathutils_AngleBetweenVecs, METH_VARARGS, M_Mathutils_AngleBetweenVecs_doc},
-       {"MidpointVecs", (PyCFunction) M_Mathutils_MidpointVecs, METH_VARARGS, M_Mathutils_MidpointVecs_doc},
-       {"ProjectVecs", (PyCFunction) M_Mathutils_ProjectVecs, METH_VARARGS, M_Mathutils_ProjectVecs_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},
-       {"OrthoProjectionMatrix", (PyCFunction) M_Mathutils_OrthoProjectionMatrix,  METH_VARARGS, M_Mathutils_OrthoProjectionMatrix_doc},
-       {"DifferenceQuats", (PyCFunction) M_Mathutils_DifferenceQuats, METH_VARARGS,M_Mathutils_DifferenceQuats_doc},
-       {"Slerp", (PyCFunction) M_Mathutils_Slerp, METH_VARARGS, M_Mathutils_Slerp_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},
-       {"QuadNormal", ( PyCFunction ) M_Mathutils_QuadNormal, METH_VARARGS, M_Mathutils_QuadNormal_doc},
-       {"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 */
-
-static struct PyModuleDef M_Mathutils_module_def = {
-       PyModuleDef_HEAD_INIT,
-       "Mathutils",  /* m_name */
-       M_Mathutils_doc,  /* m_doc */
-       0,  /* m_size */
-       M_Mathutils_methods,  /* m_methods */
-       0,  /* m_reload */
-       0,  /* m_traverse */
-       0,  /* m_clear */
-       0,  /* m_free */
-};
-
-PyObject *Mathutils_Init(void)
-{
-       PyObject *submodule;
-
-       //seed the generator for the rand function
-       BLI_srand((unsigned int) (PIL_check_seconds_timer() * 0x7FFFFFFF));
-       
-       if( PyType_Ready( &vector_Type ) < 0 )
-               return NULL;
-       if( PyType_Ready( &matrix_Type ) < 0 )
-               return NULL;    
-       if( PyType_Ready( &euler_Type ) < 0 )
-               return NULL;
-       if( PyType_Ready( &quaternion_Type ) < 0 )
-               return NULL;
-       
-       submodule = PyModule_Create(&M_Mathutils_module_def);
-       PyDict_SetItemString(PySys_GetObject("modules"), M_Mathutils_module_def.m_name, submodule);
-       
-       /* 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 );
-       
-       mathutils_matrix_vector_cb_index= Mathutils_RegisterCallback(&mathutils_matrix_vector_cb);
-
-       return (submodule);
-}
+static char M_Mathutils_doc[] = "This module provides access to matrices, eulers, quaternions and vectors.";
 
 //-----------------------------METHODS----------------------------
 //-----------------quat_rotation (internal)-----------
@@ -204,164 +124,49 @@ PyObject *quat_rotation(PyObject *arg1, PyObject *arg2)
        
 }
 
-//----------------------------------Mathutils.Rand() --------------------
-//returns a random number between a high and low value
-static PyObject *M_Mathutils_Rand(PyObject * self, PyObject * args)
-{
-       float high, low, range;
-       double drand;
-       //initializers
-       high = 1.0;
-       low = 0.0;
-
-       if(!PyArg_ParseTuple(args, "|ff", &low, &high)) {
-               PyErr_SetString(PyExc_TypeError, "Mathutils.Rand(): expected nothing or optional (float, float)\n");
-               return NULL;
-       }
-
-       if((high < low) || (high < 0 && low > 0)) {
-               PyErr_SetString(PyExc_ValueError, "Mathutils.Rand(): high value should be larger than low value\n");
-               return NULL;
-       }
-       //get the random number 0 - 1
-       drand = BLI_drand();
-
-       //set it to range
-       range = high - low;
-       drand = drand * range;
-       drand = drand + low;
-
-       return PyFloat_FromDouble(drand);
-}
-//----------------------------------VECTOR FUNCTIONS---------------------
-//----------------------------------Mathutils.AngleBetweenVecs() ---------
-//calculates the angle between 2 vectors
-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;
-       int x, size;
-
-       if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2))
-               goto AttributeError1; //not vectors
-       if(vec1->size != vec2->size)
-               goto AttributeError1; //bad sizes
-
-       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
-               return NULL;
-       
-       //since size is the same....
-       size = vec1->size;
-
-       for(x = 0; x < size; x++) {
-               test_v1 += vec1->vec[x] * vec1->vec[x];
-               test_v2 += vec2->vec[x] * vec2->vec[x];
-       }
-       if (!test_v1 || !test_v2){
-               goto AttributeError2; //zero-length vector
-       }
-
-       //dot product
-       for(x = 0; x < size; x++) {
-               dot += vec1->vec[x] * vec2->vec[x];
-       }
-       dot /= (sqrt(test_v1) * sqrt(test_v2));
-
-       angleRads = (double)saacos(dot);
-
-#ifdef USE_MATHUTILS_DEG
-       return PyFloat_FromDouble(angleRads * (180/ Py_PI));
-#else
-       return PyFloat_FromDouble(angleRads);
-#endif
-AttributeError1:
-       PyErr_SetString(PyExc_AttributeError, "Mathutils.AngleBetweenVecs(): expects (2) VECTOR objects of the same size\n");
-       return NULL;
-
-AttributeError2:
-       PyErr_SetString(PyExc_AttributeError, "Mathutils.AngleBetweenVecs(): zero length vectors are not acceptable arguments\n");
-       return NULL;
-}
-//----------------------------------Mathutils.MidpointVecs() -------------
-//calculates the midpoint between 2 vectors
-static PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args)
-{
-       VectorObject *vec1 = NULL, *vec2 = NULL;
-       float vec[4];
-       int x;
-       
-       if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) {
-               PyErr_SetString(PyExc_TypeError, "Mathutils.MidpointVecs(): expects (2) vector objects of the same size\n");
-               return NULL;
-       }
-       if(vec1->size != vec2->size) {
-               PyErr_SetString(PyExc_AttributeError, "Mathutils.MidpointVecs(): expects (2) vector objects of the same size\n");
-               return NULL;
-       }
-       
-       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
-               return NULL;
-
-       for(x = 0; x < vec1->size; x++) {
-               vec[x] = 0.5f * (vec1->vec[x] + vec2->vec[x]);
-       }
-       return newVectorObject(vec, vec1->size, Py_NEW, NULL);
-}
-//----------------------------------Mathutils.ProjectVecs() -------------
-//projects vector 1 onto vector 2
-static PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args)
-{
-       VectorObject *vec1 = NULL, *vec2 = NULL;
-       float vec[4]; 
-       double dot = 0.0f, dot2 = 0.0f;
-       int x, size;
-
-       if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2)) {
-               PyErr_SetString(PyExc_TypeError, "Mathutils.ProjectVecs(): expects (2) vector objects of the same size\n");
-               return NULL;
-       }
-       if(vec1->size != vec2->size) {
-               PyErr_SetString(PyExc_AttributeError, "Mathutils.ProjectVecs(): expects (2) vector objects of the same size\n");
-               return NULL;
-       }
-
-       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2))
-               return NULL;
-
-       
-       //since they are the same size...
-       size = vec1->size;
-
-       //get dot products
-       for(x = 0; x < size; x++) {
-               dot += vec1->vec[x] * vec2->vec[x];
-               dot2 += vec2->vec[x] * vec2->vec[x];
-       }
-       //projection
-       dot /= dot2;
-       for(x = 0; x < size; x++) {
-               vec[x] = (float)(dot * vec2->vec[x]);
-       }
-       return newVectorObject(vec, size, Py_NEW, NULL);
-}
 //----------------------------------MATRIX FUNCTIONS--------------------
 //----------------------------------Mathutils.RotationMatrix() ----------
 //mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
-//creates a rotation matrix
+static char M_Mathutils_RotationMatrix_doc[] =
+".. function:: RotationMatrix(angle, size, axis)\n"
+"\n"
+"   Create a matrix representing a rotation.\n"
+"\n"
+"   :arg angle: The angle of rotation desired.\n"
+"   :type angle: float\n"
+"   :arg size: The size of the rotation matrix to construct [2, 4].\n"
+"   :type size: int\n"
+"   :arg axis: a string in ['X', 'Y', 'Z'] or a 3D Vector Object (optional when size is 2).\n"
+"   :type axis: string or vector\n"
+"   :return: A new rotation matrix.\n"
+"   :rtype: Matrix\n";
+
 static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
 {
-       VectorObject *vec = NULL;
-       char *axis = NULL;
+       VectorObject *vec= NULL;
+       char *axis= NULL;
        int matSize;
        float angle = 0.0f;
        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};
 
-       if(!PyArg_ParseTuple(args, "fi|sO!", &angle, &matSize, &axis, &vector_Type, &vec)) {
-               PyErr_SetString(PyExc_TypeError, "Mathutils.RotationMatrix(): expected float int and optional string and vector\n");
+       if(!PyArg_ParseTuple(args, "fi|O", &angle, &matSize, &vec)) {
+               PyErr_SetString(PyExc_TypeError, "Mathutils.RotationMatrix(angle, size, axis): expected float int and a string or vector\n");
                return NULL;
        }
 
+       if(vec && !VectorObject_Check(vec)) {
+               axis= _PyUnicode_AsString((PyObject *)vec);
+               if(axis==NULL || axis[0]=='\0' || axis[1]!='\0' || axis[0] < 'X' || axis[0] > 'Z') {
+                       PyErr_SetString(PyExc_TypeError, "Mathutils.RotationMatrix(): 3rd argument axis value must be a 3D vector or a string in 'X', 'Y', 'Z'\n");
+                       return NULL;
+               }
+               else {
+                       /* use the string */
+                       vec= NULL;
+               }
+       }
+
 #ifdef USE_MATHUTILS_DEG
        /* Clamp to -360:360 */
        while (angle<-360.0f)
@@ -379,23 +184,17 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
                PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
                return NULL;
        }
-       if(matSize == 2 && (axis != NULL || vec != NULL)) {
+       if(matSize == 2 && (vec != NULL)) {
                PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): cannot create a 2x2 rotation matrix around arbitrary axis\n");
                return NULL;
        }
-       if((matSize == 3 || matSize == 4) && axis == NULL) {
+       if((matSize == 3 || matSize == 4) && (axis == NULL) && (vec == NULL)) {
                PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): please choose an axis of rotation for 3d and 4d matrices\n");
                return NULL;
        }
-       if(axis) {
-               if(((strcmp(axis, "r") == 0) || (strcmp(axis, "R") == 0)) && vec == NULL) {
-                       PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): please define the arbitrary axis of rotation\n");
-                       return NULL;
-               }
-       }
        if(vec) {
                if(vec->size != 3) {
-                       PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): the arbitrary axis must be a 3D vector\n");
+                       PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): the vector axis must be a 3D vector\n");
                        return NULL;
                }
                
@@ -414,35 +213,32 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
                mat[1] = (float) sin (angle);
                mat[2] = -((float) sin(angle));
                mat[3] = (float) cos(angle);
-       } else if((strcmp(axis, "x") == 0) || (strcmp(axis, "X") == 0)) {
+       } else if(strcmp(axis, "X") == 0) {
                //rotation around X
                mat[0] = 1.0f;
                mat[4] = (float) cos(angle);
                mat[5] = (float) sin(angle);
                mat[7] = -((float) sin(angle));
                mat[8] = (float) cos(angle);
-       } else if((strcmp(axis, "y") == 0) || (strcmp(axis, "Y") == 0)) {
+       } else if(strcmp(axis, "Y") == 0) {
                //rotation around Y
                mat[0] = (float) cos(angle);
                mat[2] = -((float) sin(angle));
                mat[4] = 1.0f;
                mat[6] = (float) sin(angle);
                mat[8] = (float) cos(angle);
-       } else if((strcmp(axis, "z") == 0) || (strcmp(axis, "Z") == 0)) {
+       } else if(strcmp(axis, "Z") == 0) {
                //rotation around Z
                mat[0] = (float) cos(angle);
                mat[1] = (float) sin(angle);
                mat[3] = -((float) sin(angle));
                mat[4] = (float) cos(angle);
                mat[8] = 1.0f;
-       } else if((strcmp(axis, "r") == 0) || (strcmp(axis, "R") == 0)) {
-               //arbitrary rotation
-               axis_angle_to_mat3( (float (*)[3])mat,vec->vec, angle);
-
        } else {
-               PyErr_SetString(PyExc_AttributeError, "Mathutils.RotationMatrix(): unrecognizable axis of rotation type - expected x,y,z or r\n");
-               return NULL;
+               /* check for valid vector/axis above */
+               axis_angle_to_mat3( (float (*)[3])mat,vec->vec, angle);
        }
+
        if(matSize == 4) {
                //resize matrix
                mat[10] = mat[8];
@@ -457,8 +253,17 @@ static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
        //pass to matrix creation
        return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL);
 }
-//----------------------------------Mathutils.TranslationMatrix() -------
-//creates a translation matrix
+
+static char M_Mathutils_TranslationMatrix_doc[] =
+".. function:: TranslationMatrix(vector)\n"
+"\n"
+"   Create a matrix representing a translation.\n"
+"\n"
+"   :arg vector: The translation vector.\n"
+"   :type vector: Vector\n"
+"   :return: An identity matrix with a translation.\n"
+"   :rtype: Matrix\n";
+
 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,
@@ -486,7 +291,20 @@ static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * v
 }
 //----------------------------------Mathutils.ScaleMatrix() -------------
 //mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
-//creates a scaling matrix
+static char M_Mathutils_ScaleMatrix_doc[] =
+".. function:: ScaleMatrix(factor, size, axis)\n"
+"\n"
+"   Create a matrix representing a scaling.\n"
+"\n"
+"   :arg factor: The factor of scaling to apply.\n"
+"   :type factor: float\n"
+"   :arg size: The size of the scale matrix to construct [2, 4].\n"
+"   :type size: int\n"
+"   :arg axis: Direction to influence scale. (optional).\n"
+"   :type axis: Vector\n"
+"   :return: A new scale matrix.\n"
+"   :rtype: Matrix\n";
+
 static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args)
 {
        VectorObject *vec = NULL;
@@ -564,7 +382,19 @@ static 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
+static char M_Mathutils_OrthoProjectionMatrix_doc[] =
+".. function:: OrthoProjectionMatrix(plane, size, axis)\n"
+"\n"
+"   Create a matrix to represent an orthographic projection.\n"
+"\n"
+"   :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ', 'R'], where a single axis is for a 2D matrix and 'R' requires axis is given.\n"
+"   :type plane: string\n"
+"   :arg size: The size of the projection matrix to construct [2, 4].\n"
+"   :type size: int\n"
+"   :arg axis: Arbitrary perpendicular plane vector.\n"
+"   :type axis: vector (optional)\n"
+"   :return: A new projection matrix.\n"
+"   :rtype: Matrix\n";
 static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args)
 {
        VectorObject *vec = NULL;
@@ -593,30 +423,21 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a
                
        }
        if(vec == NULL) {       //ortho projection onto cardinal plane
-               if(((strcmp(plane, "x") == 0)
-                     || (strcmp(plane, "X") == 0)) && matSize == 2) {
+               if((strcmp(plane, "X") == 0) && matSize == 2) {
                        mat[0] = 1.0f;
-               } else if(((strcmp(plane, "y") == 0) 
-                       || (strcmp(plane, "Y") == 0))
-                          && matSize == 2) {
+               } else if((strcmp(plane, "Y") == 0) && matSize == 2) {
                        mat[3] = 1.0f;
-               } else if(((strcmp(plane, "xy") == 0)
-                            || (strcmp(plane, "XY") == 0))
-                          && matSize > 2) {
+               } else if((strcmp(plane, "XY") == 0) && matSize > 2) {
                        mat[0] = 1.0f;
                        mat[4] = 1.0f;
-               } else if(((strcmp(plane, "xz") == 0)
-                            || (strcmp(plane, "XZ") == 0))
-                          && matSize > 2) {
+               } else if((strcmp(plane, "XZ") == 0) && matSize > 2) {
                        mat[0] = 1.0f;
                        mat[8] = 1.0f;
-               } else if(((strcmp(plane, "yz") == 0)
-                            || (strcmp(plane, "YZ") == 0))
-                          && matSize > 2) {
+               } else if((strcmp(plane, "YZ") == 0) && matSize > 2) {
                        mat[4] = 1.0f;
                        mat[8] = 1.0f;
                } else {
-                       PyErr_SetString(PyExc_AttributeError, "Mathutils.OrthoProjectionMatrix(): unknown plane - expected: x, y, xy, xz, yz\n");
+                       PyErr_SetString(PyExc_AttributeError, "Mathutils.OrthoProjectionMatrix(): unknown plane - expected: X, Y, XY, XZ, YZ\n");
                        return NULL;
                }
        } else { //arbitrary plane
@@ -628,15 +449,12 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a
                for(x = 0; x < vec->size; x++) {
                        vec->vec[x] /= norm;
                }
-               if(((strcmp(plane, "r") == 0)
-                     || (strcmp(plane, "R") == 0)) && matSize == 2) {
+               if((strcmp(plane, "R") == 0) && matSize == 2) {
                        mat[0] = 1 - (vec->vec[0] * vec->vec[0]);
                        mat[1] = -(vec->vec[0] * vec->vec[1]);
                        mat[2] = -(vec->vec[0] * vec->vec[1]);
                        mat[3] = 1 - (vec->vec[1] * vec->vec[1]);
-               } else if(((strcmp(plane, "r") == 0)
-                            || (strcmp(plane, "R") == 0))
-                          && matSize > 2) {
+               } else if((strcmp(plane, "R") == 0) && matSize > 2) {
                        mat[0] = 1 - (vec->vec[0] * vec->vec[0]);
                        mat[1] = -(vec->vec[0] * vec->vec[1]);
                        mat[2] = -(vec->vec[0] * vec->vec[2]);
@@ -665,8 +483,21 @@ static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * a
        //pass to matrix creation
        return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL);
 }
-//----------------------------------Mathutils.ShearMatrix() -------------
-//creates a shear matrix
+
+static char M_Mathutils_ShearMatrix_doc[] =
+".. function:: ShearMatrix(plane, factor, size)\n"
+"\n"
+"   Create a matrix to represent an shear transformation.\n"
+"\n"
+"   :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'], where a single axis is for a 2D matrix.\n"
+"   :type plane: string\n"
+"   :arg factor: The factor of shear to apply.\n"
+"   :type factor: float\n"
+"   :arg size: The size of the shear matrix to construct [2, 4].\n"
+"   :type size: int\n"
+"   :return: A new shear matrix.\n"
+"   :rtype: Matrix\n";
+
 static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args)
 {
        int matSize;
@@ -684,31 +515,27 @@ static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args)
                return NULL;
        }
 
-       if(((strcmp(plane, "x") == 0) || (strcmp(plane, "X") == 0))
+       if((strcmp(plane, "X") == 0)
            && matSize == 2) {
                mat[0] = 1.0f;
                mat[2] = factor;
                mat[3] = 1.0f;
-       } else if(((strcmp(plane, "y") == 0)
-                    || (strcmp(plane, "Y") == 0)) && matSize == 2) {
+       } else if((strcmp(plane, "Y") == 0) && matSize == 2) {
                mat[0] = 1.0f;
                mat[1] = factor;
                mat[3] = 1.0f;
-       } else if(((strcmp(plane, "xy") == 0)
-                    || (strcmp(plane, "XY") == 0)) && matSize > 2) {
+       } else if((strcmp(plane, "XY") == 0) && matSize > 2) {
                mat[0] = 1.0f;
                mat[4] = 1.0f;
                mat[6] = factor;
                mat[7] = factor;
-       } else if(((strcmp(plane, "xz") == 0)
-                    || (strcmp(plane, "XZ") == 0)) && matSize > 2) {
+       } else if((strcmp(plane, "XZ") == 0) && matSize > 2) {
                mat[0] = 1.0f;
                mat[3] = factor;
                mat[4] = 1.0f;
                mat[5] = factor;
                mat[8] = 1.0f;
-       } else if(((strcmp(plane, "yz") == 0)
-                    || (strcmp(plane, "YZ") == 0)) && matSize > 2) {
+       } else if((strcmp(plane, "YZ") == 0) && matSize > 2) {
                mat[0] = 1.0f;
                mat[1] = factor;
                mat[2] = factor;
@@ -732,375 +559,6 @@ static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args)
        //pass to matrix creation
        return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL);
 }
-//----------------------------------QUATERNION FUNCTIONS-----------------
-
-//----------------------------------Mathutils.DifferenceQuats() ---------
-//returns the difference between 2 quaternions
-static PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args)
-{
-       QuaternionObject *quatU = NULL, *quatV = NULL;
-       float quat[4], tempQuat[4];
-       double dot = 0.0f;
-       int x;
-
-       if(!PyArg_ParseTuple(args, "O!O!", &quaternion_Type, &quatU, &quaternion_Type, &quatV)) {
-               PyErr_SetString(PyExc_TypeError, "Mathutils.DifferenceQuats(): expected Quaternion types");
-               return NULL;
-       }
-
-       if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV))
-               return NULL;
-
-       tempQuat[0] = quatU->quat[0];
-       tempQuat[1] = -quatU->quat[1];
-       tempQuat[2] = -quatU->quat[2];
-       tempQuat[3] = -quatU->quat[3];
-
-       dot = sqrt(tempQuat[0] * tempQuat[0] + tempQuat[1] *  tempQuat[1] +
-                              tempQuat[2] * tempQuat[2] + tempQuat[3] * tempQuat[3]);
-
-       for(x = 0; x < 4; x++) {
-               tempQuat[x] /= (float)(dot * dot);
-       }
-       mul_qt_qtqt(quat, tempQuat, quatV->quat);
-       return newQuaternionObject(quat, Py_NEW, NULL);
-}
-//----------------------------------Mathutils.Slerp() ------------------
-//attemps to interpolate 2 quaternions and return the result
-static PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args)
-{
-       QuaternionObject *quatU = NULL, *quatV = NULL;
-       float quat[4], quat_u[4], quat_v[4], param;
-       double x, y, dot, sinT, angle, IsinT;
-       int z;
-
-       if(!PyArg_ParseTuple(args, "O!O!f", &quaternion_Type, &quatU, &quaternion_Type, &quatV, &param)) {
-               PyErr_SetString(PyExc_TypeError, "Mathutils.Slerp(): expected Quaternion types and float");
-               return NULL;
-       }
-
-       if(!BaseMath_ReadCallback(quatU) || !BaseMath_ReadCallback(quatV))
-               return NULL;
-
-       if(param > 1.0f || param < 0.0f) {
-               PyErr_SetString(PyExc_AttributeError, "Mathutils.Slerp(): interpolation factor must be between 0.0 and 1.0");
-               return NULL;
-       }
-
-       //copy quats
-       for(z = 0; z < 4; z++){
-               quat_u[z] = quatU->quat[z];
-               quat_v[z] = quatV->quat[z];
-       }
-
-       //dot product
-       dot = quat_u[0] * quat_v[0] + quat_u[1] * quat_v[1] +
-               quat_u[2] * quat_v[2] + quat_u[3] * quat_v[3];
-
-       //if negative negate a quat (shortest arc)
-       if(dot < 0.0f) {
-               quat_v[0] = -quat_v[0];
-               quat_v[1] = -quat_v[1];
-               quat_v[2] = -quat_v[2];
-               quat_v[3] = -quat_v[3];
-               dot = -dot;
-       }
-       if(dot > .99999f) { //very close
-               x = 1.0f - param;
-               y = param;
-       } else {
-               //calculate sin of angle
-               sinT = sqrt(1.0f - (dot * dot));
-               //calculate angle
-               angle = atan2(sinT, dot);
-               //caluculate inverse of sin(theta)
-               IsinT = 1.0f / sinT;
-               x = sin((1.0f - param) * angle) * IsinT;
-               y = sin(param * angle) * IsinT;
-       }
-       //interpolate
-       quat[0] = (float)(quat_u[0] * x + quat_v[0] * y);
-       quat[1] = (float)(quat_u[1] * x + quat_v[1] * y);
-       quat[2] = (float)(quat_u[2] * x + quat_v[2] * y);
-       quat[3] = (float)(quat_u[3] * x + quat_v[3] * y);
-
-       return newQuaternionObject(quat, Py_NEW, NULL);
-}
-//----------------------------------EULER FUNCTIONS----------------------
-//---------------------------------INTERSECTION FUNCTIONS--------------------
-//----------------------------------Mathutils.Intersect() -------------------
-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];
-       float det, inv_det, u, v, t;
-       int clip = 1;
-
-       if(!PyArg_ParseTuple(args, "O!O!O!O!O!|i", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &ray, &vector_Type, &ray_off , &clip)) {
-               PyErr_SetString( PyExc_TypeError, "expected 5 vector types\n" );
-               return NULL;
-       }
-       if(vec1->size != 3 || vec2->size != 3 || vec3->size != 3 || ray->size != 3 || ray_off->size != 3) {
-               PyErr_SetString( PyExc_TypeError, "only 3D vectors for all parameters\n");
-               return NULL;
-       }
-
-       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(ray) || !BaseMath_ReadCallback(ray_off))
-               return NULL;
-       
-       VECCOPY(v1, vec1->vec);
-       VECCOPY(v2, vec2->vec);
-       VECCOPY(v3, vec3->vec);
-
-       VECCOPY(dir, ray->vec);
-       normalize_v3(dir);
-
-       VECCOPY(orig, ray_off->vec);
-
-       /* find vectors for two edges sharing v1 */
-       sub_v3_v3v3(e1, v2, v1);
-       sub_v3_v3v3(e2, v3, v1);
-
-       /* begin calculating determinant - also used to calculated U parameter */
-       cross_v3_v3v3(pvec, dir, e2);   
-
-       /* if determinant is near zero, ray lies in plane of triangle */
-       det = dot_v3v3(e1, pvec);
-
-       if (det > -0.000001 && det < 0.000001) {
-               Py_RETURN_NONE;
-       }
-
-       inv_det = 1.0f / det;
-
-       /* calculate distance from v1 to ray origin */
-       sub_v3_v3v3(tvec, orig, v1);
-
-       /* calculate U parameter and test bounds */
-       u = dot_v3v3(tvec, pvec) * inv_det;
-       if (clip && (u < 0.0f || u > 1.0f)) {
-               Py_RETURN_NONE;
-       }
-
-       /* prepare to test the V parameter */
-       cross_v3_v3v3(qvec, tvec, e1);
-
-       /* calculate V parameter and test bounds */
-       v = dot_v3v3(dir, qvec) * inv_det;
-
-       if (clip && (v < 0.0f || u + v > 1.0f)) {
-               Py_RETURN_NONE;
-       }
-
-       /* calculate t, ray intersects triangle */
-       t = dot_v3v3(e2, qvec) * inv_det;
-
-       mul_v3_fl(dir, t);
-       add_v3_v3v3(pvec, orig, dir);
-
-       return newVectorObject(pvec, 3, Py_NEW, NULL);
-}
-//----------------------------------Mathutils.LineIntersect() -------------------
-/* Line-Line intersection using algorithm from mathworld.wolfram.com */
-static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
-{
-       PyObject * tuple;
-       VectorObject *vec1, *vec2, *vec3, *vec4;
-       float v1[3], v2[3], v3[3], v4[3], i1[3], i2[3];
-
-       if( !PyArg_ParseTuple( args, "O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4 ) ) {
-               PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" );
-               return NULL;
-       }
-       if( vec1->size != vec2->size || vec1->size != vec3->size || vec3->size != vec2->size) {
-               PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" );
-               return NULL;
-       }
-       
-       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
-               return NULL;
-       
-       if( vec1->size == 3 || vec1->size == 2) {
-               int result;
-               
-               if (vec1->size == 3) {
-                       VECCOPY(v1, vec1->vec);
-                       VECCOPY(v2, vec2->vec);
-                       VECCOPY(v3, vec3->vec);
-                       VECCOPY(v4, vec4->vec);
-               }
-               else {
-                       v1[0] = vec1->vec[0];
-                       v1[1] = vec1->vec[1];
-                       v1[2] = 0.0f;
-
-                       v2[0] = vec2->vec[0];
-                       v2[1] = vec2->vec[1];
-                       v2[2] = 0.0f;
-
-                       v3[0] = vec3->vec[0];
-                       v3[1] = vec3->vec[1];
-                       v3[2] = 0.0f;
-
-                       v4[0] = vec4->vec[0];
-                       v4[1] = vec4->vec[1];
-                       v4[2] = 0.0f;
-               }
-               
-               result = isect_line_line_v3(v1, v2, v3, v4, i1, i2);
-
-               if (result == 0) {
-                       /* colinear */
-                       Py_RETURN_NONE;
-               }
-               else {
-                       tuple = PyTuple_New( 2 );
-                       PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW, NULL) );
-                       PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW, NULL) );
-                       return tuple;
-               }
-       }
-       else {
-               PyErr_SetString( PyExc_TypeError, "2D/3D vectors only\n" );
-               return NULL;
-       }
-}
-
-
-
-//---------------------------------NORMALS FUNCTIONS--------------------
-//----------------------------------Mathutils.QuadNormal() -------------------
-static PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args )
-{
-       VectorObject *vec1;
-       VectorObject *vec2;
-       VectorObject *vec3;
-       VectorObject *vec4;
-       float v1[3], v2[3], v3[3], v4[3], e1[3], e2[3], n1[3], n2[3];
-
-       if( !PyArg_ParseTuple( args, "O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4 ) ) {
-               PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" );
-               return NULL;
-       }
-       if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec4->size) {
-               PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" );
-               return NULL;
-       }
-       if( vec1->size != 3 ) {
-               PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" );
-               return NULL;
-       }
-       
-       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3) || !BaseMath_ReadCallback(vec4))
-               return NULL;
-       
-       VECCOPY(v1, vec1->vec);
-       VECCOPY(v2, vec2->vec);
-       VECCOPY(v3, vec3->vec);
-       VECCOPY(v4, vec4->vec);
-
-       /* find vectors for two edges sharing v2 */
-       sub_v3_v3v3(e1, v1, v2);
-       sub_v3_v3v3(e2, v3, v2);
-
-       cross_v3_v3v3(n1, e2, e1);
-       normalize_v3(n1);
-
-       /* find vectors for two edges sharing v4 */
-       sub_v3_v3v3(e1, v3, v4);
-       sub_v3_v3v3(e2, v1, v4);
-
-       cross_v3_v3v3(n2, e2, e1);
-       normalize_v3(n2);
-
-       /* adding and averaging the normals of both triangles */
-       add_v3_v3v3(n1, n2, n1);
-       normalize_v3(n1);
-
-       return newVectorObject(n1, 3, Py_NEW, NULL);
-}
-
-//----------------------------Mathutils.TriangleNormal() -------------------
-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];
-
-       if( !PyArg_ParseTuple( args, "O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3 ) ) {
-               PyErr_SetString( PyExc_TypeError, "expected 3 vector types\n" );
-               return NULL;
-       }
-       if( vec1->size != vec2->size || vec1->size != vec3->size ) {
-               PyErr_SetString( PyExc_TypeError, "vectors must be of the same size\n" );
-               return NULL;
-       }
-       if( vec1->size != 3 ) {
-               PyErr_SetString( PyExc_TypeError, "only 3D vectors\n" );
-               return NULL;
-       }
-       
-       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
-               return NULL;
-
-       VECCOPY(v1, vec1->vec);
-       VECCOPY(v2, vec2->vec);
-       VECCOPY(v3, vec3->vec);
-
-       /* find vectors for two edges sharing v2 */
-       sub_v3_v3v3(e1, v1, v2);
-       sub_v3_v3v3(e2, v3, v2);
-
-       cross_v3_v3v3(n, e2, e1);
-       normalize_v3(n);
-
-       return newVectorObject(n, 3, Py_NEW, NULL);
-}
-
-//--------------------------------- AREA FUNCTIONS--------------------
-//----------------------------------Mathutils.TriangleArea() -------------------
-static PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args )
-{
-       VectorObject *vec1, *vec2, *vec3;
-       float v1[3], v2[3], v3[3];
-
-       if( !PyArg_ParseTuple
-           ( args, "O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2
-               , &vector_Type, &vec3 ) ) {
-               PyErr_SetString( PyExc_TypeError, "expected 3 vector types\n");
-               return NULL;
-       }
-       if( vec1->size != vec2->size || vec1->size != vec3->size ) {
-               PyErr_SetString( PyExc_TypeError, "vectors must be of the same size\n" );
-               return NULL;
-       }
-       
-       if(!BaseMath_ReadCallback(vec1) || !BaseMath_ReadCallback(vec2) || !BaseMath_ReadCallback(vec3))
-               return NULL;
-
-       if (vec1->size == 3) {
-               VECCOPY(v1, vec1->vec);
-               VECCOPY(v2, vec2->vec);
-               VECCOPY(v3, vec3->vec);
-
-               return PyFloat_FromDouble( area_tri_v3(v1, v2, v3) );
-       }
-       else if (vec1->size == 2) {
-               v1[0] = vec1->vec[0];
-               v1[1] = vec1->vec[1];
-
-               v2[0] = vec2->vec[0];
-               v2[1] = vec2->vec[1];
-
-               v3[0] = vec3->vec[0];
-               v3[1] = vec3->vec[1];
-
-               return PyFloat_FromDouble( area_tri_v2(v1, v2, v3) );
-       }
-       else {
-               PyErr_SetString( PyExc_TypeError, "only 2D,3D vectors are supported\n" );
-               return NULL;
-       }
-}
 
 /* Utility functions */
 
@@ -1219,3 +677,51 @@ void BaseMathObject_dealloc(BaseMathObject * self)
        Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); // breaks subtypes
 }
 
+/*----------------------------MODULE INIT-------------------------*/
+struct PyMethodDef M_Mathutils_methods[] = {
+       {"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},
+       {"OrthoProjectionMatrix", (PyCFunction) M_Mathutils_OrthoProjectionMatrix,  METH_VARARGS, M_Mathutils_OrthoProjectionMatrix_doc},
+       {NULL, NULL, 0, NULL}
+};
+
+static struct PyModuleDef M_Mathutils_module_def = {
+       PyModuleDef_HEAD_INIT,
+       "Mathutils",  /* m_name */
+       M_Mathutils_doc,  /* m_doc */
+       0,  /* m_size */
+       M_Mathutils_methods,  /* m_methods */
+       0,  /* m_reload */
+       0,  /* m_traverse */
+       0,  /* m_clear */
+       0,  /* m_free */
+};
+
+PyObject *Mathutils_Init(void)
+{
+       PyObject *submodule;
+       
+       if( PyType_Ready( &vector_Type ) < 0 )
+               return NULL;
+       if( PyType_Ready( &matrix_Type ) < 0 )
+               return NULL;    
+       if( PyType_Ready( &euler_Type ) < 0 )
+               return NULL;
+       if( PyType_Ready( &quaternion_Type ) < 0 )
+               return NULL;
+       
+       submodule = PyModule_Create(&M_Mathutils_module_def);
+       PyDict_SetItemString(PySys_GetObject("modules"), M_Mathutils_module_def.m_name, submodule);
+       
+       /* 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 );
+       
+       mathutils_matrix_vector_cb_index= Mathutils_RegisterCallback(&mathutils_matrix_vector_cb);
+
+       return (submodule);
+}
index ae7a6783358170f679b8f7cd3ebc05be93a96b9c..b48c45b322f42a8039a2b4e28880a9358595f093 100644 (file)
 #include "BLI_blenlib.h"
 
 
-//-------------------------DOC STRINGS ---------------------------
-
-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 ----------------------
-static struct PyMethodDef Euler_methods[] = {
-       {"zero", (PyCFunction) Euler_Zero, METH_NOARGS, NULL},
-       {"unique", (PyCFunction) Euler_Unique, METH_NOARGS, NULL},
-       {"toMatrix", (PyCFunction) Euler_ToMatrix, METH_NOARGS, NULL},
-       {"toQuat", (PyCFunction) Euler_ToQuat, METH_NOARGS, NULL},
-       {"rotate", (PyCFunction) Euler_Rotate, METH_VARARGS, NULL},
-       {"makeCompatible", (PyCFunction) Euler_MakeCompatible, METH_O, NULL},
-       {"__copy__", (PyCFunction) Euler_copy, METH_VARARGS, NULL},
-       {"copy", (PyCFunction) Euler_copy, METH_VARARGS, NULL},
-       {NULL, NULL, 0, NULL}
-};
-
 //----------------------------------Mathutils.Euler() -------------------
 //makes a new euler for you to play with
 static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwargs)
@@ -108,6 +85,15 @@ static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwar
 //-----------------------------METHODS----------------------------
 //----------------------------Euler.toQuat()----------------------
 //return a quaternion representation of the euler
+
+static char Euler_ToQuat_doc[] =
+".. method:: to_quat()\n"
+"\n"
+"   Return a quaternion representation of the euler.\n"
+"\n"
+"   :return: Quaternion representation of the euler.\n"
+"   :rtype: Quaternion\n";
+
 static PyObject *Euler_ToQuat(EulerObject * self)
 {
        float quat[4];
@@ -132,6 +118,14 @@ static PyObject *Euler_ToQuat(EulerObject * self)
 }
 //----------------------------Euler.toMatrix()---------------------
 //return a matrix representation of the euler
+static char Euler_ToMatrix_doc[] =
+".. method:: to_matrix()\n"
+"\n"
+"   Return a matrix representation of the euler.\n"
+"\n"
+"   :return: A 3x3 roation matrix representation of the euler.\n"
+"   :rtype: Matrix\n";
+
 static PyObject *Euler_ToMatrix(EulerObject * self)
 {
        float mat[9] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
@@ -156,6 +150,14 @@ static PyObject *Euler_ToMatrix(EulerObject * self)
 }
 //----------------------------Euler.unique()-----------------------
 //sets the x,y,z values to a unique euler rotation
+
+static char Euler_Unique_doc[] =
+".. method:: unique()\n"
+"\n"
+"   Calculate a unique rotation for this euler. Avoids gimble lock.\n"
+"   :return: an instance of itself\n"
+"   :rtype: Euler\n";
+
 static PyObject *Euler_Unique(EulerObject * self)
 {
 #define PI_2           (Py_PI * 2.0)
@@ -220,6 +222,13 @@ static PyObject *Euler_Unique(EulerObject * self)
 }
 //----------------------------Euler.zero()-------------------------
 //sets the euler to 0,0,0
+static char Euler_Zero_doc[] =
+".. method:: zero()\n"
+"\n"
+"   Set all values to zero.\n"
+"   :return: an instance of itself\n"
+"   :rtype: Euler\n";
+
 static PyObject *Euler_Zero(EulerObject * self)
 {
        self->eul[0] = 0.0;
@@ -278,6 +287,16 @@ static PyObject *Euler_Rotate(EulerObject * self, PyObject *args)
        return (PyObject *)self;
 }
 
+static char Euler_MakeCompatible_doc[] =
+".. method:: make_compatible(other)\n"
+"\n"
+"   Make this euler compatible with another, so interpolating between them works as intended.\n"
+"\n"
+"   :arg other: make compatible with this rotation.\n"
+"   :type other: Euler\n"
+"   :return: an instance of itself.\n"
+"   :rtype: Euler\n";
+
 static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
 {
 #ifdef USE_MATHUTILS_DEG
@@ -317,6 +336,17 @@ static PyObject *Euler_MakeCompatible(EulerObject * self, EulerObject *value)
 
 //----------------------------Euler.rotate()-----------------------
 // return a copy of the euler
+
+static char Euler_copy_doc[] =
+".. function:: copy()\n"
+"\n"
+"   Returns a copy of this euler.\n"
+"\n"
+"   :return: A copy of the euler.\n"
+"   :rtype: Euler\n"
+"\n"
+"   .. note:: use this to get a copy of a wrapped euler with no reference to the original data.\n";
+
 static PyObject *Euler_copy(EulerObject * self, PyObject *args)
 {
        if(!BaseMath_ReadCallback(self))
@@ -545,6 +575,20 @@ static PyGetSetDef Euler_getseters[] = {
        {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
 };
 
+
+//-----------------------METHOD DEFINITIONS ----------------------
+static struct PyMethodDef Euler_methods[] = {
+       {"zero", (PyCFunction) Euler_Zero, METH_NOARGS, Euler_Zero_doc},
+       {"unique", (PyCFunction) Euler_Unique, METH_NOARGS, Euler_Unique_doc},
+       {"to_matrix", (PyCFunction) Euler_ToMatrix, METH_NOARGS, Euler_ToMatrix_doc},
+       {"to_quat", (PyCFunction) Euler_ToQuat, METH_NOARGS, Euler_ToQuat_doc},
+       {"rotate", (PyCFunction) Euler_Rotate, METH_VARARGS, NULL},
+       {"make_compatible", (PyCFunction) Euler_MakeCompatible, METH_O, Euler_MakeCompatible_doc},
+       {"__copy__", (PyCFunction) Euler_copy, METH_VARARGS, Euler_copy_doc},
+       {"copy", (PyCFunction) Euler_copy, METH_VARARGS, Euler_copy_doc},
+       {NULL, NULL, 0, NULL}
+};
+
 //------------------PY_OBECT DEFINITION--------------------------
 PyTypeObject euler_Type = {
        PyVarObject_HEAD_INIT(NULL, 0)
index 074a397b6d967755eefd274c7b30a1ab694655cc..00749002e5973a5afd1cacdf21761b7d2d55c941 100644 (file)
@@ -105,39 +105,6 @@ Mathutils_Callback mathutils_matrix_vector_cb = {
 };
 /* matrix vector callbacks, this is so you can do matrix[i][j] = val  */
 
-/*-------------------------DOC STRINGS ---------------------------*/
-
-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 ----------------------*/
-static struct PyMethodDef Matrix_methods[] = {
-       {"zero", (PyCFunction) Matrix_Zero, METH_NOARGS, NULL},
-       {"identity", (PyCFunction) Matrix_Identity, METH_NOARGS, NULL},
-       {"transpose", (PyCFunction) Matrix_Transpose, METH_NOARGS, NULL},
-       {"determinant", (PyCFunction) Matrix_Determinant, METH_NOARGS, NULL},
-       {"invert", (PyCFunction) Matrix_Invert, METH_NOARGS, NULL},
-       {"translationPart", (PyCFunction) Matrix_TranslationPart, METH_NOARGS, NULL},
-       {"rotationPart", (PyCFunction) Matrix_RotationPart, METH_NOARGS, NULL},
-       {"scalePart", (PyCFunction) Matrix_scalePart, METH_NOARGS, NULL},
-       {"resize4x4", (PyCFunction) Matrix_Resize4x4, METH_NOARGS, NULL},
-       {"toEuler", (PyCFunction) Matrix_toEuler, METH_VARARGS, NULL},
-       {"toQuat", (PyCFunction) Matrix_toQuat, METH_NOARGS, NULL},
-       {"copy", (PyCFunction) Matrix_copy, METH_NOARGS, NULL},
-       {"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, NULL},
-       {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
@@ -214,8 +181,33 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        return newMatrixObject(matrix, argSize, seqSize, Py_NEW, NULL);
 }
 
+/* assumes rowsize == colsize is checked and the read callback has run */
+static float matrix_determinant(MatrixObject * self)
+{
+       if(self->rowSize == 2) {
+               return determinant_m2(self->matrix[0][0], self->matrix[0][1],
+                                        self->matrix[1][0], self->matrix[1][1]);
+       } else if(self->rowSize == 3) {
+               return determinant_m3(self->matrix[0][0], self->matrix[0][1],
+                                        self->matrix[0][2], self->matrix[1][0],
+                                        self->matrix[1][1], self->matrix[1][2],
+                                        self->matrix[2][0], self->matrix[2][1],
+                                        self->matrix[2][2]);
+       } else {
+               return determinant_m4((float (*)[4]) *self->matrix);
+       }
+}
+
+
 /*-----------------------------METHODS----------------------------*/
-/*---------------------------Matrix.toQuat() ---------------------*/
+static char Matrix_toQuat_doc[] =
+".. method:: to_quat()\n"
+"\n"
+"   Return a quaternion representation of the rotation matrix.\n"
+"\n"
+"   :return: Quaternion representation of the rotation matrix.\n"
+"   :rtype: Quaternion\n";
+
 static PyObject *Matrix_toQuat(MatrixObject * self)
 {
        float quat[4];
@@ -237,6 +229,16 @@ static PyObject *Matrix_toQuat(MatrixObject * self)
        return newQuaternionObject(quat, Py_NEW, NULL);
 }
 /*---------------------------Matrix.toEuler() --------------------*/
+static char Matrix_toEuler_doc[] =
+".. method:: to_euler(euler_compat)\n"
+"\n"
+"   Return an Euler representation of the rotation matrix (3x3 or 4x4 matrix only).\n"
+"\n"
+"   :arg euler_compat: Optional euler argument the new euler will be made compatible with (no axis flipping between them). Useful for converting a series of matrices to animation curves.\n"
+"   :type euler_compat: Euler\n"
+"   :return: Euler representation of the matrix.\n"
+"   :rtype: Euler\n";
+
 PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args)
 {
        float eul[3], eul_compatf[3];
@@ -288,6 +290,13 @@ PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args)
        return newEulerObject(eul, Py_NEW, NULL);
 }
 /*---------------------------Matrix.resize4x4() ------------------*/
+static char Matrix_Resize4x4_doc[] =
+".. method:: resize4x4()\n"
+"\n"
+"   Resize the matrix to 4x4.\n"
+"   :return: an instance of itself.\n"
+"   :rtype: Vector\n";
+
 PyObject *Matrix_Resize4x4(MatrixObject * self)
 {
        int x, first_row_elem, curr_pos, new_pos, blank_columns, blank_rows, index;
@@ -345,6 +354,15 @@ PyObject *Matrix_Resize4x4(MatrixObject * self)
        return (PyObject *)self;
 }
 /*---------------------------Matrix.translationPart() ------------*/
+static char Matrix_TranslationPart_doc[] =
+".. method:: translation_part()\n"
+"\n"
+"   Return a the translation part of a 4 row matrix.\n"
+"   :return: Return a the translation of a matrix.\n"
+"   :rtype: Matrix\n"
+"\n"
+"   .. note:: Note that the (4,4) element of a matrix can be used for uniform scaling too.\n";
+
 PyObject *Matrix_TranslationPart(MatrixObject * self)
 {
        float vec[4];
@@ -364,6 +382,15 @@ PyObject *Matrix_TranslationPart(MatrixObject * self)
        return newVectorObject(vec, 3, Py_NEW, NULL);
 }
 /*---------------------------Matrix.rotationPart() ---------------*/
+static char Matrix_RotationPart_doc[] =
+".. method:: rotation_part()\n"
+"\n"
+"   Return the 3d submatrix corresponding to the linear term of the embedded affine transformation in 3d. This matrix represents rotation and scale.\n"
+"   :return: Return the 3d matrix for rotation and scale.\n"
+"   :rtype: Matrix\n"
+"\n"
+"   .. note:: Note that the (4,4) element of a matrix can be used for uniform scaling too.\n";
+
 PyObject *Matrix_RotationPart(MatrixObject * self)
 {
        float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
@@ -390,6 +417,15 @@ PyObject *Matrix_RotationPart(MatrixObject * self)
        return newMatrixObject(mat, 3, 3, Py_NEW, Py_TYPE(self));
 }
 /*---------------------------Matrix.scalePart() --------------------*/
+static char Matrix_scalePart_doc[] =
+".. method:: scale_part()\n"
+"\n"
+"   Return a the scale part of a 3x3 or 4x4 matrix.\n"
+"   :return: Return a the scale of a matrix.\n"
+"   :rtype: Vector\n"
+"\n"
+"   .. note:: This method does not return negative a scale on any axis because it is not possible to obtain this data from the matrix alone.\n";
+
 PyObject *Matrix_scalePart(MatrixObject * self)
 {
        float scale[3], rot[3];
@@ -419,12 +455,22 @@ PyObject *Matrix_scalePart(MatrixObject * self)
        return newVectorObject(scale, 3, Py_NEW, NULL);
 }
 /*---------------------------Matrix.invert() ---------------------*/
+static char Matrix_Invert_doc[] =
+".. method:: invert()\n"
+"\n"
+"   Set the matrix to its inverse.\n"
+"   :return: an instance of itself.\n"
+"   :rtype: Matrix\n"
+"\n"
+"   .. note:: :exc:`ValueError` exception is raised.\n"
+"\n"
+"   .. seealso:: <http://en.wikipedia.org/wiki/Inverse_matrix>\n";
+
 PyObject *Matrix_Invert(MatrixObject * self)
 {
        
        int x, y, z = 0;
        float det = 0.0f;
-       PyObject *f = NULL;
        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};
 
@@ -437,9 +483,7 @@ PyObject *Matrix_Invert(MatrixObject * self)
        }
 
        /*calculate the determinant*/
-       f = Matrix_Determinant(self);
-       det = (float)PyFloat_AS_DOUBLE(f); /*Increfs, so we need to decref*/
-       Py_DECREF(f);
+       det = matrix_determinant(self);
 
        if(det != 0) {
                /*calculate the classical adjoint*/
@@ -478,10 +522,17 @@ PyObject *Matrix_Invert(MatrixObject * self)
 
 
 /*---------------------------Matrix.determinant() ----------------*/
+static char Matrix_Determinant_doc[] =
+".. method:: determinant()\n"
+"\n"
+"   Return the determinant of a matrix.\n"
+"   :return: Return a the determinant of a matrix.\n"
+"   :rtype: float\n"
+"\n"
+"   .. seealso:: <http://en.wikipedia.org/wiki/Determinant>\n";
+
 PyObject *Matrix_Determinant(MatrixObject * self)
 {
-       float det = 0.0f;
-
        if(!BaseMath_ReadCallback(self))
                return NULL;
        
@@ -490,22 +541,18 @@ PyObject *Matrix_Determinant(MatrixObject * self)
                return NULL;
        }
 
-       if(self->rowSize == 2) {
-               det = determinant_m2(self->matrix[0][0], self->matrix[0][1],
-                                        self->matrix[1][0], self->matrix[1][1]);
-       } else if(self->rowSize == 3) {
-               det = determinant_m3(self->matrix[0][0], self->matrix[0][1],
-                                        self->matrix[0][2], self->matrix[1][0],
-                                        self->matrix[1][1], self->matrix[1][2],
-                                        self->matrix[2][0], self->matrix[2][1],
-                                        self->matrix[2][2]);
-       } else {
-               det = determinant_m4((float (*)[4]) *self->matrix);
-       }
-
-       return PyFloat_FromDouble( (double) det );
+       return PyFloat_FromDouble((double)matrix_determinant(self));
 }
 /*---------------------------Matrix.transpose() ------------------*/
+static char Matrix_Transpose_doc[] =
+".. method:: transpose()\n"
+"\n"
+"   Set the matrix to its transpose.\n"
+"   :return: an instance of itself\n"
+"   :rtype: Matrix\n"
+"\n"
+"   .. seealso:: <http://en.wikipedia.org/wiki/Transpose>\n";
+
 PyObject *Matrix_Transpose(MatrixObject * self)
 {
        float t = 0.0f;
@@ -535,6 +582,13 @@ PyObject *Matrix_Transpose(MatrixObject * self)
 
 
 /*---------------------------Matrix.zero() -----------------------*/
+static char Matrix_Zero_doc[] =
+".. method:: zero()\n"
+"\n"
+"   Set all the matrix values to zero.\n"
+"   :return: an instance of itself\n"
+"   :rtype: Matrix\n";
+
 PyObject *Matrix_Zero(MatrixObject * self)
 {
        int row, col;
@@ -552,6 +606,17 @@ PyObject *Matrix_Zero(MatrixObject * self)
        return (PyObject *)self;
 }
 /*---------------------------Matrix.identity(() ------------------*/
+static char Matrix_Identity_doc[] =
+".. method:: identity()\n"
+"\n"
+"   Set the matrix to the identity matrix.\n"
+"   :return: an instance of itself\n"
+"   :rtype: Matrix\n"
+"\n"
+"   .. note:: An object with zero location and rotation, a scale of one, will have an identity matrix.\n"
+"\n"
+"   .. seealso:: <http://en.wikipedia.org/wiki/Identity_matrix>\n";
+
 PyObject *Matrix_Identity(MatrixObject * self)
 {
        if(!BaseMath_ReadCallback(self))
@@ -580,7 +645,14 @@ PyObject *Matrix_Identity(MatrixObject * self)
        return (PyObject *)self;
 }
 
-/*---------------------------Matrix.inverted() ------------------*/
+/*---------------------------Matrix.copy() ------------------*/
+static char Matrix_copy_doc[] =
+".. method:: copy()\n"
+"\n"
+"   Returns a copy of this matrix.\n"
+"   :return: an instance of itself\n"
+"   :rtype: Matrix\n";
+
 PyObject *Matrix_copy(MatrixObject * self)
 {
        if(!BaseMath_ReadCallback(self))
@@ -1162,6 +1234,24 @@ static PyGetSetDef Matrix_getseters[] = {
        {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
 };
 
+/*-----------------------METHOD DEFINITIONS ----------------------*/
+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},
+       {"determinant", (PyCFunction) Matrix_Determinant, METH_NOARGS, Matrix_Determinant_doc},
+       {"invert", (PyCFunction) Matrix_Invert, METH_NOARGS, Matrix_Invert_doc},
+       {"translation_part", (PyCFunction) Matrix_TranslationPart, METH_NOARGS, Matrix_TranslationPart_doc},
+       {"rotation_part", (PyCFunction) Matrix_RotationPart, METH_NOARGS, Matrix_RotationPart_doc},
+       {"scale_part", (PyCFunction) Matrix_scalePart, METH_NOARGS, Matrix_scalePart_doc},
+       {"resize4x4", (PyCFunction) Matrix_Resize4x4, METH_NOARGS, Matrix_Resize4x4_doc},
+       {"to_euler", (PyCFunction) Matrix_toEuler, METH_VARARGS, Matrix_toEuler_doc},
+       {"to_quat", (PyCFunction) Matrix_toQuat, METH_NOARGS, Matrix_toQuat_doc},
+       {"copy", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc},
+       {"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc},
+       {NULL, NULL, 0, NULL}
+};
+
 /*------------------PY_OBECT DEFINITION--------------------------*/
 PyTypeObject matrix_Type = {
        PyVarObject_HEAD_INIT(NULL, 0)
index e739e1a5036d0729b066ea7c77e09a38a78d9a3a..7facc35062510f513ae2607329abb8e09cb08fa1 100644 (file)
 #include "BKE_utildefines.h"
 #include "BLI_blenlib.h"
 
-
-//-------------------------DOC STRINGS ---------------------------
-
-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 ----------------------
-static struct PyMethodDef Quaternion_methods[] = {
-       {"identity", (PyCFunction) Quaternion_Identity, METH_NOARGS, NULL},
-       {"negate", (PyCFunction) Quaternion_Negate, METH_NOARGS, NULL},
-       {"conjugate", (PyCFunction) Quaternion_Conjugate, METH_NOARGS, NULL},
-       {"inverse", (PyCFunction) Quaternion_Inverse, METH_NOARGS, NULL},
-       {"normalize", (PyCFunction) Quaternion_Normalize, METH_NOARGS, NULL},
-       {"toEuler", (PyCFunction) Quaternion_ToEuler, METH_VARARGS, NULL},
-       {"toMatrix", (PyCFunction) Quaternion_ToMatrix, METH_NOARGS, NULL},
-       {"cross", (PyCFunction) Quaternion_Cross, METH_O, NULL},
-       {"dot", (PyCFunction) Quaternion_Dot, METH_O, NULL},
-       {"__copy__", (PyCFunction) Quaternion_copy, METH_NOARGS, NULL},
-       {"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, NULL},
-       {NULL, NULL, 0, NULL}
-};
-
-//----------------------------------Mathutils.Quaternion() --------------
-static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
-       PyObject *listObject = NULL, *n, *q;
-       int size, i;
-       float quat[4];
-       double 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, NULL);
-       } else {
-               listObject = args;
-       }
-
-       if (size == 3) { // invalid quat size
-               if(PySequence_Length(args) != 2){
-                       PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
-                       return NULL;
-               }
-       }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;
-               }
-
-               quat[i] = PyFloat_AsDouble(q);
-               Py_DECREF(q);
-
-               if (quat[i]==-1 && PyErr_Occurred()) {
-                       PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
-                       return NULL;
-               }
-       }
-
-       if(size == 3) //calculate the quat based on axis/angle
-#ifdef USE_MATHUTILS_DEG
-               axis_angle_to_quat(quat, quat, angle * (Py_PI / 180));
-#else
-               axis_angle_to_quat(quat, quat, angle);
-#endif
-
-       return newQuaternionObject(quat, Py_NEW, NULL);
-}
-
 //-----------------------------METHODS------------------------------
-//----------------------------Quaternion.toEuler()------------------
-//return the quat as a euler
+static char Quaternion_ToEuler_doc[] =
+".. method:: to_euler(euler_compat)\n"
+"\n"
+"   Return Euler representation of the quaternion.\n"
+"\n"
+"   :arg euler_compat: Optional euler argument the new euler will be made compatible with (no axis flipping between them). Useful for converting a series of matrices to animation curves.\n"
+"   :type euler_compat: Euler\n"
+"   :return: Euler representation of the quaternion.\n"
+"   :rtype: Euler\n";
+
 static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
 {
        float eul[3];
@@ -212,7 +92,14 @@ static PyObject *Quaternion_ToEuler(QuaternionObject * self, PyObject *args)
        return newEulerObject(eul, Py_NEW, NULL);
 }
 //----------------------------Quaternion.toMatrix()------------------
-//return the quat as a matrix
+static char Quaternion_ToMatrix_doc[] =
+".. method:: to_matrix(other)\n"
+"\n"
+"   Return a matrix representation of the quaternion.\n"
+"\n"
+"   :return: A 3x3 rotation matrix representation of the quaternion.\n"
+"   :rtype: Matrix\n";
+
 static PyObject *Quaternion_ToMatrix(QuaternionObject * self)
 {
        float mat[9]; /* all values are set */
@@ -225,7 +112,16 @@ static PyObject *Quaternion_ToMatrix(QuaternionObject * self)
 }
 
 //----------------------------Quaternion.cross(other)------------------
-//return the cross quat
+static char Quaternion_Cross_doc[] =
+".. method:: cross(other)\n"
+"\n"
+"   Return the cross product of this quaternion and another.\n"
+"\n"
+"   :arg other: The other quaternion to perform the cross product with.\n"
+"   :type other: Quaternion\n"
+"   :return: The cross product.\n"
+"   :rtype: Quaternion\n";
+
 static PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * value)
 {
        float quat[4];
@@ -243,7 +139,16 @@ static PyObject *Quaternion_Cross(QuaternionObject * self, QuaternionObject * va
 }
 
 //----------------------------Quaternion.dot(other)------------------
-//return the dot quat
+static char Quaternion_Dot_doc[] =
+".. method:: dot(other)\n"
+"\n"
+"   Return the dot product of this quaternion and another.\n"
+"\n"
+"   :arg other: The other quaternion to perform the dot product with.\n"
+"   :type other: Quaternion\n"
+"   :return: The dot product.\n"
+"   :rtype: Quaternion\n";
+
 static PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * value)
 {
        if (!QuaternionObject_Check(value)) {
@@ -257,8 +162,90 @@ static PyObject *Quaternion_Dot(QuaternionObject * self, QuaternionObject * valu
        return PyFloat_FromDouble(dot_qtqt(self->quat, value->quat));
 }
 
+static char Quaternion_Difference_doc[] =
+".. function:: difference(other)\n"
+"\n"
+"   Returns a quaternion representing the rotational difference.\n"
+"\n"
+"   :arg other: second quaternion.\n"
+"   :type other: Quaternion\n"
+"   :return: the rotational difference between the two quat rotations.\n"
+"   :rtype: Quaternion\n";
+
+static PyObject *Quaternion_Difference(QuaternionObject * self, QuaternionObject * value)
+{
+       float quat[4], tempQuat[4];
+       double dot = 0.0f;
+       int x;
+
+       if (!QuaternionObject_Check(value)) {
+               PyErr_SetString( PyExc_TypeError, "quat.difference(value): expected a quaternion argument" );
+               return NULL;
+       }
+
+       if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
+               return NULL;
+
+       tempQuat[0] = self->quat[0];
+       tempQuat[1] = - self->quat[1];
+       tempQuat[2] = - self->quat[2];
+       tempQuat[3] = - self->quat[3];
+
+       dot = sqrt(tempQuat[0] * tempQuat[0] + tempQuat[1] *  tempQuat[1] +
+                              tempQuat[2] * tempQuat[2] + tempQuat[3] * tempQuat[3]);
+
+       for(x = 0; x < 4; x++) {
+               tempQuat[x] /= (float)(dot * dot);
+       }
+       mul_qt_qtqt(quat, tempQuat, value->quat);
+       return newQuaternionObject(quat, Py_NEW, NULL);
+}
+
+static char Quaternion_Slerp_doc[] =
+".. function:: slerp(other, factor)\n"
+"\n"
+"   Returns the interpolation of two quaternions.\n"
+"\n"
+"   :arg other: value to interpolate with.\n"
+"   :type other: Quaternion\n"
+"   :arg factor: The interpolation value in [0.0, 1.0].\n"
+"   :type factor: float\n"
+"   :return: The interpolated rotation.\n"
+"   :rtype: Quaternion\n";
+
+static PyObject *Quaternion_Slerp(QuaternionObject *self, PyObject *args)
+{
+       QuaternionObject *value;
+       float quat[4], fac;
+
+       if(!PyArg_ParseTuple(args, "O!f", &quaternion_Type, &value, &fac)) {
+               PyErr_SetString(PyExc_TypeError, "Mathutils.Slerp(): expected Quaternion types and float");
+               return NULL;
+       }
+
+       if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
+               return NULL;
+
+       if(fac > 1.0f || fac < 0.0f) {
+               PyErr_SetString(PyExc_AttributeError, "Mathutils.Slerp(): interpolation factor must be between 0.0 and 1.0");
+               return NULL;
+       }
+
+       interp_qt_qtqt(quat, self->quat, value->quat, fac);
+
+       return newQuaternionObject(quat, Py_NEW, NULL);
+}
+
 //----------------------------Quaternion.normalize()----------------
 //normalize the axis of rotation of [theta,vector]
+static char Quaternion_Normalize_doc[] =
+".. function:: normalize()\n"
+"\n"
+"   Normalize the quaternion.\n"
+"\n"
+"   :return: an instance of itself.\n"
+"   :rtype: Quaternion\n";
+
 static PyObject *Quaternion_Normalize(QuaternionObject * self)
 {
        if(!BaseMath_ReadCallback(self))
@@ -271,7 +258,14 @@ static PyObject *Quaternion_Normalize(QuaternionObject * self)
        return (PyObject*)self;
 }
 //----------------------------Quaternion.inverse()------------------
-//invert the quat
+static char Quaternion_Inverse_doc[] =
+".. function:: inverse()\n"
+"\n"
+"   Set the quaternion to its inverse.\n"
+"\n"
+"   :return: an instance of itself.\n"
+"   :rtype: Quaternion\n";
+
 static PyObject *Quaternion_Inverse(QuaternionObject * self)
 {
        if(!BaseMath_ReadCallback(self))
@@ -284,7 +278,14 @@ static PyObject *Quaternion_Inverse(QuaternionObject * self)
        return (PyObject*)self;
 }
 //----------------------------Quaternion.identity()-----------------
-//generate the identity quaternion
+static char Quaternion_Identity_doc[] =
+".. function:: identity()\n"
+"\n"
+"   Set the quaternion to an identity quaternion.\n"
+"\n"
+"   :return: an instance of itself.\n"
+"   :rtype: Quaternion\n";
+
 static PyObject *Quaternion_Identity(QuaternionObject * self)
 {
        if(!BaseMath_ReadCallback(self))
@@ -297,7 +298,14 @@ static PyObject *Quaternion_Identity(QuaternionObject * self)
        return (PyObject*)self;
 }
 //----------------------------Quaternion.negate()-------------------
-//negate the quat
+static char Quaternion_Negate_doc[] =
+".. function:: negate()\n"
+"\n"
+"   Set the quaternion to its negative.\n"
+"\n"
+"   :return: an instance of itself.\n"
+"   :rtype: Quaternion\n";
+
 static PyObject *Quaternion_Negate(QuaternionObject * self)
 {
        if(!BaseMath_ReadCallback(self))
@@ -310,7 +318,14 @@ static PyObject *Quaternion_Negate(QuaternionObject * self)
        return (PyObject*)self;
 }
 //----------------------------Quaternion.conjugate()----------------
-//negate the vector part
+static char Quaternion_Conjugate_doc[] =
+".. function:: conjugate()\n"
+"\n"
+"   Set the quaternion to its conjugate (negate x, y, z).\n"
+"\n"
+"   :return: an instance of itself.\n"
+"   :rtype: Quaternion\n";
+
 static PyObject *Quaternion_Conjugate(QuaternionObject * self)
 {
        if(!BaseMath_ReadCallback(self))
@@ -323,7 +338,16 @@ static PyObject *Quaternion_Conjugate(QuaternionObject * self)
        return (PyObject*)self;
 }
 //----------------------------Quaternion.copy()----------------
-//return a copy of the quat
+static char Quaternion_copy_doc[] =
+".. function:: copy()\n"
+"\n"
+"   Returns a copy of this quaternion.\n"
+"\n"
+"   :return: A copy of the quaternion.\n"
+"   :rtype: Quaternion\n"
+"\n"
+"   .. note:: use this to get a copy of a wrapped quaternion with no reference to the original data.\n";
+
 static PyObject *Quaternion_copy(QuaternionObject * self)
 {
        if(!BaseMath_ReadCallback(self))
@@ -702,52 +726,139 @@ static PyObject *Quaternion_getAxisVec( QuaternionObject * self, void *type )
        return (PyObject *) newVectorObject(vec, 3, Py_NEW, NULL);
 }
 
+//----------------------------------Mathutils.Quaternion() --------------
+static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+       PyObject *listObject = NULL, *n, *q;
+       int size, i;
+       float quat[4];
+       double 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, NULL);
+       } else {
+               listObject = args;
+       }
+
+       if (size == 3) { // invalid quat size
+               if(PySequence_Length(args) != 2){
+                       PyErr_SetString(PyExc_AttributeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
+                       return NULL;
+               }
+       }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;
+               }
+
+               quat[i] = PyFloat_AsDouble(q);
+               Py_DECREF(q);
+
+               if (quat[i]==-1 && PyErr_Occurred()) {
+                       PyErr_SetString(PyExc_TypeError, "Mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
+                       return NULL;
+               }
+       }
+
+       if(size == 3) //calculate the quat based on axis/angle
+#ifdef USE_MATHUTILS_DEG
+               axis_angle_to_quat(quat, quat, angle * (Py_PI / 180));
+#else
+               axis_angle_to_quat(quat, quat, angle);
+#endif
+
+       return newQuaternionObject(quat, Py_NEW, NULL);
+}
+
+
+//-----------------------METHOD DEFINITIONS ----------------------
+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},
+       {"inverse", (PyCFunction) Quaternion_Inverse, METH_NOARGS, Quaternion_Inverse_doc},
+       {"normalize", (PyCFunction) Quaternion_Normalize, METH_NOARGS, Quaternion_Normalize_doc},
+       {"to_euler", (PyCFunction) Quaternion_ToEuler, METH_VARARGS, Quaternion_ToEuler_doc},
+       {"to_matrix", (PyCFunction) Quaternion_ToMatrix, METH_NOARGS, Quaternion_ToMatrix_doc},
+       {"cross", (PyCFunction) Quaternion_Cross, METH_O, Quaternion_Cross_doc},
+       {"dot", (PyCFunction) Quaternion_Dot, METH_O, Quaternion_Dot_doc},
+       {"difference", (PyCFunction) Quaternion_Difference, METH_O, Quaternion_Difference_doc},
+       {"slerp", (PyCFunction) Quaternion_Slerp, METH_VARARGS, Quaternion_Slerp_doc},
+       {"__copy__", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
+       {"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
+       {NULL, NULL, 0, NULL}
+};
 
 /*****************************************************************************/
 /* Python attributes get/set structure:                                      */
 /*****************************************************************************/
 static PyGetSetDef Quaternion_getseters[] = {
-       {"w",
-        (getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
-        "Quaternion W value",
-        (void *)0},
-       {"x",
-        (getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
-        "Quaternion X axis",
-        (void *)1},
-       {"y",
-        (getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
-        "Quaternion Y axis",
-        (void *)2},
-       {"z",
-        (getter)Quaternion_getAxis, (setter)Quaternion_setAxis,
-        "Quaternion Z axis",
-        (void *)3},
-       {"magnitude",
-        (getter)Quaternion_getMagnitude, (setter)NULL,
-        "Size of the quaternion",
-        NULL},
-       {"angle",
-        (getter)Quaternion_getAngle, (setter)NULL,
-        "angle of the quaternion",
-        NULL},
-       {"axis",
-        (getter)Quaternion_getAxisVec, (setter)NULL,
-        "quaternion axis as a vector",
-        NULL},
-       {"wrapped",
-        (getter)BaseMathObject_getWrapped, (setter)NULL,
-        "True when this wraps blenders internal data",
-        NULL},
-       {"_owner",
-        (getter)BaseMathObject_getOwner, (setter)NULL,
-        "Read only owner for vectors that depend on another object",
-        NULL},
-
+       {"w", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion W value", (void *)0},
+       {"x", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion X axis", (void *)1},
+       {"y", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Y axis", (void *)2},
+       {"z", (getter)Quaternion_getAxis, (setter)Quaternion_setAxis, "Quaternion Z axis", (void *)3},
+       {"magnitude", (getter)Quaternion_getMagnitude, (setter)NULL, "Size of the quaternion", NULL},
+       {"angle", (getter)Quaternion_getAngle, (setter)NULL, "angle of the quaternion", NULL},
+       {"axis",(getter)Quaternion_getAxisVec, (setter)NULL, "quaternion axis as a vector", NULL},
+       {"wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, "True when this wraps blenders internal data", NULL},
+       {"_owner", (getter)BaseMathObject_getOwner, (setter)NULL, "Read only owner for vectors that depend on another object", NULL},
        {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
 };
 
-
 //------------------PY_OBECT DEFINITION--------------------------
 PyTypeObject quaternion_Type = {
        PyVarObject_HEAD_INIT(NULL, 0)
@@ -843,3 +954,4 @@ PyObject *newQuaternionObject_cb(PyObject *cb_user, int cb_type, int cb_subtype)
 
        return (PyObject *)self;
 }
+
index 862b7338ac0a02f1784422d9a4ed82a654d8917f..558e4aac9c967c15aed3830142824fc4eae91090 100644 (file)
 
 static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat); /* utility func */
 
-/*-----------------------METHOD DEFINITIONS ----------------------*/
-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_ToTuple( VectorObject * self, PyObject *value );
-static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args );
-static PyObject *Vector_Reflect( VectorObject *self, VectorObject *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, NULL},
-       {"normalize", (PyCFunction) Vector_Normalize, METH_NOARGS, NULL},
-       {"negate", (PyCFunction) Vector_Negate, METH_NOARGS, NULL},
-       {"resize2D", (PyCFunction) Vector_Resize2D, METH_NOARGS, NULL},
-       {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, NULL},
-       {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, NULL},
-       {"toTuple", (PyCFunction) Vector_ToTuple, METH_O, NULL},
-       {"toTrackQuat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, NULL},
-       {"reflect", ( PyCFunction ) Vector_Reflect, METH_O, NULL},
-       {"cross", ( PyCFunction ) Vector_Cross, METH_O, NULL},
-       {"dot", ( PyCFunction ) Vector_Dot, METH_O, NULL},
-       {"copy", (PyCFunction) Vector_copy, METH_NOARGS, NULL},
-       {"__copy__", (PyCFunction) Vector_copy, METH_NOARGS, NULL},
-       {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 
@@ -124,8 +93,13 @@ static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 }
 
 /*-----------------------------METHODS---------------------------- */
-/*----------------------------Vector.zero() ----------------------
-  set the vector data to 0,0,0 */
+static char Vector_Zero_doc[] =
+".. method:: zero()\n"
+"\n"
+"   Set all values to zero.\n"
+"   :return: an instance of itself\n"
+"   :rtype: vector\n";
+
 static PyObject *Vector_Zero(VectorObject * self)
 {
        int i;
@@ -137,8 +111,18 @@ static PyObject *Vector_Zero(VectorObject * self)
        Py_INCREF(self);
        return (PyObject*)self;
 }
-/*----------------------------Vector.normalize() -----------------
-  normalize the vector data to a unit vector */
+/*----------------------------Vector.normalize() ----------------- */
+static char Vector_Normalize_doc[] =
+".. method:: normalize()\n"
+"\n"
+"   Normalize the vector, making the length of the vector always 1.0.\n"
+"   :return: an instance of itself\n"
+"   :rtype: vector\n"
+"\n"
+"   .. warning:: Normalizing a vector where all values are zero results in all axis having a nan value (not a number).\n"
+"\n"
+"   .. note:: Normalize works for vectors of all sizes, however 4D Vectors w axis is left untouched.\n";
+
 static PyObject *Vector_Normalize(VectorObject * self)
 {
        int i;
@@ -161,8 +145,14 @@ static PyObject *Vector_Normalize(VectorObject * self)
 }
 
 
-/*----------------------------Vector.resize2D() ------------------
-  resize the vector to x,y */
+/*----------------------------Vector.resize2D() ------------------ */
+static char Vector_Resize2D_doc[] =
+".. method:: resize2D()\n"
+"\n"
+"   Resize the vector to 2D  (x, y).\n"
+"   :return: an instance of itself\n"
+"   :rtype: vector\n";
+
 static PyObject *Vector_Resize2D(VectorObject * self)
 {
        if(self->wrapped==Py_WRAP) {
@@ -184,8 +174,14 @@ static PyObject *Vector_Resize2D(VectorObject * self)
        Py_INCREF(self);
        return (PyObject*)self;
 }
-/*----------------------------Vector.resize3D() ------------------
-  resize the vector to x,y,z */
+/*----------------------------Vector.resize3D() ------------------ */
+static char Vector_Resize3D_doc[] =
+".. method:: resize3D()\n"
+"\n"
+"   Resize the vector to 3D  (x, y, z).\n"
+"   :return: an instance of itself\n"
+"   :rtype: vector\n";
+
 static PyObject *Vector_Resize3D(VectorObject * self)
 {
        if (self->wrapped==Py_WRAP) {
@@ -210,8 +206,14 @@ static PyObject *Vector_Resize3D(VectorObject * self)
        Py_INCREF(self);
        return (PyObject*)self;
 }
-/*----------------------------Vector.resize4D() ------------------
-  resize the vector to x,y,z,w */
+/*----------------------------Vector.resize4D() ------------------ */
+static char Vector_Resize4D_doc[] =
+".. method:: resize4D()\n"
+"\n"
+"   Resize the vector to 4D (x, y, z, w).\n"
+"   :return: an instance of itself\n"
+"   :rtype: vector\n";
+
 static PyObject *Vector_Resize4D(VectorObject * self)
 {
        if(self->wrapped==Py_WRAP) {
@@ -239,8 +241,17 @@ static PyObject *Vector_Resize4D(VectorObject * self)
        return (PyObject*)self;
 }
 
-/*----------------------------Vector.resize4D() ------------------
-  resize the vector to x,y,z,w */
+/*----------------------------Vector.toTuple() ------------------ */
+static char Vector_ToTuple_doc[] =
+".. method:: to_tuple(precision)\n"
+"\n"
+"   Return this vector as a tuple with.\n"
+"\n"
+"   :arg precision: The number to round the value to in [0, 21].\n"
+"   :type precision: int\n"
+"   :return: the values of the vector rounded by *precision*\n"
+"   :rtype: tuple\n";
+
 static PyObject *Vector_ToTuple(VectorObject * self, PyObject *value)
 {
        int ndigits= PyLong_AsSsize_t(value);
@@ -265,8 +276,19 @@ static PyObject *Vector_ToTuple(VectorObject * self, PyObject *value)
        return ret;
 }
 
-/*----------------------------Vector.toTrackQuat(track, up) ----------------------
-  extract a quaternion from the vector and the track and up axis */
+/*----------------------------Vector.toTrackQuat(track, up) ---------------------- */
+static char Vector_ToTrackQuat_doc[] =
+".. method:: to_track_quat(track, up)\n"
+"\n"
+"   Return a quaternion rotation from the vector and the track and up axis.\n"
+"\n"
+"   :arg track: Track axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z'].\n"
+"   :type track: string\n"
+"   :arg up: Up axis in ['X', 'Y', 'Z'].\n"
+"   :type up: string\n"
+"   :return: rotation from the vector and the track and up axis."
+"   :rtype: Quaternion\n";
+
 static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
 {
        float vec[3], quat[4];
@@ -290,14 +312,11 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
                        if (strack[0] == '-') {
                                switch(strack[1]) {
                                        case 'X':
-                                       case 'x':
                                                track = 3;
                                                break;
                                        case 'Y':
-                                       case 'y':
                                                track = 4;
                                                break;
-                                       case 'z':
                                        case 'Z':
                                                track = 5;
                                                break;
@@ -315,14 +334,11 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
                        switch(strack[0]) {
                        case '-':
                        case 'X':
-                       case 'x':
                                track = 0;
                                break;
                        case 'Y':
-                       case 'y':
                                track = 1;
                                break;
-                       case 'z':
                        case 'Z':
                                track = 2;
                                break;
@@ -341,14 +357,11 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
                if (strlen(sup) == 1) {
                        switch(*sup) {
                        case 'X':
-                       case 'x':
                                up = 0;
                                break;
-                       case 'Y':
                        case 'y':
                                up = 1;
                                break;
-                       case 'z':
                        case 'Z':
                                up = 2;
                                break;
@@ -385,6 +398,16 @@ static PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
   return a reflected vector on the mirror normal
    vec - ((2 * DotVecs(vec, mirror)) * mirror)
 */
+static char Vector_Reflect_doc[] =
+".. method:: reflect(mirror)\n"
+"\n"
+"   Return the reflection vector from the *mirror* argument.\n"
+"\n"
+"   :arg mirror: This vector could be a normal from the reflecting surface.\n"
+"   :type mirror: vector\n"
+"   :return: The reflected vector.\n"
+"   :rtype: Vector object matching the size of this vector.\n";
+
 static PyObject *Vector_Reflect( VectorObject * self, VectorObject * value )
 {
        float mirror[3], vec[3];
@@ -414,6 +437,18 @@ static PyObject *Vector_Reflect( VectorObject * self, VectorObject * value )
        return newVectorObject(reflect, self->size, Py_NEW, NULL);
 }
 
+static char Vector_Cross_doc[] =
+".. method:: cross(other)\n"
+"\n"
+"   Return the cross product of this vector and another.\n"
+"\n"
+"   :arg other: The other vector to perform the cross product with.\n"
+"   :type other: vector\n"
+"   :return: The cross product.\n"
+"   :rtype: Vector\n"
+"\n"
+"   .. note:: both vectors must be 3D\n";
+
 static PyObject *Vector_Cross( VectorObject * self, VectorObject * value )
 {
        VectorObject *vecCross = NULL;
@@ -436,6 +471,16 @@ static PyObject *Vector_Cross( VectorObject * self, VectorObject * value )
        return (PyObject *)vecCross;
 }
 
+static char Vector_Dot_doc[] =
+".. method:: dot(other)\n"
+"\n"
+"   Return the dot product of this vector and another.\n"
+"\n"
+"   :arg other: The other vector to perform the dot product with.\n"
+"   :type other: vector\n"
+"   :return: The dot product.\n"
+"   :rtype: Vector\n";
+
 static PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
 {
        double dot = 0.0;
@@ -460,8 +505,156 @@ static PyObject *Vector_Dot( VectorObject * self, VectorObject * value )
        return PyFloat_FromDouble(dot);
 }
 
-/*----------------------------Vector.copy() --------------------------------------
-  return a copy of the vector */
+static char Vector_Angle_doc[] = 
+".. function:: angle(other)\n"
+"\n"
+"   Return the angle between two vectors.\n"
+"\n"
+"   :type other: vector\n"
+"   :return angle: angle in radians\n"
+"   :rtype: float\n"
+"\n"
+"   .. note:: Zero length vectors raise an :exc:`AttributeError`.\n";
+static PyObject *Vector_Angle(VectorObject * self, VectorObject * value)
+{
+    double dot = 0.0f, angleRads, test_v1 = 0.0f, test_v2 = 0.0f;
+       int x, size;
+       
+       if (!VectorObject_Check(value)) {
+               PyErr_SetString( PyExc_TypeError, "vec.angle(value): expected a vector argument" );
+               return NULL;
+       }
+       
+       if(self->size != value->size) {
+               PyErr_SetString(PyExc_AttributeError, "vec.angle(value): expects both vectors to have the same size\n");
+               return NULL;
+       }
+       
+       if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
+               return NULL;
+
+       //since size is the same....
+       size = self->size;
+
+       for(x = 0; x < size; x++) {
+               test_v1 += self->vec[x] * self->vec[x];
+               test_v2 += value->vec[x] * value->vec[x];
+       }
+       if (!test_v1 || !test_v2){
+               PyErr_SetString(PyExc_AttributeError, "vector.angle(other): zero length vectors are not acceptable arguments\n");
+               return NULL;
+       }
+
+       //dot product
+       for(x = 0; x < size; x++) {
+               dot += self->vec[x] * value->vec[x];
+       }
+       dot /= (sqrt(test_v1) * sqrt(test_v2));
+
+       angleRads = (double)saacos(dot);
+
+#ifdef USE_MATHUTILS_DEG
+       return PyFloat_FromDouble(angleRads * (180/ Py_PI));
+#else
+       return PyFloat_FromDouble(angleRads);
+#endif
+}
+
+static char Vector_Project_doc[] =
+".. function:: project(other)\n"
+"\n"
+"   Return the projection of this vector onto the *other*.\n"
+"\n"
+"   :type other: vector\n"
+"   :return projection: the parallel projection vector\n"
+"   :rtype: vector\n";
+
+static PyObject *Vector_Project(VectorObject * self, VectorObject * value)
+{
+       float vec[4];
+       double dot = 0.0f, dot2 = 0.0f;
+       int x, size;
+
+       if (!VectorObject_Check(value)) {
+               PyErr_SetString( PyExc_TypeError, "vec.project(value): expected a vector argument" );
+               return NULL;
+       }
+
+       if(self->size != value->size) {
+               PyErr_SetString(PyExc_AttributeError, "vec.project(value): expects both vectors to have the same size\n");
+               return NULL;
+       }
+
+       if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value))
+               return NULL;
+
+
+       //since they are the same size...
+       size = self->size;
+
+       //get dot products
+       for(x = 0; x < size; x++) {
+               dot += self->vec[x] * value->vec[x];
+               dot2 += value->vec[x] * value->vec[x];
+       }
+       //projection
+       dot /= dot2;
+       for(x = 0; x < size; x++) {
+               vec[x] = (float)(dot * value->vec[x]);
+       }
+       return newVectorObject(vec, size, Py_NEW, NULL);
+}
+
+//----------------------------------Mathutils.MidpointVecs() -------------
+static char Vector_Lerp_doc[] =
+".. function:: lerp(other, factor)\n"
+"\n"
+"   Returns the interpolation of two vectors.\n"
+"\n"
+"   :arg other: value to interpolate with.\n"
+"   :type other: Vector\n"
+"   :arg factor: The interpolation value in [0.0, 1.0].\n"
+"   :type factor: float\n"
+"   :return: The interpolated rotation.\n"
+"   :rtype: Vector\n";
+
+static PyObject *Vector_Lerp(VectorObject * self, PyObject * args)
+{
+       VectorObject *vec2 = NULL;
+       float fac, ifac, vec[4];
+       int x;
+
+       if(!PyArg_ParseTuple(args, "O!f", &vector_Type, &vec2, &fac)) {
+               PyErr_SetString(PyExc_TypeError, "vector.lerp(): expects a vector of the same size and float");
+               return NULL;
+       }
+       if(self->size != vec2->size) {
+               PyErr_SetString(PyExc_AttributeError, "Mathutils.MidpointVecs(): expects (2) vector objects of the same size");
+               return NULL;
+       }
+
+       if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(vec2))
+               return NULL;
+
+       ifac= 1.0 - fac;
+
+       for(x = 0; x < self->size; x++) {
+               vec[x] = (ifac * self->vec[x]) + (fac * vec2->vec[x]);
+       }
+       return newVectorObject(vec, self->size, Py_NEW, NULL);
+}
+
+/*----------------------------Vector.copy() -------------------------------------- */
+static char Vector_copy_doc[] =
+".. function:: copy()\n"
+"\n"
+"   Returns a copy of this vector.\n"
+"\n"
+"   :return: A copy of the vector.\n"
+"   :rtype: Vector\n"
+"\n"
+"   .. note:: use this to get a copy of a wrapped vector with no reference to the original data.\n";
+
 static PyObject *Vector_copy(VectorObject * self)
 {
        if(!BaseMath_ReadCallback(self))
@@ -1808,7 +2001,87 @@ if len(unique) != len(items):
 
 */
 
+//-----------------row_vector_multiplication (internal)-----------
+//ROW VECTOR Multiplication - Vector X Matrix
+//[x][y][z] *  [1][4][7]
+//             [2][5][8]
+//             [3][6][9]
+//vector/matrix multiplication IS NOT COMMUTATIVE!!!!
+static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat)
+{
+       float vecNew[4], vecCopy[4];
+       double dot = 0.0f;
+       int x, y, z = 0, vec_size = vec->size;
+
+       if(mat->colSize != vec_size){
+               if(mat->colSize == 4 && vec_size != 3){
+                       PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same");
+                       return NULL;
+               }else{
+                       vecCopy[3] = 1.0f;
+               }
+       }
+       
+       if(!BaseMath_ReadCallback(vec) || !BaseMath_ReadCallback(mat))
+               return NULL;
+       
+       for(x = 0; x < vec_size; x++){
+               vecCopy[x] = vec->vec[x];
+       }
+       vecNew[3] = 1.0f;
+       //muliplication
+       for(x = 0; x < mat->rowSize; x++) {
+               for(y = 0; y < mat->colSize; y++) {
+                       dot += mat->matrix[x][y] * vecCopy[y];
+               }
+               vecNew[z++] = (float)dot;
+               dot = 0.0f;
+       }
+       return newVectorObject(vecNew, vec_size, Py_NEW, NULL);
+}
+
+/*----------------------------Vector.negate() -------------------- */
+static char Vector_Negate_doc[] =
+".. method:: negate()\n"
+"\n"
+"   Set all values to their negative.\n"
+"   :return: an instance of itself\n"
+"   :rtype: vector\n";
 
+static PyObject *Vector_Negate(VectorObject * self)
+{
+       int i;
+       if(!BaseMath_ReadCallback(self))
+               return NULL;
+       
+       for(i = 0; i < self->size; i++)
+               self->vec[i] = -(self->vec[i]);
+       
+       BaseMath_WriteCallback(self); // alredy checked for error
+       
+       Py_INCREF(self);
+       return (PyObject*)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},
+       {"resize2D", (PyCFunction) Vector_Resize2D, METH_NOARGS, Vector_Resize2D_doc},
+       {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, Vector_Resize3D_doc},
+       {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, Vector_Resize4D_doc},
+       {"to_tuple", (PyCFunction) Vector_ToTuple, METH_O, Vector_ToTuple_doc},
+       {"to_track_quat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, Vector_ToTrackQuat_doc},
+       {"reflect", ( PyCFunction ) Vector_Reflect, METH_O, Vector_Reflect_doc},
+       {"cross", ( PyCFunction ) Vector_Cross, METH_O, Vector_Cross_doc},
+       {"dot", ( PyCFunction ) Vector_Dot, METH_O, Vector_Dot_doc},
+       {"angle", ( PyCFunction ) Vector_Angle, METH_O, Vector_Angle_doc},
+       {"project", ( PyCFunction ) Vector_Project, METH_O, Vector_Project_doc},
+       {"lerp", ( PyCFunction ) Vector_Lerp, METH_VARARGS, Vector_Lerp_doc},
+       {"copy", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc},
+       {"__copy__", (PyCFunction) Vector_copy, METH_NOARGS, NULL},
+       {NULL, NULL, 0, NULL}
+};
 
 
 /* Note
@@ -1817,6 +2090,8 @@ if len(unique) != len(items):
  vec*mat and mat*vec both get sent to Vector_mul and it neesd to sort out the order
 */
 
+static char vector_doc[] = "This object gives access to Vectors in Blender.";
+
 PyTypeObject vector_Type = {
        PyVarObject_HEAD_INIT(NULL, 0)
        /*  For printing, in format "<module>.<name>" */
@@ -1852,7 +2127,7 @@ PyTypeObject vector_Type = {
 
   /*** Flags to define presence of optional/expanded features ***/
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
-       NULL,                       /*  char *tp_doc;  Documentation string */
+       vector_doc,                       /*  char *tp_doc;  Documentation string */
   /*** Assigned meaning in release 2.0 ***/
        /* call function for all accessible objects */
        NULL,                       /* traverseproc tp_traverse; */
@@ -1897,7 +2172,6 @@ PyTypeObject vector_Type = {
        NULL
 };
 
-
 /*------------------------newVectorObject (internal)-------------
   creates a new vector object
   pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER
@@ -1956,59 +2230,3 @@ PyObject *newVectorObject_cb(PyObject *cb_user, int size, int cb_type, int cb_su
        
        return (PyObject *)self;
 }
-
-//-----------------row_vector_multiplication (internal)-----------
-//ROW VECTOR Multiplication - Vector X Matrix
-//[x][y][z] *  [1][4][7]
-//             [2][5][8]
-//             [3][6][9]
-//vector/matrix multiplication IS NOT COMMUTATIVE!!!!
-static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat)
-{
-       float vecNew[4], vecCopy[4];
-       double dot = 0.0f;
-       int x, y, z = 0, vec_size = vec->size;
-
-       if(mat->colSize != vec_size){
-               if(mat->colSize == 4 && vec_size != 3){
-                       PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same");
-                       return NULL;
-               }else{
-                       vecCopy[3] = 1.0f;
-               }
-       }
-       
-       if(!BaseMath_ReadCallback(vec) || !BaseMath_ReadCallback(mat))
-               return NULL;
-       
-       for(x = 0; x < vec_size; x++){
-               vecCopy[x] = vec->vec[x];
-       }
-       vecNew[3] = 1.0f;
-       //muliplication
-       for(x = 0; x < mat->rowSize; x++) {
-               for(y = 0; y < mat->colSize; y++) {
-                       dot += mat->matrix[x][y] * vecCopy[y];
-               }
-               vecNew[z++] = (float)dot;
-               dot = 0.0f;
-       }
-       return newVectorObject(vecNew, vec_size, Py_NEW, NULL);
-}
-
-/*----------------------------Vector.negate() --------------------
-  set the vector to it's negative -x, -y, -z */
-static PyObject *Vector_Negate(VectorObject * self)
-{
-       int i;
-       if(!BaseMath_ReadCallback(self))
-               return NULL;
-       
-       for(i = 0; i < self->size; i++)
-               self->vec[i] = -(self->vec[i]);
-       
-       BaseMath_WriteCallback(self); // alredy checked for error
-       
-       Py_INCREF(self);
-       return (PyObject*)self;
-}
index a882e145aec8a0a936ee814ef95f669f7fc35094..6ff845a794ef2d0f5cd3aefe90ccd1ca219f8e45 100644 (file)
@@ -29,6 +29,7 @@ Generate html docs  by running...
     sphinx-build source/blender/python/doc/sphinx-in source/blender/python/doc/sphinx-out
 '''
 
+
 import os
 import inspect
 import bpy
@@ -121,6 +122,10 @@ def pyprop2sphinx(ident, fw, identifier, py_prop):
 
 def pymodule2sphinx(BASEPATH, module_name, module, title):
     import types
+    # lame, python wont give some access
+    MethodDescriptorType = type(dict.get)
+    GetSetDescriptorType = type(int.real)
+    
 
     filepath = os.path.join(BASEPATH, module_name + ".rst")
     
@@ -138,21 +143,45 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
         # Note, may contain sphinx syntax, dont mangle!
         fw(module.__doc__.strip())
         fw("\n\n")
+    
+    classes = []
 
     for attribute in dir(module):
         if not attribute.startswith("_"):
             value = getattr(module, attribute)
 
             value_type = type(value)
-            print(attribute, value_type)
+
             if value_type == types.FunctionType:
                 pyfunc2sphinx("", fw, attribute, value, is_class=False)
             elif value_type in (types.BuiltinMethodType, types.BuiltinFunctionType): # both the same at the moment but to be future proof
                 # note: can't get args from these, so dump the string as is
                 # this means any module used like this must have fully formatted docstrings.
                 py_c_func2sphinx("", fw, attribute, value, is_class=False)
-
+            elif value_type == type:
+                classes.append((attribute, value))
             # TODO, more types...
+    
+    # write collected classes now
+    for (attribute, value) in classes:
+        # May need to be its own function
+        fw(".. class:: %s\n\n" % attribute)
+        if value.__doc__:
+            for l in value.__doc__.split("\n"):
+                fw("   %s\n" % l)
+        fw("\n")
+
+        for key, descr in value.__dict__.items():
+            if key.startswith("__"):
+                continue
+
+            descr_type = type(descr)
+            if descr_type in (MethodDescriptorType, ): # GetSetDescriptorType, GetSetDescriptorType's are not documented yet
+                if descr.__doc__:
+                    for l in descr.__doc__.split("\n"):
+                        fw("   %s\n" % l)
+                    fw("\n")
+        fw("\n\n")
 
     file.close()
 
@@ -186,8 +215,8 @@ def rna2sphinx(BASEPATH):
     fw("\n")
     fw(".. toctree::\n")
     fw("   :glob:\n\n")
-    fw("   bpy.ops.*\n\n")
-    fw("   bpy.types.*\n\n")
+    #fw("   bpy.ops.*\n\n")
+    #fw("   bpy.types.*\n\n")
     
     # py modules
     fw("   bpy.utils\n\n")
@@ -196,6 +225,8 @@ def rna2sphinx(BASEPATH):
     # C modules
     fw("   bpy.props\n\n")
     
+    fw("   Mathutils\n\n")
+
     file.close()
 
     # python modules
@@ -206,6 +237,9 @@ def rna2sphinx(BASEPATH):
 
     from bpy import props as module
     pymodule2sphinx(BASEPATH, "bpy.props", module, "Blender Python Property Definitions")
+    
+    import Mathutils as module
+    pymodule2sphinx(BASEPATH, "Mathutils", module, "Module Mathutils")
     del module