svn merge -r 12208:12294 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorDaniel Genrich <daniel.genrich@gmx.net>
Thu, 18 Oct 2007 23:27:31 +0000 (23:27 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Thu, 18 Oct 2007 23:27:31 +0000 (23:27 +0000)
80 files changed:
release/Makefile
release/scripts/scripttemplate_pyconstraint.py
source/blender/blenkernel/BKE_armature.h
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_constraint.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenloader/intern/readfile.c
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/intern/dds/BlockDXT.h
source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
source/blender/imbuf/intern/dds/Stream.cpp
source/blender/imbuf/intern/dds/Stream.h
source/blender/imbuf/intern/dds/dds_api.cpp
source/blender/imbuf/intern/rotate.c
source/blender/include/BIF_editmesh.h
source/blender/include/BIF_editseq.h
source/blender/include/BIF_editsima.h
source/blender/include/BSE_sequence.h
source/blender/include/BSE_time.h
source/blender/include/BSE_view.h
source/blender/include/editmesh.h
source/blender/include/mydevice.h
source/blender/makesdna/DNA_armature_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_sequence_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/python/BPY_interface.c
source/blender/python/api2_2x/BGL.c
source/blender/python/api2_2x/Mesh.c
source/blender/python/api2_2x/doc/BGL.py
source/blender/python/api2_2x/sceneSequence.c
source/blender/render/intern/source/rayshade.c
source/blender/src/booleanops.c
source/blender/src/buttons_editing.c
source/blender/src/drawaction.c
source/blender/src/drawarmature.c
source/blender/src/drawipo.c
source/blender/src/drawmesh.c
source/blender/src/drawnla.c
source/blender/src/drawnode.c
source/blender/src/drawseq.c
source/blender/src/drawsound.c
source/blender/src/drawtime.c
source/blender/src/drawview.c
source/blender/src/editaction.c
source/blender/src/editipo.c
source/blender/src/editmesh_add.c
source/blender/src/editmesh_mods.c
source/blender/src/editmesh_tools.c
source/blender/src/editnla.c
source/blender/src/editobject.c
source/blender/src/editseq.c
source/blender/src/editsima.c
source/blender/src/editsound.c
source/blender/src/edittime.c
source/blender/src/editview.c
source/blender/src/header_action.c
source/blender/src/header_ipo.c
source/blender/src/header_nla.c
source/blender/src/header_seq.c
source/blender/src/header_sound.c
source/blender/src/header_view3d.c
source/blender/src/imagepaint.c
source/blender/src/interface.c
source/blender/src/sequence.c
source/blender/src/space.c
source/blender/src/toets.c
source/blender/src/toolbox.c
source/blender/src/transform.c
source/blender/src/transform_constraints.c
source/blender/src/transform_conversions.c
source/blender/src/transform_generics.c
source/blender/src/view.c

index e04645a7075c2b2a487cfe925a17a7c95c8aaa31..c55e62be003ca9922dfbfeeae090ae1b2b89f22e 100644 (file)
@@ -116,8 +116,9 @@ install: package
     ifneq ($(OS), darwin)
        @[ ! -d $(OCGDIR)/bin/.blender ] || \
                cp -r $(OCGDIR)/bin/.blender $(DISTDIR)
-       cp $(NANBLENDERHOME)/bin/.blender/.Blanguages $(CONFDIR)
-       cp $(NANBLENDERHOME)/bin/.blender/.bfont.ttf $(CONFDIR)
+       @rm -rf $(DISTDIR)/.svn $(DISTDIR)/*/.svn $(DISTDIR)/*/*/.svn
+       @cp $(NANBLENDERHOME)/bin/.blender/.Blanguages $(CONFDIR)
+       @cp $(NANBLENDERHOME)/bin/.blender/.bfont.ttf $(CONFDIR)
     endif
        @echo "----> Copy blender$(EXT0) executable"
     ifeq ($(TYPE),-static)
@@ -141,7 +142,7 @@ ifneq ($(NOPLUGINS),true)
        @cp ../source/blender/blenpluginapi/*.h $(DISTDIR)/plugins/include/
        @chmod 755 $(DISTDIR)/plugins/bmake
        @$(MAKE) -C $(DISTDIR)/plugins all  > /dev/null || exit 1;
-       @rm -fr $(DISTDIR)/plugins/CVS $(DISTDIR)/plugins/*/CVS \
+       @rm -fr $(DISTDIR)/plugins/.svn $(DISTDIR)/plugins/*/.svn \
              $(DISTDIR)/plugins/*/*.o
 
 #on OS X the plugins move to the installation directory
@@ -155,7 +156,7 @@ endif
 
        @echo "----> Copy python infrastructure"
        @[ ! -d scripts ] || cp -r scripts $(CONFDIR)/scripts
-       @[ ! -d $(CONFDIR)/scripts ] || rm -fr $(CONFDIR)/scripts/CVS
+       @[ ! -d $(CONFDIR)/scripts ] || rm -fr $(CONFDIR)/scripts/.svn $(CONFDIR)/scripts/*/.svn $(CONFDIR)/scripts/*/*/.svn
 
     ifeq ($(OS),darwin)
        @echo "----> Move .blender to .app/Contents/MacOS/"
index 9ea00a2a2b116eb525d61ede2381608d6680820b..8dcc04360d0d9117401d96ea9a590b6323dd248d 100644 (file)
 Name: 'Script Constraint'
 Blender: 245
 Group: 'ScriptTemplate'
-Tooltip: 'Add a new text for custom constraints'
+Tooltip: 'Add a new script for custom constraints'
 """
 
 from Blender import Window
 import bpy
 
 script_data = \
-'''#BPYCONSTRAINT
+"""#BPYCONSTRAINT
+'''
+       PyConstraint template, access this in the "add constraint" scripts submenu.
+       Add docstring here
+'''
 
-""" <------- Start removable description section -----------> 
-PyConstraints are text buffers that start with #BPYCONSTRAINT.
+import Blender
+from Blender import Draw
+from Blender import Mathutils
+import math
 
-They must define a doConstraint function.  The doConstraint 
-function is called with the matrix of the parent object/posebone
-as the first argument, the matrix of the target object/posebone as
-the second, and an ID property that's attached to the current constraint
-instance.  The function then must return a 4x4 Mathutils.Matrix() object.
+USE_TARGET = True
 
-They must also define a getSettings function. The getSettings 
-function is called with the ID property that's attached to the current constraint
-instance. It should create a pupblock using the Blender.Draw module to 
-get/set the relevant values of the ID properties.
 
-When a constraint needs to have a Target Object/Bone, the USE_TARGET line
-below must be present. Also, if any special matrix creation needs to be performed
-for the target, a doTarget function must also be defined.
+'''
+ This function is called to evaluate the constraint
+       obmatrix:               (Matrix) copy of owner's worldspace matrix
+       targetmatrix:   (Matrix) copy of target's worldspace matrix (where applicable)
+       idprop:                 (IDProperties) wrapped data referring to this 
+                                       constraint instance's idproperties
+'''
+def doConstraint(obmatrix, targetmatrix, idprop):
+       # Separate out the tranformation components for easy access.
+       obloc = obmatrix.translationPart()      # Translation
+       obrot = obmatrix.toEuler()                      # Rotation
+       obsca = obmatrix.scalePart()            # Scale
+
+       # Define user-settable parameters.\
+       # Must also be defined in getSettings().
+       if not idprop.has_key('user_toggle'): idprop['user_toggle'] = 1
+       if not idprop.has_key('user_slider'): idprop['user_slider'] = 1.0
+       
+       
+       # Do stuff here, changing obloc, obrot, and obsca.
 
-Optionally, a doDriver function may be defined. This function is used
-to get and/or modify settings of the owner and target, and as such, should
-be used with caution. Under no circumstances, should you modify the transforms
-of either the owner or the target in this function, as they will either have 
-no effect, or will result in other things not being updated correctly. Therefore,
-it should be used sparringly.
+       
+       # Convert back into a matrix for loc, scale, rotation,
+       mtxloc = Mathutils.TranslationMatrix( obloc )
+       mtxrot = obrot.toMatrix().resize4x4()
+       mtxsca = Mathutils.Matrix([obsca[0],0,0,0], [0,obsca[1],0,0], [0,0,obsca[2],0], [0,0,0,1])
+       
+       # Recombine the separate elements into a transform matrix.
+       outputmatrix = mtxsca * mtxrot * mtxloc
 
-<------- End removable description section -----------> """
+       # Return the new matrix.
+       return outputmatrix
 
-# Add a licence here if you wish to re-distribute, we recommend the GPL
 
-# uncomment the following line if Target access is wanted
-"""
-USE_TARGET = True
-""" 
 
-import Blender
-from Blender import Draw
-from Blender import Mathutils
-from math import *
-
-# this function is called to evaluate the constraint
-#      inputmatrix: (Matrix) copy of owner's worldspace matrix
-#      targetmatrix: (Matrix) copy of target's worldspace matrix (where applicable)
-#      idproperty: (IDProperties) wrapped data referring to this 
-#                      constraint instance's idproperties
-def doConstraint(inputmatrix, targetmatrix, idproperty):
-       # must return a 4x4 matrix (owner's new matrix)
-       return inputmatrix;
-       
-# this function draws a pupblock that lets the user set
-# the values of custom settings the constraint defines
-#      idprop: (IDProperties) wrapped data referring to this 
-#                      constraint instance's idproperties
-# You MUST use a pupblock. There are errors if you try to use the UIBlock ones.
-def getSettings(idproperty):
-       pass;
-
-
-# this optional function performs special actions that only require
-# access to the target data - calculation of special information
-#      targetobject: (Object) wrapped data referring to the target object
-#      subtarget: (String/PoseChannel) 
-#                      - If the target is a PoseChannel in an armature, then this
-#                        is a wrapped copy of that PoseChannel.
-#                      - Otherwise, this field will either be an empty string or the
-#                        name of the vertex group
-#      targetmatrix: (Matrix) matrix that will be used as the target matrix
-#      idprop: (IDProperties) wrapped data referring to this 
-#                      constraint instance's idproperties
-"""    
-def doTarget (targetobject, subtarget, targetmatix, idproperty):
-       # return a 4x4 matrix (which acts as the matrix of the target)
-       return targetmatrix;
-"""
+'''
+ This function manipulates the target matrix prior to sending it to doConstraint()
+       target_object:                                  wrapped data, representing the target object
+       subtarget_bone:                                 wrapped data, representing the subtarget pose-bone (where applicable)
+       target_matrix:                                  (Matrix) the transformation matrix of the target
+       id_properties_of_constraint:    (IDProperties) wrapped idproperties
+'''
+def doTarget(target_object, subtarget_bone, target_matrix, id_properties_of_constraint):
+       return target_matrix
 
-# This optional function is used to modify/get values on the owner and the
-# target for creating certain setups. It should be used sparingly
-#      ownerobject: (Object) wrapped data referring to the owning object
-#      subowner: (PoseChannel) wrapped data referring to the PoseChannel that
-#                      owns the constraint (where applicable)
-#      target: (Object) wrapped data referring to the target
-#      subtarget: (String/PoseChannel) 
-#                      - If the target is a PoseChannel in an armature, then this
-#                        is a wrapped copy of that PoseChannel.
-#                      - Otherwise, this field will either be an empty string or the
-#                        name of the vertex group
-"""
-def doDriver (ownerobject, subowner, targetobject, subtarget, idproperty):
-       pass;
-"""
 
 '''
+ This function draws a pupblock that lets the user set
+       the values of custom settings the constraint defines.
+       This function is called when the user presses the settings button.
+       idprop: (IDProperties) wrapped data referring to this 
+                       constraint instance's idproperties
+'''
+def getSettings(idprop):
+       # Define user-settable parameters.
+       # Must also be defined in getSettings().
+       if not idprop.has_key('user_toggle'): idprop['user_toggle'] = 1
+       if not idprop.has_key('user_slider'): idprop['user_slider'] = 1.0
+       
+       # create temporary vars for interface 
+       utoggle = Draw.Create(idprop['user_toggle'])
+       uslider = Draw.Create(idprop['user_slider'])
+       
+
+       # define and draw pupblock
+       block = []
+       block.append("Buttons: ")
+       block.append(("Toggle", utoggle, "This is a toggle button."))
+       block.append("More buttons: ")
+       block.append(("Slider", uslider, 0.0000001, 1000.0, "This is a number field."))
+
+       retval = Draw.PupBlock("Constraint Template", block)
+       
+       # update id-property values after user changes settings
+       if (retval):
+               idprop['user_toggle']= utoggle.val
+               idprop['user_slider']= uslider.val
+
+"""
 
 new_text = bpy.data.texts.new('pyconstraint_template.py')
 new_text.write(script_data)
 bpy.data.texts.active = new_text
-Window.RedrawAll()
\ No newline at end of file
+Window.RedrawAll()
index 37022d89ac166c5857adb147ad5db318c6dfedfe..0e3857603b66e1a934348070af533f1be7135662 100644 (file)
@@ -112,7 +112,7 @@ typedef struct Mat4 {
        float mat[4][4];
 } Mat4;
 
-Mat4 *b_bone_spline_setup(struct bPoseChannel *pchan);
+Mat4 *b_bone_spline_setup(struct bPoseChannel *pchan, int rest);
 
 #ifdef __cplusplus
 }
index c79076b4e6884b142496ab2bcb1893b047bba0df..328d9775deb3ca4bf18f8271f8fc39c54b3bf354 100644 (file)
@@ -44,7 +44,7 @@ struct ListBase;
 struct MemFile;
 
 #define BLENDER_VERSION                        245
-#define BLENDER_SUBVERSION             3
+#define BLENDER_SUBVERSION             4
 
 #define BLENDER_MINVERSION             240
 #define BLENDER_MINSUBVERSION  0
index c2fdd551d797b7439f60ea993d6676b498e37745..39a3cf13087724102189d4c36ed9feddbaf7c783 100644 (file)
@@ -76,7 +76,7 @@ void free_constraint_data(struct bConstraint *con);
 /* Constraint Channel function prototypes */
 struct bConstraintChannel *get_constraint_channel(ListBase *list, const char *name);
 struct bConstraintChannel *verify_constraint_channel(ListBase *list, const char *name);
-void do_constraint_channels(struct ListBase *conbase, struct ListBase *chanbase, float ctime);
+void do_constraint_channels(struct ListBase *conbase, struct ListBase *chanbase, float ctime, int onlydrivers);
 void copy_constraint_channels(ListBase *dst, ListBase *src);
 void clone_constraint_channels(struct ListBase *dst, struct ListBase *src);
 void free_constraint_channels(ListBase *chanbase);
index 8274e3253a9e9d5e8e2c2574a669dc7c75d32e0d..22e621a27e2b83b05ed55834b8ca9755409dfcba 100644 (file)
@@ -718,7 +718,8 @@ void extract_pose_from_action(bPose *pose, bAction *act, float ctime)
                                /* This call also sets the pchan flags */
                                execute_action_ipo(achan, pchan);
                        }
-                       do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime);
+                       /* 0 = do all ipos, not only drivers */
+                       do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime, 0);
                }
        }
        
@@ -1068,7 +1069,7 @@ static void do_nla(Object *ob, int blocktype)
        bActionStrip *strip, *striplast=NULL, *stripfirst=NULL;
        float striptime, frametime, length, actlength;
        float blendfac, stripframe;
-       float scene_cfra= G.scene->r.cfra;
+       float scene_cfra= frame_to_float(G.scene->r.cfra); 
        int     doit, dostride;
        
        if(blocktype==ID_AR) {
index 31a25a984c40163a7c9643a6ad36cccac8f6dfb4..10b2a3648271148f6350a2861c5a5df71233233f 100644 (file)
@@ -404,12 +404,14 @@ static void equalize_bezier(float *data, int desired)
 
 /* returns pointer to static array, filled with desired amount of bone->segments elements */
 /* this calculation is done  within unit bone space */
-Mat4 *b_bone_spline_setup(bPoseChannel *pchan)
+Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
 {
        static Mat4 bbone_array[MAX_BBONE_SUBDIV];
+       static Mat4 bbone_rest_array[MAX_BBONE_SUBDIV];
+       Mat4 *result_array= (rest)? bbone_rest_array: bbone_array;
        bPoseChannel *next, *prev;
        Bone *bone= pchan->bone;
-       float h1[3], h2[3], length, hlength1, hlength2, roll;
+       float h1[3], h2[3], length, hlength1, hlength2, roll1, roll2;
        float mat3[3][3], imat[4][4];
        float data[MAX_BBONE_SUBDIV+1][4], *fp;
        int a;
@@ -430,32 +432,69 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan)
                first point = (0,0,0)
                last point =  (0, length, 0) */
        
-       Mat4Invert(imat, pchan->pose_mat);
+       if(rest)
+               Mat4Invert(imat, pchan->bone->arm_mat);
+       else
+               Mat4Invert(imat, pchan->pose_mat);
        
        if(prev) {
+               float difmat[4][4], result[3][3], imat3[3][3];
+
                /* transform previous point inside this bone space */
-               VECCOPY(h1, prev->pose_head);
+               if(rest)
+                       VECCOPY(h1, prev->bone->arm_head)
+               else
+                       VECCOPY(h1, prev->pose_head)
                Mat4MulVecfl(imat, h1);
-               /* if previous bone is B-bone too, use average handle direction */
-               if(prev->bone->segments>1) h1[1]-= length;
+
+               if(prev->bone->segments>1) {
+                       /* if previous bone is B-bone too, use average handle direction */
+                       h1[1]-= length;
+                       roll1= 0.0f;
+               }
+
                Normalize(h1);
                VecMulf(h1, -hlength1);
+
+               if(prev->bone->segments==1) {
+                       /* find the previous roll to interpolate */
+                       if(rest)
+                               Mat4MulMat4(difmat, prev->bone->arm_mat, imat);
+                       else
+                               Mat4MulMat4(difmat, prev->pose_mat, imat);
+                       Mat3CpyMat4(result, difmat);                            // the desired rotation at beginning of next bone
+                       
+                       vec_roll_to_mat3(h1, 0.0f, mat3);                       // the result of vec_roll without roll
+                       
+                       Mat3Inv(imat3, mat3);
+                       Mat3MulMat3(mat3, result, imat3);                       // the matrix transforming vec_roll to desired roll
+                       
+                       roll1= atan2(mat3[2][0], mat3[2][2]);
+               }
        }
        else {
                h1[0]= 0.0f; h1[1]= hlength1; h1[2]= 0.0f;
+               roll1= 0.0f;
        }
        if(next) {
                float difmat[4][4], result[3][3], imat3[3][3];
                
                /* transform next point inside this bone space */
-               VECCOPY(h2, next->pose_tail);
+               if(rest)
+                       VECCOPY(h2, next->bone->arm_tail)
+               else
+                       VECCOPY(h2, next->pose_tail)
                Mat4MulVecfl(imat, h2);
                /* if next bone is B-bone too, use average handle direction */
                if(next->bone->segments>1);
                else h2[1]-= length;
+               Normalize(h2);
                
                /* find the next roll to interpolate as well */
-               Mat4MulMat4(difmat, next->pose_mat, imat);
+               if(rest)
+                       Mat4MulMat4(difmat, next->bone->arm_mat, imat);
+               else
+                       Mat4MulMat4(difmat, next->pose_mat, imat);
                Mat3CpyMat4(result, difmat);                            // the desired rotation at beginning of next bone
                
                vec_roll_to_mat3(h2, 0.0f, mat3);                       // the result of vec_roll without roll
@@ -463,18 +502,16 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan)
                Mat3Inv(imat3, mat3);
                Mat3MulMat3(mat3, imat3, result);                       // the matrix transforming vec_roll to desired roll
                
-               roll= atan2(mat3[2][0], mat3[2][2]);
+               roll2= atan2(mat3[2][0], mat3[2][2]);
                
                /* and only now negate handle */
-               Normalize(h2);
                VecMulf(h2, -hlength2);
-               
        }
        else {
                h2[0]= 0.0f; h2[1]= -hlength2; h2[2]= 0.0f;
-               roll= 0.0;
+               roll2= 0.0;
        }
-       
+
        /* make curve */
        if(bone->segments > MAX_BBONE_SUBDIV)
                bone->segments= MAX_BBONE_SUBDIV;
@@ -482,7 +519,7 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan)
        forward_diff_bezier(0.0, h1[0],         h2[0],                  0.0,            data[0],        MAX_BBONE_SUBDIV, 4);
        forward_diff_bezier(0.0, h1[1],         length + h2[1], length,         data[0]+1,      MAX_BBONE_SUBDIV, 4);
        forward_diff_bezier(0.0, h1[2],         h2[2],                  0.0,            data[0]+2,      MAX_BBONE_SUBDIV, 4);
-       forward_diff_bezier(0.0, 0.390464f*roll, (1.0f-0.390464f)*roll, roll,   data[0]+3,      MAX_BBONE_SUBDIV, 4);
+       forward_diff_bezier(roll1, roll1 + 0.390464f*(roll2-roll1), roll2 - 0.390464f*(roll2-roll1),    roll2,  data[0]+3,      MAX_BBONE_SUBDIV, 4);
        
        equalize_bezier(data[0], bone->segments);       // note: does stride 4!
        
@@ -490,19 +527,20 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan)
        for(a=0, fp= data[0]; a<bone->segments; a++, fp+=4) {
                VecSubf(h1, fp+4, fp);
                vec_roll_to_mat3(h1, fp[3], mat3);              // fp[3] is roll
-               Mat4CpyMat3(bbone_array[a].mat, mat3);
-               VECCOPY(bbone_array[a].mat[3], fp);
+               Mat4CpyMat3(result_array[a].mat, mat3);
+               VECCOPY(result_array[a].mat[3], fp);
        }
        
-       return bbone_array;
+       return result_array;
 }
 
 /* ************ Armature Deform ******************* */
 
-static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion)
+static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion, int rest_def)
 {
        Bone *bone= pchan->bone;
-       Mat4 *b_bone= b_bone_spline_setup(pchan);
+       Mat4 *b_bone= b_bone_spline_setup(pchan, 0);
+       Mat4 *b_bone_rest= (rest_def)? NULL: b_bone_spline_setup(pchan, 1);
        Mat4 *b_bone_mats;
        DualQuat *b_bone_dual_quats= NULL;
        float tmat[4][4];
@@ -529,7 +567,10 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion)
        Mat4One(tmat);
 
        for(a=0; a<bone->segments; a++) {
-               tmat[3][1] = -a*(bone->length/(float)bone->segments);
+               if(b_bone_rest)
+                       Mat4Invert(tmat, b_bone_rest[a].mat);
+               else
+                       tmat[3][1] = -a*(bone->length/(float)bone->segments);
 
                Mat4MulSerie(b_bone_mats[a+1].mat, pchan->chan_mat, bone->arm_mat,
                        b_bone[a].mat, tmat, b_bone_mats[0].mat, NULL, NULL, NULL);
@@ -726,6 +767,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
        float obinv[4][4], premat[4][4], postmat[4][4];
        int use_envelope = deformflag & ARM_DEF_ENVELOPE;
        int use_quaternion = deformflag & ARM_DEF_QUATERNION;
+       int bbone_rest_def = deformflag & ARM_DEF_B_BONE_REST;
        int numGroups = 0;              /* safety for vertexgroup index overflow */
        int i, target_totvert = 0;      /* safety for vertexgroup overflow */
        int use_dverts = 0;
@@ -751,7 +793,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
        for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) {
                if(!(pchan->bone->flag & BONE_NO_DEFORM)) {
                        if(pchan->bone->segments > 1)
-                               pchan_b_bone_defmats(pchan, use_quaternion);
+                               pchan_b_bone_defmats(pchan, use_quaternion, bbone_rest_def);
 
                        if(use_quaternion) {
                                pchan->dual_quat= &dualquats[totchan++];
index 9ee158be531a9783a8515e0954ac64e29c55714f..020350d9e6f1864f6067147c306d9d41ab1c82c4 100644 (file)
@@ -886,7 +886,7 @@ void constraints_clear_evalob (bConstraintOb *cob)
 /* -------------------------------- Constraint Channels ---------------------------- */
 
 /* does IPO's of constraint channels only */
-void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime)
+void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime, int onlydrivers)
 {
        bConstraint *con;
        bConstraintChannel *chan;
@@ -901,13 +901,15 @@ void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime)
                        calc_ipo(chan->ipo, ctime);
                        
                        for (icu=chan->ipo->curve.first; icu; icu=icu->next) {
-                               switch (icu->adrcode) {
-                                       case CO_ENFORCE:
-                                       {
-                                               /* Influence is clamped to 0.0f -> 1.0f range */
-                                               con->enforce = CLAMPIS(icu->curval, 0.0f, 1.0f);
+                               if(!onlydrivers || icu->driver) {
+                                       switch (icu->adrcode) {
+                                               case CO_ENFORCE:
+                                               {
+                                                       /* Influence is clamped to 0.0f -> 1.0f range */
+                                                       con->enforce = CLAMPIS(icu->curval, 0.0f, 1.0f);
+                                               }
+                                                       break;
                                        }
-                                               break;
                                }
                        }
                }
@@ -1688,14 +1690,14 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void *own
                        }
                        
                        /* if the script doesn't set the target matrix for any reason, fall back to standard methods */
-                       if (BPY_pyconstraint_targets(data, mat) < 1) {
-                               if (data->tar) {
-                                       constraint_target_to_mat4(data->tar, data->subtarget, mat, CONSTRAINT_SPACE_WORLD, con->tarspace);
+                       if (data->tar) {
+                               constraint_target_to_mat4(data->tar, data->subtarget, mat, CONSTRAINT_SPACE_WORLD, con->tarspace);
+                               if (BPY_pyconstraint_targets(data, mat) >= 1) {
                                        valid = 1;
                                }
-                               else
-                                       Mat4One(mat);
                        }
+                       if (!valid)
+                               Mat4One(mat);
                }
                break;
        case CONSTRAINT_TYPE_CLAMPTO:
index 7b869f8b0e859b8ec51e56609c60200d30bde2d8..eb651a925e024acdcdfe620b6fde335d9fcb0fbc 100644 (file)
@@ -348,6 +348,7 @@ static void dag_add_driver_relation(Ipo *ipo, DagForest *dag, DagNode *node, int
 static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int mask)
 {
        bConstraint *con;
+       bConstraintChannel *conchan;
        DagNode * node;
        DagNode * node2;
        DagNode * node3;
@@ -401,9 +402,12 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int
        if(key && key->ipo)
                dag_add_driver_relation(key->ipo, dag, node, 1);
        
+       for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next)
+               if(conchan->ipo)
+                       dag_add_driver_relation(conchan->ipo, dag, node, 0);
+
        if(ob->action) {
                bActionChannel *chan;
-               bConstraintChannel *conchan;
                for (chan = ob->action->chanbase.first; chan; chan=chan->next){
                        if(chan->ipo)
                                dag_add_driver_relation(chan->ipo, dag, node, 1);
index c1f097e84470d2a7f556dd34500621b1ab0b0fc7..bb6297361fe67d690d2b5b53c82832e206281995 100644 (file)
@@ -5000,7 +5000,7 @@ static DerivedMesh *booleanModifier_applyModifier(
        /* we do a quick sanity check */
        if(((Mesh *)ob->data)->totface > 3
           && bmd->object && ((Mesh *)bmd->object->data)->totface > 3) {
-               DerivedMesh *result = NewBooleanDerivedMesh(ob, bmd->object,
+               DerivedMesh *result = NewBooleanDerivedMesh(bmd->object, ob,
                                                            1 + bmd->operation);
 
                /* if new mesh returned, return it; otherwise there was
index ba8d047644b1d37ea9bc1bb53159cdb88461268e..20d61456f05b7f3df6f6af3367b2e665d34999cf 100644 (file)
@@ -1542,12 +1542,14 @@ void where_is_object_time(Object *ob, float ctime)
                else 
                        do_all_object_actions(ob);
                
-               /* do constraint ipos ..., note it needs stime */
-               do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime);
+               /* do constraint ipos ..., note it needs stime (0 = all ipos) */
+               do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime, 0);
        }
        else {
                /* but, the drivers have to be done */
                if(ob->ipo) do_ob_ipodrivers(ob, ob->ipo, stime);
+               /* do constraint ipos ..., note it needs stime (1 = only drivers ipos) */
+               do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime, 1);
        }
        
        if(ob->parent) {
index 93bda9ac530fd80e7c9e5ecd3f3139f69db59d3a..c62f59106a317a957554a3b02b3effe5a89daf7f 100644 (file)
@@ -1551,7 +1551,8 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
        GHash *hash;
        GHashIterator *ihash;
        float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], dv1[3],ve[3],avel[3],
-    vv1[3], vv2[3], vv3[3], vv4[3],
+    vv1[3], vv2[3], vv3[3], vv4[3], coledge[3], mindistedge = 1000.0f, 
+       outerforceaccu[3],innerforceaccu[3],
                facedist,n_mag,force_mag_norm,minx,miny,minz,maxx,maxy,maxz,
                innerfacethickness = -0.5f, outerfacethickness = 0.2f,
                ee = 5.0f, ff = 0.1f, fa;
@@ -1560,6 +1561,8 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
        *intrusion = 0.0f;
        hash  = vertexowner->soft->scratch->colliderhash;
        ihash = BLI_ghashIterator_new(hash);
+       outerforceaccu[0]=outerforceaccu[1]=outerforceaccu[2]=0.0f;
+       innerforceaccu[0]=innerforceaccu[1]=innerforceaccu[2]=0.0f;
 /* go */
     while (!BLI_ghashIterator_isDone(ihash) ) {
 
@@ -1675,16 +1678,24 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
                                        Crossf(d_nvect, edge2, edge1);
                                        n_mag = Normalize(d_nvect);
                                        facedist = Inpf(dv1,d_nvect);
+                                       // so rules are
+                                       //
 
                                        if ((facedist > innerfacethickness) && (facedist < outerfacethickness)){                
                                                if (point_in_tri_prism(opco, nv1, nv2, nv3) ){
                                                        force_mag_norm =(float)exp(-ee*facedist);
                                                        if (facedist > outerfacethickness*ff)
                                                                force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
-                                                       Vec3PlusStVec(force,force_mag_norm,d_nvect);
                                                        *damp=ob->pd->pdef_sbdamp;
                                                        if (facedist > 0.0f){
                                                                *damp *= (1.0f - facedist/outerfacethickness);
+                                                               Vec3PlusStVec(outerforceaccu,force_mag_norm,d_nvect);
+                                                               deflected = 3;
+
+                                                       }
+                                                       else {
+                                                               Vec3PlusStVec(innerforceaccu,force_mag_norm,d_nvect);
+                                                               if (deflected < 2) deflected = 2;
                                                        }
                                                        if ((mprevvert) && (*damp > 0.0f)){
                                                                choose_winner(ve,opco,nv1,nv2,nv3,vv1,vv2,vv3);
@@ -1693,7 +1704,6 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
                                                        }
                                                        *intrusion += facedist;
                                                        ci++;
-                                                       deflected = 2;
                                                }
                                        }               
                                        if (mface->v4){ /* quad */
@@ -1711,11 +1721,17 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
                                                                force_mag_norm =(float)exp(-ee*facedist);
                                                                if (facedist > outerfacethickness*ff)
                                                                        force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
-                                                               Vec3PlusStVec(force,force_mag_norm,d_nvect);
                                                                *damp=ob->pd->pdef_sbdamp;
-                                                               if (facedist > 0.0f){
-                                                                       *damp *= (1.0f - facedist/outerfacethickness);
-                                                               }
+                                                       if (facedist > 0.0f){
+                                                               *damp *= (1.0f - facedist/outerfacethickness);
+                                                               Vec3PlusStVec(outerforceaccu,force_mag_norm,d_nvect);
+                                                               deflected = 3;
+
+                                                       }
+                                                       else {
+                                                               Vec3PlusStVec(innerforceaccu,force_mag_norm,d_nvect);
+                                                               if (deflected < 2) deflected = 2;
+                                                       }
 
                                                                if ((mprevvert) && (*damp > 0.0f)){
                                                                        choose_winner(ve,opco,nv1,nv3,nv4,vv1,vv3,vv4);
@@ -1724,9 +1740,61 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
                                                                }
                                                            *intrusion += facedist;
                                                                ci++;
-                                                               deflected = 2;
                                                        }
 
+                                               }
+                                               if ((deflected < 2)&& (G.rt != 444)) // we did not hit a face until now
+                                               { // see if 'outer' hits an edge
+                                                       float dist;
+
+                                                       PclosestVL3Dfl(ve, opco, nv1, nv2);
+                                           VECSUB(ve,opco,ve); 
+                                                       dist = Normalize(ve);
+                                                       if ((dist < outerfacethickness)&&(dist < mindistedge )){
+                                                               VECCOPY(coledge,ve);
+                                                               mindistedge = dist,
+                                                               deflected=1;
+                                                       }
+
+                                                       PclosestVL3Dfl(ve, opco, nv2, nv3);
+                                           VECSUB(ve,opco,ve); 
+                                                       dist = Normalize(ve);
+                                                       if ((dist < outerfacethickness)&&(dist < mindistedge )){
+                                                               VECCOPY(coledge,ve);
+                                                               mindistedge = dist,
+                                                               deflected=1;
+                                                       }
+
+                                                       PclosestVL3Dfl(ve, opco, nv3, nv1);
+                                           VECSUB(ve,opco,ve); 
+                                                       dist = Normalize(ve);
+                                                       if ((dist < outerfacethickness)&&(dist < mindistedge )){
+                                                               VECCOPY(coledge,ve);
+                                                               mindistedge = dist,
+                                                               deflected=1;
+                                                       }
+                                                       if (mface->v4){ /* quad */
+                                                               PclosestVL3Dfl(ve, opco, nv3, nv4);
+                                                               VECSUB(ve,opco,ve); 
+                                                               dist = Normalize(ve);
+                                                               if ((dist < outerfacethickness)&&(dist < mindistedge )){
+                                                                       VECCOPY(coledge,ve);
+                                                                       mindistedge = dist,
+                                                                               deflected=1;
+                                                               }
+
+                                                               PclosestVL3Dfl(ve, opco, nv1, nv4);
+                                                               VECSUB(ve,opco,ve); 
+                                                               dist = Normalize(ve);
+                                                               if ((dist < outerfacethickness)&&(dist < mindistedge )){
+                                                                       VECCOPY(coledge,ve);
+                                                                       mindistedge = dist,
+                                                                               deflected=1;
+                                                               }
+                                                       
+                                                       }
+
+
                                                }
                                        }
                                        mface++;
@@ -1735,6 +1803,25 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
                        } /* if(ob->pd && ob->pd->deflect) */
                        BLI_ghashIterator_step(ihash);
        } /* while () */
+
+       if (deflected == 1){ // no face but 'outer' edge cylinder sees vert
+               force_mag_norm =(float)exp(-ee*mindistedge);
+               if (mindistedge > outerfacethickness*ff)
+                       force_mag_norm =(float)force_mag_norm*fa*(mindistedge - outerfacethickness)*(mindistedge - outerfacethickness);
+               Vec3PlusStVec(force,force_mag_norm,coledge);
+               *damp=ob->pd->pdef_sbdamp;
+               if (mindistedge > 0.0f){
+                       *damp *= (1.0f - mindistedge/outerfacethickness);
+               }
+
+       }
+       if (deflected == 2){ //  face inner detected
+               VECADD(force,force,innerforceaccu);
+       }
+       if (deflected == 3){ //  face outer detected
+               VECADD(force,force,outerforceaccu);
+       }
+
        BLI_ghashIterator_free(ihash);
        if (cavel) VecMulf(avel,1.0f/(float)cavel);
        VECCOPY(vel,avel);
@@ -2313,6 +2400,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
                                VECCOPY(bp->prevvec, bp->vec);
                                VECCOPY(bp->prevdv, dv);
                        }
+
                        if (mode ==2){
                                /* be optimistic and execute step */
                                bp->vec[0] = bp->prevvec[0] + 0.5f * (dv[0] + bp->prevdv[0]);
@@ -2330,10 +2418,9 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
                        /* x(t + dt) = x(t) + v(t) * dt */ 
                        
                        VECCOPY(dx,bp->vec);
-                       dx[0]*=forcetime ; 
-                       dx[1]*=forcetime ; 
-                       dx[2]*=forcetime ; 
-                       
+                       dx[0]*=forcetime; 
+                       dx[1]*=forcetime; 
+                       dx[2]*=forcetime; 
                        /* again some nasty if's to have heun in here too */
                        if (mode ==1){
                                VECCOPY(bp->prevpos,bp->pos);
@@ -2492,6 +2579,7 @@ static void springs_from_mesh(Object *ob)
        Mesh *me= ob->data;
        BodyPoint *bp;
        int a;
+       float scale =1.0f;
        
        sb= ob->soft;   
        if (me && sb)
@@ -2509,9 +2597,13 @@ static void springs_from_mesh(Object *ob)
                        
                }
                /* recalculate spring length for meshes here */
+               /* special hidden feature! shrink to fit */
+               if (G.rt > 500){
+                       scale = (G.rt - 500) / 100.0f;
+               }
                for(a=0; a<sb->totspring; a++) {
                        BodySpring *bs = &sb->bspring[a];
-                       bs->len= VecLenf(sb->bpoint[bs->v1].origS, sb->bpoint[bs->v2].origS);
+                       bs->len= scale*VecLenf(sb->bpoint[bs->v1].origS, sb->bpoint[bs->v2].origS);
                }
        }
 }
@@ -3035,6 +3127,11 @@ SoftBody *sbNew(void)
        sb->balldamp = 0.50f;
        sb->ballstiff= 1.0f;
        sb->sbc_mode = 1;
+
+
+       sb->minloops = 10;
+
+       sb->choke = 3;
        sb_new_scratch(sb);
        return sb;
 }
@@ -3244,9 +3341,12 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
                                        /* do predictive euler step */
                                        softbody_calc_forces(ob, forcetime,timedone/dtime);
                                        softbody_apply_forces(ob, forcetime, 1, NULL);
+
+
                                        /* crop new slope values to do averaged slope step */
                                        softbody_calc_forces(ob, forcetime,timedone/dtime);
                                        softbody_apply_forces(ob, forcetime, 2, &err);
+
                                        softbody_apply_goalsnap(ob);
                                        
                                        if (err > SoftHeunTol) { /* error needs to be scaled to some quantity */
index c3ba4b9e292f43b725f3aad6a6f0a64633f7efda..83bae60df306f09f4b6fb3fd9b66523632172a94 100644 (file)
@@ -6765,6 +6765,21 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
 
+       if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 4)) {
+               bArmature *arm;
+               ModifierData *md;
+               Object *ob;
+
+               for(arm= main->armature.first; arm; arm= arm->id.next)
+                       arm->deformflag |= ARM_DEF_B_BONE_REST;
+
+               for(ob = main->object.first; ob; ob= ob->id.next)
+                       for(md=ob->modifiers.first; md; md=md->next)
+                               if(md->type==eModifierType_Armature)
+                                       ((ArmatureModifierData*)md)->deformflag |= ARM_DEF_B_BONE_REST;
+       }
+
+
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
 
index e56fb5a776d2ecd2e79c8d0e427ddce058781a13..2ca21e548c470f9f6be9c74426c6ec32659b4019 100644 (file)
@@ -524,6 +524,7 @@ extern float rgb_to_bw[4][4];
  *
  * @attention Defined in rotate.c
  */
+void IMB_flipx(struct ImBuf *ibuf);
 void IMB_flipy(struct ImBuf * ibuf);
 
 /**
index fde1bceac0de5781c5e58fdedc7031ed0982d6ba..1f710360c3cdaf0d4efa87aa0572d5b2172f673b 100644 (file)
@@ -144,24 +144,24 @@ struct AlphaBlockDXT5
 {
        union {
                struct {
-                       unsigned long long alpha0 : 8;  // 8
-                       unsigned long long alpha1 : 8;  // 16
-                       unsigned long long bits0 : 3;   // 3 - 19
-                       unsigned long long bits1 : 3;   // 6 - 22
-                       unsigned long long bits2 : 3;   // 9 - 25
-                       unsigned long long bits3 : 3;   // 12 - 28
-                       unsigned long long bits4 : 3;   // 15 - 31
-                       unsigned long long bits5 : 3;   // 18 - 34
-                       unsigned long long bits6 : 3;   // 21 - 37
-                       unsigned long long bits7 : 3;   // 24 - 40
-                       unsigned long long bits8 : 3;   // 27 - 43
-                       unsigned long long bits9 : 3;   // 30 - 46
-                       unsigned long long bitsA : 3;   // 33 - 49
-                       unsigned long long bitsB : 3;   // 36 - 52
-                       unsigned long long bitsC : 3;   // 39 - 55
-                       unsigned long long bitsD : 3;   // 42 - 58
-                       unsigned long long bitsE : 3;   // 45 - 61
-                       unsigned long long bitsF : 3;   // 48 - 64
+                       unsigned int alpha0 : 8;        // 8
+                       unsigned int alpha1 : 8;        // 16
+                       unsigned int bits0 : 3;         // 3 - 19
+                       unsigned int bits1 : 3;         // 6 - 22
+                       unsigned int bits2 : 3;         // 9 - 25
+                       unsigned int bits3 : 3;         // 12 - 28
+                       unsigned int bits4 : 3;         // 15 - 31
+                       unsigned int bits5 : 3;         // 18 - 34
+                       unsigned int bits6 : 3;         // 21 - 37
+                       unsigned int bits7 : 3;         // 24 - 40
+                       unsigned int bits8 : 3;         // 27 - 43
+                       unsigned int bits9 : 3;         // 30 - 46
+                       unsigned int bitsA : 3;         // 33 - 49
+                       unsigned int bitsB : 3;         // 36 - 52
+                       unsigned int bitsC : 3;         // 39 - 55
+                       unsigned int bitsD : 3;         // 42 - 58
+                       unsigned int bitsE : 3;         // 45 - 61
+                       unsigned int bitsF : 3;         // 48 - 64
                };
                unsigned long long u;
        };
index 6937840334d1cc7a86387303806bcd446342689f..c28f8b5b72d33155945d42e51b9b906539b5fbec 100644 (file)
@@ -434,16 +434,15 @@ bool DirectDrawSurface::isSupported() const
                        return false;
                }
        }
-       /*
        else if (header.pf.flags & DDPF_RGB)
        {
                if (header.pf.bitcount == 24)
                {
-                       return false;
+                       return true;
                }
                else if (header.pf.bitcount == 32)
                {
-                       return false;
+                       return true;
                }
                else
                {
@@ -451,7 +450,6 @@ bool DirectDrawSurface::isSupported() const
                        return false;
                }
        }
-       */
        else
        {
                return false;
@@ -500,8 +498,18 @@ unsigned int DirectDrawSurface::depth() const
 
 bool DirectDrawSurface::hasAlpha() const
 {
-       if (header.pf.fourcc == FOURCC_DXT1) return false;
-       else return true;
+       if ((header.pf.flags & DDPF_RGB) && (header.pf.amask == 0))
+       {
+               return false;
+       }
+       else if (header.pf.fourcc == FOURCC_DXT1)
+       {
+               return false;
+       }
+       else
+       {
+               return true;
+       }
 }
 
 bool DirectDrawSurface::isTexture2D() const
@@ -545,10 +553,98 @@ void DirectDrawSurface::mipmap(Image * img, unsigned int face, unsigned int mipm
        }
 }
 
+/* helper function for readLinearImage */
+void maskShiftAndSize(unsigned int mask, unsigned int * shift, unsigned int * size)
+{
+       if (!mask)
+       {
+               *shift = 0;
+               *size = 0;
+               return;
+       }
+
+       *shift = 0;
+       while((mask & 1) == 0) {
+               ++(*shift);
+               mask >>= 1;
+       }
+       
+       *size = 0;
+       while((mask & 1) == 1) {
+               ++(*size);
+               mask >>= 1;
+       }
+}
+
+/* helper function for readLinearImage */
+unsigned int convert(unsigned int c, unsigned int inbits, unsigned int outbits)
+{
+       if (inbits == 0) {
+               return 0;
+       }
+       else if (inbits == outbits)
+       {
+               return c;
+       }
+       else if (inbits > outbits) 
+       {
+               // truncate
+               return c >> (inbits - outbits);
+       }
+       else
+       {
+               // bitexpand
+               return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits);
+       }
+}
+
 void DirectDrawSurface::readLinearImage(Image * img)
 {
-       // @@ Read linear RGB images.
-       printf("DDS: linear RGB images not supported\n");
+       const unsigned int w = img->width();
+       const unsigned int h = img->height();
+
+       unsigned int rshift, rsize;
+       maskShiftAndSize(header.pf.rmask, &rshift, &rsize);
+       
+       unsigned int gshift, gsize;
+       maskShiftAndSize(header.pf.gmask, &gshift, &gsize);
+       
+       unsigned int bshift, bsize;
+       maskShiftAndSize(header.pf.bmask, &bshift, &bsize);
+       
+       unsigned int ashift, asize;
+       maskShiftAndSize(header.pf.amask, &ashift, &asize);
+
+       unsigned int byteCount = (header.pf.bitcount + 7) / 8;
+       if (byteCount > 4)
+       {
+               /* just in case... we could have segfaults later on if byteCount > 4 */
+               printf("DDS: bitcount too large (file corrupt?)");
+               return;
+       }
+
+       if (header.pf.amask != 0)
+       {
+               img->setFormat(Image::Format_ARGB);
+       }
+
+       // Read linear RGB images.
+       for (unsigned int y = 0; y < h; y++)
+       {
+               for (unsigned int x = 0; x < w; x++)
+               {
+                       unsigned int c = 0;
+                       mem_read(stream, (unsigned char *)(&c), byteCount);
+
+                       Color32 pixel(0, 0, 0, 0xFF);
+                       pixel.r = convert(c >> rshift, rsize, 8);
+                       pixel.g = convert(c >> gshift, gsize, 8);
+                       pixel.b = convert(c >> bshift, bsize, 8);
+                       pixel.a = convert(c >> ashift, asize, 8);
+
+                       img->pixel(x, y) = pixel;
+               }
+       }
 }
 
 void DirectDrawSurface::readBlockImage(Image * img)
index a181ec74476e0bcc03cadd078b617cb6e3d9df5d..2340598b4fab6e99d7dce819673107f9ca5e29d6 100644 (file)
@@ -86,3 +86,14 @@ unsigned int mem_read(Stream & mem, unsigned char & i)
        return(1);
 }
 
+unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt)
+{
+       if (mem.pos + cnt > mem.size) {
+               printf("DDS: trying to read beyond end of stream (corrupt file?)");
+               return(0);
+       };
+       memcpy(i, mem.mem + mem.pos, cnt);
+       mem.pos += cnt;
+       return(cnt);
+}
+
index 1e7d3c6b5366d6ee742108d8e0f515fca19b332c..373e68db44e7d30185a4278d9d4ced684d1fbee0 100644 (file)
@@ -43,6 +43,7 @@ unsigned int mem_read(Stream & mem, unsigned long long & i);
 unsigned int mem_read(Stream & mem, unsigned int & i);
 unsigned int mem_read(Stream & mem, unsigned short & i);
 unsigned int mem_read(Stream & mem, unsigned char & i);
+unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt);
 
 #endif // _STREAM_H
 
index 0e06fd3e50b64dcdb1aef103f90281733212c77e..3de30b9f1830786858732a9e3abdbcd5361770c0 100644 (file)
@@ -28,8 +28,8 @@
 #include <dds_api.h>
 #include <Stream.h>
 #include <DirectDrawSurface.h>
-
 #include <stdio.h> // printf
+#include <fstream>
 
 extern "C" {
 
@@ -39,12 +39,24 @@ extern "C" {
 #include "IMB_imbuf.h"
 #include "IMB_allocimbuf.h"
 
-/* not supported yet
+
 short imb_save_dds(struct ImBuf * ibuf, char *name, int flags)
 {
-       return(0);
+       return(0); /* todo: finish this function */
+
+       /* check image buffer */
+       if (ibuf == 0) return (0);
+       if (ibuf->rect == 0) return (0);
+
+       /* open file for writing */
+       std::ofstream fildes(name);
+
+       /* write header */
+       fildes << "DDS ";
+       fildes.close();
+
+       return(1);
 }
-*/
 
 int imb_is_a_dds(unsigned char *mem) // note: use at most first 32 bytes
 {
@@ -60,7 +72,7 @@ struct ImBuf *imb_load_dds(unsigned char *mem, int size, int flags)
 {
        struct ImBuf * ibuf = 0;
        DirectDrawSurface dds(mem, size); /* reads header */
-       unsigned char bytes_per_pixel;
+       unsigned char bits_per_pixel;
        unsigned int *rect;
        Image img;
        unsigned int numpixels = 0;
@@ -85,9 +97,9 @@ struct ImBuf *imb_load_dds(unsigned char *mem, int size, int flags)
        }
 
        /* convert DDS into ImBuf */
-       if (dds.hasAlpha()) bytes_per_pixel = 32;
-       else bytes_per_pixel = 24;
-       ibuf = IMB_allocImBuf(dds.width(), dds.height(), bytes_per_pixel, 0, 0); 
+       if (dds.hasAlpha()) bits_per_pixel = 32;
+       else bits_per_pixel = 24;
+       ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0, 0); 
        if (ibuf == 0) return(0); /* memory allocation failed */
 
        ibuf->ftype = DDS;
@@ -107,7 +119,7 @@ struct ImBuf *imb_load_dds(unsigned char *mem, int size, int flags)
                        cp[0] = pixel.r; /* set R component of col */
                        cp[1] = pixel.g; /* set G component of col */
                        cp[2] = pixel.b; /* set B component of col */
-                       if (bytes_per_pixel == 32)
+                       if (bits_per_pixel == 32)
                                cp[3] = pixel.a; /* set A component of col */
                        rect[i] = col;
                }
index 13edfbf0a33ab0c9d1659a295b0986ff66a52475..42b30d6284f2b53c8f5b803a1cbc097144d206d6 100644 (file)
@@ -86,3 +86,35 @@ void IMB_flipy(struct ImBuf * ibuf)
        MEM_freeN(line);
        if(linef) MEM_freeN(linef);
 }
+
+void IMB_flipx(struct ImBuf * ibuf)
+{
+       short x, y, xr, xl, yi;
+       unsigned int px;
+       float px_f[4];
+       
+       if (ibuf == NULL) return;
+
+       x = ibuf->x;
+       y = ibuf->y;
+
+       if (ibuf->rect) {
+               for(yi=y-1;yi>=0;yi--) {
+                       for(xr=x-1, xl=0; xr>=xl; xr--, xl++) {
+                               px = ibuf->rect[(x*yi)+xr];
+                               ibuf->rect[(x*yi)+xr] = ibuf->rect[(x*yi)+xl];
+                               ibuf->rect[(x*yi)+xl] = px;             
+                       }
+               }
+       }
+       
+       if (ibuf->rect_float) {
+               for(yi=y-1;yi>=0;yi--) {
+                       for(xr=x-1, xl=0; xr>=xl; xr--, xl++) {
+                               memcpy(&px_f, &ibuf->rect_float[((x*yi)+xr)*4], 4*sizeof(float));
+                               memcpy(&ibuf->rect_float[((x*yi)+xr)*4], &ibuf->rect_float[((x*yi)+xl)*4], 4*sizeof(float));
+                               memcpy(&ibuf->rect_float[((x*yi)+xl)*4], &px_f, 4*sizeof(float));
+                       }
+               }
+       }
+}
index 7ad3fd480a3b4c4bf9c6a9f6d37e98754015d861..42d581ee758aeac0c2ec66de90105ac55515e839 100644 (file)
@@ -206,7 +206,7 @@ extern short sharesFace(struct EditEdge* e1, struct EditEdge* e2);
 #define SUBDIV_SELECT_LOOPCUT 3
 
 extern void convert_to_triface(int direction);
-extern int removedoublesflag(short flag, float limit);
+extern int removedoublesflag(short flag, short automerge, float limit);
 extern void xsortvert_flag(int flag);
 extern void hashvert_flag(int flag);
 
index c9d4bf6ab061695736b10afbc72ea8970d61d243..54c57e3331dfb1070a0ab8107d63b9711581423a 100644 (file)
@@ -48,11 +48,14 @@ void                                clear_last_seq();
 void                           del_seq(void);
 void                           enter_meta(void);
 void                           exit_meta(void);
-struct Sequence*       find_neighboring_sequence(struct Sequence *test, int lr);
+struct Sequence*       find_neighboring_sequence(struct Sequence *test, int lr, int sel);
+struct Sequence*       find_next_prev_sequence(struct Sequence *test, int lr, int sel);
 struct Sequence*       find_nearest_seq(int *hand);
 int                                    insert_gap(int gap, int cfra);
 void                           make_meta(void);
 void                           select_channel_direction(struct Sequence *test,int lr);
+void                           select_more_seq(void);
+void                           select_less_seq(void);
 void                           mouse_select_seq(void);
 void                           no_gaps(void);
 void                           seq_snap(short event);
@@ -62,15 +65,67 @@ void                                swap_select_seq(void);
 void                           touch_seq_files(void);
 void                           seq_remap_paths(void);
 void                           transform_seq(int mode, int context);
+void                           transform_seq_nomarker(int mode, int context);
 void                           un_meta(void);
 void                           seq_cut(int cutframe);
+void                           seq_separate_images(void);
 void                           reassign_inputs_seq_effect(void);
 void                           select_surrounding_handles(struct Sequence *test);
 void                           select_surround_from_last();
 void                           select_dir_from_last(int lr);
 void                           select_neighbor_from_last(int lr);
+void                           select_linked_seq(int mode);
 struct Sequence*       alloc_sequence(ListBase *lb, int cfra, int machine); /*used from python*/
+int                            check_single_image_seq(struct Sequence *seq);
 
+/* sequence transform functions, for internal used */
+int seq_tx_get_start(struct Sequence *seq);
+int seq_tx_get_end(struct Sequence *seq);
+
+int seq_tx_get_final_left(struct Sequence *seq);
+int seq_tx_get_final_right(struct Sequence *seq);
+
+void seq_tx_set_final_left(struct Sequence *seq, int i);
+void seq_tx_set_final_right(struct Sequence *seq, int i);
+
+/* check if one side can be transformed */
+int seq_tx_check_left(struct Sequence *seq);
+int seq_tx_check_right(struct Sequence *seq);
+
+#define SEQ_DEBUG_INFO(seq) printf("seq into '%s' -- len:%i  start:%i  startstill:%i  endstill:%i  startofs:%i  endofs:%i\n",\
+                   seq->name, seq->len, seq->start, seq->startstill, seq->endstill, seq->startofs, seq->endofs)
+
+/* seq macro's for transform
+ notice the difference between start/end and left/right.
+ left and right are the bounds at which the setuence is rendered,
+start and end are from the start and fixed length of the sequence.
+*/
+/*
+#define SEQ_GET_START(seq)     (seq->start)
+#define SEQ_GET_END(seq)       (seq->start+seq->len)
+
+#define SEQ_GET_FINAL_LEFT(seq)                ((seq->start - seq->startstill) + seq->startofs)
+#define SEQ_GET_FINAL_RIGHT(seq)       (((seq->start+seq->len) + seq->endstill) - seq->endofs)
+
+#define SEQ_SET_FINAL_LEFT(seq, val) \
+       if (val < (seq)->start) { \
+               (seq)->startstill = abs(val - (seq)->start); \
+               (seq)->startofs = 0; \
+} else { \
+               (seq)->startofs = abs(val - (seq)->start); \
+               (seq)->startstill = 0; \
+}
+
+#define SEQ_SET_FINAL_RIGHT(seq, val) \
+       if (val > (seq)->start + (seq)->len) { \
+               (seq)->endstill = abs(val - ((seq)->start + (seq)->len)); \
+               (seq)->endofs = 0; \
+} else { \
+               (seq)->endofs = abs(val - ((seq)->start + (seq)->len)); \
+               (seq)->endstill = 0; \
+}
+*/
 /* drawseq.c */
 void do_seqbuttons(short);
 
index a515a01061aa85fe40c1df54bd653347b6cbc07f..a8a5c16df1a59e7dea4cb099c1f6416026093134 100644 (file)
@@ -96,6 +96,7 @@ void reveal_tface_uv(void);
 void stitch_limit_uv_tface(void);
 void stitch_vert_uv_tface(void);
 void unlink_selection(void);
+void uvface_setsel__internal(short select);
 void select_linked_tface_uv(int mode);
 void pin_tface_uv(int mode);
 void weld_align_menu_tface_uv(void);
index 47a09e154dfd7c9259c877effcc3857390ff1c1e..ff79d417537ac6f624528a1b3f13cb4e1806cba2 100644 (file)
@@ -51,6 +51,7 @@ void free_sequence(struct Sequence *seq);
 void build_seqar(struct ListBase *seqbase, struct Sequence  ***seqar, int *totseq);
 void free_editing(struct Editing *ed);
 void calc_sequence(struct Sequence *seq);
+void calc_sequence_disp(struct Sequence *seq);
 void sort_seq(void);
 void clear_scene_in_allseqs(struct Scene *sce);
 
index 459101f592daec0cd6b79cb38624c3411fd05ca2..c7f235bccbd3d4333c41c8ca74505dd540b09ffd 100644 (file)
@@ -54,7 +54,7 @@ int find_nearest_marker_time(float dx);
 void add_marker_to_cfra_elem(struct ListBase *lb, struct TimeMarker *marker, short only_sel);
 void make_marker_cfra_list(struct ListBase *lb, short only_sel);
 
-void draw_markers_timespace(void);
+void draw_markers_timespace(int lines);
 
 /* ******** Animation - Preview Range ************* */
 void anim_previewrange_set(void);
index 91f360338e91af7d8ce91a7d155359faab3fab35..4e27f9f1a813aa17c72d87175123918004be45aa 100644 (file)
@@ -76,6 +76,7 @@ void sdrawbox(short x1, short y1, short x2, short y2);
 void calctrackballvecfirst(struct rcti *area, short *mval, float *vec);
 void calctrackballvec(struct rcti *area, short *mval, float *vec);
 void viewmove(int mode);
+void view_zoom_mouseloc(float dfac, short *mouseloc);
 
 int get_view3d_viewplane(int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize);
 void setwinmatrixview3d(int winx, int winy, struct rctf *rect);
index ba96dff5aca71b5599a20a39e972c55d64573c24..1b2d91e22b80a156f0cc24183401a372efbbcc05 100644 (file)
@@ -90,6 +90,7 @@ extern int convex(float *v1, float *v2, float *v3, float *v4);
 
 /* ******************* editmesh_mods.c */
 extern EditEdge *findnearestedge(int *dist);
+extern void EM_automerge(int update);
 
 /**
  * findnearestvert
index 113b281a017f0f61709e03e87a66e59a198511ad..02e7404584b6c20867d782349285b731e0ccc756 100644 (file)
 #define REDRAWANIM                     0x4037
 #define REDRAWNODE                     0x4038
 #define RECALC_COMPOSITE       0x4039
+#define REDRAWMARKER           0x4040 /* all views that display markers */
+
 
 #endif /* !__MYDEVICE_H__ */
 
index 31a95363802b5323f8aef127180d42626796e346..1fc50f4eec464a913f959122ac6dcaab462d9f69 100644 (file)
@@ -114,6 +114,7 @@ typedef struct bArmature {
 #define                ARM_DEF_VGROUP          1
 #define                ARM_DEF_ENVELOPE        2
 #define                ARM_DEF_QUATERNION      4
+#define                ARM_DEF_B_BONE_REST     8
 
 /* armature->pathflag */
 #define                ARM_PATH_FNUMS  0x001
index 51ec3a9e1335029e9cd719cb61865e75eec135d6..2ba5ef5437c5c0b2d9cdefc9a5280ad69c33cde6 100644 (file)
@@ -418,8 +418,10 @@ typedef struct Scene {
        float editbutsize;                      /* size of normals */
        short selectmode;
        short proportional, prop_mode;
+       short automerge, pad5, pad6, pad7;
        
        short use_nodes;
+       
        struct bNodeTree *nodetree;     
        
        void *ed;                                                               /* sequence editor data is allocated here */
index 5db102e9868ccaafdde2a6542842584d5084688a..bd6976f1414339be3602f60f7249d21ff60c86df 100644 (file)
@@ -88,21 +88,23 @@ typedef struct PluginSeq {
 
 typedef struct Sequence {
 
-       struct Sequence *next, *prev, *newseq;
-       void *lib;
-       char name[24];
+       struct Sequence *next, *prev;
+       void *tmp; /* tmp var for copying, and tagging for linked selection */
+       void *lib; /* needed (to be like ipo), else it will raise libdata warnings, this should never be used */
+       char name[24]; /* name, not set by default and dosnt need to be unique as with ID's */
 
        short flag, type;       /*flags bitmap (see below) and the type of sequence*/
-       int len;
+       int len; /* the length of the contense of this strip - before handles are applied */
        int start, startofs, endofs;
        int startstill, endstill;
-       int machine, depth;
+       int machine, depth; /*machine - the strip channel, depth - the depth in the sequence when dealing with metastrips */
        int startdisp, enddisp; /*starting and ending points in the sequence*/
        float mul, handsize;
-       int sfra;               /* starting frame according to the timeline of the scene */
+                                       /* is sfra needed anymore? - it looks like its only used in one place */
+       int sfra;               /* starting frame according to the timeline of the scene. */
 
        Strip *strip;
-       StripElem *curelem;
+       StripElem *curelem;     /* reference the current frame - value from give_stripelem */
 
        struct Ipo *ipo;
        struct Scene *scene;
@@ -114,8 +116,7 @@ typedef struct Sequence {
        /* pointers for effects: */
        struct Sequence *seq1, *seq2, *seq3;
 
-       /* meta */
-       ListBase seqbase;
+       ListBase seqbase;       /* list of strips for metastrips */
 
        struct bSound *sound;   /* the linked "bSound" object */
         struct hdaudio *hdaudio; /* external hdaudio object */
@@ -205,6 +206,8 @@ typedef struct SpeedControlVars {
 #define SEQ_IPO_FRAME_LOCKED   256
 #define SEQ_EFFECT_NOT_LOADED  512
 #define SEQ_FLAG_DELETE                        1024
+#define SEQ_FLIPX                              2048
+#define SEQ_FLIPY                              4096
 
 /* seq->type WATCH IT: SEQ_EFFECT BIT is used to determine if this is an effect strip!!! */
 #define SEQ_IMAGE              0
index 13e35c3c1d5fdf8f897af5b1bda9c9ab4e6af5c5..10f488c9f612347b921301996ed8f013eaccf9aa 100644 (file)
@@ -621,6 +621,7 @@ typedef struct SpaceImaSel {
 
 /* sseq->flag */
 #define SEQ_DRAWFRAMES  1
+#define SEQ_MARKER_TRANS 2
 
 /* space types, moved from DNA_screen_types.h */
 enum {
index 7aa4dbdcf788138feed1b045ad2bfe08364400e1..b4436dc69b2fa1e1305d352087ce7b62708c9eaf 100644 (file)
@@ -189,23 +189,23 @@ extern UserDef U; /* from usiblender.c !!!! */
 /* ***************** USERDEF ****************** */
 
 /* flag */
-#define USER_AUTOSAVE                  1
-#define USER_AUTOGRABGRID              2
-#define USER_AUTOROTGRID               4
-#define USER_AUTOSIZEGRID              8
-#define USER_SCENEGLOBAL               16
-#define USER_TRACKBALL                 32
-#define USER_DUPLILINK                 64
-#define USER_FSCOLLUM                  128
-#define USER_MAT_ON_OB                 256
-#define USER_NO_CAPSLOCK               512
-#define USER_VIEWMOVE                  1024
-#define USER_TOOLTIPS                  2048
-#define USER_TWOBUTTONMOUSE            4096
-#define USER_NONUMPAD                  8192
-#define USER_LMOUSESELECT              16384
-#define USER_FILECOMPRESS              32768
-#define USER_SAVE_PREVIEWS             65536
+#define USER_AUTOSAVE                  (1 << 0)
+#define USER_AUTOGRABGRID              (1 << 1)
+#define USER_AUTOROTGRID               (1 << 2)
+#define USER_AUTOSIZEGRID              (1 << 3)
+#define USER_SCENEGLOBAL               (1 << 4)
+#define USER_TRACKBALL                 (1 << 5)
+#define USER_DUPLILINK                 (1 << 6)
+#define USER_FSCOLLUM                  (1 << 7)
+#define USER_MAT_ON_OB                 (1 << 8)
+#define USER_NO_CAPSLOCK               (1 << 9)
+#define USER_VIEWMOVE                  (1 << 10)
+#define USER_TOOLTIPS                  (1 << 11)
+#define USER_TWOBUTTONMOUSE            (1 << 12)
+#define USER_NONUMPAD                  (1 << 13)
+#define USER_LMOUSESELECT              (1 << 14)
+#define USER_FILECOMPRESS              (1 << 15)
+#define USER_SAVE_PREVIEWS             (1 << 16)
 
 /* viewzom */
 #define USER_ZOOM_CONT                 0
@@ -214,51 +214,52 @@ extern UserDef U; /* from usiblender.c !!!! */
 
 /* uiflag */
 
-#define        USER_KEYINSERTACT               1
-#define        USER_KEYINSERTOBJ               2
-#define USER_WHEELZOOMDIR              4
-#define USER_FILTERFILEEXTS            8
-#define USER_DRAWVIEWINFO              16
-#define USER_PLAINMENUS                        32              // old EVTTOCONSOLE print ghost events, here for tuhopuu compat. --phase
+#define        USER_KEYINSERTACT               (1 << 0)
+#define        USER_KEYINSERTOBJ               (1 << 1)
+#define USER_WHEELZOOMDIR              (1 << 2)
+#define USER_FILTERFILEEXTS            (1 << 3)
+#define USER_DRAWVIEWINFO              (1 << 4)
+#define USER_PLAINMENUS                        (1 << 5)                // old EVTTOCONSOLE print ghost events, here for tuhopuu compat. --phase
                                                                // old flag for hide pulldown was here 
-#define USER_FLIPFULLSCREEN            128
-#define USER_ALLWINCODECS              256
-#define USER_MENUOPENAUTO              512
-#define USER_PANELPINNED               1024
-#define USER_AUTOPERSP                 2048
-#define USER_LOCKAROUND        4096
-#define USER_GLOBALUNDO        8192
-#define USER_ORBIT_SELECTION   16384
-#define USER_KEYINSERTAVAI             32768
-#define USER_HIDE_DOT                  65536
-#define USER_SHOW_ROTVIEWICON  131072
-#define USER_SHOW_VIEWPORTNAME 262144
-#define USER_KEYINSERTNEED             524288
+#define USER_FLIPFULLSCREEN            (1 << 7)
+#define USER_ALLWINCODECS              (1 << 8)
+#define USER_MENUOPENAUTO              (1 << 9)
+#define USER_PANELPINNED               (1 << 10)
+#define USER_AUTOPERSP                 (1 << 11)
+#define USER_LOCKAROUND        (1 << 12)
+#define USER_GLOBALUNDO        (1 << 13)
+#define USER_ORBIT_SELECTION   (1 << 14)
+#define USER_KEYINSERTAVAI             (1 << 15)
+#define USER_HIDE_DOT                  (1 << 16)
+#define USER_SHOW_ROTVIEWICON  (1 << 17)
+#define USER_SHOW_VIEWPORTNAME (1 << 18)
+#define USER_KEYINSERTNEED             (1 << 19)
+#define USER_ZOOM_TO_MOUSEPOS  (1 << 20)
 
 /* transopts */
 
-#define        USER_TR_TOOLTIPS                1
-#define        USER_TR_BUTTONS                 2
-#define USER_TR_MENUS                  4
-#define USER_TR_FILESELECT             8
-#define USER_TR_TEXTEDIT               16
-#define USER_DOTRANSLATE               32
-#define USER_USETEXTUREFONT            64
-#define CONVERT_TO_UTF8                        128
+#define        USER_TR_TOOLTIPS                (1 << 0)
+#define        USER_TR_BUTTONS                 (1 << 1)
+#define USER_TR_MENUS                  (1 << 2)
+#define USER_TR_FILESELECT             (1 << 3)
+#define USER_TR_TEXTEDIT               (1 << 4)
+#define USER_DOTRANSLATE               (1 << 5)
+#define USER_USETEXTUREFONT            (1 << 6)
+#define CONVERT_TO_UTF8                        (1 << 7)
 
 /* dupflag */
 
-#define USER_DUP_MESH                  1
-#define USER_DUP_CURVE                 2
-#define USER_DUP_SURF                  4
-#define USER_DUP_FONT                  8
-#define USER_DUP_MBALL                 16
-#define USER_DUP_LAMP                  32
-#define USER_DUP_IPO                   64
-#define USER_DUP_MAT                   128
-#define USER_DUP_TEX                   256
-#define        USER_DUP_ARM                    512
-#define        USER_DUP_ACT                    1024
+#define USER_DUP_MESH                  (1 << 0)
+#define USER_DUP_CURVE                 (1 << 1)
+#define USER_DUP_SURF                  (1 << 2)
+#define USER_DUP_FONT                  (1 << 3)
+#define USER_DUP_MBALL                 (1 << 4)
+#define USER_DUP_LAMP                  (1 << 5)
+#define USER_DUP_IPO                   (1 << 6)
+#define USER_DUP_MAT                   (1 << 7)
+#define USER_DUP_TEX                   (1 << 8)
+#define        USER_DUP_ARM                    (1 << 9)
+#define        USER_DUP_ACT                    (1 << 10)
 
 /* gameflags */
 
index 28593f740be25804d7d139057cf50700471585b5..9fbd1d9a2049f5dc593536880fbe480187faf87b 100644 (file)
@@ -1461,7 +1461,7 @@ int BPY_pyconstraint_targets(bPythonConstraint *con, float targetmat[][4])
        
        /* try to find USE_TARGET global constant */
        gval = PyDict_GetItemString(globals, "USE_TARGET");
-       if (!gval) {
+       if (!gval || PyObject_IsTrue(gval) != 1) {
                ReleaseGlobalDictionary( globals );
        
                /* free temp objects */
@@ -1627,6 +1627,7 @@ void BPY_pyconstraint_settings(void *arg1, void *arg2)
                
                /* free temp objects */
                Py_XDECREF( idprop );
+               Py_DECREF( retval );
                return;
        }
 }
index b18b71b39fa61c86a7765a476055ddbd37b859f2..56cc8c63b5f244e1162601481dc3d30b295ce3ca 100644 (file)
@@ -618,10 +618,12 @@ BGL_Wrap(2, PolygonMode,      void,     (GLenum, GLenum))
 BGL_Wrap(2, PolygonOffset,    void,     (GLfloat, GLfloat))
 BGL_Wrap(1, PolygonStipple,   void,     (GLubyteP))
 BGL_Wrap(1, PopAttrib,        void,     (void))
+BGL_Wrap(1, PopClientAttrib,  void,     (void))
 BGL_Wrap(1, PopMatrix,        void,     (void))
 BGL_Wrap(1, PopName,          void,     (void))
 BGL_Wrap(3, PrioritizeTextures,   void,   (GLsizei, GLuintP, GLclampfP))
 BGL_Wrap(1, PushAttrib,       void,     (GLbitfield))
+BGL_Wrap(1, PushClientAttrib, void,     (GLbitfield))
 BGL_Wrap(1, PushMatrix,       void,     (void))
 BGL_Wrap(1, PushName,         void,     (GLuint))
 BGL_Wrap(2, RasterPos2d,      void,     (GLdouble, GLdouble))
@@ -951,10 +953,12 @@ static struct PyMethodDef BGL_methods[] = {
        MethodDef(PolygonOffset),
        MethodDef(PolygonStipple),
        MethodDef(PopAttrib),
+       MethodDef(PopClientAttrib),
        MethodDef(PopMatrix),
        MethodDef(PopName),
        MethodDef(PrioritizeTextures), 
        MethodDef(PushAttrib),
+       MethodDef(PushClientAttrib),
        MethodDef(PushMatrix),
        MethodDef(PushName),
        MethodDef(RasterPos2d),
index 659ecd79d8186cf30f8d31260a9c97fd434b1bbe..494a1250728b0750852793d29bc4eced1b3f154d 100644 (file)
@@ -3526,7 +3526,7 @@ static PyObject *MEdgeSeq_collapse( BPy_MEdgeSeq * self, PyObject *args )
        basact = BASACT;
        BASACT = base;
        
-       removedoublesflag( 1, 0.0 );
+       removedoublesflag( 1, 0, 0.0 );
        /* make mesh's object active, enter mesh edit mode */
        G.obedit = object;
        
@@ -7214,7 +7214,7 @@ static PyObject *Mesh_Tools( BPy_Mesh * self, int type, void **args )
                esubdivideflag( 1, 0.0, *((int *)args[0]), 1, 0 );
                break;
        case MESH_TOOL_REMDOUB:
-               result = removedoublesflag( 1, *((float *)args[0]) );
+               result = removedoublesflag( 1, 0, *((float *)args[0]) );
 
                attr = PyInt_FromLong( result );
                if( !attr )
index 26bbfe0def6023dd855623b2251063ba1372f8f3..661042f341b8054380bcdaa7a018639006a5613a 100644 (file)
@@ -1213,6 +1213,12 @@ def glPopAttrib():
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushattrib.html}
   """
 
+def glPopClientAttrib():
+  """
+  Pop the client attribute stack
+  @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushclientattrib.html}
+  """
+
 def glPopMatrix():
   """
   Pop the current matrix stack
@@ -1248,6 +1254,15 @@ def glPushAttrib(mask):
   @param mask: Specifies a mask that indicates which attributes to save.
   """
 
+def glPushClientAttrib(mask):
+  """
+  Push the client attribute stack
+  @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushclientattrib.html}
+
+  @type mask: Enumerated constant(s)
+  @param mask: Specifies a mask that indicates which attributes to save.
+  """
+
 def glPushMatrix():
   """
   Push the current matrix stack
index 1cc4c8a2e15781a0bf659c752458749bb556a7be..9d3d4eb55082dc6cc8522f99b80e4f8c2a4c4068 100644 (file)
@@ -587,23 +587,7 @@ static PyObject *getIntAttr( BPy_Sequence *self, void *type )
 /* internal functions for recursivly updating metastrip locatons */
 static void intern_pos_update(Sequence * seq) {
        /* update startdisp and enddisp */
-       if(seq->startofs && seq->startstill) seq->startstill= 0;
-       if(seq->endofs && seq->endstill) seq->endstill= 0;
-
-       seq->startdisp= seq->start + seq->startofs - seq->startstill;
-       seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
-
-       seq->handsize= 10.0;    /* 10 frames */
-       if( seq->enddisp-seq->startdisp < 20 ) {
-               seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
-       }
-       else if(seq->enddisp-seq->startdisp > 250) {
-               seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
-       }
-       
-       /* original Cambo code; replaced with c&p from function in blenkernel/sequence.c 
-       seq->startdisp = seq->start + seq->startofs - seq->startstill;
-       seq->enddisp = ((seq->start + seq->len) - seq->endofs )+ seq->endstill; */
+       calc_sequence_disp(seq);
 }
 
 void intern_recursive_pos_update(Sequence * seq, int offset) {
index dfcecbe50ddbe59afe5e9dd63bd873a27fc95ac1..08fbe8472c095f01d416f360cce6078f2a3b725e 100644 (file)
@@ -1098,8 +1098,8 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
                if(shi->passflag & SCE_PASS_REFRACT)
                        VECSUB(shr->refr, diff, olddiff);
                
-               if(shi->combinedflag & SCE_PASS_REFRACT)
-                       VECCOPY(olddiff, diff);
+               if(!(shi->combinedflag & SCE_PASS_REFRACT))
+                       VECSUB(diff, diff, shr->refr);
                
                shr->alpha= tracol[3];
        }
index 2640a19ebf17fcfb8422d4345e3f10317b8898d1..04214beeb90c1a901b7e2278157cb5106ac1fe25 100644 (file)
@@ -449,8 +449,8 @@ DerivedMesh *NewBooleanDerivedMesh_intern(
        float map_mat[4][4];
 
        DerivedMesh *dm = NULL;
-       Mesh *me1 = get_mesh(ob);
-       Mesh *me2 = get_mesh(ob_select);
+       Mesh *me1 = get_mesh(ob_select);
+       Mesh *me2 = get_mesh(ob);
 
        if (me1 == NULL || me2 == NULL) return 0;
        if (!me1->totface || !me2->totface) return 0;
@@ -458,9 +458,9 @@ DerivedMesh *NewBooleanDerivedMesh_intern(
        // we map the final object back into ob's local coordinate space. For this
        // we need to compute the inverse transform from global to ob (inv_mat),
        // and the transform from ob to ob_select for use in interpolation (map_mat)
-       Mat4Invert(inv_mat, ob_select->obmat);
-       Mat4MulMat4(map_mat, ob->obmat, inv_mat);
        Mat4Invert(inv_mat, ob->obmat);
+       Mat4MulMat4(map_mat, ob_select->obmat, inv_mat);
+       Mat4Invert(inv_mat, ob_select->obmat);
 
        {
                // interface with the boolean module:
@@ -484,8 +484,8 @@ DerivedMesh *NewBooleanDerivedMesh_intern(
                        default : op_type = e_csg_intersection;
                }
                
-               BuildMeshDescriptors(ob, 0, &fd_1, &vd_1);
-               BuildMeshDescriptors(ob_select, me1->totface, &fd_2, &vd_2);
+               BuildMeshDescriptors(ob_select, 0, &fd_1, &vd_1);
+               BuildMeshDescriptors(ob, me1->totface, &fd_2, &vd_2);
 
                bool_op = CSG_NewBooleanFunction();
 
@@ -500,7 +500,7 @@ DerivedMesh *NewBooleanDerivedMesh_intern(
                        // iterate through results of operation and insert
                        // into new object
                        dm = ConvertCSGDescriptorsToDerivedMesh(
-                               &fd_o, &vd_o, inv_mat, map_mat, mat, totmat, ob, ob_select);
+                               &fd_o, &vd_o, inv_mat, map_mat, mat, totmat, ob_select, ob);
 
                        // free up the memory
                        CSG_FreeVertexDescriptor(&vd_o);
@@ -540,7 +540,7 @@ int NewBooleanMesh(Base *base, Base *base_select, int int_op_type)
        }
 
        /* create a new blender mesh object - using 'base' as  a template */
-       ob_new= AddNewBlenderMesh(base);
+       ob_new= AddNewBlenderMesh(base_select);
        me_new= ob_new->data;
 
        DM_to_mesh(dm, me_new);
index f73983be4400c2dc19466fcdc49c92b989c28767..194241c438048230f3545602d4040eba369ab84f 100644 (file)
@@ -1914,9 +1914,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
                        uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
                        uiDefButBitS(block, TOG, ARM_DEF_VGROUP, B_ARM_RECALCDATA, "Vert.Groups",       lx,cy-=19,buttonWidth/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable VertexGroups defining deform");
                        uiDefButBitS(block, TOG, ARM_DEF_ENVELOPE, B_ARM_RECALCDATA, "Envelopes",       lx+buttonWidth/2,cy,(buttonWidth + 1)/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable Bone Envelopes defining deform");
-                       uiDefButBitS(block, TOG, ARM_DEF_QUATERNION, B_ARM_RECALCDATA, "Quaternion",    lx,(cy-=19),buttonWidth + 1,20, &amd->deformflag, 0, 0, 0, 0, "Enable deform rotation interpolation with Quaternions");
-
-                       
+                       uiDefButBitS(block, TOG, ARM_DEF_QUATERNION, B_ARM_RECALCDATA, "Quaternion",    lx,(cy-=19),buttonWidth/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable deform rotation interpolation with Quaternions");
+                       uiDefButBitS(block, TOG, ARM_DEF_B_BONE_REST, B_ARM_RECALCDATA, "B-Bone Rest", lx+buttonWidth/2,cy,(buttonWidth + 1)/2,20, &amd->deformflag, 0, 0, 0, 0, "Make B-Bones deform already in rest position");
                } else if (md->type==eModifierType_Hook) {
                        HookModifierData *hmd = (HookModifierData*) md;
                        uiDefButF(block, NUM, B_MODIFIER_RECALC, "Falloff: ",           lx, (cy-=19), buttonWidth,19, &hmd->falloff, 0.0, 100.0, 100, 0, "If not zero, the distance from hook where influence ends");
@@ -3649,8 +3648,9 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm)
        uiDefButBitS(block, TOG, ARM_DEF_VGROUP, B_ARM_RECALCDATA, "Vertex Groups",     10, 20,100,20, &arm->deformflag, 0, 0, 0, 0, "Enable VertexGroups defining deform (not for Modifiers)");
        uiDefButBitS(block, TOG, ARM_DEF_ENVELOPE, B_ARM_RECALCDATA, "Envelopes",       110,20,100,20, &arm->deformflag, 0, 0, 0, 0, "Enable Bone Envelopes defining deform (not for Modifiers)");
        uiDefButBitS(block, TOG, ARM_DEF_QUATERNION, B_ARM_RECALCDATA, "Quaternion", 210,20,100,20, &arm->deformflag, 0, 0, 0, 0, "Enable deform rotation interpolation with Quaternions (not for Modifiers)");
-       uiDefButBitI(block, TOG, ARM_RESTPOS, B_ARM_RECALCDATA,"Rest Position",         10,0,150,20, &arm->flag, 0, 0, 0, 0, "Show armature rest position, no posing possible");
-       uiDefButBitI(block, TOG, ARM_DELAYDEFORM, REDRAWVIEW3D, "Delay Deform",         160,0,150,20, &arm->flag, 0, 0, 0, 0, "Don't deform children when manipulating bones in pose mode");
+       uiDefButBitI(block, TOG, ARM_RESTPOS, B_ARM_RECALCDATA,"Rest Position",         10,0,100,20, &arm->flag, 0, 0, 0, 0, "Show armature rest position, no posing possible");
+       uiDefButBitI(block, TOG, ARM_DELAYDEFORM, REDRAWVIEW3D, "Delay Deform",         110,0,100,20, &arm->flag, 0, 0, 0, 0, "Don't deform children when manipulating bones in pose mode");
+       uiDefButBitS(block, TOG, ARM_DEF_B_BONE_REST, B_ARM_RECALCDATA,"B-Bone Rest", 210,0,100,20, &arm->deformflag, 0, 0, 0, 0, "Make B-Bones deform already in rest position");
        uiBlockEndAlign(block);
 }
 
@@ -4234,7 +4234,7 @@ void do_meshbuts(unsigned short event)
                G.f -= G_DISABLE_OK;
                break;
        case B_REMDOUB:
-               count= removedoublesflag(1, G.scene->toolsettings->doublimit);
+               count= removedoublesflag(1, 1, G.scene->toolsettings->doublimit);
                notice("Removed: %d", count);
                if (count) { /* only undo and redraw if an action is taken */
                        countall ();
index 8a9841ce70d29a5c521af5a5ca42687e5df80d6c..183558b65bcf1f661f96e454489de21c522feeb2 100644 (file)
@@ -928,7 +928,7 @@ void drawactionspace(ScrArea *sa, void *spacedata)
        draw_cfra_action();
        
        /* Draw markers */
-       draw_markers_timespace();
+       draw_markers_timespace(0);
        
        /* Draw 'curtains' for preview */
        draw_anim_preview_timespace();
index 1592a05aeb345259ae2921c0857b72387c2e227d..601a3fdf589cb58263217f35882543d0312ead80 100644 (file)
@@ -888,7 +888,7 @@ static void draw_b_bone_boxes(int dt, bPoseChannel *pchan, float xwidth, float l
        
        if(segments>1 && pchan) {
                float dlen= length/(float)segments;
-               Mat4 *bbone= b_bone_spline_setup(pchan);
+               Mat4 *bbone= b_bone_spline_setup(pchan, 0);
                int a;
                
                for(a=0; a<segments; a++, bbone++) {
index cf9e8c2ea28c8b24dea6e0053e68d7deec7f18b2..ee4c2cc365953ed0a3d307aedef34b927311c7c4 100644 (file)
@@ -2240,7 +2240,7 @@ void drawipospace(ScrArea *sa, void *spacedata)
                draw_anim_preview_timespace();
                
                /* draw markers */
-               draw_markers_timespace();
+               draw_markers_timespace(0);
                
                /* restore viewport */
                mywinset(sa->win);
index 32ed6be0f6bbdb544f21533107afd702497d2035..6fbd0c71997b3f9102c736787bacd27960ee7511 100644 (file)
@@ -239,14 +239,22 @@ int set_tpage(MTFace *tface)
                        }
                        else if(alphamode==TF_ALPHA) {
                                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                               
+                               /* added after 2.45 to clip alpha */
+                               glEnable ( GL_ALPHA_TEST );
+                               glAlphaFunc ( GL_GREATER, 0.001 );
+                               
+                               
                        /*      glBlendEquationEXT(GL_FUNC_ADD_EXT); */
                        }
                        /* else { */
                        /*      glBlendFunc(GL_ONE, GL_ONE); */
                        /*      glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); */
                        /* } */
+               } else {
+                       glDisable(GL_BLEND);
+                       glDisable ( GL_ALPHA_TEST );
                }
-               else glDisable(GL_BLEND);
        }
 
        ima= tface->tpage;
index c48cca702c2d8b707fe507c908795e545c7c6c28..0394fcce80b4e3ff9f98c3ed060ba9e25a176e83 100644 (file)
@@ -754,7 +754,7 @@ void drawnlaspace(ScrArea *sa, void *spacedata)
        draw_cfra_action();
        
        /* draw markers */
-       draw_markers_timespace();
+       draw_markers_timespace(0);
        
        /* Draw preview 'curtains' */
        draw_anim_preview_timespace();
index d338542e9d0b7f932cf2122a508619122ad87734..30d70ba3c4384733bf0eb1750bb006708d7b6bb9 100644 (file)
@@ -885,14 +885,14 @@ static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *nod
                                dy-= 19;
                                uiDefButI(block, NUM, B_NODE_EXEC+node->nr, "Frs:",
                                                  xmin, dy, width, 19, 
-                                                 &iuser->frames, 0.0, 10000.0, 0, 0, "Amount of images used in animation");
+                                                 &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Amount of images used in animation");
                                uiDefButI(block, NUM, B_NODE_EXEC+node->nr, "SFra:",
                                                  xmin+width, dy, width, 19, 
-                                                 &iuser->sfra, 1.0, 10000.0, 0, 0, "Start frame of animation");
+                                                 &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Start frame of animation");
                                dy-= 19;
                                uiDefButI(block, NUM, B_NODE_EXEC+node->nr, "Offs:",
                                                  xmin, dy, width, 19, 
-                                                 &iuser->offset, -10000.0, 10000.0, 0, 0, "Offsets the number of the frame to use in the animation");
+                                                 &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation");
                                uiDefButS(block, TOG, B_NODE_EXEC+node->nr, "Cycl",
                                                  xmin+width, dy, width-20, 19, 
                                                  &iuser->cycl, 0.0, 0.0, 0, 0, "Make animation go cyclic");
index 86246759a3b6b71eeedb7e2efdb6beaec38075cc..37f5126b27ca629e83464d3277f060206914908f 100644 (file)
@@ -76,6 +76,7 @@
 #include "BSE_seqeffects.h"
 #include "BSE_seqscopes.h"
 #include "BSE_seqaudio.h"
+#include "BSE_time.h"
 
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
@@ -392,7 +393,7 @@ static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, short direction)
        /* clamp handles to defined size in pixel space */
        handsize = seq->handsize;
        minhandle = 7;
-       maxhandle = 28;
+       maxhandle = 40;
        CLAMP(handsize, minhandle*pixelx, maxhandle*pixelx);
        
        /* set up co-ordinates/dimensions for either left or right handle */
@@ -686,9 +687,12 @@ so wave file sample drawing precission is zoom adjusted
 static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq)
 {
        float x1, x2, y1, y2;
-       char col[3];
+       char col[3], is_single_image;
        Sequence *last_seq = get_last_seq();
 
+       /* we need to know if this is a single image or not for drawing */
+       is_single_image = (char)check_single_image_seq(seq);
+       
        /* body */
        if(seq->startstill) x1= seq->start;
        else x1= seq->startdisp;
@@ -702,11 +706,18 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq)
        get_seq_color3ubv(seq, col);
        
        /* draw the main strip body */
-       draw_shadedstrip(seq, col, x1, y1, x2, y2);
+       if (is_single_image) /* single image */
+               draw_shadedstrip(seq, col, seq_tx_get_final_left(seq), y1, seq_tx_get_final_right(seq), y2);
+       else /* normal operation */
+               draw_shadedstrip(seq, col, x1, y1, x2, y2);
        
        /* draw additional info and controls */
-       if (seq->type == SEQ_RAM_SOUND) drawseqwave(seq, x1, y1, x2, y2, sa->winx);
-       draw_seq_extensions(seq, sseq);
+       if (seq->type == SEQ_RAM_SOUND)
+               drawseqwave(seq, x1, y1, x2, y2, sa->winx);
+       
+       if (!is_single_image)
+               draw_seq_extensions(seq, sseq);
+       
        draw_seq_handle(seq, sseq, SEQ_LEFTHANDLE);
        draw_seq_handle(seq, sseq, SEQ_RIGHTHANDLE);
        
@@ -741,10 +752,10 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq)
        if(x2<G.v2d->cur.xmin) x2= G.v2d->cur.xmin;
        else if(x2>G.v2d->cur.xmax) x2= G.v2d->cur.xmax;
 
+       /* nice text here would require changing the view matrix for texture text */
        if(x1 != x2) {
                draw_seq_text(seq, x1, x2, y1, y2);
        }
-               
 }
 
 static Sequence *special_seq_update= 0;
@@ -860,7 +871,7 @@ static void draw_extra_seqinfo(void)
 {
        Sequence *last_seq = get_last_seq();
        StripElem *se, *last;
-       float xco, xfac;
+       float xco, xfac, yco, yfac;
        int sta, end;
        char str[256];
 
@@ -869,61 +880,77 @@ static void draw_extra_seqinfo(void)
        /* xfac: size of 1 pixel */
        xfac= G.v2d->cur.xmax - G.v2d->cur.xmin;
        xfac/= (float)(G.v2d->mask.xmax-G.v2d->mask.xmin);
-       xco= G.v2d->cur.xmin+40*xfac;
+       xco= G.v2d->cur.xmin+10*xfac;
 
-       BIF_ThemeColor(TH_TEXT);
+       yfac= G.v2d->cur.ymax - G.v2d->cur.ymin;
+       yfac/= (float)(G.v2d->mask.ymax-G.v2d->mask.ymin);
+       yco= G.v2d->cur.ymin+40*yfac;
+       
+       BIF_ThemeColor(TH_TEXT_HI);
 
        /* NAME */
-       glRasterPos3f(xco,  0.3, 0.0);
+       glRasterPos3f(xco,  yco, 0.0);
        strncpy(str, give_seqname(last_seq), 255);
        BMF_DrawString(G.font, str);
-       xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
+       xco += xfac*BMF_GetStringWidth(G.font, str) +10.0*xfac;
 
        if(last_seq->type==SEQ_SCENE && last_seq->scene) {
-               glRasterPos3f(xco,  0.3, 0.0);
+               glRasterPos3f(xco,  yco, 0.0);
                BMF_DrawString(G.font, last_seq->scene->id.name+2);
                xco += xfac*BMF_GetStringWidth(G.font, last_seq->scene->id.name+2) +30.0*xfac;
        }
 
-       /* LEN */
-       if(last_seq->type & SEQ_EFFECT)
-               sprintf(str, "len: %d   From %d - %d", last_seq->len, last_seq->startdisp, last_seq->enddisp-1);
-       else
-               sprintf(str, "len: %d (%d)", last_seq->enddisp-last_seq->startdisp, last_seq->len);
+       /* LEN, dont bother with single images */
+       if (check_single_image_seq(last_seq)==0) {
+               if(last_seq->type & SEQ_EFFECT)
+                       sprintf(str, "len: %d   From %d - %d", last_seq->len, last_seq->startdisp, last_seq->enddisp-1);
+               else
+                       sprintf(str, "len: %d (%d)", last_seq->enddisp-last_seq->startdisp, last_seq->len);
+               
+               glRasterPos3f(xco,  yco, 0.0);
+       
+               BMF_DrawString(G.font, str);
+               xco += xfac*BMF_GetStringWidth(G.font, str) +10.0*xfac;
+       }
 
-       glRasterPos3f(xco,  0.3, 0.0);
-       BMF_DrawString(G.font, str);
-       xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
 
        if(last_seq->type==SEQ_IMAGE) {
-
-               /* CURRENT */
-               se= (StripElem *)give_stripelem(last_seq,  (G.scene->r.cfra));
-               if(se) {
-                       sprintf(str, "Cur: %s", se->name);
-                       glRasterPos3f(xco,  0.3, 0.0);
-                       BMF_DrawString(G.font, str);
-                       xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
-               }
-
-               /* FIRST AND LAST */
-
-               if(last_seq->strip) {
-                       se= last_seq->strip->stripdata;
-                       last= se+last_seq->len-1;
-                       if(last_seq->startofs) se+= last_seq->startofs;
-                       if(last_seq->endofs) last-= last_seq->endofs;
-
-                       sprintf(str, "First: %s at %d   Last: %s at %d", se->name, last_seq->startdisp, last->name, last_seq->enddisp-1);
-                       glRasterPos3f(xco,  0.3, 0.0);
-                       BMF_DrawString(G.font, str);
-                       xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
-
-                       /* orig size */
-                       sprintf(str, "OrigSize: %d x %d", last_seq->strip->orx, last_seq->strip->ory);
-                       glRasterPos3f(xco,  0.3, 0.0);
-                       BMF_DrawString(G.font, str);
-                       xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
+               if (last_seq->len > 1) {
+                       /* CURRENT */
+                       se= (StripElem *)give_stripelem(last_seq,  (G.scene->r.cfra));
+                       if(se) {
+                               sprintf(str, "Cur: %s", se->name);
+                               glRasterPos3f(xco,  yco, 0.0);
+                               BMF_DrawString(G.font, str);
+                               xco += xfac*BMF_GetStringWidth(G.font, str) +10.0*xfac;
+                       }
+       
+                       /* FIRST AND LAST */
+       
+                       if(last_seq->strip) {
+                               se= last_seq->strip->stripdata;
+                               last= se+last_seq->len-1;
+                               if(last_seq->startofs) se+= last_seq->startofs;
+                               if(last_seq->endofs) last-= last_seq->endofs;
+       
+                               sprintf(str, "First: %s at %d   Last: %s at %d", se->name, last_seq->startdisp, last->name, last_seq->enddisp-1);
+                               glRasterPos3f(xco,  yco, 0.0);
+                               BMF_DrawString(G.font, str);
+                               xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
+       
+                               /* orig size */
+                               sprintf(str, "OrigSize: %d x %d", last_seq->strip->orx, last_seq->strip->ory);
+                               glRasterPos3f(xco,  yco, 0.0);
+                               BMF_DrawString(G.font, str);
+                               xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
+                       }
+               } else { /* single image */
+                       if (last_seq->strip) {
+                               sprintf(str, "Single: %s   len: %d", last_seq->strip->stripdata->name, last_seq->enddisp-last_seq->startdisp);
+                               glRasterPos3f(xco,  yco, 0.0);
+                               BMF_DrawString(G.font, str);
+                               xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
+                       }
                }
        }
        else if(last_seq->type==SEQ_MOVIE) {
@@ -935,14 +962,14 @@ static void draw_extra_seqinfo(void)
                                last_seq->name+2, last_seq->strip->dir, last_seq->strip->stripdata->name,
                                sta, last_seq->startdisp, end, last_seq->enddisp-1,  (G.scene->r.cfra)-last_seq->startdisp);
 
-               glRasterPos3f(xco,  0.3, 0.0);
+               glRasterPos3f(xco,  yco, 0.0);
                BMF_DrawString(G.font, str);
        }
        else if(last_seq->type==SEQ_SCENE) {
                se= (StripElem *)give_stripelem(last_seq,  (G.scene->r.cfra));
                if(se && last_seq->scene) {
                        sprintf(str, "Cur: %d  First: %d  Last: %d", last_seq->sfra+se->nr, last_seq->sfra, last_seq->sfra+last_seq->len-1); 
-                       glRasterPos3f(xco,  0.3, 0.0);
+                       glRasterPos3f(xco,  yco, 0.0);
                        BMF_DrawString(G.font, str);
                }
        }
@@ -957,7 +984,7 @@ static void draw_extra_seqinfo(void)
                                sta, last_seq->startdisp, end, last_seq->enddisp-1,  (G.scene->r.cfra)-last_seq->startdisp,
                                last_seq->level, last_seq->pan);
 
-               glRasterPos3f(xco,  0.3, 0.0);
+               glRasterPos3f(xco,  yco, 0.0);
                BMF_DrawString(G.font, str);
        }
 }
@@ -1091,12 +1118,16 @@ static void seq_panel_properties(short cntrl)   // SEQ_HANDLER_PROPERTIES
        }
        else if(last_seq->type==SEQ_IMAGE) {
 
-               uiDefBut(block, LABEL, 0, "Type: Image", 10,140,150,20, 0, 0, 0, 0, 0, "");
-               uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
+               uiDefBut(block, LABEL, 0, "Type: Image", 10,160,150,20, 0, 0, 0, 0, 0, "");
+               uiDefBut(block, TEX, B_NOP, "Name: ", 10,140,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
                
                uiBlockBeginAlign(block);
-               uiDefButBitS(block, TOG, SEQ_MAKE_PREMUL, SEQ_BUT_RELOAD, "Convert to Premul", 10,90,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Converts RGB values to become premultiplied with Alpha");
-               uiDefButBitS(block, TOG, SEQ_FILTERY, SEQ_BUT_RELOAD, "FilterY",        10,70,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "For video movies to remove fields");
+               uiDefButBitS(block, TOG, SEQ_MAKE_PREMUL, SEQ_BUT_RELOAD, "Convert to Premul", 10,110,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Converts RGB values to become premultiplied with Alpha");
+               uiDefButBitS(block, TOG, SEQ_FILTERY, SEQ_BUT_RELOAD, "FilterY",        10,90,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "For video movies to remove fields");
+               
+               uiDefButBitS(block, TOG, SEQ_FLIPX, SEQ_BUT_RELOAD, "FlipX",    10,70,75,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Flip on the X axis");
+               uiDefButBitS(block, TOG, SEQ_FLIPY, SEQ_BUT_RELOAD, "FlipY",    85,70,75,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Flip on the Y axis");
+               
                uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Mul:",                   10,50,150,19, &last_seq->mul, 0.001, 5.0, 100, 0, "Multiply colors");
                uiDefButS(block, TOG|BIT|7, SEQ_BUT_RELOAD, "Reverse Frames", 10,30,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Reverse frame order");
                uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Strobe:",                        10,10,150,19, &last_seq->strobe, 1.0, 30.0, 100, 0, "Only display every nth frame");
@@ -1200,10 +1231,10 @@ static void seq_panel_properties(short cntrl)   // SEQ_HANDLER_PROPERTIES
                        uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Percent", 10, 30, 150, 19, &transform->percent, 0.0, 1.0, 0.0, 0.0, "Percent Translate");
                        uiDefButI(block, ROW, SEQ_BUT_EFFECT, "Pixels", 160, 30, 150, 19, &transform->percent, 0.0, 0.0, 0.0, 0.0, "Pixels Translate");
                        if(transform->percent==1){
-                               uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x Start:",       10,10,150,19, &transform->xIni, -100.0, 100.0, 0, 0, "X Position Start");
-                               uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x End:",         160,10,150,19, &transform->xFin, -100.0, 100.0, 0, 0, "X Position End");
-                               uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y Start:",       10,-10,150,19, &transform->yIni, -100.0, 100.0, 0, 0, "Y Position Start");
-                               uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y End:",         160,-10,150,19, &transform->yFin, -100.0, 100.0, 0, 0, "Y Position End");
+                               uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x Start:",       10,10,150,19, &transform->xIni, -500.0, 500.0, 0, 0, "X Position Start");
+                               uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x End:",         160,10,150,19, &transform->xFin, -500.0, 500.0, 0, 0, "X Position End");
+                               uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y Start:",       10,-10,150,19, &transform->yIni, -500.0, 500.0, 0, 0, "Y Position Start");
+                               uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y End:",         160,-10,150,19, &transform->yFin, -500.0, 500.0, 0, 0, "Y Position End");
                        }else{
                                uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x Start:",       10,10,150,19, &transform->xIni, -10000.0, 10000.0, 0, 0, "X Position Start");
                                uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x End:",         160,10,150,19, &transform->xFin, -10000.0, 10000.0, 0, 0, "X Position End");
@@ -1413,6 +1444,9 @@ void drawseqspace(ScrArea *sa, void *spacedata)
 
        draw_extra_seqinfo();
 
+       /* Draw markers */
+       draw_markers_timespace(1);
+       
        /* restore viewport */
        mywinset(sa->win);
 
index 1fe10bf2c1739a5110b2d8d08b5234a23be81f96..e5b1026e72a147011403bdcb8172fe667ae1d98d 100644 (file)
@@ -219,7 +219,7 @@ void drawsoundspace(ScrArea *sa, void *spacedata)
        }
        
        draw_cfra_sound(spacedata);
-       draw_markers_timespace();
+       draw_markers_timespace(0);
 
        /* restore viewport */
        mywinset(curarea->win);
index 237c42e328da796d6180896dd6ad4e37351dca13..9ad24b54ad8c750bd27b7fed9c4532287f7922ef 100644 (file)
@@ -127,13 +127,13 @@ static void draw_cfra_time(SpaceTime *stime)
                
                ui_rasterpos_safe(x * xscale, y * yscale, 1.0);
                BIF_DrawString(G.fonts, str, 0);
-               
+               printf("%f -- %f\n", xscale, yscale);
                glScalef(xscale, yscale, 1.0);
        }
        
 }
 
-static void draw_marker(TimeMarker *marker)
+static void draw_marker(TimeMarker *marker, int lines)
 {
        float xpos, ypixels, xscale, yscale;
 
@@ -145,10 +145,25 @@ static void draw_marker(TimeMarker *marker)
        yscale = (G.v2d->mask.ymax-G.v2d->mask.ymin)/(G.v2d->cur.ymax-G.v2d->cur.ymin);
 
        glScalef( 1.0/xscale, 1.0/yscale, 1.0);
-
+       
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);                      
        
+       /* verticle line */
+       if (lines) {
+               setlinestyle(3);
+               if(marker->flag & SELECT)
+                       glColor4ub(255,255,255, 96);
+               else
+                       glColor4ub(0,0,0, 96);
+               
+               glBegin(GL_LINES);
+               glVertex2f((xpos*xscale)+0.5, 12);
+               glVertex2f((xpos*xscale)+0.5, 34*yscale); /* a bit lazy but we know it cant be greater then 34 strips high*/
+               glEnd();
+               setlinestyle(0);
+       }
+       
        /* 5 px to offset icon to align properly, space / pixels corrects for zoom */
        if(marker->flag & SELECT)
                BIF_icon_draw(xpos*xscale-5.0, 12.0, ICON_MARKER_HLT);
@@ -176,24 +191,24 @@ static void draw_marker(TimeMarker *marker)
        glScalef(xscale, yscale, 1.0);
 }
 
-static void draw_markers_time(void)
+static void draw_markers_time(int lines)
 {
        TimeMarker *marker;
 
        /* unselected markers are drawn at the first time */
        for(marker= G.scene->markers.first; marker; marker= marker->next) {
-               if(!(marker->flag & SELECT)) draw_marker(marker);
+               if(!(marker->flag & SELECT)) draw_marker(marker, lines);
        }
 
        /* selected markers are drawn later ... selected markers have to cover unselected
         * markers laying at the same position as selected markers
         * (jiri: it is hack, it could be solved better) */
        for(marker= G.scene->markers.first; marker; marker= marker->next) {
-               if(marker->flag & SELECT) draw_marker(marker);
+               if(marker->flag & SELECT) draw_marker(marker, lines);
        }
 }
 
-void draw_markers_timespace()
+void draw_markers_timespace(int lines)
 {
        TimeMarker *marker;
        float yspace, ypixels;
@@ -208,13 +223,13 @@ void draw_markers_timespace()
                
        /* unselected markers are drawn at the first time */
        for(marker= G.scene->markers.first; marker; marker= marker->next) {
-               if(!(marker->flag & SELECT)) draw_marker(marker);
+               if(!(marker->flag & SELECT)) draw_marker(marker, lines);
        }
        
        /* selected markers are drawn later ... selected markers have to cover unselected
                * markers laying at the same position as selected markers */
        for(marker= G.scene->markers.first; marker; marker= marker->next) {
-               if(marker->flag & SELECT) draw_marker(marker);
+               if(marker->flag & SELECT) draw_marker(marker, lines);
        }
 
        glTranslatef(0.0f, -G.v2d->cur.ymin, 0.0f);
@@ -386,7 +401,7 @@ void drawtimespace(ScrArea *sa, void *spacedata)
 
        draw_cfra_time(spacedata);
        draw_ob_keys();
-       draw_markers_time();
+       draw_markers_time(0);
 
        /* restore viewport */
        mywinset(curarea->win);
index 2bcc7ed76a7c204f14dec88fdcf7809468c2ad76..d67df1e0e972a20e3652fd8321df37d88c70679f 100644 (file)
@@ -2443,7 +2443,7 @@ static void view3d_panel_properties(short cntrl)  // VIEW3D_HANDLER_SETTINGS
        uiBlockBeginAlign(block);
        uiDefButF(block, NUM, REDRAWVIEW3D, "Spacing:",         10, 200, 140, 19, &vd->grid, 0.001, 100.0, 10, 0, "Set the distance between grid lines");
        uiDefButS(block, NUM, REDRAWVIEW3D, "Lines:",           10, 180, 140, 19, &vd->gridlines, 0.0, 100.0, 100, 0, "Set the number of grid lines in perspective view");
-       uiDefButS(block, NUM, REDRAWVIEW3D, "Divisions:",               10, 160, 140, 19, &vd->gridsubdiv, 0.0, 100.0, 100, 0, "Set the number of grid lines");
+       uiDefButS(block, NUM, REDRAWVIEW3D, "Divisions:",               10, 160, 140, 19, &vd->gridsubdiv, 1.0, 100.0, 100, 0, "Set the number of grid lines");
        uiBlockEndAlign(block);
 
        uiDefBut(block, LABEL, 1, "3D Display:",                                                        160, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
index ea5117a3991554a3960edebf5a36d310066fa98a..3957b10781449ad2a70876af77f4c7f9f51853a2 100644 (file)
@@ -2253,11 +2253,7 @@ static void mouse_action (int selectmode)
                
                std_rmouse_transform(transform_markers);
                
-               allqueue(REDRAWTIME, 0);
-               allqueue(REDRAWIPO, 0);
-               allqueue(REDRAWACTION, 0);
-               allqueue(REDRAWNLA, 0);
-               allqueue(REDRAWSOUND, 0);
+               allqueue(REDRAWMARKER, 0);
        }
 }
 
@@ -2680,10 +2676,7 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                column_select_action_keys(val);
                        }
                        
-                       allqueue(REDRAWTIME, 0);
-                       allqueue(REDRAWIPO, 0);
-                       allqueue(REDRAWACTION, 0);
-                       allqueue(REDRAWNLA, 0);
+                       allqueue(REDRAWMARKER, 0);
                        break;
                        
                case MKEY:
@@ -2706,11 +2699,7 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        rename_marker();
                                else 
                                        break;
-                               allqueue(REDRAWTIME, 0);
-                               allqueue(REDRAWIPO, 0);
-                               allqueue(REDRAWACTION, 0);
-                               allqueue(REDRAWNLA, 0);
-                               allqueue(REDRAWSOUND, 0);
+                               allqueue(REDRAWMARKER, 0);
                        }
                        break;
                        
@@ -2734,11 +2723,8 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                        else if (G.qual & LR_ALTKEY) /* clear preview range */
                                anim_previewrange_clear();
                                
-                       allqueue(REDRAWTIME, 0);
+                       allqueue(REDRAWMARKER, 0);
                        allqueue(REDRAWBUTSALL, 0);
-                       allqueue(REDRAWACTION, 0);
-                       allqueue(REDRAWNLA, 0);
-                       allqueue(REDRAWIPO, 0);
                        break;
                        
                case SKEY: 
index b329bfcce76a2ba85f2829a6a5084778c22b8250..2e35fd1581fc7ab5512664f7e2a0c0191ae313db 100644 (file)
@@ -4266,7 +4266,7 @@ void set_speed_editipo(float speed)
        EditIpo *ei;
        BezTriple *bezt, *beztar[3];
        float vec1[3], vec2[3];
-       int a, b, totvert, didit=0;
+       int a, b, totvert, didit=0, done_error = 0;
                
        if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
 
@@ -4315,7 +4315,10 @@ void set_speed_editipo(float speed)
                                                didit= 1;
                                        }
                                        else {
-                                               error("Only works for 3 visible curves with handles");
+                                               if (done_error==0) {
+                                                       error("Only works for 3 visible curves with handles");
+                                               }
+                                               done_error = 1;
                                        }
                                }
                        }
index 49913b345edf9ca86943b7269e33e5bd21b7a941..ccd8b58c47e3d1cf096ae1fb5f219a313e341085 100644 (file)
@@ -960,7 +960,7 @@ void make_prim(int type, float imat[3][3], int tot, int seg,
                        rotateflag(2, v1->co, cmat);
                }
 
-               removedoublesflag(4, 0.0001);
+               removedoublesflag(4, 0, 0.0001);
 
                /* and now do imat */
                eve= em->verts.first;
index 5cfeab03c0aa080ae594c0325207c88cb6d9d8e9..a0c864de0167f4174141976184f90b422ee3b541 100644 (file)
@@ -131,6 +131,18 @@ void EM_select_mirrored(void)
        }
 }
 
+void EM_automerge(int update) {
+       if  (G.scene->automerge) {
+               if (G.obedit && G.obedit->type==OB_MESH) {
+                       if (removedoublesflag(1, 1, G.scene->toolsettings->doublimit)) {
+                               if (update) {
+                                       DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+                               }
+                       }
+               }
+       }
+}
+
 /* ****************************** SELECTION ROUTINES **************** */
 
 unsigned int em_solidoffs=0, em_wireoffs=0, em_vertoffs=0;     /* set in drawobject.c ... for colorindices */
@@ -2494,6 +2506,7 @@ void reveal_mesh(void)
        BIF_undo_push("Reveal");
 }
 
+/* TODO - improve this with sync sel and selection flushing */
 void hide_tface_uv(int swap)
 {
        EditMesh *em = G.editMesh;
@@ -3330,7 +3343,7 @@ void Vertex_Menu() {
        switch(ret)
        {
                case 1:
-                       notice("Removed %d Vertices", removedoublesflag(1, G.scene->toolsettings->doublimit));
+                       notice("Removed %d Vertices", removedoublesflag(1, 0, G.scene->toolsettings->doublimit));
                        BIF_undo_push("Remove Doubles");
                        break;
                case 2: 
index 2afac79be1d6688ff244cff2467b8539701f7b28..56db0ea70169774f0dac11af3abc7338cf4aa04b 100644 (file)
@@ -195,8 +195,15 @@ void convert_to_triface(int direction)
        
 }
 
-int removedoublesflag(short flag, float limit)         /* return amount */
+int removedoublesflag(short flag, short automerge, float limit)                /* return amount */
 {
+       /*
+               flag -  Test with vert->flags
+               weld -  Alternative operation, merge unselected into selected.
+                               Used for "Auto Weld" mode. warning.
+               limit - Quick manhattan distance between verts.
+       */
+       
        EditMesh *em = G.editMesh;
        /* all verts with (flag & 'flag') are being evaluated */
        EditVert *eve, *v1, *nextve;
@@ -209,12 +216,15 @@ int removedoublesflag(short flag, float limit)            /* return amount */
        
        if(multires_test()) return 0;
 
+       
        /* flag 128 is cleared, count */
+
+       /* Normal non weld operation */
        eve= em->verts.first;
        amount= 0;
        while(eve) {
                eve->f &= ~128;
-               if(eve->h==0 && (eve->f & flag)) amount++;
+               if(eve->h==0 && (automerge || (eve->f & flag))) amount++;
                eve= eve->next;
        }
        if(amount==0) return 0;
@@ -223,7 +233,7 @@ int removedoublesflag(short flag, float limit)              /* return amount */
        sb= sortblock= MEM_mallocN(sizeof(xvertsort)*amount,"sortremovedoub");
        eve= em->verts.first;
        while(eve) {
-               if(eve->h==0 && (eve->f & flag)) {
+               if(eve->h==0 && (automerge || (eve->f & flag))) {
                        sb->x= eve->co[0]+eve->co[1]+eve->co[2];
                        sb->v1= eve;
                        sb++;
@@ -232,44 +242,72 @@ int removedoublesflag(short flag, float limit)            /* return amount */
        }
        qsort(sortblock, amount, sizeof(xvertsort), vergxco);
 
+       
        /* test for doubles */
-       sb= sortblock;
-       for(a=0; a<amount; a++) {
-               eve= sb->v1;
-               if( (eve->f & 128)==0 ) {
-                       sb1= sb+1;
-                       for(b=a+1; b<amount; b++) {
-                               /* first test: simpel dist */
-                               dist= sb1->x - sb->x;
-                               if(dist > limit) break;
-                               
-                               /* second test: is vertex allowed */
-                               v1= sb1->v1;
-                               if( (v1->f & 128)==0 ) {
+       sb= sortblock;  
+       if (automerge) {
+               for(a=0; a<amount; a++, sb++) {
+                       eve= sb->v1;
+                       if( (eve->f & 128)==0 ) {
+                               sb1= sb+1;
+                               for(b=a+1; b<amount && (eve->f & 128)==0; b++, sb1++) {
+                                       if(sb1->x - sb->x > limit) break;
                                        
-                                       dist= (float)fabs(v1->co[0]-eve->co[0]);
-                                       if(dist<=limit) {
-                                               dist= (float)fabs(v1->co[1]-eve->co[1]);
-                                               if(dist<=limit) {
-                                                       dist= (float)fabs(v1->co[2]-eve->co[2]);
-                                                       if(dist<=limit) {
+                                       /* when welding, only allow selected-> unselected*/
+                                       v1= sb1->v1;
+                                       if( (v1->f & 128)==0 ) {
+                                               if ((eve->f & flag)==0 && (v1->f & flag)==1) {
+                                                       if(     (float)fabs(v1->co[0]-eve->co[0])<=limit && 
+                                                               (float)fabs(v1->co[1]-eve->co[1])<=limit &&
+                                                               (float)fabs(v1->co[2]-eve->co[2])<=limit)
+                                                       {       /* unique bit */
+                                                               eve->f|= 128;
+                                                               eve->tmp.v = v1;
+                                                       }
+                                               } else if(      (eve->f & flag)==1 && (v1->f & flag)==0 ) {
+                                                       if(     (float)fabs(v1->co[0]-eve->co[0])<=limit && 
+                                                               (float)fabs(v1->co[1]-eve->co[1])<=limit &&
+                                                               (float)fabs(v1->co[2]-eve->co[2])<=limit)
+                                                       {       /* unique bit */
                                                                v1->f|= 128;
                                                                v1->tmp.v = eve;
                                                        }
                                                }
                                        }
                                }
-                               sb1++;
                        }
                }
-               sb++;
+       } else {
+               for(a=0; a<amount; a++, sb++) {
+                       eve= sb->v1;
+                       if( (eve->f & 128)==0 ) {
+                               sb1= sb+1;
+                               for(b=a+1; b<amount; b++, sb1++) {
+                                       /* first test: simpel dist */
+                                       if(sb1->x - sb->x > limit) break;
+                                       v1= sb1->v1;
+                                       
+                                       /* second test: is vertex allowed */
+                                       if( (v1->f & 128)==0 ) {
+                                               if(     (float)fabs(v1->co[0]-eve->co[0])<=limit && 
+                                                       (float)fabs(v1->co[1]-eve->co[1])<=limit &&
+                                                       (float)fabs(v1->co[2]-eve->co[2])<=limit)
+                                               {
+                                                       v1->f|= 128;
+                                                       v1->tmp.v = eve;
+                                               }
+                                       }
+                               }
+                       }
+               }
        }
        MEM_freeN(sortblock);
-
-       for(eve = em->verts.first; eve; eve=eve->next)
-               if((eve->f & flag) && (eve->f & 128))
-                       EM_data_interp_from_verts(eve, eve->tmp.v, eve->tmp.v, 0.5f);
-
+       
+       if (!automerge)
+               for(eve = em->verts.first; eve; eve=eve->next)
+                       if((eve->f & flag) && (eve->f & 128))
+                               EM_data_interp_from_verts(eve, eve->tmp.v, eve->tmp.v, 0.5f);
+       
        /* test edges and insert again */
        eed= em->edges.first;
        while(eed) {
@@ -445,7 +483,7 @@ int removedoublesflag(short flag, float limit)              /* return amount */
        eve= (struct EditVert *)em->verts.first;
        while(eve) {
                nextve= eve->next;
-               if(eve->f & flag) {
+               if(automerge || eve->f & flag) {
                        if(eve->f & 128) {
                                a++;
                                BLI_remlink(&em->verts, eve);
@@ -4023,7 +4061,7 @@ static void bevel_mesh(float bsize, int allfaces)
 
        waitcursor(1);
 
-       removedoublesflag(1, limit);
+       removedoublesflag(1, 0, limit);
 
        /* tag all original faces */
        efa= em->faces.first;
@@ -4378,7 +4416,7 @@ static void bevel_mesh(float bsize, int allfaces)
        allqueue(REDRAWVIEW3D, 0);
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
        
-       removedoublesflag(1, limit);
+       removedoublesflag(1, 0, limit);
 
        /* flush selected vertices to edges/faces */
        EM_select_flush();
@@ -4531,7 +4569,7 @@ int EdgeLoopDelete(void) {
                return 0;
        }
        select_more();
-       removedoublesflag(1,0.001);
+       removedoublesflag(1,0, 0.001);
        EM_select_flush();
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
        return 1;
@@ -5079,6 +5117,8 @@ int EdgeSlide(short immediate, float imperc)
        }
        
        force_draw(0);
+       
+       EM_automerge(0);
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
        scrarea_queue_winredraw(curarea);                
        
@@ -6113,7 +6153,7 @@ int collapseEdges(void)
                
        }
        freecollections(&allcollections);
-       removedoublesflag(1, MERGELIMIT);
+       removedoublesflag(1, 0, MERGELIMIT);
        /*get rid of this!*/
        countall();
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
@@ -6157,7 +6197,7 @@ int merge_firstlast(int first, int uvmerge)
        }
        
        countall();
-       return removedoublesflag(1,MERGELIMIT);
+       return removedoublesflag(1, 0, MERGELIMIT);
 }
 
 int merge_target(int target, int uvmerge)
@@ -6180,7 +6220,7 @@ int merge_target(int target, int uvmerge)
        countall();
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
        allqueue(REDRAWVIEW3D, 0);
-       return removedoublesflag(1,MERGELIMIT);
+       return removedoublesflag(1, 0, MERGELIMIT);
        
 }
 #undef MERGELIMIT
index fd869feda2a26e7a17f4f9fca105336e8e1776b5..0361d5395c2fef4a52f234dbe2ad3b7b48e1e565 100644 (file)
@@ -1203,11 +1203,7 @@ void borderselect_nla(void)
                        }
                }       
                BIF_undo_push("Border select NLA");
-               allqueue(REDRAWTIME, 0);
-               allqueue(REDRAWIPO, 0);
-               allqueue(REDRAWACTION, 0);
-               allqueue(REDRAWNLA, 0);
-               allqueue(REDRAWSOUND, 0);
+               allqueue(REDRAWMARKER, 0);
        }
 }
 
@@ -1262,11 +1258,7 @@ static void mouse_nla(int selectmode)
                
                std_rmouse_transform(transform_markers);
                
-               allqueue(REDRAWTIME, 0);
-               allqueue(REDRAWIPO, 0);
-               allqueue(REDRAWACTION, 0);
-               allqueue(REDRAWNLA, 0);
-               allqueue(REDRAWSOUND, 0);
+               allqueue(REDRAWMARKER, 0);
        }
        else {
                /* Try action ipo selection */
@@ -1725,11 +1717,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        shift_nlastrips_up();
                                else {
                                        nextprev_marker(1);
-                                       allqueue(REDRAWTIME, 0);
-                                       allqueue(REDRAWIPO, 0);
-                                       allqueue(REDRAWACTION, 0);
-                                       allqueue(REDRAWNLA, 0);
-                                       allqueue(REDRAWSOUND, 0);
+                                       allqueue(REDRAWMARKER, 0);
                                }                               
                                break;
                                
@@ -1742,11 +1730,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        shift_nlastrips_down();
                                else {
                                        nextprev_marker(-1);
-                                       allqueue(REDRAWTIME, 0);
-                                       allqueue(REDRAWIPO, 0);
-                                       allqueue(REDRAWACTION, 0);
-                                       allqueue(REDRAWNLA, 0);
-                                       allqueue(REDRAWSOUND, 0);
+                                       allqueue(REDRAWMARKER, 0);
                                }
                                break;
                                
@@ -1758,11 +1742,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                }
                                else if (G.qual & LR_CTRLKEY) {
                                        deselect_markers(1, 0);
-                                       allqueue(REDRAWTIME, 0);
-                                       allqueue(REDRAWIPO, 0);
-                                       allqueue(REDRAWACTION, 0);
-                                       allqueue(REDRAWNLA, 0);
-                                       allqueue(REDRAWSOUND, 0);
+                                       allqueue(REDRAWMARKER, 0);
                                }
                                else{
                                        if (mval[0]>=NLAWIDTH)
@@ -1831,11 +1811,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        rename_marker();
                                else 
                                        break;
-                               allqueue(REDRAWTIME, 0);
-                               allqueue(REDRAWIPO, 0);
-                               allqueue(REDRAWACTION, 0);
-                               allqueue(REDRAWNLA, 0);
-                               allqueue(REDRAWSOUND, 0);
+                               allqueue(REDRAWMARKER, 0);
                                break;                          
                        
                        case NKEY:
@@ -1856,11 +1832,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        anim_previewrange_set();
                                else if (G.qual & LR_ALTKEY) /* clear preview range */
                                        anim_previewrange_clear();
-                               allqueue(REDRAWTIME, 0);
-                               allqueue(REDRAWBUTSALL, 0);
-                               allqueue(REDRAWACTION, 0);
-                               allqueue(REDRAWNLA, 0);
-                               allqueue(REDRAWIPO, 0);
+                               allqueue(REDRAWMARKER, 0);
                                break;
                                
                        case SKEY:
@@ -1908,11 +1880,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                                
                                                remove_marker();
                                                
-                                               allqueue(REDRAWTIME, 0);
-                                               allqueue(REDRAWIPO, 0);
-                                               allqueue(REDRAWACTION, 0);
-                                               allqueue(REDRAWNLA, 0);
-                                               allqueue(REDRAWSOUND, 0);
+                                               allqueue(REDRAWMARKER, 0);
                                        }
                                }
                                break;
index 1062649a8f2b910e42d782e86646f1e1595f13b3..8f35e64b79fe4d2107993f1916cc80a92974dcf0 100644 (file)
@@ -1082,7 +1082,7 @@ void reset_slowparents(void)
 {
        /* back to original locations */
        Base *base;
-       
+
        base= FIRSTBASE;
        while(base) {
                if(base->object->parent) {
@@ -1740,7 +1740,7 @@ void exit_editmode(int flag)      /* freedata==0 at render, 1= freedata, 2= do undo b
        /* total remake of softbody data */
        if(modifiers_isSoftbodyEnabled(ob)) {
                if (ob->soft && ob->soft->keys) {
-                       notice("Erased Baked SoftBody");
+                       notice("Erase Baked SoftBody");
                }
 
                sbObjectToSoftbody(ob);
@@ -2428,12 +2428,12 @@ void special_editmenu(void)
                        esubdivideflag(1, fac, G.scene->toolsettings->editbutflag | B_SMOOTH, 1, 0);
                        BIF_undo_push("Subdivide Smooth");
                        break;          
-                       
+
                case 4:
                        mergemenu();
                        break;
                case 5:
-                       notice("Removed %d Vertices", removedoublesflag(1, G.scene->toolsettings->doublimit));
+                       notice("Removed %d Vertices", removedoublesflag(1, 1, G.scene->toolsettings->doublimit));
                        BIF_undo_push("Remove Doubles");
                        break;
                case 6:
@@ -3386,6 +3386,9 @@ void copy_attr(short event)
                                else if(event==29) { /* protected bits */
                                        base->object->protectflag= ob->protectflag;
                                }
+                               else if(event==30) { /* index object */
+                                       base->object->index= ob->index;
+                               }
                        }
                }
                base= base->next;
@@ -3448,6 +3451,8 @@ void copy_attr_menu()
 
        if(ob->soft) strcat(str, "|Soft Body Settings%x23");
        
+       strcat(str, "|Pass Index%x30");
+       
        if(ob->type==OB_MESH || ob->type==OB_CURVE || ob->type==OB_LATTICE || ob->type==OB_SURF){
                strcat(str, "|Modifiers ...%x24");
        }
index 67fd86e5e9cd38f8821a1d23517a1e40d3b95e6a..70c37b8f2cbd08991e94f0b2b6ec47bf94d568e4 100644 (file)
@@ -83,6 +83,7 @@
 #include "BIF_editview.h"
 #include "BIF_scrarea.h"
 #include "BIF_editsound.h"
+#include "BIF_imasel.h"
 
 #include "BSE_edit.h"
 #include "BSE_sequence.h"
@@ -90,6 +91,7 @@
 #include "BSE_filesel.h"
 #include "BSE_drawipo.h"
 #include "BSE_seqaudio.h"
+#include "BSE_time.h"
 
 #include "BDR_editobject.h"
 
@@ -137,12 +139,113 @@ void set_last_seq(Sequence *seq)
        _last_seq_init = 1;
 }
 
-void clear_last_seq()
+void clear_last_seq(Sequence *seq)
 {
        _last_seq = NULL;
        _last_seq_init = 0;
 }
 
+
+/* seq funcs's for transforming internally
+ notice the difference between start/end and left/right.
+ left and right are the bounds at which the setuence is rendered,
+start and end are from the start and fixed length of the sequence.
+*/
+int seq_tx_get_start(Sequence *seq) {
+       return seq->start;
+}
+int seq_tx_get_end(Sequence *seq)
+{
+       return seq->start+seq->len;
+}
+
+int seq_tx_get_final_left(Sequence *seq)
+{
+       return (seq->start - seq->startstill) + seq->startofs;
+}
+int  seq_tx_get_final_right(Sequence *seq)
+{
+       return ((seq->start+seq->len) + seq->endstill) - seq->endofs;
+}
+
+void seq_tx_set_final_left(Sequence *seq, int val)
+{
+       if (val < (seq)->start) {
+               seq->startstill = abs(val - (seq)->start);
+                               (seq)->startofs = 0;
+       } else {
+               seq->startofs = abs(val - (seq)->start);
+               seq->startstill = 0;
+       }
+}
+
+void seq_tx_set_final_right(Sequence *seq, int val)
+{
+       if (val > (seq)->start + (seq)->len) {
+               seq->endstill = abs(val - (seq->start + (seq)->len));
+               (seq)->endofs = 0;
+       } else {
+               seq->endofs = abs(val - ((seq)->start + (seq)->len));
+               seq->endstill = 0;
+       }
+}
+
+/* check if one side can be transformed */
+int seq_tx_check_left(Sequence *seq)
+{
+       if (seq->flag & SELECT) {
+               if (seq->flag & SEQ_LEFTSEL)
+                       return 1;
+               else if (seq->flag & SEQ_RIGHTSEL)
+                       return 0;
+               
+               return 1; /* selected and neither left or right handles are, so let us move both */
+       }
+       return 0;
+}
+
+int seq_tx_check_right(Sequence *seq)
+{
+       if (seq->flag & SELECT) {
+               if (seq->flag & SEQ_RIGHTSEL)
+                       return 1;
+               else if (seq->flag & SEQ_LEFTSEL)
+                       return 0;
+               
+               return 1; /* selected and neither left or right handles are, so let us move both */
+       }
+       return 0;
+}
+
+/* used so we can do a quick check for single image seq
+   since they work a bit differently to normal image seq's (during transform) */
+int check_single_image_seq(Sequence *seq)
+{
+       if (seq->type == SEQ_IMAGE && seq->len == 1 )
+               return 1;
+       else
+               return 0;
+}
+
+static void fix_single_image_seq(Sequence *seq)
+{
+       int left, start, offset;
+       if (!check_single_image_seq(seq))
+               return;
+       
+       /* make sure the image is always at the start since there is only one,
+          adjusting its start should be ok */
+       left = seq_tx_get_final_left(seq);
+       start = seq->start;
+       if (start != left) {
+               offset = left - start;
+               seq_tx_set_final_left( seq, seq_tx_get_final_left(seq) - offset );
+               seq_tx_set_final_right( seq, seq_tx_get_final_right(seq) - offset );
+               seq->start += offset;
+       }
+}
+
 static void change_plugin_seq(char *str)       /* called from fileselect */
 {
        struct SeqEffectHandle sh;
@@ -160,7 +263,7 @@ static void change_plugin_seq(char *str)    /* called from fileselect */
 
        if( test_overlap_seq(last_seq) ) shuffle_seq(last_seq);
        
-       BIF_undo_push("Load/change Sequencer plugin");
+       BIF_undo_push("Load/Change Plugin, Sequencer");
 }
 
 
@@ -201,46 +304,92 @@ int sequence_is_free_transformable(Sequence * seq)
                || (get_sequence_effect_num_inputs(seq->type) == 0);
 }
 
-Sequence *find_neighboring_sequence(Sequence *test, int lr) {
-/* looks to the left on lr==1, to the right on lr==2 */
-       Sequence *seq,*foundneighbor = 0;
-       int found=0;
+Sequence *find_neighboring_sequence(Sequence *test, int lr, int sel) {
+/*     looks to the left on lr==1, to the right on lr==2
+       sel - 0==unselected, 1==selected, -1==done care*/
+       Sequence *seq;
        Editing *ed;
 
        ed= G.scene->ed;
        if(ed==0) return 0;
 
+       if (sel>0) sel = SELECT;
+       
        seq= ed->seqbasep->first;
        while(seq) {
-               if(seq!=test) {
-                       if (test->machine==seq->machine) {
-                               if(test->depth==seq->depth) {
-                                       switch (lr) {
-                                       case 1:
-                                               if (test->startdisp == (seq->enddisp)) {
-                                                       foundneighbor=seq;
-                                                       found=1;
-                                               }
-                                               break;
-                                       case 2:
-                                               if (test->enddisp == (seq->startdisp)) {
-                                                       foundneighbor=seq;
-                                                       found=1;
-                                               }
-                                               break;
-                                       }
+               if(     (seq!=test) &&
+                       (test->machine==seq->machine) &&
+                       (test->depth==seq->depth) && 
+                       ((sel == -1) || (sel && (seq->flag & SELECT)) || (sel==0 && (seq->flag & SELECT)==0)  ))
+               {
+                       switch (lr) {
+                       case 1:
+                               if (test->startdisp == (seq->enddisp)) {
+                                       return seq;
+                               }
+                               break;
+                       case 2:
+                               if (test->enddisp == (seq->startdisp)) {
+                                       return seq;
                                }
+                               break;
                        }
                }
                seq= seq->next;
        }
-       if (found==1) {
-               return foundneighbor;
-       } else {
-               return 0;
+       return NULL;
+}
+
+Sequence *find_next_prev_sequence(Sequence *test, int lr, int sel) {
+/*     looks to the left on lr==1, to the right on lr==2
+       sel - 0==unselected, 1==selected, -1==done care*/
+       Sequence *seq,*best_seq = NULL;
+       Editing *ed;
+       
+       int dist, best_dist;
+       best_dist = MAXFRAME*2;
+
+       ed= G.scene->ed;
+       if(ed==0) return 0;
+
+       if (sel) sel = SELECT;
+       
+       seq= ed->seqbasep->first;
+       while(seq) {
+               if(             (seq!=test) &&
+                               (test->machine==seq->machine) &&
+                               (test->depth==seq->depth) &&
+                               ((sel == -1) || (sel==(seq->flag & SELECT))))
+               {
+                       dist = MAXFRAME*2;
+                       
+                       switch (lr) {
+                       case 1:
+                               if (seq->enddisp <= test->startdisp) {
+                                       dist = test->enddisp - seq->startdisp;
+                               }
+                               break;
+                       case 2:
+                               if (seq->startdisp >= test->enddisp) {
+                                       dist = seq->startdisp - test->enddisp;
+                               }
+                               break;
+                       }
+                       
+                       if (dist==0) {
+                               best_seq = seq;
+                               break;
+                       } else if (dist < best_dist) {
+                               best_dist = dist;
+                               best_seq = seq;
+                       }
+               }
+               seq= seq->next;
        }
+       return best_seq; /* can be null */
 }
 
+
 Sequence *find_nearest_seq(int *hand)
 {
        Sequence *seq;
@@ -435,7 +584,7 @@ static void deselect_all_seq(void)
        }
        END_SEQ
                
-       BIF_undo_push("(De)select all Sequencer");
+       BIF_undo_push("(De)select all Strips, Sequencer");
 }
 
 static void recurs_sel_seq(Sequence *seqm)
@@ -477,7 +626,7 @@ void swap_select_seq(void)
        END_SEQ
 
        allqueue(REDRAWSEQ, 0);
-       BIF_undo_push("Swap select all Sequencer");
+       BIF_undo_push("Swap Selected Strips, Sequencer");
 
 }
 
@@ -510,21 +659,27 @@ void select_channel_direction(Sequence *test,int lr) {
 void select_dir_from_last(int lr)
 {
        Sequence *seq=get_last_seq();
+       if (seq==NULL)
+               return;
+       
+       select_channel_direction(seq,lr);
+       allqueue(REDRAWSEQ, 0);
        
-       if (seq) select_channel_direction(seq,lr);
+       if (lr==1)      BIF_undo_push("Select Strips to the Left, Sequencer");
+       else            BIF_undo_push("Select Strips to the Right, Sequencer");
 }
 
 void select_surrounding_handles(Sequence *test) 
 {
        Sequence *neighbor;
        
-       neighbor=find_neighboring_sequence(test, 1);
+       neighbor=find_neighboring_sequence(test, 1, -1);
        if (neighbor) {
                neighbor->flag |= SELECT;
                recurs_sel_seq(neighbor);
                neighbor->flag |= SEQ_RIGHTSEL;
        }
-       neighbor=find_neighboring_sequence(test, 2);
+       neighbor=find_neighboring_sequence(test, 2, -1);
        if (neighbor) {
                neighbor->flag |= SELECT;
                recurs_sel_seq(neighbor);
@@ -537,16 +692,21 @@ void select_surround_from_last()
 {
        Sequence *seq=get_last_seq();
        
-       if (seq) select_surrounding_handles(seq);
+       if (seq==NULL)
+               return;
+       
+       select_surrounding_handles(seq);
+       allqueue(REDRAWSEQ, 0);
+       BIF_undo_push("Select Surrounding Handles, Sequencer");
 }
 
 void select_neighbor_from_last(int lr)
 {
        Sequence *seq=get_last_seq();
        Sequence *neighbor;
-       
+       int change = 0;
        if (seq) {
-               neighbor=find_neighboring_sequence(seq, lr);
+               neighbor=find_neighboring_sequence(seq, lr, -1);
                if (neighbor) {
                        switch (lr) {
                        case 1:
@@ -563,107 +723,156 @@ void select_neighbor_from_last(int lr)
                                break;
                        }
                seq->flag |= SELECT;
+               change = 1;
                }
        }
+       if (change) {
+               allqueue(REDRAWSEQ, 0);
+               
+               if (lr==1)      BIF_undo_push("Select Left Handles, Sequencer");
+               else            BIF_undo_push("Select Right Handles, Sequencer");
+       }
 }
 
 void mouse_select_seq(void)
 {
        Sequence *seq,*neighbor;
        int hand,seldir;
-
-       seq= find_nearest_seq(&hand);
-
-       if(!(G.qual & LR_SHIFTKEY)&&!(G.qual & LR_ALTKEY)&&!(G.qual & LR_CTRLKEY)) deselect_all_seq();
-
-       if(seq) {
-               set_last_seq(seq);
-
-               if ((seq->type == SEQ_IMAGE) || (seq->type == SEQ_MOVIE)) {
-                       if(seq->strip) {
-                               strncpy(last_imagename, seq->strip->dir, FILE_MAXDIR-1);
-                       }
-               } else
-               if (seq->type == SEQ_HD_SOUND || seq->type == SEQ_RAM_SOUND) {
-                       if(seq->strip) {
-                               strncpy(last_sounddir, seq->strip->dir, FILE_MAXDIR-1);
-                       }
-               }
-
-               if((G.qual & LR_SHIFTKEY) && (seq->flag & SELECT)) {
-                       if(hand==0) seq->flag &= SEQ_DESEL;
-                       else if(hand==1) {
-                               if(seq->flag & SEQ_LEFTSEL) 
-                                       seq->flag &= ~SEQ_LEFTSEL;
-                               else seq->flag |= SEQ_LEFTSEL;
-                       }
-                       else if(hand==2) {
-                               if(seq->flag & SEQ_RIGHTSEL) 
-                                       seq->flag &= ~SEQ_RIGHTSEL;
-                               else seq->flag |= SEQ_RIGHTSEL;
-                       }
+       TimeMarker *marker;
+       
+       marker=find_nearest_marker(1);
+       
+       if (marker) {
+               int oldflag;
+               /* select timeline marker */
+               if ((G.qual & LR_SHIFTKEY)==0) {
+                       oldflag= marker->flag;
+                       deselect_markers(0, 0);
+                       
+                       if (oldflag & SELECT)
+                               marker->flag &= ~SELECT;
+                       else
+                               marker->flag |= SELECT;
                }
                else {
-                       seq->flag |= SELECT;
-                       if(hand==1) seq->flag |= SEQ_LEFTSEL;
-                       if(hand==2) seq->flag |= SEQ_RIGHTSEL;
+                       marker->flag |= SELECT;                         
                }
+               allqueue(REDRAWMARKER, 0);
+               force_draw(0);
+
+               BIF_undo_push("Select Strips, Sequencer");
                
-               /* On Ctrl-Alt selection, select the strip and bordering handles */
-               if ((G.qual & LR_CTRLKEY) && (G.qual & LR_ALTKEY)) {
-                       if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
-                       seq->flag |= SELECT;
-                       select_surrounding_handles(seq);
+       } else {
+       
+               seq= find_nearest_seq(&hand);
+               if(!(G.qual & LR_SHIFTKEY)&&!(G.qual & LR_ALTKEY)&&!(G.qual & LR_CTRLKEY)) deselect_all_seq();
+       
+               if(seq) {
+                       set_last_seq(seq);
+       
+                       if ((seq->type == SEQ_IMAGE) || (seq->type == SEQ_MOVIE)) {
+                               if(seq->strip) {
+                                       strncpy(last_imagename, seq->strip->dir, FILE_MAXDIR-1);
+                               }
+                       } else
+                       if (seq->type == SEQ_HD_SOUND || seq->type == SEQ_RAM_SOUND) {
+                               if(seq->strip) {
+                                       strncpy(last_sounddir, seq->strip->dir, FILE_MAXDIR-1);
+                               }
+                       }
+       
+                       if((G.qual & LR_SHIFTKEY) && (seq->flag & SELECT)) {
+                               if(hand==0) seq->flag &= SEQ_DESEL;
+                               else if(hand==1) {
+                                       if(seq->flag & SEQ_LEFTSEL) 
+                                               seq->flag &= ~SEQ_LEFTSEL;
+                                       else seq->flag |= SEQ_LEFTSEL;
+                               }
+                               else if(hand==2) {
+                                       if(seq->flag & SEQ_RIGHTSEL) 
+                                               seq->flag &= ~SEQ_RIGHTSEL;
+                                       else seq->flag |= SEQ_RIGHTSEL;
+                               }
+                       }
+                       else {
+                               seq->flag |= SELECT;
+                               if(hand==1) seq->flag |= SEQ_LEFTSEL;
+                               if(hand==2) seq->flag |= SEQ_RIGHTSEL;
+                       }
                        
-               /* Ctrl signals Left, Alt signals Right
-                  First click selects adjacent handles on that side.
-                  Second click selects all strips in that direction.
-                  If there are no adjacent strips, it just selects all in that direction. */
-               } else if (((G.qual & LR_CTRLKEY) || (G.qual & LR_ALTKEY)) && (seq->flag & SELECT)) {
-       
-                       if (G.qual & LR_CTRLKEY) seldir=1;
-                               else seldir=2;
-                       neighbor=find_neighboring_sequence(seq, seldir);
-                       if (neighbor) {
-                               switch (seldir) {
-                               case 1:
-                                       if ((seq->flag & SEQ_LEFTSEL)&&(neighbor->flag & SEQ_RIGHTSEL)) {
-                                               if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
-                                               select_channel_direction(seq,1);
-                                       } else {
-                                               neighbor->flag |= SELECT;
-                                               recurs_sel_seq(neighbor);
-                                               neighbor->flag |= SEQ_RIGHTSEL;
-                                               seq->flag |= SEQ_LEFTSEL;
-                                       }
-                                       break;
-                               case 2:
-                                       if ((seq->flag & SEQ_RIGHTSEL)&&(neighbor->flag & SEQ_LEFTSEL)) {
-                                               if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
-                                               select_channel_direction(seq,2);
-                                       } else {
-                                               neighbor->flag |= SELECT;
-                                               recurs_sel_seq(neighbor);
-                                               neighbor->flag |= SEQ_LEFTSEL;
-                                               seq->flag |= SEQ_RIGHTSEL;
+                       /* On Ctrl-Alt selection, select the strip and bordering handles */
+                       if ((G.qual & LR_CTRLKEY) && (G.qual & LR_ALTKEY)) {
+                               if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+                               seq->flag |= SELECT;
+                               select_surrounding_handles(seq);
+                               
+                       /* Ctrl signals Left, Alt signals Right
+                       First click selects adjacent handles on that side.
+                       Second click selects all strips in that direction.
+                       If there are no adjacent strips, it just selects all in that direction. */
+                       } else if (((G.qual & LR_CTRLKEY) || (G.qual & LR_ALTKEY)) && (seq->flag & SELECT)) {
+               
+                               if (G.qual & LR_CTRLKEY) seldir=1;
+                                       else seldir=2;
+                               neighbor=find_neighboring_sequence(seq, seldir, -1);
+                               if (neighbor) {
+                                       switch (seldir) {
+                                       case 1:
+                                               if ((seq->flag & SEQ_LEFTSEL)&&(neighbor->flag & SEQ_RIGHTSEL)) {
+                                                       if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+                                                       select_channel_direction(seq,1);
+                                               } else {
+                                                       neighbor->flag |= SELECT;
+                                                       recurs_sel_seq(neighbor);
+                                                       neighbor->flag |= SEQ_RIGHTSEL;
+                                                       seq->flag |= SEQ_LEFTSEL;
+                                               }
+                                               break;
+                                       case 2:
+                                               if ((seq->flag & SEQ_RIGHTSEL)&&(neighbor->flag & SEQ_LEFTSEL)) {
+                                                       if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+                                                       select_channel_direction(seq,2);
+                                               } else {
+                                                       neighbor->flag |= SELECT;
+                                                       recurs_sel_seq(neighbor);
+                                                       neighbor->flag |= SEQ_LEFTSEL;
+                                                       seq->flag |= SEQ_RIGHTSEL;
+                                               }
+                                               break;
                                        }
-                                       break;
+                               } else {
+                                       if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+                                       select_channel_direction(seq,seldir);
                                }
-                       } else {
-                               if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
-                               select_channel_direction(seq,seldir);
                        }
-               }
-               
-               recurs_sel_seq(seq);
-       }
 
-       force_draw(0);
+                       recurs_sel_seq(seq);
+               }
+               force_draw(0);
 
-       if(get_last_seq()) allqueue(REDRAWIPO, 0);
-       BIF_undo_push("Select Sequencer");
+               if(get_last_seq()) allqueue(REDRAWIPO, 0);
+               BIF_undo_push("Select Strips, Sequencer");
 
-       std_rmouse_transform(transform_seq);
+               std_rmouse_transform(transform_seq_nomarker);
+       }
+       
+       /* marker transform */
+       if (marker) {
+               short mval[2], xo, yo;
+               getmouseco_areawin(mval);
+               xo= mval[0]; 
+               yo= mval[1];
+               
+               while(get_mbut()&R_MOUSE) {             
+                       getmouseco_areawin(mval);
+                       if(abs(mval[0]-xo)+abs(mval[1]-yo) > 4) {
+                               transform_markers('g', 0);
+                               allqueue(REDRAWMARKER, 0);
+                               return;
+                       }
+                       BIF_wait_for_statechange();
+               }
+       }
 }
 
 
@@ -1090,8 +1299,8 @@ static void add_image_strips(char *name)
 
        waitcursor(0);
 
-       BIF_undo_push("Add image strip Sequencer");
-       transform_seq('g', 0);
+       BIF_undo_push("Add Image Strip, Sequencer");
+       transform_seq_nomarker('g', 0);
 
 }
 
@@ -1125,8 +1334,8 @@ static void add_movie_strip(char *name)
 
        waitcursor(0);
 
-       BIF_undo_push("Add movie strip Sequencer");
-       transform_seq('g', 0);
+       BIF_undo_push("Add Movie Strip, Sequencer");
+       transform_seq_nomarker('g', 0);
 
 }
 
@@ -1161,8 +1370,8 @@ static void add_movie_and_hdaudio_strip(char *name)
 
        waitcursor(0);
 
-       BIF_undo_push("Add movie and HD-audio strip Sequencer");
-       transform_seq('g', 0);
+       BIF_undo_push("Add Movie and HD-Audio Strip, Sequencer");
+       transform_seq_nomarker('g', 0);
 
 }
 
@@ -1190,8 +1399,8 @@ static void add_sound_strip_ram(char *name)
 
        waitcursor(0);
 
-       BIF_undo_push("Add ram sound strip Sequencer");
-       transform_seq('g', 0);
+       BIF_undo_push("Add Sound (RAM) Strip, Sequencer");
+       transform_seq_nomarker('g', 0);
 }
 
 static void add_sound_strip_hd(char *name)
@@ -1218,8 +1427,8 @@ static void add_sound_strip_hd(char *name)
 
        waitcursor(0);
 
-       BIF_undo_push("Add hd sound strip Sequencer");
-       transform_seq('g', 0);
+       BIF_undo_push("Add Sound (HD) Strip, Sequencer");
+       transform_seq_nomarker('g', 0);
 }
 
 #if 0
@@ -1459,12 +1668,12 @@ static int add_seq_effect(int type, char *str)
 
        /* push undo and go into grab mode */
        if(newseq->type == SEQ_PLUGIN) {
-               BIF_undo_push("Add plugin strip Sequencer");
+               BIF_undo_push("Add Plugin Strip, Sequencer");
        } else {
-               BIF_undo_push("Add effect strip Sequencer");
+               BIF_undo_push("Add Effect Strip, Sequencer");
        }
 
-       transform_seq('g', 0);
+       transform_seq_nomarker('g', 0);
 
        return 1;
 }
@@ -1555,7 +1764,7 @@ void add_sequence(int type)
        }
        else {
                event= pupmenu("Add Sequence Strip%t"
-                              "|Images%x1"
+                              "|Image Sequence%x1"
                               "|Movie%x102"
 #ifdef WITH_FFMPEG
                                   "|Movie + Audio (HD)%x105"
@@ -1591,8 +1800,11 @@ void add_sequence(int type)
 
        switch(event) {
        case 1:
-
-               activate_fileselect(FILE_SPECIAL, "Select Images", last_imagename, add_image_strips);
+               /* Image Dosnt work at the moment - TODO */
+               //if(G.qual & LR_CTRLKEY)
+               //      activate_imageselect(FILE_SPECIAL, "Select Images", last_imagename, add_image_strips);
+               //else
+                       activate_fileselect(FILE_SPECIAL, "Select Images", last_imagename, add_image_strips);
                break;
        case 105:
                activate_fileselect(FILE_SPECIAL, "Select Movie+Audio", last_imagename, add_movie_and_hdaudio_strip);
@@ -1638,8 +1850,8 @@ void add_sequence(int type)
                                strip->us= 1;
                                if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
 
-                               BIF_undo_push("Add scene strip Sequencer");
-                               transform_seq('g', 0);
+                               BIF_undo_push("Add Scene Strip, Sequencer");
+                               transform_seq_nomarker('g', 0);
                        }
                }
                MEM_freeN(str);
@@ -1744,7 +1956,7 @@ void change_sequence(void)
 
                        update_changed_seq_and_deps(last_seq, 0, 1);
                        allqueue(REDRAWSEQ, 0);
-                       BIF_undo_push("Change effect Sequencer");
+                       BIF_undo_push("Change Strip Effect, Sequencer");
                }
        }
        else if(last_seq->type == SEQ_IMAGE) {
@@ -1901,7 +2113,7 @@ void del_seq(void)
                ms= ms->prev;
        }
 
-       BIF_undo_push("Delete from Sequencer");
+       BIF_undo_push("Delete Strip(s), Sequencer");
        allqueue(REDRAWSEQ, 0);
 }
 
@@ -1915,12 +2127,12 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
        seq= old->first;
 
        while(seq) {
-               seq->newseq= 0;
+               seq->tmp= NULL;
                if(seq->flag & SELECT) {
 
                        if(seq->type==SEQ_META) {
                                seqn= MEM_dupallocN(seq);
-                               seq->newseq= seqn;
+                               seq->tmp= seqn;
                                BLI_addtail(new, seqn);
 
                                seqn->strip= MEM_dupallocN(seq->strip);
@@ -1936,7 +2148,7 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
                        }
                        else if(seq->type == SEQ_SCENE) {
                                seqn= MEM_dupallocN(seq);
-                               seq->newseq= seqn;
+                               seq->tmp= seqn;
                                BLI_addtail(new, seqn);
 
                                seqn->strip= MEM_dupallocN(seq->strip);
@@ -1948,7 +2160,7 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
                        }
                        else if(seq->type == SEQ_MOVIE) {
                                seqn= MEM_dupallocN(seq);
-                               seq->newseq= seqn;
+                               seq->tmp= seqn;
                                BLI_addtail(new, seqn);
 
                                seqn->strip= MEM_dupallocN(seq->strip);
@@ -1971,7 +2183,7 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
                        }
                        else if(seq->type == SEQ_RAM_SOUND) {
                                seqn= MEM_dupallocN(seq);
-                               seq->newseq= seqn;
+                               seq->tmp= seqn;
                                BLI_addtail(new, seqn);
 
                                seqn->strip= MEM_dupallocN(seq->strip);
@@ -1996,7 +2208,7 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
                        }
                        else if(seq->type == SEQ_HD_SOUND) {
                                seqn= MEM_dupallocN(seq);
-                               seq->newseq= seqn;
+                               seq->tmp= seqn;
                                BLI_addtail(new, seqn);
 
                                seqn->strip= MEM_dupallocN(seq->strip);
@@ -2021,7 +2233,7 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
                        }
                        else if(seq->type < SEQ_EFFECT) {
                                seqn= MEM_dupallocN(seq);
-                               seq->newseq= seqn;
+                               seq->tmp= seqn;
                                BLI_addtail(new, seqn);
 
                                seqn->strip->us++;
@@ -2031,12 +2243,12 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
                        }
                        else {
                                seqn= MEM_dupallocN(seq);
-                               seq->newseq= seqn;
+                               seq->tmp= seqn;
                                BLI_addtail(new, seqn);
 
-                               if(seq->seq1 && seq->seq1->newseq) seqn->seq1= seq->seq1->newseq;
-                               if(seq->seq2 && seq->seq2->newseq) seqn->seq2= seq->seq2->newseq;
-                               if(seq->seq3 && seq->seq3->newseq) seqn->seq3= seq->seq3->newseq;
+                               if(seq->seq1 && seq->seq1->tmp) seqn->seq1= seq->seq1->tmp;
+                               if(seq->seq2 && seq->seq2->tmp) seqn->seq2= seq->seq2->tmp;
+                               if(seq->seq3 && seq->seq3->tmp) seqn->seq3= seq->seq3->tmp;
 
                                if(seqn->ipo) seqn->ipo->id.us++;
 
@@ -2076,8 +2288,8 @@ void add_duplicate_seq(void)
        recurs_dupli_seq(ed->seqbasep, &new);
        addlisttolist(ed->seqbasep, &new);
 
-       BIF_undo_push("Add duplicate Sequencer");
-       transform_seq('g', 0);
+       BIF_undo_push("Add Duplicate, Sequencer");
+       transform_seq_nomarker('g', 0);
 }
 
 int insert_gap(int gap, int cfra)
@@ -2193,7 +2405,7 @@ void seq_remap_paths(void)
        }
        END_SEQ
                
-       BIF_undo_push("Remap paths in Sequencer");
+       BIF_undo_push("Remap Paths, Sequencer");
        allqueue(REDRAWSEQ, 0);
 }
 
@@ -2220,7 +2432,7 @@ void no_gaps(void)
                }
        }
 
-       BIF_undo_push("No gaps Sequencer");
+       BIF_undo_push("No Gaps, Sequencer");
        allqueue(REDRAWSEQ, 0);
 }
 
@@ -2305,7 +2517,7 @@ void make_meta(void)
        if(seqm->len) seqm->strip->stripdata= MEM_callocN(seqm->len*sizeof(StripElem), "metastripdata");
        set_meta_stripdata(seqm);
 
-       BIF_undo_push("Make Meta Sequencer");
+       BIF_undo_push("Make Meta Strip, Sequencer");
        allqueue(REDRAWSEQ, 0);
 }
 
@@ -2328,7 +2540,7 @@ void un_meta(void)
 
        if(last_seq==0 || last_seq->type!=SEQ_META) return;
 
-       if(okee("Un Meta")==0) return;
+       if(okee("Un Meta Strip")==0) return;
 
        addlisttolist(ed->seqbasep, &last_seq->seqbase);
 
@@ -2358,7 +2570,7 @@ void un_meta(void)
 
        sort_seq();
 
-       BIF_undo_push("Un-make Meta Sequencer");
+       BIF_undo_push("Un-Make Meta Strip, Sequencer");
        allqueue(REDRAWSEQ, 0);
 
 }
@@ -2397,7 +2609,7 @@ void exit_meta(void)
        MEM_freeN(ms);
        allqueue(REDRAWSEQ, 0);
 
-       BIF_undo_push("Exit meta strip Sequence");
+       BIF_undo_push("Exit Meta Strip, Sequence");
 }
 
 
@@ -2424,33 +2636,113 @@ void enter_meta(void)
 
        set_last_seq(NULL);
        allqueue(REDRAWSEQ, 0);
-       BIF_undo_push("Enter meta strip Sequence");
+       BIF_undo_push("Enter Meta Strip, Sequence");
 }
 
 
 /* ****************** END META ************************* */
 
+static int seq_get_snaplimit(void)
+{
+       /* fake mouse coords to get the snap value
+       a bit lazy but its only done once pre transform */
+       float xmouse, ymouse, x;
+       short mval[2] = {24, 0}; /* 24 screen px snap */
+       areamouseco_to_ipoco(G.v2d, mval, &xmouse, &ymouse);
+       x = xmouse;
+       mval[0] = 0;
+       areamouseco_to_ipoco(G.v2d, mval, &xmouse, &ymouse);
+       return (int)(x - xmouse);
+}
 
 typedef struct TransSeq {
        int start, machine;
        int startstill, endstill;
        int startdisp, enddisp;
        int startofs, endofs;
+       int final_left, final_right;
        int len;
 } TransSeq;
 
+/* use to impose limits when dragging/extending - so impossible situations dont happen */
+static void transform_grab_xlimits(Sequence *seq, int leftflag, int rightflag)
+{
+       if(leftflag) {
+               if (seq_tx_get_final_left(seq) >= seq_tx_get_final_right(seq)) {
+                       seq_tx_set_final_left(seq, seq_tx_get_final_right(seq)-1);
+               }
+               
+               if (check_single_image_seq(seq)==0) {
+                       if (seq_tx_get_final_left(seq) >= seq_tx_get_end(seq)) {
+                               seq_tx_set_final_left(seq, seq_tx_get_end(seq)-1);
+                       }
+                       
+                       /* dosnt work now - TODO */
+                       /*
+                       if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq)) {
+                               int ofs;
+                               ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq);
+                               seq->start -= ofs;
+                               seq_tx_set_final_left(seq, seq_tx_get_final_left(seq) + ofs );
+                       }*/
+                       
+               }
+       }
+       
+       if(rightflag) {
+               if (seq_tx_get_final_right(seq) <=  seq_tx_get_final_left(seq)) {
+                       seq_tx_set_final_right(seq, seq_tx_get_final_left(seq)+1);
+               }
+                                                                       
+               if (check_single_image_seq(seq)==0) {
+                       if (seq_tx_get_final_right(seq) <= seq_tx_get_start(seq)) {
+                               seq_tx_set_final_right(seq, seq_tx_get_start(seq)+1);
+                       }
+               }
+       }
+       
+       /* sounds cannot be extended past their endpoints */
+       if (seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) {
+               seq->startstill= 0;
+               seq->endstill= 0;
+       }
+}
+
 void transform_seq(int mode, int context)
 {
-       Sequence *seq;
+       SpaceSeq *sseq= curarea->spacedata.first;
+       Sequence *seq, *last_seq;
        Editing *ed;
        float dx, dy, dvec[2], div;
        TransSeq *transmain, *ts;
-       int tot=0, ix, iy, firsttime=1, afbreek=0, midtog= 0, proj= 0;
+       int tot=0, firsttime=1, afbreek=0, midtog= 0, proj= 0;
+       int ix, iy; /* these values are used for storing the mouses offset from its original location */
+       int ix_old = 0;
        unsigned short event = 0;
        short mval[2], val, xo, yo, xn, yn;
        char str[32];
-
-       if(mode!='g') return;   /* from gesture */
+       char side; /* for extend mode only - use to know which side to extend on */
+       
+       /* used for extend in a number of places */
+       int cfra = CFRA;
+       
+       /* for snapping */
+       char snapskip = 0, snap, snap_old;
+       int snapdist_max = seq_get_snaplimit();
+       /* at the moment there are only 4 possible snap points,
+       -       last_seq (start,end)
+       -       selected bounds (start/end)
+       -       last_seq (next/prev)
+       -       current frame */
+       int snap_points[4], snap_point_num = 0;
+       int j; /* loop on snap_points */
+       
+       /* for markers */
+       int *oldframe = NULL, totmark, a;
+       TimeMarker *marker;
+       
+       
+       if(mode!='g' && mode!='e') return;      /* from gesture */
 
        /* which seqs are involved */
        ed= G.scene->ed;
@@ -2464,133 +2756,372 @@ void transform_seq(int mode, int context)
        if(tot==0) return;
 
        G.moving= 1;
-
+       
+       last_seq = get_last_seq();
+       
        ts=transmain= MEM_callocN(tot*sizeof(TransSeq), "transseq");
 
        WHILE_SEQ(ed->seqbasep) {
 
                if(seq->flag & SELECT) {
-
                        ts->start= seq->start;
                        ts->machine= seq->machine;
                        ts->startstill= seq->startstill;
                        ts->endstill= seq->endstill;
                        ts->startofs= seq->startofs;
                        ts->endofs= seq->endofs;
-
+                       
+                       /* for extend only */
+                       if (mode=='e') {
+                               ts->final_left = seq_tx_get_final_left(seq);
+                               ts->final_right = seq_tx_get_final_right(seq);
+                       }
                        ts++;
                }
        }
        END_SEQ
-
+       
        getmouseco_areawin(mval);
+       
+       /* choose the side based on which side of the playhead the mouse is on */
+       if (mode=='e') {
+               float xmouse, ymouse;
+               areamouseco_to_ipoco(G.v2d, mval, &xmouse, &ymouse);
+               side = (xmouse > cfra) ? 'R' : 'L';
+       }
+       
+       /* Markers */
+       if (sseq->flag & SEQ_MARKER_TRANS) {
+               for(marker= G.scene->markers.first; marker; marker= marker->next) {
+                       if(marker->flag & SELECT) totmark++;
+               }
+               if (totmark) {
+                       oldframe= MEM_mallocN(totmark*sizeof(int), "marker array");
+                       for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {
+                               if(marker->flag & SELECT) {
+                                       if (mode=='e') {
+                                               
+                                               /* when extending, invalidate markers on the other side by using an invalid frame value */
+                                               if ((side == 'L' && marker->frame > cfra) || (side == 'R' && marker->frame < cfra)) {
+                                                       oldframe[a] = MAXFRAME+1;
+                                               } else {
+                                                       oldframe[a]= marker->frame;
+                                               }
+                                       } else {
+                                               oldframe[a]= marker->frame;
+                                       }
+                                       a++;
+                               }
+                       }
+               }
+       }
+       
        xo=xn= mval[0];
        yo=yn= mval[1];
        dvec[0]= dvec[1]= 0.0;
 
        while(afbreek==0) {
                getmouseco_areawin(mval);
-               if(mval[0]!=xo || mval[1]!=yo || firsttime) {
-                       firsttime= 0;
+               G.qual = get_qual();
+               snap = (G.qual & LR_CTRLKEY) ? 1 : 0;
+               
+               if(mval[0]!=xo || mval[1]!=yo || firsttime || snap != snap_old) {
+                       if (firsttime) {
+                               snap_old = snap;
+                               firsttime= 0;
+                       }
+                       
+                       /* run for either grab or extend */
+                       dx= mval[0]- xo;
+                       dy= mval[1]- yo;
 
-                       if(mode=='g') {
+                       div= G.v2d->mask.xmax-G.v2d->mask.xmin;
+                       dx= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
 
-                               dx= mval[0]- xo;
-                               dy= mval[1]- yo;
+                       div= G.v2d->mask.ymax-G.v2d->mask.ymin;
+                       dy= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
 
-                               div= G.v2d->mask.xmax-G.v2d->mask.xmin;
-                               dx= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
+                       if(G.qual & LR_SHIFTKEY) {
+                               if(dx>1.0) dx= 1.0; else if(dx<-1.0) dx= -1.0;
+                       }
 
-                               div= G.v2d->mask.ymax-G.v2d->mask.ymin;
-                               dy= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
+                       dvec[0]+= dx;
+                       dvec[1]+= dy;
 
-                               if(G.qual & LR_SHIFTKEY) {
-                                       if(dx>1.0) dx= 1.0; else if(dx<-1.0) dx= -1.0;
+                       if(midtog) dvec[proj]= 0.0;
+                       ix= floor(dvec[0]+0.5);
+                       iy= floor(dvec[1]+0.5);
+                       
+                       ts= transmain;
+                       
+                       /* SNAP! use the active Seq */
+                       snap = G.qual & LR_CTRLKEY ? 1 : 0;
+                       
+                       if (!snap) {
+                               snapskip = 0;
+                       } else {
+                               int dist;
+                               int snap_ofs;
+                               int snap_dist= snapdist_max;
+                               
+                               /* Get sequence points to snap to the markers */
+                               
+                               snap_point_num=0;
+                               if (last_seq && (last_seq->flag & SELECT)) { /* active seq bounds */
+                                       if(seq_tx_check_left(last_seq))
+                                               snap_points[snap_point_num++] = seq_tx_get_final_left(last_seq);
+                                       if(seq_tx_check_right(last_seq))
+                                               snap_points[snap_point_num++] = seq_tx_get_final_right(last_seq);
+                                       
+                               }
+                               if (tot > 1) { /* selection bounds */
+                                       int bounds_left = MAXFRAME*2;
+                                       int bounds_right = -(MAXFRAME*2);
+                                       
+                                       WHILE_SEQ(ed->seqbasep) {
+                                               if(seq->flag & SELECT) {
+                                                       if(seq_tx_check_left(seq))
+                                                               bounds_left             = MIN2(bounds_left,     seq_tx_get_final_left(seq));
+                                                       if(seq_tx_check_right(seq))
+                                                               bounds_right    = MAX2(bounds_right,seq_tx_get_final_right(seq));
+                                               }
+                                       }
+                                       END_SEQ
+                                       
+                                       /* its possible there were no points to set on either side */
+                                       if (bounds_left != MAXFRAME*2)
+                                               snap_points[snap_point_num++] = bounds_left;
+                                       if (bounds_right != -(MAXFRAME*2))
+                                               snap_points[snap_point_num++] = bounds_right;
+                               }
+                               
+                               
+                               /* Define so we can snap to other points without hassle */
+                               
+#define TESTSNAP(test_frame)\
+                               for(j=0; j<snap_point_num; j++) {\
+                                       /* see if this beats the current best snap point */\
+                                       dist = abs(snap_points[j] - test_frame);\
+                                       if (dist < snap_dist) {\
+                                               snap_ofs = test_frame - snap_points[j];\
+                                               snap_dist = dist;\
+                                       }\
+                               }
+                               
+                               
+                               /* Detect the best marker to snap to! */
+                               for(a=0, marker= G.scene->markers.first; marker; a++, marker= marker->next) {
+                                       
+                                       /* dont snap to a marker on the wrong extend side */
+                                       if (mode=='e' && ((side == 'L' && marker->frame > cfra) || (side == 'R' && marker->frame < cfra)))
+                                               continue;
+                                       
+                                       /* when we are moving markers, dont snap to selected markers, durr */
+                                       if ((sseq->flag & SEQ_MARKER_TRANS)==0 || (marker->flag & SELECT)==0) {
+                                               
+                                               /* loop over the sticky points - max 4 */
+                                               TESTSNAP(marker->frame);
+                                               if (snap_dist == 0) break; /* alredy snapped? - stop looking */
+                                       }
+                               }
+                               
+                               if (snap_dist) {
+                                       TESTSNAP(cfra);
+                               }
+                               
+                               /* check seq's next to the active also - nice for quick snapping */
+                               if (snap_dist && seq_tx_check_left(last_seq)) {
+                                       seq = find_next_prev_sequence(last_seq, 1, 0); /* left */
+                                       if(seq && !seq_tx_check_right(seq))
+                                               TESTSNAP(seq_tx_get_final_right(seq));
+                               }
+                               
+                               if (snap_dist && seq_tx_check_right(last_seq)) {
+                                       seq = find_next_prev_sequence(last_seq, 2, 0); /* right */
+                                       if(seq && !seq_tx_check_left(seq))
+                                               TESTSNAP(seq_tx_get_final_left(seq));
                                }
 
-                               dvec[0]+= dx;
-                               dvec[1]+= dy;
-
-                               if(midtog) dvec[proj]= 0.0;
-                               ix= floor(dvec[0]+0.5);
-                               iy= floor(dvec[1]+0.5);
-
-
-                               ts= transmain;
-
+#undef TESTSNAP
+
+                               if (abs(ix_old-ix) >= snapdist_max) {
+                                       /* mouse has moved out of snap range */
+                                       snapskip = 0;
+                               } else if (snap_dist==0) {
+                                       /* nowhere to move, dont do anything */
+                                       snapskip = 1;
+                               } else if (snap_dist < snapdist_max) {
+                                       /* do the snapping by adjusting the mouse offset value */
+                                       ix = ix_old + snap_ofs;
+                               }
+                       }
+                       
+                       if (mode=='g' && !snapskip) {
+                               /* Grab */
                                WHILE_SEQ(ed->seqbasep) {
                                        if(seq->flag & SELECT) {
+                                               int myofs;
+                                               // SEQ_DEBUG_INFO(seq);
+                                               
+                                               /* X Transformation */
                                                if(seq->flag & SEQ_LEFTSEL) {
-                                                       if(ts->startstill) {
-                                                               seq->startstill= ts->startstill-ix;
-                                                               if(seq->startstill<0) seq->startstill= 0;
-                                                       }
-                                                       else if(ts->startofs) {
-                                                               seq->startofs= ts->startofs+ix;
-                                                               if(seq->startofs<0) seq->startofs= 0;
-                                                       }
-                                                       else {
-                                                               if(ix>0) {
-                                                                       seq->startofs= ix;
-                                                                       seq->startstill= 0;
-                                                               }
-                                                               else if (seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND) {
-                                                                       seq->startstill= -ix;
-                                                                       seq->startofs= 0;
-                                                               }
-                                                       }
-                                                       if(seq->len <= seq->startofs+seq->endofs) {
-                                                               seq->startofs= seq->len-seq->endofs-1;
-                                                       }
+                                                       myofs = (ts->startofs - ts->startstill);
+                                                       seq_tx_set_final_left(seq, ts->start + (myofs + ix));
                                                }
                                                if(seq->flag & SEQ_RIGHTSEL) {
-                                                       if(ts->endstill) {
-                                                               seq->endstill= ts->endstill+ix;
-                                                               if(seq->endstill<0) seq->endstill= 0;
-                                                       }
-                                                       else if(ts->endofs) {
-                                                               seq->endofs= ts->endofs-ix;
-                                                               if(seq->endofs<0) seq->endofs= 0;
-                                                       }
-                                                       else {
-                                                               if(ix<0) {
-                                                                       seq->endofs= -ix;
-                                                                       seq->endstill= 0;
-                                                               }
-                                                               else if (seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND) {
-                                                                       seq->endstill= ix;
-                                                                       seq->endofs= 0;
-                                                               }
-                                                       }
-                                                       if(seq->len <= seq->startofs+seq->endofs) {
-                                                               seq->endofs= seq->len-seq->startofs-1;
-                                                       }
+                                                       myofs = (ts->endstill - ts->endofs);
+                                                       seq_tx_set_final_right(seq, ts->start + seq->len + (myofs + ix));
                                                }
+                                               transform_grab_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL);
+                                               
                                                if( (seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) {
                                                        if(sequence_is_free_transformable(seq)) seq->start= ts->start+ ix;
 
+                                                       /* Y Transformation */
                                                        if(seq->depth==0) seq->machine= ts->machine+ iy;
 
                                                        if(seq->machine<1) seq->machine= 1;
                                                        else if(seq->machine>= MAXSEQ) seq->machine= MAXSEQ;
                                                }
-
                                                calc_sequence(seq);
-
                                                ts++;
                                        }
                                }
                                END_SEQ
-
-                               sprintf(str, "X: %d   Y: %d  ", ix, iy);
-                               headerprint(str);
+                               
+                               /* Markers */
+                               if (sseq->flag & SEQ_MARKER_TRANS) {
+                                       for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {
+                                               if(marker->flag & SELECT) {
+                                                       marker->frame= oldframe[a] + ix;
+                                                       a++;
+                                               }
+                                       }
+                               }
+                       
+                       /* Extend, grabs one side of the current frame */
+                       } else if (mode=='e' && !snapskip) {
+                               int myofs; /* offset from start of the seq clip */
+                               int xnew, final_left, final_right; /* just to store results from seq_tx_get_final_left/right */
+                               
+                               /* we dont use seq side selection flags for this,
+                               instead we need to calculate which sides to move
+                               based on its initial position from the cursor */
+                               int move_left, move_right;
+                               
+                               /* Extend, Similar to grab but operate on one side of the cursor */
+                               WHILE_SEQ(ed->seqbasep) {
+                                       if(seq->flag & SELECT) {
+                                               /* only move the contents of the metastrip otherwise the transformation is applied twice */
+                                               if (sequence_is_free_transformable(seq) && seq->type != SEQ_META) {
+                                                       
+                                                       move_left = move_right = 0;
+                                                       
+                                                       //SEQ_DEBUG_INFO(seq);
+                                                       
+                                                       final_left =    seq_tx_get_final_left(seq);
+                                                       final_right =   seq_tx_get_final_right(seq);
+                                                       
+                                                       /* Only X Axis moving */
+                                                       
+                                                       /* work out which sides to move first */
+                                                       if (side=='L') {
+                                                               if (final_left <= cfra || ts->final_left <= cfra)       move_left = 1;
+                                                               if (final_right <= cfra || ts->final_right <= cfra)     move_right = 1;
+                                                       } else {
+                                                               if (final_left >= cfra || ts->final_left >= cfra)       move_left = 1;
+                                                               if (final_right >= cfra || ts->final_right >= cfra)     move_right = 1;
+                                                       }
+                                                       
+                                                       if (move_left && move_right) {
+                                                               /* simple move - dont need to do anything complicated */
+                                                               seq->start= ts->start+ ix;
+                                                       } else {
+                                                               if (side=='L') {
+                                                                       if (move_left) {
+                                                                               
+                                                                               /* Similar to other funcs */
+                                                                               myofs = (ts->startofs - ts->startstill);
+                                                                               xnew = ts->start + (ix + myofs);
+                                                                               
+                                                                               /* make sure the we dont resize down to 0 or less in size
+                                                                               also include the startstill so the contense dosnt go outside the bounds, 
+                                                                               if the seq->startofs is 0 then its ignored */
+                                                                               
+                                                                               /* TODO remove, add check to transform_grab_xlimits, works ok for now */
+                                                                               if (xnew + seq->startstill > final_right-1) {
+                                                                                       xnew = (final_right-1) - seq->startstill;
+                                                                               }
+                                                                               /* Note, this is the only case where the start needs to be adjusted
+                                                                               since its not needed when modifying the end or when moving the entire sequence  */
+                                                                               //seq->start = ts->start+ix;   // This works when xnew is not clamped, line below takes clamping into account
+                                                                               seq->start= xnew - myofs;  /* TODO see above */
+                                                                               /* done with unique stuff */
+                                                                               
+                                                                               seq_tx_set_final_left(seq, xnew);
+                                                                               transform_grab_xlimits(seq, 1, 0);
+                                                                               
+                                                                               /* Special case again - setting the end back to what it was */
+                                                                               seq_tx_set_final_right(seq, final_right);
+                                                                       }
+                                                                       if (move_right) {
+                                                                               myofs = (ts->endstill - ts->endofs);
+                                                                               xnew = ts->start + seq->len + (myofs + ix);
+                                                                               seq_tx_set_final_right(seq, xnew);
+                                                                               transform_grab_xlimits(seq, 0, 1);
+                                                                       }
+                                                               } else { /* R */
+                                                                       if (move_left) {
+                                                                               myofs = (ts->startofs - ts->startstill);
+                                                                               xnew = ts->start + (myofs + ix);
+                                                                               seq_tx_set_final_left(seq, xnew);
+                                                                               transform_grab_xlimits(seq, 1, 0);
+                                                                       }
+                                                                       if (move_right) {
+                                                                               myofs = (ts->endstill - ts->endofs);
+                                                                               xnew = ts->start + seq->len + (myofs + ix);
+                                                                               seq_tx_set_final_right(seq, xnew);
+                                                                               transform_grab_xlimits(seq, 0, 1);
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                               calc_sequence(seq);
+                                               ts++;
+                                       }
+                               }
+                               END_SEQ
+                               
+                               /* markers */
+                               if (sseq->flag & SEQ_MARKER_TRANS) {
+                                       for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {\
+                                               if (marker->flag & SELECT) {
+                                                       if(oldframe[a] != MAXFRAME+1) {
+                                                               marker->frame= oldframe[a] + ix;
+                                                       }
+                                                       a++;
+                                               }
+                                       }
+                               }
                        }
-
+                       
+                       sprintf(str, "X: %d   Y: %d  ", ix, iy);
+                       headerprint(str);
+                       
+                       /* remember the last value for snapping,
+                       only set if we are not currently snapped,
+                       prevents locking on a keyframe */
+                       if (!snapskip)
+                               ix_old = ix; 
+                       
+                       /* just to tell if ctrl was pressed, this means we get a recalc when pressing ctrl */
+                       snap_old = snap;
+                       
+                       /* rememver last mouse values so we can skip transform when nothing happens */
                        xo= mval[0];
                        yo= mval[1];
 
                        /* test for effect and overlap */
-
                        WHILE_SEQ(ed->seqbasep) {
                                if(seq->flag & SELECT) {
                                        seq->flag &= ~SEQ_OVERLAP;
@@ -2607,6 +3138,7 @@ void transform_seq(int mode, int context)
                        END_SEQ;
 
                        force_draw(0);
+                       
                }
                else BIF_wait_for_statechange();
 
@@ -2658,14 +3190,31 @@ void transform_seq(int mode, int context)
                                else if(seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(seq);
                                else if(seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(seq);
                        }
-
                }
                END_SEQ
-       }
-       else {
+                               
+                               
+               /* Markers */
+               if (sseq->flag & SEQ_MARKER_TRANS) {
+                       for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {
+                               if (marker->flag & SELECT) {
+                                       if(oldframe[a] != MAXFRAME+1) {
+                                               marker->frame= oldframe[a];
+                                       }
+                                       a++;
+                               }
+                       }
+               }               
+       } else {
 
                /* images, effects and overlap */
                WHILE_SEQ(ed->seqbasep) {
+                       
+                       /* fixes single image strips - makes sure their start is not out of bounds
+                       ideally this would be done during transform since data is rendered at that time
+                       however it ends up being a lot messier! - Campbell */
+                       fix_single_image_seq(seq);
+                       
                        if(seq->type == SEQ_META) {
                                calc_sequence(seq);
                                seq->flag &= ~SEQ_OVERLAP;
@@ -2686,11 +3235,32 @@ void transform_seq(int mode, int context)
 
        G.moving= 0;
        MEM_freeN(transmain);
-
-       BIF_undo_push("Transform Sequencer");
+       
+       if (oldframe)
+               MEM_freeN(oldframe);
+       
+       if (mode=='g')
+               BIF_undo_push("Transform Grab, Sequencer");
+       else if (mode=='e')
+               BIF_undo_push("Transform Extend, Sequencer");
+       
        allqueue(REDRAWSEQ, 0);
 }
 
+/*     since grab can move markers, we must turn this off before adding a new sequence
+       I am not so happy with this, but the baddness in contained here - Campbell */
+void transform_seq_nomarker(int mode, int context) {
+       SpaceSeq *sseq= curarea->spacedata.first;
+       int flag_back;
+       if (!sseq) return; /* should never happen */
+       flag_back = sseq->flag;
+       sseq->flag &= ~SEQ_MARKER_TRANS;
+       
+       transform_seq(mode, context);
+       
+       sseq->flag = flag_back;
+}
+
 void seq_cut(int cutframe)
 {
        Editing *ed;
@@ -2710,7 +3280,7 @@ void seq_cut(int cutframe)
                }
        }
        if(seq) {
-               error("Cannot cut Meta strips");
+               error("Cannot Cut Meta Strips");
                return;
        }
        
@@ -2725,7 +3295,7 @@ void seq_cut(int cutframe)
        }
        
        if(tot==0) {
-               error("No strips to cut");
+               error("No Strips to Cut");
                return;
        }
        
@@ -2819,6 +3389,179 @@ void seq_cut(int cutframe)
        MEM_freeN(transmain);
        
        allqueue(REDRAWSEQ, 0);
+       BIF_undo_push("Cut Strips, Sequencer");
+}
+
+void seq_separate_images(void)
+{
+       Editing *ed;
+       Sequence *seq, *seq_new, *seq_next;
+       Strip *strip_new;
+       StripElem *se, *se_new;
+       int start_ofs, cfra, frame_end; 
+       static int step= 1;
+       
+       add_numbut(0, NUM|INT, "Image Duration:", 1, 256, &step, NULL);
+       if (!do_clever_numbuts("Separate Images", 1, REDRAW))
+               return;
+       
+       ed= G.scene->ed;
+       if(ed==0) return;
+       
+       seq= ed->seqbasep->first;
+       
+       while (seq) {
+               if((seq->flag & SELECT) && (seq->type == SEQ_IMAGE) && (seq->len > 1)) {
+                       /* remove seq so overlap tests dont conflict,
+                       see free_sequence below for the real free'ing */
+                       seq_next = seq->next;
+                       BLI_remlink(ed->seqbasep, seq); 
+                       if(seq->ipo) seq->ipo->id.us--;
+                       
+                       start_ofs = cfra = seq_tx_get_final_left(seq);
+                       frame_end = seq_tx_get_final_right(seq);
+                       
+                       while (cfra < frame_end) {
+                               /* new seq */
+                               se = give_stripelem(seq, cfra);
+                               
+                               seq_new= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, start_ofs, seq->machine);
+                               seq_new->type= SEQ_IMAGE;
+                               seq_new->len = 1;
+                               seq_new->endstill = step-1;
+                               
+                               /* new strip */
+                               seq_new->strip= strip_new= MEM_callocN(sizeof(Strip)*1, "strip");
+                               strip_new->len= 1;
+                               strip_new->us= 1;
+                               strncpy(strip_new->dir, seq->strip->dir, FILE_MAXDIR-1);
+                               
+                               /* new stripdata */
+                               strip_new->stripdata= se_new= MEM_callocN(sizeof(StripElem)*1, "stripelem");
+                               strncpy(se_new->name, se->name, FILE_MAXFILE-1);
+                               se_new->ok= 1;
+                               
+                               calc_sequence(seq_new);
+                               seq_new->flag &= ~SEQ_OVERLAP;
+                               if (test_overlap_seq(seq_new)) {
+                                       shuffle_seq(seq_new);
+                               }
+                               
+                               cfra++;
+                               start_ofs += step;
+                       }
+                       
+                       free_sequence(seq);
+                       seq = seq->next;
+               } else {
+                       seq = seq->next;
+               }
+       }
+       
+       /* as last: */
+       sort_seq();
+       BIF_undo_push("Separate Image Strips, Sequencer");
+       allqueue(REDRAWSEQ, 0);
+}
+
+/* run recursivly to select linked */
+static int select_more_less_seq__internal(int sel, int linked) {
+       Editing *ed;
+       Sequence *seq, *neighbor;
+       int change=0;
+       int isel;
+       
+       ed= G.scene->ed;
+       if(ed==0) return 0;
+       
+       if (sel) {
+               sel = SELECT;
+               isel = 0;
+       } else {
+               sel = 0;
+               isel = SELECT;
+       }
+       
+       if (!linked) {
+               /* if not linked we only want to touch each seq once, newseq */
+               for(seq= ed->seqbasep->first; seq; seq= seq->next) {
+                       seq->tmp = NULL;
+               }
+       }
+       
+       for(seq= ed->seqbasep->first; seq; seq= seq->next) {
+               if((int)(seq->flag & SELECT) == sel) {
+                       if ((linked==0 && seq->tmp)==0) {
+                               /* only get unselected nabours */
+                               neighbor = find_neighboring_sequence(seq, 1, isel);
+                               if (neighbor) {
+                                       if (sel) {neighbor->flag |= SELECT; recurs_sel_seq(neighbor);}
+                                       else            neighbor->flag &= ~SELECT;
+                                       if (linked==0) neighbor->tmp = (Sequence *)1;
+                                       change = 1;
+                               }
+                               neighbor = find_neighboring_sequence(seq, 2, isel);
+                               if (neighbor) {
+                                       if (sel) {neighbor->flag |= SELECT; recurs_sel_seq(neighbor);}
+                                       else            neighbor->flag &= ~SELECT;
+                                       if (linked==0) neighbor->tmp = (void *)1;
+                                       change = 1;
+                               }
+                       }
+               }
+       }
+       
+       return change;
+}
+
+void select_less_seq(void)
+{
+       if (select_more_less_seq__internal(0, 0)) {
+               BIF_undo_push("Select Less, Sequencer");
+               allqueue(REDRAWSEQ, 0);
+       }
+}
+
+void select_more_seq(void)
+{
+       if (select_more_less_seq__internal(1, 0)) {
+               BIF_undo_push("Select More, Sequencer");
+               allqueue(REDRAWSEQ, 0);
+       }
+}
+
+/* TODO not all modes supported - if you feel like being picky, add them! ;) */
+void select_linked_seq(int mode) {
+       Editing *ed;
+       Sequence *seq, *mouse_seq;
+       int selected, hand;
+       
+       ed= G.scene->ed;
+       if(ed==0) return;
+       
+       /* replace current selection */
+       if (mode==0 || mode==2) {
+               /* this works like UV, not mesh */
+               if (mode==0) {
+                       mouse_seq= find_nearest_seq(&hand);
+                       if (!mouse_seq)
+                               return; /* user error as with mesh?? */
+                       
+                       for(seq= ed->seqbasep->first; seq; seq= seq->next) {
+                               seq->flag &= ~SELECT;
+                       }
+                       mouse_seq->flag |= SELECT;
+                       recurs_sel_seq(mouse_seq);
+               }
+               
+               selected = 1;
+               while (selected) {
+                       selected = select_more_less_seq__internal(1, 1);
+               }
+               BIF_undo_push("Select Linked, Sequencer");
+               allqueue(REDRAWSEQ, 0);
+       }
+       /* TODO - more modes... */
 }
 
 void seq_snap_menu(void)
@@ -2873,7 +3616,7 @@ void seq_snap(short event)
        /* as last: */
        sort_seq();
 
-       BIF_undo_push("Snap menu Sequencer");
+       BIF_undo_push("Snap Strips, Sequencer");
        allqueue(REDRAWSEQ, 0);
 }
 
@@ -2922,7 +3665,7 @@ void borderselect_seq(void)
                        seq= seq->next;
                }
 
-               BIF_undo_push("Border select Sequencer");
+               BIF_undo_push("Border Select, Sequencer");
                addqueue(curarea->win, REDRAW, 1);
        }
 }
index a53e9dade2de01b5a38aa344acb7baff1920a63e..1b713609174fd0395397b2ab751065cae11a1416 100644 (file)
@@ -830,13 +830,14 @@ void borderselect_sima(short whichuvs)
        MTFace *tface;
        rcti rect;
        rctf rectf;
-       int val;
-       short mval[2];
+       int val, ok = 1;
+       short mval[2], select;
 
        if( is_uv_tface_editing_allowed()==0) return;
 
        val= get_border(&rect, 3);
-
+       select = (val==LEFTMOUSE) ? 1 : 0; 
+       
        if(val) {
                mval[0]= rect.xmin;
                mval[1]= rect.ymin;
@@ -844,66 +845,86 @@ void borderselect_sima(short whichuvs)
                mval[0]= rect.xmax;
                mval[1]= rect.ymax;
                areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
-
-               for (efa= em->faces.first; efa; efa= efa->next) {
-                       tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                       if (SIMA_FACEDRAW_CHECK(efa, tface)) {
-                               if (whichuvs == UV_SELECT_ALL || (G.sima->flag & SI_SYNC_UVSEL) ) {
-                                       /* SI_SYNC_UVSEL - cant do pinned selection */
-                                       if(BLI_in_rctf(&rectf, (float)tface->uv[0][0], (float)tface->uv[0][1])) {
-                                               if(val==LEFTMOUSE)      SIMA_UVSEL_SET(efa, tface, 0);
-                                               else                            SIMA_UVSEL_UNSET(efa, tface, 0);
-                                       }
-                                       if(BLI_in_rctf(&rectf, (float)tface->uv[1][0], (float)tface->uv[1][1])) {
-                                               if(val==LEFTMOUSE)      SIMA_UVSEL_SET(efa, tface, 1);
-                                               else                            SIMA_UVSEL_UNSET(efa, tface, 1);
-                                       }
-                                       if(BLI_in_rctf(&rectf, (float)tface->uv[2][0], (float)tface->uv[2][1])) {
-                                               if(val==LEFTMOUSE)      SIMA_UVSEL_SET(efa, tface, 2);
-                                               else                            SIMA_UVSEL_UNSET(efa, tface, 2);
-                                       }
-                                       if(efa->v4 && BLI_in_rctf(&rectf, (float)tface->uv[3][0], (float)tface->uv[3][1])) {
-                                               if(val==LEFTMOUSE)      SIMA_UVSEL_SET(efa, tface, 3);
-                                               else                            SIMA_UVSEL_UNSET(efa, tface, 3);
-                                       }
-                               } else if (whichuvs == UV_SELECT_PINNED) {
-                                       if ((tface->unwrap & TF_PIN1) && 
-                                               BLI_in_rctf(&rectf, (float)tface->uv[0][0], (float)tface->uv[0][1])) {
-                                               
-                                               if(val==LEFTMOUSE)      SIMA_UVSEL_SET(efa, tface, 0);
-                                               else                            SIMA_UVSEL_UNSET(efa, tface, 0);
-                                       }
-                                       if ((tface->unwrap & TF_PIN2) && 
-                                               BLI_in_rctf(&rectf, (float)tface->uv[1][0], (float)tface->uv[1][1])) {
-                                               
-                                               if(val==LEFTMOUSE)      SIMA_UVSEL_SET(efa, tface, 1);
-                                               else                            SIMA_UVSEL_UNSET(efa, tface, 1);
-                                       }
-                                       if ((tface->unwrap & TF_PIN3) && 
-                                               BLI_in_rctf(&rectf, (float)tface->uv[2][0], (float)tface->uv[2][1])) {
-                                               
-                                               if(val==LEFTMOUSE)      SIMA_UVSEL_SET(efa, tface, 2);
-                                               else                            SIMA_UVSEL_UNSET(efa, tface, 2);
+               
+               if (draw_uvs_face_check() && whichuvs != UV_SELECT_PINNED) {
+                       float cent[2];
+                       ok = 0;
+                       for (efa= em->faces.first; efa; efa= efa->next) {
+                               /* assume not touched */
+                               efa->tmp.l = 0;
+                               tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                               if (SIMA_FACEDRAW_CHECK(efa, tface)) {
+                                       tface_center(tface, cent, (void *)efa->v4);
+                                       if(BLI_in_rctf(&rectf, cent[0], cent[1])) {
+                                               efa->tmp.l = ok = 1;
                                        }
-                                       if ((efa->v4) && (tface->unwrap & TF_PIN4) && BLI_in_rctf(&rectf, (float)tface->uv[3][0], (float)tface->uv[3][1])) {
-                                               if(val==LEFTMOUSE)      SIMA_UVSEL_SET(efa, tface, 3);
-                                               else                            SIMA_UVSEL_UNSET(efa, tface, 3);
+                               }
+                       }
+                       /* (de)selects all tagged faces and deals with sticky modes */
+                       if (ok)
+                               uvface_setsel__internal(select);
+               } else {
+                       for (efa= em->faces.first; efa; efa= efa->next) {
+                               tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                               if (SIMA_FACEDRAW_CHECK(efa, tface)) {
+                                       if (whichuvs == UV_SELECT_ALL || (G.sima->flag & SI_SYNC_UVSEL) ) {
+                                               /* SI_SYNC_UVSEL - cant do pinned selection */
+                                               if(BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) {
+                                                       if(select)      SIMA_UVSEL_SET(efa, tface, 0);
+                                                       else            SIMA_UVSEL_UNSET(efa, tface, 0);
+                                               }
+                                               if(BLI_in_rctf(&rectf, tface->uv[1][0], tface->uv[1][1])) {
+                                                       if(select)      SIMA_UVSEL_SET(efa, tface, 1);
+                                                       else            SIMA_UVSEL_UNSET(efa, tface, 1);
+                                               }
+                                               if(BLI_in_rctf(&rectf, tface->uv[2][0], tface->uv[2][1])) {
+                                                       if(select)      SIMA_UVSEL_SET(efa, tface, 2);
+                                                       else            SIMA_UVSEL_UNSET(efa, tface, 2);
+                                               }
+                                               if(efa->v4 && BLI_in_rctf(&rectf, tface->uv[3][0], tface->uv[3][1])) {
+                                                       if(select)      SIMA_UVSEL_SET(efa, tface, 3);
+                                                       else            SIMA_UVSEL_UNSET(efa, tface, 3);
+                                               }
+                                       } else if (whichuvs == UV_SELECT_PINNED) {
+                                               if ((tface->unwrap & TF_PIN1) && 
+                                                       BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) {
+                                                       
+                                                       if(select)      SIMA_UVSEL_SET(efa, tface, 0);
+                                                       else            SIMA_UVSEL_UNSET(efa, tface, 0);
+                                               }
+                                               if ((tface->unwrap & TF_PIN2) && 
+                                                       BLI_in_rctf(&rectf, tface->uv[1][0], tface->uv[1][1])) {
+                                                       
+                                                       if(select)      SIMA_UVSEL_SET(efa, tface, 1);
+                                                       else            SIMA_UVSEL_UNSET(efa, tface, 1);
+                                               }
+                                               if ((tface->unwrap & TF_PIN3) && 
+                                                       BLI_in_rctf(&rectf, tface->uv[2][0], tface->uv[2][1])) {
+                                                       
+                                                       if(select)      SIMA_UVSEL_SET(efa, tface, 2);
+                                                       else            SIMA_UVSEL_UNSET(efa, tface, 2);
+                                               }
+                                               if ((efa->v4) && (tface->unwrap & TF_PIN4) && BLI_in_rctf(&rectf, tface->uv[3][0], tface->uv[3][1])) {
+                                                       if(select)      SIMA_UVSEL_SET(efa, tface, 3);
+                                                       else            SIMA_UVSEL_UNSET(efa, tface, 3);
+                                               }
                                        }
                                }
                        }
                }
-               
-               /* make sure newly selected vert selection is updated*/
-               if (G.sima->flag & SI_SYNC_UVSEL) {
-                       if (G.scene->selectmode != SCE_SELECT_FACE) {
-                               if (val==LEFTMOUSE)     EM_select_flush();
-                               else                            EM_deselect_flush();
+               if (ok) {
+                       /* make sure newly selected vert selection is updated*/
+                       if (G.sima->flag & SI_SYNC_UVSEL) {
+                               if (G.scene->selectmode != SCE_SELECT_FACE) {
+                                       if (select)     EM_select_flush();
+                                       else            EM_deselect_flush();
+                               }
                        }
                        allqueue(REDRAWVIEW3D, 0); /* mesh selection has changed */
+                       
+                       BIF_undo_push("Border select UV");
+                       scrarea_queue_winredraw(curarea);
                }
-               
-               BIF_undo_push("Border select UV");
-               scrarea_queue_winredraw(curarea);
        }
 }
 
@@ -1550,29 +1571,148 @@ void unlink_selection(void)
        scrarea_queue_winredraw(curarea);
 }
 
-/*
-void toggle_uv_select(int mode)
+/* this function sets the selection on tagged faces
+ * This is needed because setting the selection on a face is done in
+ * a number of places but it also needs to respect the sticky modes
+ * for the UV verts - dealing with the sticky modes is best done in a seperate function
+ * 
+ * de-selects faces that have been tagged on efa->tmp.l 
+ */
+void uvface_setsel__internal(short select)
 {
-       switch(mode){
-       case 'f':
-               G.sima->flag ^= SI_SELACTFACE;
-               break;
-       case 's':
-               G.sima->flag &= ~SI_LOCALSTICKY;
-               G.sima->flag |= SI_STICKYUVS;
-               break;
-       case 'l':
-               G.sima->flag &= ~SI_STICKYUVS;
-               G.sima->flag &= ~SI_LOCALSTICKY;
-               break;
-       case 'o':
-                G.sima->flag &= ~SI_STICKYUVS;
-                G.sima->flag |= SI_LOCALSTICKY;
-               break;
+       
+       /* All functions calling this should call
+        * draw_uvs_face_check() 
+        */
+       
+               
+       /* selecting UV Faces with some modes requires us to change 
+        * the selection in other faces (depending on the stickt mode)
+        * 
+        * This only needs to be done when the Mesh is not used for selection
+        * (So for sticky modes - vertex or location based)
+        * */
+       
+       EditMesh *em = G.editMesh;
+       EditFace *efa;
+       MTFace *tf;
+       int nverts, i;
+       
+       if ((G.sima->flag & SI_SYNC_UVSEL)==0 && G.sima->sticky == SI_STICKY_VERTEX) {
+               /* tag all verts as untouched,
+                * then touch the ones that have a face center in the loop
+                * and select all MTFace UV's that use a touched vert */
+               
+               EditVert *eve;
+               
+               for (eve= em->verts.first; eve; eve= eve->next)
+                       eve->tmp.l = 0;
+               
+               for (efa= em->faces.first; efa; efa= efa->next) {
+                       if (efa->tmp.l) {
+                               if (efa->v4) {
+                                       efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= efa->v4->tmp.l=1;
+                               } else {
+                                       efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= 1;
+                               }
+                       }
+               }
+               /* now select tagged verts */
+               for (efa= em->faces.first; efa; efa= efa->next) {
+                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);               
+                       nverts= efa->v4? 4: 3;
+                       for(i=0; i<nverts; i++) {
+                               if ((*(&efa->v1 + i))->tmp.l) {
+                                       if (select) {
+                                               SIMA_UVSEL_SET(efa, tf, i);
+                                       } else {
+                                               SIMA_UVSEL_UNSET(efa, tf, i);
+                                       }
+                               }
+                       }
+               }
+       } else if ((G.sima->flag & SI_SYNC_UVSEL)==0 && G.sima->sticky == SI_STICKY_LOC) {
+               EditFace *efa_vlist;
+               MTFace *tf_vlist;
+               UvMapVert *vlist, *start_vlist, *vlist_iter;
+               struct UvVertMap *vmap;
+               float limit[2];
+               int efa_index;
+               //EditVert *eve; /* removed vert counting for now */ 
+               //int a;
+               
+               get_connected_limit_tface_uv(limit);
+               
+               EM_init_index_arrays(0, 0, 1);
+               vmap= make_uv_vert_map_EM(0, 0, limit);
+               
+               /* verts are numbered above in make_uv_vert_map_EM, make sure this stays true! */
+               /*for (a=0, eve= em->verts.first; eve; a++, eve= eve->next)
+                       eve->tmp.l = a; */
+               
+               if(vmap == NULL)
+                       return;
+               
+               for (efa_index=0, efa= em->faces.first; efa; efa_index++, efa= efa->next) {
+                       if (efa->tmp.l) {
+                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                               nverts= efa->v4? 4: 3;
+                               for(i=0; i<nverts; i++) {
+                                       if (select) {
+                                               SIMA_UVSEL_SET(efa, tf, i);
+                                       } else {
+