svn merge -r 12347:12382 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorDaniel Genrich <daniel.genrich@gmx.net>
Wed, 24 Oct 2007 17:20:53 +0000 (17:20 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Wed, 24 Oct 2007 17:20:53 +0000 (17:20 +0000)
45 files changed:
intern/bmfont/intern/BMF_BitmapFont.cpp
intern/iksolver/extern/IK_solver.h
intern/iksolver/intern/IK_QJacobian.cpp
intern/iksolver/intern/IK_QJacobian.h
intern/iksolver/intern/IK_QJacobianSolver.cpp
intern/iksolver/intern/IK_QJacobianSolver.h
intern/iksolver/intern/IK_QSegment.cpp
intern/iksolver/intern/IK_QSegment.h
intern/iksolver/intern/IK_QTask.h
intern/iksolver/intern/IK_Solver.cpp
release/scripts/mesh_unfolder.py
source/blender/blenkernel/BKE_constraint.h
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/imbuf/intern/rectop.c
source/blender/include/BIF_editseq.h
source/blender/include/BIF_usiblender.h
source/blender/include/butspace.h
source/blender/makesdna/DNA_constraint_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_world_types.h
source/blender/python/BPY_interface.c
source/blender/python/api2_2x/Blender.c
source/blender/render/intern/source/rayshade.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/buttons_scene.c
source/blender/src/buttons_shading.c
source/blender/src/drawobject.c
source/blender/src/drawseq.c
source/blender/src/editconstraint.c
source/blender/src/editmesh_mods.c
source/blender/src/editobject.c
source/blender/src/editseq.c
source/blender/src/header_info.c
source/blender/src/header_seq.c
source/blender/src/header_view3d.c
source/blender/src/space.c
source/blender/src/toets.c
source/blender/src/usiblender.c
source/creator/creator.c

index 99ded41007f39f86daaed7c4c6358f9215c80155..c47b2b0719562b820da8ea488534e55e65dcd2d5 100644 (file)
@@ -241,8 +241,6 @@ void BMF_BitmapFont::DrawStringTexture(char *str, float x, float y, float z)
 }
 
 #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
-
-
 void BMF_BitmapFont::DrawStringBuf(char *str, int posx, int posy, float *col, unsigned char *buf, float *fbuf, int w, int h)
 {
        int x, y;
@@ -255,11 +253,11 @@ void BMF_BitmapFont::DrawStringBuf(char *str, int posx, int posy, float *col, un
        posy -= m_fontData->ymin;
        
        if (buf) {
-               unsigned char colch[3];
+               unsigned char colch[4];
                unsigned char *max, *pixel;
                unsigned char c;
                
-               for (x=0; x<3; x++) {
+               for (x=0; x<4; x++) {
                        colch[x] = FTOCHAR(col[x]);
                }
                
@@ -279,6 +277,8 @@ void BMF_BitmapFont::DrawStringBuf(char *str, int posx, int posy, float *col, un
                                                                pixel[0] = colch[0];
                                                                pixel[1] = colch[1];
                                                                pixel[2] = colch[2];
+                                                               pixel[4] = 1; /*colch[3];*/
+                                                               
                                                        }
                                                }
                                        }
@@ -310,6 +310,7 @@ void BMF_BitmapFont::DrawStringBuf(char *str, int posx, int posy, float *col, un
                                                                pixel[0] = col[0];
                                                                pixel[1] = col[1];
                                                                pixel[2] = col[2];
+                                                               pixel[3] = 1; /*col[3];*/
                                                        }
                                                }
                                        }
index 8626ca22beb01cf60b35c87e624c4979d7cffc4f..bf53a9e3724e861bdc20c75aec1770ae79039d01 100644 (file)
@@ -158,6 +158,8 @@ void IK_FreeSolver(IK_Solver *solver);
 
 void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float weight);
 void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[][3], float weight);
+void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float goal[3], float polegoal[3], float poleangle, int getangle);
+float IK_SolverGetPoleAngle(IK_Solver *solver);
 
 int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations);
 
index 03c5f9500be147c60cb847951d41d0c391a5d765..1dd4d086aa84342481a65d9e59a5f38dfa3d785f 100644 (file)
@@ -42,11 +42,10 @@ IK_QJacobian::~IK_QJacobian()
 {
 }
 
-void IK_QJacobian::ArmMatrices(int dof, int task_size, int tasks)
+void IK_QJacobian::ArmMatrices(int dof, int task_size)
 {
        m_dof = dof;
        m_task_size = task_size;
-       m_tasks = tasks;
 
        m_jacobian.newsize(task_size, dof);
        m_jacobian = 0;
index b80db1d8f53aeef0a5bc534dd83c74dd5c68e1ad..3e20e4a9fd07b1be97352bd4e32d00bf8929f2f5 100644 (file)
@@ -49,7 +49,7 @@ public:
        ~IK_QJacobian();
 
        // Call once to initialize
-       void ArmMatrices(int dof, int task_size, int tasks);
+       void ArmMatrices(int dof, int task_size);
        void SetDoFWeight(int dof, MT_Scalar weight);
 
        // Iteratively called
@@ -75,7 +75,7 @@ private:
        void InvertSDLS();
        void InvertDLS();
 
-       int m_dof, m_task_size, m_tasks;
+       int m_dof, m_task_size;
        bool m_transpose;
 
        // the jacobian matrix and it's null space projector
index ea18f0b20036751017578b259983b5e60b85f1f0..f19b2a162fa224ce43b8ee1de94a4ef8be69aace 100644 (file)
 
 #include <stdio.h>
 #include "IK_QJacobianSolver.h"
+#include "MT_Quaternion.h"
+
+//#include "analyze.h"
+IK_QJacobianSolver::IK_QJacobianSolver()
+{
+       m_poleconstraint = false;
+       m_getpoleangle = false;
+       m_rootmatrix.setIdentity();
+}
 
 void IK_QJacobianSolver::AddSegmentList(IK_QSegment *seg)
 {
@@ -47,7 +56,7 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks)
        m_segments.clear();
        AddSegmentList(root);
 
-       // assing each segment a unique id for the jacobian
+       // assign each segment a unique id for the jacobian
        std::vector<IK_QSegment*>::iterator seg;
        int num_dof = 0;
 
@@ -105,9 +114,9 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks)
        }
 
        // set matrix sizes
-       m_jacobian.ArmMatrices(num_dof, primary_size, primary);
+       m_jacobian.ArmMatrices(num_dof, primary_size);
        if (secondary > 0)
-               m_jacobian_sub.ArmMatrices(num_dof, secondary_size, secondary);
+               m_jacobian_sub.ArmMatrices(num_dof, secondary_size);
 
        // set dof weights
        int i;
@@ -119,6 +128,109 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks)
        return true;
 }
 
+void IK_QJacobianSolver::SetPoleVectorConstraint(IK_QSegment *tip, MT_Vector3& goal, MT_Vector3& polegoal, float poleangle, bool getangle)
+{
+       m_poleconstraint = true;
+       m_poletip = tip;
+       m_goal = goal;
+       m_polegoal = polegoal;
+       m_poleangle = (getangle)? 0.0f: poleangle;
+       m_getpoleangle = getangle;
+}
+
+static MT_Scalar safe_acos(MT_Scalar f)
+{
+       // acos that does not return NaN with rounding errors
+       if (f <= -1.0f) return MT_PI;
+       else if (f >= 1.0f) return 0.0;
+       else return acos(f);
+}
+
+static MT_Vector3 normalize(const MT_Vector3& v)
+{
+       // a sane normalize function that doesn't give (1, 0, 0) in case
+       // of a zero length vector, like MT_Vector3.normalize
+       MT_Scalar len = v.length();
+       return MT_fuzzyZero(len)?  MT_Vector3(0, 0, 0): v/len;
+}
+
+static float angle(const MT_Vector3& v1, const MT_Vector3& v2)
+{
+       return safe_acos(v1.dot(v2));
+}
+
+void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask*>& tasks)
+{
+       // this function will be called before and after solving. calling it before
+       // solving gives predictable solutions by rotating towards the solution,
+       // and calling it afterwards ensures the solution is exact.
+
+       if(!m_poleconstraint)
+               return;
+       
+       // disable pole vector constraint in case of multiple position tasks
+       std::list<IK_QTask*>::iterator task;
+       int positiontasks = 0;
+
+       for (task = tasks.begin(); task != tasks.end(); task++)
+               if((*task)->PositionTask())
+                       positiontasks++;
+       
+       if (positiontasks >= 2) {
+               m_poleconstraint = false;
+               return;
+       }
+
+       // get positions and rotations
+       root->UpdateTransform(m_rootmatrix);
+
+       const MT_Vector3 rootpos = root->GlobalStart();
+       const MT_Vector3 endpos = m_poletip->GlobalEnd();
+       const MT_Matrix3x3& rootbasis = root->GlobalTransform().getBasis();
+
+       // construct "lookat" matrices (like gluLookAt), based on a direction and
+       // an up vector, with the direction going from the root to the end effector
+       // and the up vector going from the root to the pole constraint position.
+       MT_Vector3 dir = normalize(endpos - rootpos);
+       MT_Vector3 rootx= rootbasis.getColumn(0);
+       MT_Vector3 rootz= rootbasis.getColumn(2);
+       MT_Vector3 up = rootx*cos(m_poleangle) + rootz*sin(m_poleangle);
+
+       // in post, don't rotate towards the goal but only correct the pole up
+       MT_Vector3 poledir = (m_getpoleangle)? dir: normalize(m_goal - rootpos);
+       MT_Vector3 poleup = normalize(m_polegoal - rootpos);
+
+       MT_Matrix3x3 mat, polemat;
+
+       mat[0] = normalize(MT_cross(dir, up));
+       mat[1] = MT_cross(mat[0], dir);
+       mat[2] = -dir;
+
+       polemat[0] = normalize(MT_cross(poledir, poleup));
+       polemat[1] = MT_cross(polemat[0], poledir);
+       polemat[2] = -poledir;
+
+       if(m_getpoleangle) {
+               // we compute the pole angle that to rotate towards the target
+               m_poleangle = angle(mat[1], polemat[1]);
+
+               if(rootz.dot(mat[1]*cos(m_poleangle) + mat[0]*sin(m_poleangle)) > 0.0f)
+                       m_poleangle = -m_poleangle;
+
+               // solve again, with the pole angle we just computed
+               m_getpoleangle = false;
+               ConstrainPoleVector(root, tasks);
+       }
+       else {
+               // now we set as root matrix the difference between the current and
+               // desired rotation based on the pole vector constraint. we use
+               // transpose instead of inverse because we have orthogonal matrices
+               // anyway, and in case of a singular matrix we don't get NaN's.
+               MT_Transform trans(MT_Point3(0, 0, 0), polemat.transposed()*mat);
+               m_rootmatrix = trans*m_rootmatrix;
+       }
+}
+
 bool IK_QJacobianSolver::UpdateAngles(MT_Scalar& norm)
 {
        // assing each segment a unique id for the jacobian
@@ -181,15 +293,17 @@ bool IK_QJacobianSolver::Solve(
        const int max_iterations
 )
 {
+       bool solved = false;
        //double dt = analyze_time();
 
-       if (!Setup(root, tasks))
-               return false;
+       ConstrainPoleVector(root, tasks);
+
+       root->UpdateTransform(m_rootmatrix);
 
        // iterate
        for (int iterations = 0; iterations < max_iterations; iterations++) {
                // update transform
-               root->UpdateTransform(MT_Transform::Identity());
+               root->UpdateTransform(m_rootmatrix);
 
                std::list<IK_QTask*>::iterator task;
 
@@ -211,7 +325,7 @@ bool IK_QJacobianSolver::Solve(
                                        m_jacobian.SubTask(m_jacobian_sub);
                        }
                        catch (...) {
-                               printf("IK Exception\n");
+                               fprintf(stderr, "IK Exception\n");
                                return false;
                        }
 
@@ -230,12 +344,19 @@ bool IK_QJacobianSolver::Solve(
 
                // check for convergence
                if (norm < 1e-3) {
+                       solved = true;
+                       break;
                        //analyze_add_run(iterations, analyze_time()-dt);
+
                        return true;
                }
        }
 
+       if(m_poleconstraint)
+               root->PrependBasis(m_rootmatrix.getBasis());
+
        //analyze_add_run(max_iterations, analyze_time()-dt);
-       return false;
+
+       return solved;
 }
 
index adf95eb82dcb57af01c7e164b98060c9c56c224d..bc3d1686b59870c597325b566f0daff1f7e95500 100644 (file)
@@ -43,6 +43,7 @@
 #include <list>
 
 #include "MT_Vector3.h"
+#include "MT_Transform.h"
 #include "IK_QJacobian.h"
 #include "IK_QSegment.h"
 #include "IK_QTask.h"
 class IK_QJacobianSolver
 {
 public:
-       IK_QJacobianSolver() {};
+       IK_QJacobianSolver();
        ~IK_QJacobianSolver() {};
 
-       // returns true if converged, false if max number of iterations was used
+       // setup pole vector constraint
+       void SetPoleVectorConstraint(IK_QSegment *tip, MT_Vector3& goal,
+               MT_Vector3& polegoal, float poleangle, bool getangle);
+       float GetPoleAngle() { return m_poleangle; };
+
+       // call setup once before solving, if it fails don't solve
+       bool Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks);
 
+       // returns true if converged, false if max number of iterations was used
        bool Solve(
                IK_QSegment *root,
                std::list<IK_QTask*> tasks,
@@ -64,8 +72,8 @@ public:
 
 private:
        void AddSegmentList(IK_QSegment *seg);
-       bool Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks);
        bool UpdateAngles(MT_Scalar& norm);
+       void ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask*>& tasks);
 
 private:
 
@@ -75,6 +83,15 @@ private:
        bool m_secondary_enabled;
 
        std::vector<IK_QSegment*> m_segments;
+
+       MT_Transform m_rootmatrix;
+
+       bool m_poleconstraint;
+       bool m_getpoleangle;
+       MT_Vector3 m_goal;
+       MT_Vector3 m_polegoal;
+       float m_poleangle;
+       IK_QSegment *m_poletip;
 };
 
 #endif
index cf9e1615d8cd28fe429a8ce8114c91bc1794b826..1855c1e3db3b626812607f2f7f79953408495aae 100644 (file)
@@ -236,6 +236,18 @@ IK_QSegment::IK_QSegment(int num_DoF, bool translational)
        m_orig_translation = m_translation;
 }
 
+void IK_QSegment::Reset()
+{
+       m_locked[0] = m_locked[1] = m_locked[2] = false;
+
+       m_basis = m_orig_basis;
+       m_translation = m_orig_translation;
+       SetBasis(m_basis);
+
+       for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling)
+               seg->Reset();
+}
+
 void IK_QSegment::SetTransform(
        const MT_Vector3& start,
        const MT_Matrix3x3& rest_basis,
@@ -326,6 +338,11 @@ void IK_QSegment::UpdateTransform(const MT_Transform& global)
                seg->UpdateTransform(m_global_transform);
 }
 
+void IK_QSegment::PrependBasis(const MT_Matrix3x3& mat)
+{
+       m_basis = m_rest_basis.inverse() * mat * m_rest_basis * m_basis;
+}
+
 // IK_QSphericalSegment
 
 IK_QSphericalSegment::IK_QSphericalSegment()
index e406585bc8bea4b9553f981e444d3793264b679b..ca0abafb06adc8df8397332645fa30a32942024e 100644 (file)
@@ -165,6 +165,10 @@ public:
 
        virtual void SetBasis(const MT_Matrix3x3& basis) { m_basis = basis; }
 
+       // functions needed for pole vector constraint
+       void PrependBasis(const MT_Matrix3x3& mat);
+       void Reset();
+
 protected:
 
        // num_DoF: number of degrees of freedom
index 0e00925d908d5025be98b27d57e200ecce8d6fe5..26beaa386229e310f465ab4319e3c9ada0672aff 100644 (file)
@@ -75,6 +75,8 @@ public:
 
        virtual MT_Scalar Distance() const=0;
 
+       virtual bool PositionTask() const { return false; }
+
 protected:
        int m_id;
        int m_size;
@@ -97,6 +99,8 @@ public:
 
        MT_Scalar Distance() const;
 
+       bool PositionTask() const { return true; }
+
 private:
        MT_Vector3 m_goal;
        MT_Scalar m_clamp_length;
index 919eeb739ce08ef48160e82fa4959fce2be17e48..b2d75d783c6016be5383e03ad7bac9ee6993ac34 100644 (file)
@@ -318,6 +318,31 @@ void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[
        qsolver->tasks.push_back(orient);
 }
 
+void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float goal[3], float polegoal[3], float poleangle, int getangle)
+{
+       if (solver == NULL || tip == NULL)
+               return;
+
+       IK_QSolver *qsolver = (IK_QSolver*)solver;
+       IK_QSegment *qtip = (IK_QSegment*)tip;
+
+       MT_Vector3 qgoal(goal);
+       MT_Vector3 qpolegoal(polegoal);
+
+       qsolver->solver.SetPoleVectorConstraint(
+               qtip, qgoal, qpolegoal, poleangle, getangle);
+}
+
+float IK_SolverGetPoleAngle(IK_Solver *solver)
+{
+       if (solver == NULL)
+               return 0.0f;
+
+       IK_QSolver *qsolver = (IK_QSolver*)solver;
+
+       return qsolver->solver.GetPoleAngle();
+}
+
 void IK_SolverAddCenterOfMass(IK_Solver *solver, IK_Segment *root, float goal[3], float weight)
 {
        if (solver == NULL || root == NULL)
@@ -346,6 +371,9 @@ int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations)
        std::list<IK_QTask*>& tasks = qsolver->tasks;
        MT_Scalar tol = tolerance;
 
+       if(!jacobian.Setup(root, tasks))
+               return 0;
+
        bool result = jacobian.Solve(root, tasks, tol, max_iterations);
 
        return ((result)? 1: 0);
index bf7459235b27e9a00cece15ce24e30c4d02040be..906e0f0a3006828daac9ae3d2d022335c3bb226f 100644 (file)
@@ -1,10 +1,10 @@
 #!BPY
 """
 Name: 'Unfold'
-Blender: 243
+Blender: 245
 Group: 'Mesh'
 Tip: 'Unfold meshes to create nets'
-Version:  v2.2.4
+Version:  v2.5
 Author: Matthew Chadwick
 """
 import Blender
@@ -29,7 +29,7 @@ except:
        xml_sax_handler_ContentHandler = type(0)
 
 __author__ = 'Matthew Chadwick'
-__version__ = '2.2.4 24032007'
+__version__ = '2.5 06102007'
 __url__ = ["http://celeriac.net/unfolder/", "blender", "blenderartist"]
 __email__ = ["post at cele[remove this text]riac.net", "scripts"]
 __bpydoc__ = """\
@@ -81,7 +81,7 @@ class FacesAndEdges:
                                        self.edgeFaces[key].append(face)
        def findTakenAdjacentFace(self, bface, edge):
                return self.findAdjacentFace(bface, edge)
-       # find the first untaken (non-selected) adjacent face in the list of adjacent faces for the given edge
+       # find the first untaken (non-selected) adjacent face in the list of adjacent faces for the given edge (allows for manifold meshes too)
        def findAdjacentFace(self, bface, edge):
                faces = self.edgeFaces[edge.key()]
                for i in xrange(len(faces)):
@@ -109,84 +109,7 @@ class FacesAndEdges:
                if(bface!=None):
                        bface.sel= True
                        self.nfaces+=1
-       
-       
-class IntersectionResult:
-       def __init__(self, rn, rd, v=None):
-               self.v = v
-               self.rd = rd
-               self.rn = rn
-       def intersected(self):
-               return not(not(self.v))
-       def isParallel(self):
-               return (self.rd==0)
-       def isColinear(self):
-               return (self.rn==0)
-       def intersection(self):
-               return self.v
-       
-# represents a line segment between two points [p1, p2]. the points are [x,y]
-class LineSegment:
-       def __init__(self, p):
-               self.p = p
-       def intersects(self, s):
-               rn = ((self.p[0].y-s.p[0].y)*(s.p[1].x-s.p[0].x)-(self.p[0].x-s.p[0].x)*(s.p[1].y-s.p[0].y)) 
-               rd = ((self.p[1].x-self.p[0].x)*(s.p[1].y-s.p[0].y)-(self.p[1].y-self.p[0].y)*(s.p[1].x-s.p[0].x))
-               # need an epsilon closeTo() here
-               if(rd<0.0000001 or rn==0.0):
-                       return IntersectionResult(rn,rd)
-               r = rn/rd
-               s = ((self.p[0].y-s.p[0].y)*(self.p[1].x-self.p[0].x)-(self.p[0].x-s.p[0].x)*(self.p[1].y-self.p[0].y)) / rd
-               i = (0.0<=r and r<=1.0 and 0.0<=s and s<=1.0)
-               if not(i):
-                       return None
-               ix = self.p[0].x + r*(self.p[1].x - self.p[0].x)
-               iy = self.p[0].y + r*(self.p[1].y - self.p[0].y)
-               t = 0.0001
-               if ( abs(ix-self.p[0].x)>t and abs(iy-self.p[0].x)>t and abs(ix-self.p[1].x)>t and abs(iy-self.p[1].y)>t ):
-                       return IntersectionResult( rn, rd,Vector([ix,iy,0.0]))
-               else:
-                       return None
-               
-class LineSegments:
-       def __init__(self, face):
-               self.face = face
-       def segmentAt(self, i):
-               if(i>self.face.nPoints()-1):
-                       return None
-               if(i==self.face.nPoints()-1):
-                       j = 0
-               else:
-                       j = i+1
-               return LineSegment([ self.face.v[i], self.face.v[j] ])
-       def iterateSegments(self, something):
-               results = []
-               for i in xrange(self.face.nPoints()):
-                       results.extend(something.haveSegment(self.segmentAt(i))) 
-               return results
-       def compareSegments(self, something, segment):
-               results = []
-               for i in xrange(self.face.nPoints()):
-                       results.append(something.compareSegments([self.segmentAt(i), segment]))
-               return results
 
-class FaceOverlapTest:
-       def __init__(self, face1, face2):
-               self.faces = [face1, face2]
-               self.segments = [ LineSegments(self.faces[0]), LineSegments(self.faces[1]) ]
-       def suspectsOverlap(self):
-               tests = self.segments[0].iterateSegments(self)
-               gi = 0
-               for i in tests:
-                       if( i!=None and i.intersected() ):
-                               gi+=1
-               return gi>0
-       def haveSegment(self, segment):
-               return self.segments[1].compareSegments(self, segment)
-       def compareSegments(self, segments):
-               return segments[0].intersects(segments[1])
-
-               
        
 # A fold between two faces with a common edge
 class Fold:
@@ -400,7 +323,7 @@ class Net:
                if(len(ff.v)<3):
                        raise Exception("This mesh contains an isolated edge - it must consist only of faces")
                testFace = Poly.fromVectors( [ Vector([0.0,0.0,0.0]), Vector([0.0,1.0,0.0]), Vector([1.0,1.0,0.0])  ] )
-               # hmmm
+               # hmmm. I honestly can't remember why this needs to be done, but it does.
                u=0
                v=1
                w=2
@@ -414,6 +337,7 @@ class Net:
                xyFold =  Fold(None,   xyFace, refFace, Edge(xyFace.v[0], xyFace.v[1] ))
                self.refFold = Fold(xyFold, refFace, ff,         Edge(refFace.v[0], refFace.v[1] ))
                self.refFold.srcFace = self.firstFace
+               # prepare to grow the trees
                trunk = Tree(self, None, self.refFold)
                trunk.generations = self.generations
                self.firstPoly = ff
@@ -425,6 +349,7 @@ class Net:
                self.folds.append(self.refFold)
                trunk.grow()
                i = 0
+               # keep the trees growing while they can
                while(self.myFacesVisited<len(self.src.faces) and len(self.branches) > 0):
                        if self.edgeIteratorClass==RandomEdgeIterator:
                                i = random.randint(0,len(self.branches)-1)
@@ -461,11 +386,12 @@ class Net:
                for afold in folds:
                        mdf = afold.unfoldedFace()
                        if(afold!=fold):
-                               it1 = FaceOverlapTest(mf, mdf)
-                               it2 = FaceOverlapTest(mdf, mf)
-                               overlap = (it1.suspectsOverlap() or it2.suspectsOverlap())
+                               # currently need to get agreement from both polys because
+                               # a touch by a vertex of one the other's edge is acceptable &
+                               # they disagree on that
+                               intersects = mf.intersects2D(mdf) and mdf.intersects2D(mf)
                                inside = ( mdf.containsAnyOf(mf) or mf.containsAnyOf(mdf) )
-                               if(  overlap or inside or mdf.overlays(mf)):
+                               if(  intersects or inside or mdf.overlays(mf)):
                                        c.append(afold)
                return c
        def getOverlapsBetweenGL(self, fold, folds):
@@ -646,9 +572,9 @@ class Net:
                        overlaps = self.report()
                        attempts+=1
                return attempts
-       def unfoldSelected(feedback=None, netName=None):
+       def fromSelected(feedback=None, netName=None):
                return Net.createNet(Blender.Object.GetSelected()[0], feedback, netName)
-       unfoldSelected = staticmethod(unfoldSelected)
+       fromSelected = staticmethod(fromSelected)
        def clone(self, object=None):
                if(object==None):
                        object = self.object
@@ -825,7 +751,7 @@ class Curvature(EdgeIterator):
                                g += f.dihedralAngle()
                self.gooodness = g
                
-       
+
 class Edge:
        def __init__(self, v1=None, v2=None, mEdge=None, i=-1):
                self.idx = i
@@ -893,6 +819,23 @@ class Edge:
                        return +1
                else:
                        return -1
+       # Does the given segment intersect this, for overlap detection.
+       # endpoints are allowed to touch the line segment
+       def intersects2D(self, s):
+               if(self.matches(s)):
+                       return False
+               else:
+                       i = Geometry.LineIntersect2D(self.v1, self.v2, s.v1, s.v2)
+                       if(i!=None):
+                               i.resize4D()
+                               i.z = self.v1.z # hack to put the point on the same plane as this edge for comparison
+                       return(i!=None and not(self.endsWith(i)))
+       def matches(self, s):
+               return ( (self.v1==s.v1 and self.v2==s.v2) or (self.v2==s.v1 and self.v1==s.v2) )
+       # Is the given point on the end of this segment ? 10-5 seems to an acceptable limit for closeness in Blender
+       def endsWith(self, aPoint, e=0.0001):
+               return ( (self.v1-aPoint).length < e or (self.v2-aPoint).length < e )
+
        
 class Poly:
        ids = -1
@@ -901,6 +844,7 @@ class Poly:
                self.v = []
                self.id = Poly.ids
                self.boundz = None
+               self.edges = None
        def getID(self):
                return self.id
        def normal(self):
@@ -912,6 +856,21 @@ class Poly:
                q = a-c
                q.resize3D()
                return CrossVecs(p,q)
+       def makeEdges(self):
+               self.edges = []
+               for i in xrange(self.nPoints()):
+                       self.edges.append(Edge( self.v[i % self.nPoints()], self.v[ (i+1) % self.nPoints()] ))
+       def edgeAt(self, i):
+               if(self.edges==None):
+                       self.makeEdges()
+               return self.edges[i]
+       def intersects2D(self, poly):
+               for i in xrange(self.nPoints()):
+                       edge = self.edgeAt(i)
+                       for j in xrange(poly.nPoints()):
+                               if edge.intersects2D(poly.edgeAt(j)):
+                                       return True
+               return False
        def isBad(self):
                badness = 0
                for vv in self.v:
@@ -1033,8 +992,7 @@ class Poly:
        def toString(self):
                return self.v
        # This is the BEST algorithm for point-in-polygon detection.
-       # It's by W. Randolph Franklin. It's also very beautiful (looks even better in C).
-       # All the others are shite; they give false positives.
+       # It's by W. Randolph Franklin.
        # returns 1 for inside, 1 or 0 for edges
        def contains(self, tp):
                c = 0
@@ -1116,6 +1074,7 @@ class SVGExporter:
        def export(self):
                self.net.unfoldTo(1)
                bb = self.object.getBoundBox()
+               print bb
                self.vxmin = bb[0][0]
                self.vymin = bb[0][1]
                self.vxmax = bb[7][0]
@@ -1143,14 +1102,14 @@ class SVGExporter:
                self.addPolys()
                self.e.endElement("clipPath")
        def addUVImage(self):
-               image = Blender.Image.GetCurrent()
+               image = Blender.Image.GetCurrent() #hmm - how to determine the desired image ?
                if image==None:
                        return
                ifn = image.getFilename()
-               #ifn = self.filename.replace(".svg", ".jpg")
-               #image.setFilename(ifn)
-               #ifn = ifn[ifn.rfind("/")+1:]
-               #image.save()
+               ifn = self.filename.replace(".svg", ".jpg")
+               image.setFilename(ifn)
+               ifn = ifn[ifn.rfind("/")+1:]
+               image.save()
                atts = {}
                atts["clip-path"] = "url(#netClip)"
                atts["xlink:href"] = ifn
@@ -1244,8 +1203,8 @@ class SVGExporter:
                        traceback.print_exc(file=sys.stdout)
        fileSelected = staticmethod(fileSelected)       
 
-
-class NetHandler(xml_sax_handler_ContentHandler):
+# for importing nets saved by the above exporter
+class NetHandler(xml.sax.handler.ContentHandler):
        def __init__(self, net):
                self.net = net
                self.first = (41==41)
@@ -1415,7 +1374,7 @@ class GUI:
                        while(s):# and search < searchLimit):
                                if(net!=None):
                                        name = net.des.name
-                               net = Net.unfoldSelected(self, name)
+                               net = Net.fromSelected(self, name)
                                net.setAvoidsOverlaps(not(self.overlaps.val))
                                print
                                print "Unfolding selected object"
@@ -1518,6 +1477,14 @@ class GUI:
                        else:
                                self.nOverlaps = 0
                        Draw.Redraw(1)
+               if(evt==233):
+                       f1 = Poly.fromBlenderFace(Blender.Object.GetSelected()[0].getData().faces[0])
+                       f2 = Poly.fromBlenderFace(Blender.Object.GetSelected()[1].getData().faces[0])
+                       print
+                       print Blender.Object.GetSelected()[0].getName()
+                       print Blender.Object.GetSelected()[1].getName()
+                       print f1.intersects2D(f2)
+                       print f2.intersects2D(f1)
                if(evt==714):
                        Net.unfoldAll(self)
                        Draw.Redraw(1)
@@ -1569,6 +1536,7 @@ class GUI:
                Draw.Button("Unfold",           1, l.nx(), l.ny(), l.cw, l.ch, "Unfold selected mesh to net")
                Draw.Button("save",             104,   l.nx(), l.ny(), l.cw, l.ch,  "Save net as SVG")
                Draw.Button("load",             107,   l.nx(), l.ny(), l.cw, l.ch,  "Load net from SVG")
+               #Draw.Button("test",             233,   l.nx(), l.ny(), l.cw, l.ch,  "test")
                # unfolding enthusiasts - try uncommenting this
                self.ancestors = Draw.Number("depth", 654,        l.nx(), l.ny(), cw, ch, self.ancestors.val, 0, 9999,  "depth of branching 0=diffuse")
                #self.noise = Draw.Number("noise", 631,        l.nx(), l.ny(), cw, ch, self.noise.val, 0.0, 1.0,  "noisyness of branching")
@@ -1576,7 +1544,7 @@ class GUI:
                options = "order %t|random %x0|brightest %x1|curvature %x2|winding %x3| 1010 %x4|largest %x5"
                self.shape = Draw.Menu(options, 713,  l.nx(), l.ny(), cw, ch, self.shape.val, "shape of net")
                Draw.Button("exit",         6,   l.nx(), l.ny(), l.cw, l.ch, "exit")
-               BGL.glClearColor(0.5, 0.5, 0.5, 1)
+               BGL.glClearColor(0.3, 0.3, 0.3, 1)
                BGL.glColor3f(0.3,0.3,0.3)
                l.newLine()
                BGL.glRasterPos2i(32, 100)
index 40fd8c5ed1848c440d3bc401e8245de75ac090da..aa8e9cf18f8b3b149fa937f1aa3ae6400ea391c6 100644 (file)
@@ -126,14 +126,13 @@ void copy_constraint_channels(struct ListBase *dst, struct ListBase *src);
 void clone_constraint_channels(struct ListBase *dst, struct ListBase *src);
 void free_constraint_channels(struct ListBase *chanbase);
 
-
 /* Constraint Evaluation function prototypes */
 struct bConstraintOb *constraints_make_evalob(struct Object *ob, void *subdata, short datatype);
 void constraints_clear_evalob(struct bConstraintOb *cob);
 
 void constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[][4], short from, short to);
 
-void get_constraint_target_matrix(struct bConstraint *con, short ownertype, void *ownerdata, float mat[][4], float ctime);
+void get_constraint_target_matrix(struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime);
 void solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
 
 
index 2030859000f3cc444762c7dc642abe71edb070e0..38a6a05017c54ff804e109a0157f0150e1821511 100644 (file)
@@ -411,7 +411,7 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
        Mat4 *result_array= (rest)? bbone_rest_array: bbone_array;
        bPoseChannel *next, *prev;
        Bone *bone= pchan->bone;
-       float h1[3], h2[3], length, hlength1, hlength2, roll1, roll2;
+       float h1[3], h2[3], length, hlength1, hlength2, roll1=0.0f, roll2;
        float mat3[3][3], imat[4][4];
        float data[MAX_BBONE_SUBDIV+1][4], *fp;
        int a;
@@ -1512,7 +1512,7 @@ static void execute_posetree(Object *ob, PoseTree *tree)
        IK_Segment *seg, *parent, **iktree, *iktarget;
        IK_Solver *solver;
        PoseTarget *target;
-       bKinematicConstraint *data;
+       bKinematicConstraint *data, *poleangledata=NULL;
        Bone *bone;
 
        if (tree->totchannel == 0)
@@ -1624,12 +1624,15 @@ static void execute_posetree(Object *ob, PoseTree *tree)
        Mat4Invert (goalinv, imat);
        
        for (target=tree->targets.first; target; target=target->next) {
+               float polepos[3];
+               int poleconstrain= 0;
+
                data= (bKinematicConstraint*)target->con->data;
                
                /* 1.0=ctime, we pass on object for auto-ik (owner-type here is object, even though
                 * strictly speaking, it is a posechannel)
                 */
-               get_constraint_target_matrix(target->con, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
+               get_constraint_target_matrix(target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
                
                /* and set and transform goal */
                Mat4MulMat4(goal, rootmat, goalinv);
@@ -1637,6 +1640,26 @@ static void execute_posetree(Object *ob, PoseTree *tree)
                VECCOPY(goalpos, goal[3]);
                Mat3CpyMat4(goalrot, goal);
                
+               /* same for pole vector target */
+               if(data->poletar) {
+                       get_constraint_target_matrix(target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
+
+                       if(data->flag & CONSTRAINT_IK_SETANGLE) {
+                               /* don't solve IK when we are setting the pole angle */
+                               break;
+                       }
+                       else {
+                               Mat4MulMat4(goal, rootmat, goalinv);
+                               VECCOPY(polepos, goal[3]);
+                               poleconstrain= 1;
+
+                               if(data->flag & CONSTRAINT_IK_GETANGLE) {
+                                       poleangledata= data;
+                                       data->flag &= ~CONSTRAINT_IK_GETANGLE;
+                               }
+                       }
+               }
+
                /* do we need blending? */
                if (target->con->enforce!=1.0) {
                        float q1[4], q2[4], q[4];
@@ -1664,14 +1687,24 @@ static void execute_posetree(Object *ob, PoseTree *tree)
                
                iktarget= iktree[target->tip];
                
-               if(data->weight != 0.0)
+               if(data->weight != 0.0) {
+                       if(poleconstrain)
+                               IK_SolverSetPoleVectorConstraint(solver, iktarget, goalpos,
+                                       polepos, data->poleangle*M_PI/180, (poleangledata == data));
                        IK_SolverAddGoal(solver, iktarget, goalpos, data->weight);
-               if((data->flag & CONSTRAINT_IK_ROT) && (data->orientweight != 0.0) && (data->flag & CONSTRAINT_IK_AUTO)==0)
-                       IK_SolverAddGoalOrientation(solver, iktarget, goalrot, data->orientweight);
+               }
+               if((data->flag & CONSTRAINT_IK_ROT) && (data->orientweight != 0.0))
+                       if((data->flag & CONSTRAINT_IK_AUTO)==0)
+                               IK_SolverAddGoalOrientation(solver, iktarget, goalrot,
+                                       data->orientweight);
        }
 
        /* solve */
        IK_Solve(solver, 0.0f, tree->iterations);
+
+       if(poleangledata)
+               poleangledata->poleangle= IK_SolverGetPoleAngle(solver)*180/M_PI;
+
        IK_FreeSolver(solver);
 
        /* gather basis changes */
index c9fb21d4333ab5e7445e6307c87e4a4f45665076..a8305a7dec15941a2cd90bc9f1c13a34c9e68e4d 100644 (file)
@@ -804,12 +804,12 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain
  * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
  *  really just to help this code easier to read)
  */
-#define SINGLETARGET_GET_TARS(con, data, ct, list) \
+#define SINGLETARGET_GET_TARS(con, datatar, datasubtarget, ct, list) \
        { \
                ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
                 \
-               ct->tar= data->tar; \
-               strcpy(ct->subtarget, data->subtarget); \
+               ct->tar= datatar; \
+               strcpy(ct->subtarget, datasubtarget); \
                ct->space= con->tarspace; \
                ct->flag= CONSTRAINT_TAR_TEMP; \
                 \
@@ -827,11 +827,11 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain
  * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
  *  really just to help this code easier to read)
  */
-#define SINGLETARGETNS_GET_TARS(con, data, ct, list) \
+#define SINGLETARGETNS_GET_TARS(con, datatar, ct, list) \
        { \
                ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
                 \
-               ct->tar= data->tar; \
+               ct->tar= datatar; \
                ct->space= con->tarspace; \
                ct->flag= CONSTRAINT_TAR_TEMP; \
                 \
@@ -845,16 +845,16 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain
  * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
  *  really just to help this code easier to read)
  */
-#define SINGLETARGET_FLUSH_TARS(con, data, ct, list, nocopy) \
+#define SINGLETARGET_FLUSH_TARS(con, datatar, datasubtarget, ct, list, nocopy) \
        { \
                if (ct) { \
                        if (nocopy == 0) { \
-                               data->tar= ct->tar; \
-                               strcpy(data->subtarget, ct->subtarget); \
+                               datatar= ct->tar; \
+                               strcpy(datasubtarget, ct->subtarget); \
                                con->tarspace= ct->space; \
                        } \
                         \
-                       BLI_freelistN(list); \
+                       BLI_freelinkN(list, ct); \
                } \
        }
        
@@ -863,15 +863,15 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstrain
  * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
  *  really just to help this code easier to read)
  */
-#define SINGLETARGETNS_FLUSH_TARS(con, data, ct, list, nocopy) \
+#define SINGLETARGETNS_FLUSH_TARS(con, datatar, ct, list, nocopy) \
        { \
                if (ct) { \
                        if (nocopy == 0) { \
-                               data->tar= ct->tar; \
+                               datatar= ct->tar; \
                                con->tarspace= ct->space; \
                        } \
                         \
-                       BLI_freelistN(list); \
+                       BLI_freelinkN(list, ct); \
                } \
        }
  
@@ -894,7 +894,7 @@ static void childof_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* standard target-getting macro for single-target constraints */
-               SINGLETARGET_GET_TARS(con, data, ct, list)
+               SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
        }
 }
 
@@ -905,7 +905,7 @@ static void childof_flush_tars (bConstraint *con, ListBase *list, short nocopy)
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGET_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
        }
 }
 
@@ -992,7 +992,7 @@ static void trackto_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* standard target-getting macro for single-target constraints */
-               SINGLETARGET_GET_TARS(con, data, ct, list)
+               SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
        }
 }
 
@@ -1003,7 +1003,7 @@ static void trackto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGET_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
        }
 }
 
@@ -1169,7 +1169,8 @@ static void kinematic_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* standard target-getting macro for single-target constraints */
-               SINGLETARGET_GET_TARS(con, data, ct, list)
+               SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+               SINGLETARGET_GET_TARS(con, data->poletar, data->polesubtarget, ct, list)
        }
 }
 
@@ -1180,7 +1181,9 @@ static void kinematic_flush_tars (bConstraint *con, ListBase *list, short nocopy
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGET_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+               ct= ct->next;
+               SINGLETARGET_FLUSH_TARS(con, data->poletar, data->polesubtarget, ct, list, nocopy)
        }
 }
 
@@ -1245,7 +1248,7 @@ static void followpath_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* standard target-getting macro for single-target constraints without subtargets */
-               SINGLETARGETNS_GET_TARS(con, data, ct, list)
+               SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
        }
 }
 
@@ -1256,7 +1259,7 @@ static void followpath_flush_tars (bConstraint *con, ListBase *list, short nocop
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGETNS_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
        }
 }
 
@@ -1283,7 +1286,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
                
                if (cu->path && cu->path->data) {
                        curvetime= bsystem_time(ct->tar, (float)ctime, 0.0) - data->offset;
-                       
+
                        if (calc_ipo_spec(cu->ipo, CU_SPEED, &curvetime)==0) {
                                curvetime /= cu->pathlen;
                                CLAMP(curvetime, 0.0, 1.0);
@@ -1546,7 +1549,7 @@ static void loclike_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* standard target-getting macro for single-target constraints */
-               SINGLETARGET_GET_TARS(con, data, ct, list)
+               SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
        }
 }
 
@@ -1557,7 +1560,7 @@ static void loclike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGET_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
        }
 }
 
@@ -1661,7 +1664,7 @@ static void rotlike_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* standard target-getting macro for single-target constraints */
-               SINGLETARGET_GET_TARS(con, data, ct, list)
+               SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
        }
 }
 
@@ -1672,7 +1675,7 @@ static void rotlike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGET_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
        }
 }
 
@@ -1749,7 +1752,7 @@ static void sizelike_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* standard target-getting macro for single-target constraints */
-               SINGLETARGET_GET_TARS(con, data, ct, list)
+               SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
        }
 }
 
@@ -1760,7 +1763,7 @@ static void sizelike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGET_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
        }
 }
 
@@ -1804,15 +1807,13 @@ static bConstraintTypeInfo CTI_SIZELIKE = {
 static void pycon_free (bConstraint *con)
 {
        bPythonConstraint *data= con->data;
-       bConstraintTarget *ct;
        
        /* id-properties */
        IDP_FreeProperty(data->prop);
        MEM_freeN(data->prop);
        
        /* multiple targets */
-       while ( (ct = data->targets.first) ) 
-               MEM_freeN(ct);
+       BLI_freelistN(&data->targets);
 }      
 
 static void pycon_relink (bConstraint *con)
@@ -1930,7 +1931,7 @@ static void actcon_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* standard target-getting macro for single-target constraints */
-               SINGLETARGET_GET_TARS(con, data, ct, list)
+               SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
        }
 }
 
@@ -1941,7 +1942,7 @@ static void actcon_flush_tars (bConstraint *con, ListBase *list, short nocopy)
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGET_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
        }
 }
 
@@ -2070,7 +2071,7 @@ static void locktrack_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGET_GET_TARS(con, data, ct, list)
+               SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
        }
 }
 
@@ -2081,7 +2082,7 @@ static void locktrack_flush_tars (bConstraint *con, ListBase *list, short nocopy
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGET_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
        }
 }
 
@@ -2421,7 +2422,7 @@ static void stretchto_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* standard target-getting macro for single-target constraints */
-               SINGLETARGET_GET_TARS(con, data, ct, list)
+               SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
        }
 }
 
@@ -2432,7 +2433,7 @@ static void stretchto_flush_tars (bConstraint *con, ListBase *list, short nocopy
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGET_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
        }
 }
 
@@ -2597,7 +2598,7 @@ static void minmax_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* standard target-getting macro for single-target constraints */
-               SINGLETARGET_GET_TARS(con, data, ct, list)
+               SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
        }
 }
 
@@ -2608,7 +2609,7 @@ static void minmax_flush_tars (bConstraint *con, ListBase *list, short nocopy)
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGET_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
        }
 }
 
@@ -2727,7 +2728,7 @@ static void rbj_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* standard target-getting macro for single-target constraints without subtargets */
-               SINGLETARGETNS_GET_TARS(con, data, ct, list)
+               SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
        }
 }
 
@@ -2738,7 +2739,7 @@ static void rbj_flush_tars (bConstraint *con, ListBase *list, short nocopy)
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGETNS_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
        }
 }
 
@@ -2766,7 +2767,7 @@ static void clampto_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* standard target-getting macro for single-target constraints without subtargets */
-               SINGLETARGETNS_GET_TARS(con, data, ct, list)
+               SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
        }
 }
 
@@ -2777,7 +2778,7 @@ static void clampto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGETNS_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
        }
 }
 
@@ -2939,7 +2940,7 @@ static void transform_get_tars (bConstraint *con, ListBase *list)
                bConstraintTarget *ct;
                
                /* standard target-getting macro for single-target constraints */
-               SINGLETARGET_GET_TARS(con, data, ct, list)
+               SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
        }
 }
 
@@ -2950,7 +2951,7 @@ static void transform_flush_tars (bConstraint *con, ListBase *list, short nocopy
                bConstraintTarget *ct= list->first;
                
                /* the following macro is used for all standard single-target constraints */
-               SINGLETARGET_FLUSH_TARS(con, data, ct, list, nocopy)
+               SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
        }
 }
 
@@ -3227,7 +3228,7 @@ void copy_constraints (ListBase *dst, ListBase *src)
  * None of the actual calculations of the matricies should be done here! Also, this function is 
  * not to be used by any new constraints, particularly any that have multiple targets.
  */
-void get_constraint_target_matrix (bConstraint *con, short ownertype, void *ownerdata, float mat[][4], float ctime)
+void get_constraint_target_matrix (bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime)
 {
        bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
        ListBase targets = {NULL, NULL};
@@ -3274,6 +3275,9 @@ void get_constraint_target_matrix (bConstraint *con, short ownertype, void *owne
                
                /* only calculate the target matrix on the first target */
                ct= (bConstraintTarget *)targets.first;
+               while(ct && n-- > 0)
+                       ct= ct->next;
+
                if (ct) {
                        if (cti->get_target_matrix)
                                cti->get_target_matrix(con, cob, ct, ctime);
index a40131b3d7b6cc78d16e9d8e2cae96d224a9e100..ea086481bac43780a70de9e225ad87fdbfe5d77a 100644 (file)
@@ -780,7 +780,7 @@ void BKE_add_image_extension(char *string, int imtype)
 void BKE_stamp(struct ImBuf *ibuf)
 {
        char text[256], infotext[256];
-       int x, y, h, m, s, f;
+       int x=0, y=0, h, m, s, f;
        int font_height;
        int text_width;
        int text_pad;
@@ -813,23 +813,79 @@ void BKE_stamp(struct ImBuf *ibuf)
        case 4: /* huge */
                font = BMF_GetFont(BMF_kHelveticaBold14);
                break;
+       default:
+               font = NULL;
+               break;
        }
        
        font_height = BMF_GetFontHeight(font);
+       /* All texts get halfspace+1 pixel on each side and 1 pix
+          above and below as padding against their backing rectangles */
        text_pad = BMF_GetStringWidth(font, " ");
        
        IMB_imginfo_change_field (ibuf, "File", G.sce);
        if (G.scene->r.stamp & R_STAMP_DRAW) {
-               x = 1;
-               y = ibuf->y - font_height;
-               sprintf(text, "File: %s", G.sce);
+               /* Top left corner */
+               x = 1; /* Inits for everyone, text position, so 1 for padding, not 0 */
+               y = ibuf->y - font_height - 1; /* Also inits for everyone, notice padding pixel */
+               sprintf(text, "File %s", G.sce);
                text_width = BMF_GetStringWidth(font, text);
                IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-               BMF_DrawStringBuf(font, G.sce, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
-               x = 1;
-               y -= font_height+1;
+               BMF_DrawStringBuf(font, text, x+(text_pad/2), y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+               y -= font_height+2; /* Top and bottom 1 pix padding each */
        }
 
+       if (G.scene->r.stamp & R_STAMP_NOTE) {
+               IMB_imginfo_change_field (ibuf, "Note", G.scene->r.stamp_udata);
+               if (G.scene->r.stamp & R_STAMP_DRAW) {
+                       /* Top left corner, below File */
+                       text_width = BMF_GetStringWidth(font, G.scene->r.stamp_udata);
+                       IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+                       BMF_DrawStringBuf(font, G.scene->r.stamp_udata, x+(text_pad/2), y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+                       y -= font_height+2; /* Top and bottom 1 pix padding each */
+               }
+       }
+       
+       if (G.scene->r.stamp & R_STAMP_DATE) {
+#ifdef WIN32
+               _strdate (sdate);
+               sprintf (infotext, "%s", sdate);
+#else
+               t = time (NULL);
+               tl = localtime (&t);
+               sprintf (infotext, "%04d-%02d-%02d", tl->tm_year+1900, tl->tm_mon+1, tl->tm_mday);
+#endif /* WIN32 */
+               IMB_imginfo_change_field (ibuf, "Date", infotext);
+
+               if (G.scene->r.stamp & R_STAMP_DRAW) {
+                       /* Top left corner, below File (or Note) */
+                       sprintf (text, "Date %s", infotext);
+                       text_width = BMF_GetStringWidth(font, text);
+                       IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+                       BMF_DrawStringBuf(font, text, x+(text_pad/2), y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+               }
+       }
+
+
+       if (G.scene->r.stamp & R_STAMP_MARKER) {
+               TimeMarker *marker = get_frame_marker(CFRA);
+               
+               if (marker) strcpy(infotext, marker->name);
+               else            strcpy(infotext, "<none>");
+               
+               IMB_imginfo_change_field (ibuf, "Marker", infotext);
+               
+               if (G.scene->r.stamp & R_STAMP_DRAW) {
+                       /* Bottom left corner, leaving space for timing */
+                       x = 1;
+                       y = font_height+2+1; /* 2 for padding in TIME|FRAME fields below and 1 for padding in this one */
+                       sprintf (text, "Marker %s", infotext);
+                       text_width = BMF_GetStringWidth(font, text);
+                       IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+                       BMF_DrawStringBuf(font, text, x+(text_pad/2), y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+               }
+       }
 
        if (G.scene->r.stamp & R_STAMP_TIME) {
                h= m= s= f= 0;
@@ -854,11 +910,14 @@ void BKE_stamp(struct ImBuf *ibuf)
                IMB_imginfo_change_field (ibuf, "Time", infotext);
                
                if (G.scene->r.stamp & R_STAMP_DRAW) {
+                       /* Left bottom corner */
+                       x = 1;
+                       y = 1;
                        sprintf (text, "Time %s", infotext);
                        text_width = BMF_GetStringWidth(font, text);
                        IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-                       BMF_DrawStringBuf(font, text, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
-                       x += text_width;
+                       BMF_DrawStringBuf(font, text, x+(text_pad/2), y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+                       x += text_width+text_pad+2; /* Both sides have 1 pix additional padding each */
                }
        }
 
@@ -867,47 +926,35 @@ void BKE_stamp(struct ImBuf *ibuf)
                IMB_imginfo_change_field (ibuf, "Frame", infotext);
 
                if (G.scene->r.stamp & R_STAMP_DRAW) {
-                       sprintf (text, "    Frame %s", infotext);
-                       text_width = BMF_GetStringWidth(font, text);
-                       IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-                       BMF_DrawStringBuf(font, text, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
-                       x += BMF_GetStringWidth(font, text);
-               }
-       }
-
-       if (G.scene->r.stamp & R_STAMP_DATE) {
-#ifdef WIN32
-               _strdate (sdate);
-               sprintf (infotext, "%s", sdate);
-#else
-               t = time (NULL);
-               tl = localtime (&t);
-               sprintf (infotext, "%02d-%02d-%02d", tl->tm_mon+1, tl->tm_mday, tl->tm_year-100);
-#endif /* WIN32 */
-               IMB_imginfo_change_field (ibuf, "Date", infotext);
+                       char format[32];
 
-               if (G.scene->r.stamp & R_STAMP_DRAW) {
-                       x = 1;
-                       y = 1;
-                       sprintf (text, "Date %s", infotext);
+                       /* First build "Frame %03i" for anims ending in frame 100-999, etc */
+                       sprintf(format, "Frame %%0%di\n", 1 + (int) log10(G.scene->r.efra));
+                       sprintf (text, format, G.scene->r.cfra);
                        text_width = BMF_GetStringWidth(font, text);
+                       /* Left bottom corner (after SMPTE if exists) */
+                       if (!(G.scene->r.stamp & R_STAMP_TIME)) {
+                               x = 1;
+                       }
+                       y = 1;
                        IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-                       BMF_DrawStringBuf(font, text, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
-                       x += text_width;
+                       BMF_DrawStringBuf(font, text, x+(text_pad/2), y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
                }
        }
 
+
        if (G.scene->r.stamp & R_STAMP_CAMERA) {
                sprintf(infotext, ((Camera *) G.scene->camera)->id.name+2);
                IMB_imginfo_change_field (ibuf, "Camera", infotext);
 
                if (G.scene->r.stamp & R_STAMP_DRAW) {
-                       sprintf (text, "Camera: %s", infotext);
+                       sprintf (text, "Camera %s", infotext);
                        text_width = BMF_GetStringWidth(font, text);
+                       /* Center of bottom edge */
                        x = (ibuf->x/2) - (BMF_GetStringWidth(font, text)/2);
                        y = 1;
                        IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-                       BMF_DrawStringBuf(font, text, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+                       BMF_DrawStringBuf(font, text, x+(text_pad/2), y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
                }
        }
 
@@ -916,41 +963,13 @@ void BKE_stamp(struct ImBuf *ibuf)
                IMB_imginfo_change_field (ibuf, "Scene", infotext);
 
                if (G.scene->r.stamp & R_STAMP_DRAW) {
-                       sprintf (text, "Scene: %s", infotext);
+                       sprintf (text, "Scene %s", infotext);
                        text_width = BMF_GetStringWidth(font, text);
+                       /* Bottom right corner */
                        x = ibuf->x - (BMF_GetStringWidth(font, text)+1+text_pad);
+                       y = 1;
                        IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-                       BMF_DrawStringBuf(font, text, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
-               }
-       }
-       
-       if (G.scene->r.stamp & R_STAMP_NOTE) {
-               IMB_imginfo_change_field (ibuf, "Note", G.scene->r.stamp_udata);
-               if (G.scene->r.stamp & R_STAMP_DRAW) {
-                       x = 1;
-                       y = font_height+1;
-                       text_width = BMF_GetStringWidth(font, G.scene->r.stamp_udata);
-                       IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-                       BMF_DrawStringBuf(font, G.scene->r.stamp_udata, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
-               }
-       }
-       
-       if (G.scene->r.stamp & R_STAMP_MARKER) {
-               TimeMarker *marker = get_frame_marker(CFRA);
-               
-               if (marker) strcpy(infotext, marker->name);
-               else            strcpy(infotext, "None");
-               
-               IMB_imginfo_change_field (ibuf, "Marker", infotext);
-               
-               if (G.scene->r.stamp & R_STAMP_DRAW) {
-                       sprintf (text, "Marker: %s", infotext);
-                       x = 1;
-                       y = ibuf->y - (font_height+1)*3;
-                       text_width = BMF_GetStringWidth(font, text);
-                       IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
-                       BMF_DrawStringBuf(font, text, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+                       BMF_DrawStringBuf(font, text, x+(text_pad/2), y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
                }
        }
 }
index 6e27f580d8838c6dfae3aed38a78463ea0110deb..e6e6ba49066307bc246f00e3ff6e255c5fa51cd5 100644 (file)
@@ -933,8 +933,8 @@ void nurbs_to_mesh(Object *ob)
                        index= dl->index;
                        while(a--) {
                                mface->v1= startvert+index[0];
-                               mface->v2= startvert+index[1];
-                               mface->v3= startvert+index[2];
+                               mface->v2= startvert+index[2];
+                               mface->v3= startvert+index[1];
                                mface->v4= 0;
                                test_index_face(mface, NULL, 0, 3);
                                
index 8143a4cf65fe4116e15a9e5b2726baf312bfd746..fe84ae570961ca91a594d9e6b6511bac13e65b2e 100644 (file)
@@ -1666,6 +1666,7 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
                                bKinematicConstraint *data;
                                data = ((bKinematicConstraint*)con->data);
                                data->tar = newlibadr(fd, id->lib, data->tar);
+                               data->poletar = newlibadr(fd, id->lib, data->poletar);
                        }
                        break;
                case CONSTRAINT_TYPE_TRACKTO:
@@ -1746,6 +1747,7 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
                cons->data = newdataadr(fd, cons->data);
                if (cons->type == CONSTRAINT_TYPE_PYTHON) {
                        bPythonConstraint *data= cons->data;
+                       link_list(fd, &data->targets);
                        data->prop = newdataadr(fd, data->prop);
                        IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
                }
@@ -6777,7 +6779,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
        if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 2)) {
                Image *ima;
-               Scene *sce;
 
                /* initialize 1:1 Aspect */
                for(ima= main->image.first; ima; ima= ima->id.next) {
@@ -6807,6 +6808,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                Scene *sce;
                for(sce= main->scene.first; sce; sce=sce->id.next) {
                        sce->r.fg_stamp[0] = sce->r.fg_stamp[1] = sce->r.fg_stamp[2] = 0.8;
+                       sce->r.fg_stamp[3] = 1.0; /* dont use text alpha yet */
+                       sce->r.bg_stamp[3] = 0.25; /* make sure the background has full alpha */
                }
        }
 
@@ -7312,6 +7315,7 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
                        {
                                bKinematicConstraint *data = (bKinematicConstraint*)curcon->data;
                                expand_doit(fd, mainvar, data->tar);
+                               expand_doit(fd, mainvar, data->poletar);
                        }
                        break;
                case CONSTRAINT_TYPE_TRACKTO:
index 3066f61717439d503031ab7abf35138489685778..ba4cbd1b9506e0abded49a6e160611ca7e230127 100644 (file)
@@ -711,7 +711,12 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
                        switch (con->type) {
                                case CONSTRAINT_TYPE_PYTHON:
                                {
-                                       bPythonConstraint *data = (bPythonConstraint*) con->data;
+                                       bPythonConstraint *data = (bPythonConstraint *)con->data;
+                                       bConstraintTarget *ct;
+                                       
+                                       /* write targets */
+                                       for (ct= data->targets.first; ct; ct= ct->next)
+                                               writestruct(wd, DATA, "bConstraintTarget", 1, ct);
                                        
                                        /* Write ID Properties -- and copy this comment EXACTLY for easy finding
                                         of library blocks that implement this.*/
index 55cd4b9b6a1f846bda14d32b881037ffdf8b77a5..591ab066c57f1297aec36e4770574dc57d112f44 100644 (file)
@@ -524,7 +524,7 @@ void IMB_rectfill(struct ImBuf *drect, float col[4])
 void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, int y2)
 {
        int i, j;
-       
+       float a, ai;
        if ((!ibuf) || (!col))
                return;
        
@@ -538,6 +538,9 @@ void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, i
        if (y1>y2) SWAP(int,y1,y2);
        if (x1==x2 || y1==y2) return;
        
+       a = col[3];
+       ai = 1-a;
+       
        if (ibuf->rect) {
                unsigned char *img, *pixel; 
                unsigned char chr, chg, chb;
@@ -550,9 +553,16 @@ void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, i
                for (j = 0; j < y2-y1; j++) {
                        for (i = 0; i < x2-x1; i++) {
                                pixel = img + 4 * (((y1 + j) * ibuf->x) + (x1 + i));
-                               pixel[0] = chr;
-                               pixel[1] = chg;
-                               pixel[2] = chb;
+                               if (a == 1.0) {
+                                       pixel[0] = chr;
+                                       pixel[1] = chg;
+                                       pixel[2] = chb;
+                               } else {
+                                       pixel[0] = (char)((chr*a) + (pixel[0]*ai));
+                                       pixel[1] = (char)((chg*a) + (pixel[1]*ai));
+                                       pixel[2] = (char)((chb*a) + (pixel[2]*ai));
+                               }
+                               
                        }
                }
        }
@@ -563,9 +573,15 @@ void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, i
                for (j = 0; j < y2-y1; j++) {
                        for (i = 0; i < x2-x1; i++) {
                                pixel = img + 4 * (((y1 + j) * ibuf->x) + (x1 + i));
-                               pixel[0] = col[0];
-                               pixel[1] = col[1];
-                               pixel[2] = col[2];
+                               if (a == 1.0) {
+                                       pixel[0] = col[0];
+                                       pixel[1] = col[1];
+                                       pixel[2] = col[2];
+                               } else {
+                                       pixel[0] = (col[0]*a) + (pixel[0]*ai);
+                                       pixel[1] = (col[1]*a) + (pixel[1]*ai);
+                                       pixel[2] = (col[2]*a) + (pixel[2]*ai);
+                               }
                        }
                }
        }
index 54c57e3331dfb1070a0ab8107d63b9711581423a..74baf12c11a19a11e2f1e178537c4b3ad784ff3b 100644 (file)
@@ -40,6 +40,7 @@ void                          add_sequence(int type);
 void                           borderselect_seq(void);
 void                           boundbox_seq(void);
 void                           change_sequence(void);
+void                           reload_sequence(void);
 void                           update_seq_ipo_rect(struct Sequence * seq);
 void                           update_seq_icu_rects(struct Sequence * seq);
 struct Sequence*       get_last_seq();
@@ -76,7 +77,7 @@ 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);
+int                            check_single_seq(struct Sequence *seq);
 
 /* sequence transform functions, for internal used */
 int seq_tx_get_start(struct Sequence *seq);
index e7475af3ab7f63207364ea3a769af4ce4b047d92..e77d1e98487bb718cea6b0e82a64e5df005b46d5 100644 (file)
@@ -43,7 +43,7 @@ void exit_usiblender(void);
 void BIF_init(void);
 
 void BIF_read_file(char *name);
-int BIF_read_homefile(int from_memory);
+int BIF_read_homefile(int from_memory, int do_undo);
 void BIF_read_autosavefile(void);
 
 void BIF_write_file(char *target);
index 8f08608ec1114edbda12f0d9a9db3dd3dc429c37..e492490fbaba71a3aec16198d16180dd09424435 100644 (file)
@@ -298,7 +298,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
 #define B_COLZEN               1503
 #define B_WMTEXPASTE   1504
 #define B_WMTEXCOPY            1505
-#define B_AO_DISTANCES 1506
+#define B_AO_FALLOFF   1506
 
 /* *********************** */
 #define B_RENDERBUTS   1700
index e06063a11a15093de37ce5303f8502464065a038..431ef56e1c4e05ed78314a2da64577f14ff2de11 100644 (file)
@@ -125,10 +125,13 @@ typedef struct bKinematicConstraint {
        int                     rootbone;       /* index to rootbone, if zero go all the way to mother bone */
        char            subtarget[32];  /* String to specify sub-object target */
 
+       Object          *poletar;                       /* Pole vector target */
+       char            polesubtarget[32];      /* Pole vector sub-object target */
+       float           poleangle;                      /* Pole vector rest angle */
+
        float           weight;                 /* Weight of goal in IK tree */
        float           orientweight;   /* Amount of rotation a target applies on chain */
        float           grabtarget[3];  /* for target-less IK */
-       int                     pad;
 } bKinematicConstraint;
 
 /* Track To Constraint */
@@ -439,6 +442,8 @@ typedef enum B_CONSTRAINTCHANNEL_FLAG {
 #define CONSTRAINT_IK_TEMP             8
 #define CONSTRAINT_IK_STRETCH  16
 #define CONSTRAINT_IK_POS              32
+#define CONSTRAINT_IK_SETANGLE 64
+#define CONSTRAINT_IK_GETANGLE 128
 
 /* MinMax (floor) flags */
 #define MINMAX_STICKY  0x01
index 467397e749e0929af34dbc4417ad56104feae214..1d2ff1d0bf2f705a27f2db219b0faa28d5c78140 100644 (file)
@@ -599,10 +599,12 @@ typedef struct Scene {
 #define SCE_SNAP_TARGET_MEDIAN 2
 
 /* sce->selectmode */
-#define SCE_SELECT_VERTEX      1
+#define SCE_SELECT_VERTEX      1 /* for mesh */
 #define SCE_SELECT_EDGE                2
 #define SCE_SELECT_FACE                4
 
+#define SCE_SELECT_CU_HANDLES_HIDE 8 /* for curve, when flagged hide handles */ 
+
 /* sce->recalc (now in use by previewrender) */
 #define SCE_PRV_CHANGED                1
 
index 769d11ecebee5c4d7a015d6a62bcc1355fc629e9..9e5ec4cdb9a01a20cd99687f985401234ce37ed0 100644 (file)
@@ -103,8 +103,8 @@ typedef struct World {
        /* ambient occlusion */
        float aodist, aodistfac, aoenergy, aobias;
        short aomode, aosamp, aomix, aocolor;
-       float ao_adapt_thresh;
-       float pad2[3];
+       float ao_adapt_thresh, ao_adapt_speed_fac;
+       float pad2[2];
        short ao_samp_method;
        short pad1[3];
        
index 27cfc2fa11cc027c6efb006b12a3a327e38ec246..238c05d54a483dca73e67cbc0c3b73ea69a450bf 100644 (file)
@@ -1188,11 +1188,11 @@ void BPY_pyconstraint_update(Object *owner, bConstraint *con)
                /* script does exist. it is assumed that this is a valid pyconstraint script */
                PyObject *globals;
                PyObject *retval, *gval;
-               int num;
+               int num, i;
                
-               /* clear the flag first */
+               /* clear the relevant flags first */
                data->flag = 0;
-               
+                               
                /* populate globals dictionary */
                globals = CreateGlobalDictionary();
                retval = RunPython(data->text, globals);
@@ -1222,18 +1222,23 @@ void BPY_pyconstraint_update(Object *owner, bConstraint *con)
                        /* check if the number of targets has changed */
                        if (num < data->tarnum) {
                                /* free a few targets */
-                               for (ct=data->targets.last; num > -1; num--, ct=data->targets.last, data->tarnum--)
+                               num= data->tarnum - num;
+                               for (i = 0; i < num; i++, data->tarnum--) {
+                                       ct= data->targets.last;
                                        BLI_freelinkN(&data->targets, ct);
+                               }
                        }
                        else if (num > data->tarnum) {
                                /* add a few targets */
-                               for ( ; num > -1; num--, data->tarnum++) {
+                               num = num - data->tarnum;
+                               for (i = 0; i < num; i++, data->tarnum++) {
                                        ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
                                        BLI_addtail(&data->targets, ct);
                                }
                        }
                        
                        /* validate targets */
+                       con->flag &= ~CONSTRAINT_DISABLE;
                        for (ct= data->targets.first; ct; ct= ct->next) {
                                if (!exist_object(ct->tar)) {
                                        ct->tar = NULL;
@@ -1241,11 +1246,11 @@ void BPY_pyconstraint_update(Object *owner, bConstraint *con)
                                        break;
                                }
                                
-                               if ( (ct->tar == owner) &&
-                                        (!get_named_bone(get_armature(owner), ct->subtarget)) ) 
-                               {
-                                       con->flag |= CONSTRAINT_DISABLE;
-                                       break;
+                               if ((ct->tar == owner) && (ct->subtarget[0] != 0)) {
+                                       if (get_named_bone(get_armature(owner), ct->subtarget) == NULL) {
+                                               con->flag |= CONSTRAINT_DISABLE;
+                                               break;
+                                       }
                                }
                        }
                        
@@ -1268,6 +1273,7 @@ void BPY_pyconstraint_update(Object *owner, bConstraint *con)
                /* no script, so clear any settings/data now */
                data->tarnum = 0;
                data->flag = 0;
+               con->flag &= ~CONSTRAINT_DISABLE;
                
                BLI_freelistN(&data->targets);
                
index 07384391d273b82f1e333c26b6b973f13ac379e9..24b9f4d5186ff59eb6d2ee4c1df591152f3d49ce 100644 (file)
@@ -637,7 +637,7 @@ static PyObject *Blender_Load( PyObject * self, PyObject * args )
                 * enough here.  Note: the default file requires extra clean-up done by
                 * BIF_read_homefile: freeing the user theme data. */
                if( !fname || ( strstr( fname, ".B.blend" ) && is_blend_file ) )
-                       BIF_read_homefile(0);
+                       BIF_read_homefile(0, 1);
                else
                        BIF_read_file( fname );
 
index 08fbe8472c095f01d416f360cce6078f2a3b725e..3a859b083ed0c83b041a124900be176a9243f394 100644 (file)
@@ -641,7 +641,7 @@ static void halton_sample(double *ht_invprimes, double *ht_nums, double *v)
        
        for (i = 0; i < 2; i++)
        {
-               double r = (1.0 - ht_nums[i]) - 1e-10;
+               double r = fabs((1.0 - ht_nums[i]) - 1e-10);
                
                if (ht_invprimes[i] >= r)
                {
@@ -806,6 +806,23 @@ static void QMC_sampleHemi(float *vec, QMCSampler *qsa, int thread, int num)
        vec[2] = 1.f - s[1]*s[1];
 }
 
+/* cosine weighted hemisphere sampling */
+static void QMC_sampleHemiCosine(float *vec, QMCSampler *qsa, int thread, int num)
+{
+       double s[2];
+       float phi, sqr;
+       
+       QMC_getSample(s, qsa, thread, num);
+       
+       phi = s[0]*2.f*M_PI;    
+       sqr = s[1]*sqrt(2-s[1]*s[1]);
+
+       vec[0] = cos(phi)*sqr;
+       vec[1] = sin(phi)*sqr;
+       vec[2] = 1.f - s[1]*s[1];
+
+}
+
 /* called from convertBlenderScene.c */
 /* samples don't change per pixel, so build the samples in advance for efficiency */
 void init_lamp_hammersley(LampRen *lar)
@@ -861,6 +878,20 @@ static int adaptive_sample_contrast_val(int samples, float prev, float val, floa
                return 0;
 }
 
+static float get_avg_speed(ShadeInput *shi)
+{
+       float pre_x, pre_y, post_x, post_y, speedavg;
+       
+       pre_x = (shi->winspeed[0] == PASS_VECTOR_MAX)?0.0:shi->winspeed[0];
+       pre_y = (shi->winspeed[1] == PASS_VECTOR_MAX)?0.0:shi->winspeed[1];
+       post_x = (shi->winspeed[2] == PASS_VECTOR_MAX)?0.0:shi->winspeed[2];
+       post_y = (shi->winspeed[3] == PASS_VECTOR_MAX)?0.0:shi->winspeed[3];
+       
+       speedavg = (sqrt(pre_x*pre_x + pre_y*pre_y) + sqrt(post_x*post_x + post_y*post_y)) / 2.0;
+       
+       return speedavg;
+}
+
 /* ***************** main calls ************** */
 
 
@@ -1407,6 +1438,7 @@ void ray_ao_qmc(ShadeInput *shi, float *shadfac)
        float maxdist = R.wrld.aodist;
        float fac=0.0f, prev=0.0f;
        float adapt_thresh = G.scene->world->ao_adapt_thresh;
+       float adapt_speed_fac = G.scene->world->ao_adapt_speed_fac;
        float bias = G.scene->world->aobias;
        
        int samples=0;
@@ -1447,9 +1479,16 @@ void ray_ao_qmc(ShadeInput *shi, float *shadfac)
        VecOrthoBasisf(nrm, up, side);
        
        /* sampling init */
-       if (R.wrld.ao_samp_method==WO_AOSAMP_HALTON) 
+       if (R.wrld.ao_samp_method==WO_AOSAMP_HALTON) {
+               float speedfac;
+               
+               speedfac = get_avg_speed(shi) * adapt_speed_fac;
+               CLAMP(speedfac, 1.0, 1000.0);
+               max_samples /= speedfac;
+               if (max_samples < 5) max_samples = 5;
+               
                qsa = QMC_initSampler(SAMP_TYPE_HALTON, max_samples);
-       else if (R.wrld.ao_samp_method==WO_AOSAMP_HAMMERSLEY)
+       else if (R.wrld.ao_samp_method==WO_AOSAMP_HAMMERSLEY)
                qsa = R.qsa;
 
        QMC_initPixel(qsa, shi->thread);
@@ -1458,7 +1497,7 @@ void ray_ao_qmc(ShadeInput *shi, float *shadfac)
 
                /* sampling, returns quasi-random vector in unit hemisphere */
                QMC_sampleHemi(samp3d, qsa, shi->thread, samples);
-               
+
                dir[0] = (samp3d[0]*up[0] + samp3d[1]*side[0] + samp3d[2]*nrm[0]);
                dir[1] = (samp3d[0]*up[1] + samp3d[1]*side[1] + samp3d[2]*nrm[1]);
                dir[2] = (samp3d[0]*up[2] + samp3d[1]*side[2] + samp3d[2]*nrm[2]);
@@ -1662,7 +1701,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
        float adapt_thresh = lar->adapt_thresh;
        int max_samples = lar->ray_totsamp;
        float pos[3];
-       int do_soft=1;
+       int do_soft=1, full_osa=0;
 
        colsq[0] = colsq[1] = colsq[2] = 0.0;
        if(isec->mode==RE_RAY_SHADOW_TRA) {
@@ -1671,8 +1710,9 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
                shadfac[3]= 1.0f;
        
        if (lar->ray_totsamp < 2) do_soft = 0;
-               
-       if (shi->vlr->flag & R_FULL_OSA) {
+       if ((R.r.mode & R_OSA) && (R.osa > 0) && (shi->vlr->flag & R_FULL_OSA)) full_osa = 1;
+       
+       if (full_osa) {
                if (do_soft) max_samples  = max_samples/R.osa + 1;
                else max_samples = 1;
        } else {
@@ -1702,7 +1742,7 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *
                 * based on the pre-generated OSA texture sampling offsets, 
                 * for anti-aliasing sharp shadow edges. */
                VECCOPY(pos, shi->co);
-               if (shi->vlr && ((shi->vlr->flag & R_FULL_OSA) == 0)) {
+               if (shi->vlr && !full_osa) {
                        QMC_sampleRect(jit, qsa_jit, shi->thread, samples, 1.0, 1.0);
                        
                        pos[0] += shi->dxco[0]*jit[0] + shi->dyco[0]*jit[1];
index 13aae38810667f3956c830d08d5f3cd8ff5687c7..c8ac0fc4b158b3ffd98907618fec99164f93a8e1 100644 (file)
@@ -2953,13 +2953,16 @@ static void editing_panel_curve_tools1(Object *ob, Curve *cu)
                uiDefBut(block, BUT, B_SPINNURB, "Spin",         400,160,150,20, 0, 0, 0, 0, 0, "Spin selected 360 degrees");
        }
        uiBlockBeginAlign(block);
-       uiDefBut(block, BUT,B_HIDE,             "Hide",                 400,120,150,18, 0, 0, 0, 0, 0, "Hides selected faces");
-       uiDefBut(block, BUT,B_REVEAL,   "Reveal",               400,100,150,18, 0, 0, 0, 0, 0, "Reveals selected faces");
-       uiDefBut(block, BUT,B_SELSWAP,  "Select Swap",  400,80,150,18, 0, 0, 0, 0, 0, "Selects unselected faces, and deselects selected faces");
+       uiDefBut(block, BUT,B_HIDE,             "Hide",                 400,140,150,18, 0, 0, 0, 0, 0, "Hides selected faces");
+       uiDefBut(block, BUT,B_REVEAL,   "Reveal",               400,120,150,18, 0, 0, 0, 0, 0, "Reveals selected faces");
+       uiDefBut(block, BUT,B_SELSWAP,  "Select Swap",  400,100,150,18, 0, 0, 0, 0, 0, "Selects unselected faces, and deselects selected faces");
        uiBlockEndAlign(block);
 
-       uiDefButF(block, NUM,   REDRAWVIEW3D, "NSize:", 400, 40, 150, 19, &G.scene->editbutsize, 0.001, 1.0, 10, 0, "Normal size for drawing");
-
+       uiBlockBeginAlign(block);
+       uiDefButF(block, NUM,   REDRAWVIEW3D, "NSize:", 400, 60, 150, 19, &G.scene->editbutsize, 0.001, 1.0, 10, 0, "Normal size for drawing");
+       uiDefButBitI(block, TOGN, SCE_SELECT_CU_HANDLES_HIDE, REDRAWVIEW3D, "Draw Handles",     400, 40, 150, 19, &G.scene->selectmode, 0, 0, 0, 0, "Draw curve handles in 3D view");
+       uiBlockEndAlign(block);
+       
        if(G.obedit) {
                uiBut *but;
                uiBlockBeginAlign(block);
index c264d684d7713ffd7bd698bac1194a1ce3000a1f..0754aa62016fb58f3a0e56f1a7af5fc38325c8ee 100644 (file)
@@ -412,6 +412,24 @@ void autocomplete_vgroup(char *str, void *arg_v)
        }
 }
 
+/* pole angle callback */
+void con_kinematic_set_pole_angle(void *ob_v, void *con_v)
+{
+       bConstraint *con= con_v;
+       bKinematicConstraint *data = con->data;
+
+       if(data->poletar) {
+               if(data->flag & CONSTRAINT_IK_SETANGLE) {
+                       data->flag |= CONSTRAINT_IK_GETANGLE;
+                       data->flag &= ~CONSTRAINT_IK_SETANGLE;
+               }
+               else {
+                       data->flag &= ~CONSTRAINT_IK_GETANGLE;
+                       data->flag |= CONSTRAINT_IK_SETANGLE;
+               }
+       }
+}
+
 /* some commonly used macros in the constraints drawing code */
 #define is_armature_target(target) (target && target->type==OB_ARMATURE)
 #define is_armature_owner(ob) ((ob->type == OB_ARMATURE) && (ob->flag & OB_POSEMODE))
@@ -484,12 +502,14 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
 
        cti= constraint_get_typeinfo(con);
        if (cti == NULL) {
-               printf("Argh! No valid constraint type-info... aborting constraint drawing. \n");
-               return;
+               /* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
+               if (con->type == CONSTRAINT_TYPE_NULL)
+                       strcpy(typestr, "Null");
+               else
+                       strcpy(typestr, "Unknown");
        }
-       else {
+       else
                strcpy(typestr, cti->name);
-       }
                
        /* unless button has own callback, it adds this callback to button */
        uiBlockSetFunc(block, constraint_active_func, ob, con);
@@ -585,21 +605,21 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
                                                
                                                /* target label */
                                                sprintf(tarstr, "Target %02d:", tarnum);
-                                               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, tarstr, *xco+60, *yco-(48+yoffset), 55, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
+                                               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, tarstr, *xco+45, *yco-(48+yoffset), 60, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
                                                
                                                /* target space-selector - per target */
                                                if (is_armature_target(ct->tar)) {
                                                        uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1", 
-                                                                                                                       *xco+60, *yco-(66+yoffset), 55, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");        
+                                                                                                                       *xco+10, *yco-(66+yoffset), 100, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");       
                                                }
                                                else {
                                                        uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Local (Without Parent) Space %x1", 
-                                                                                                                       *xco+60, *yco-(66+yoffset), 55, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");        
+                                                                                                                       *xco+10, *yco-(66+yoffset), 100, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");       
                                                }
                                                
                                                uiBlockBeginAlign(block);
                                                        /* target object */
-                                                       uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-48, 150, 18, &ct->tar, "Target Object"); 
+                                                       uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-(48+yoffset), 150, 18, &ct->tar, "Target Object"); 
                                                        
                                                        /* subtarget */
                                                        if (is_armature_target(ct->tar)) {
@@ -880,47 +900,76 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
                        {
                                bKinematicConstraint *data = con->data;
                                
-                               height = 111;
+                               height = 146;
+                               if(data->poletar) 
+                                       height += 30;
+
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
                                
-                               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
+                               /* IK Target */
+                               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
                                /* Draw target parameters */
-                               uiDefButBitS(block, TOG, CONSTRAINT_IK_ROT, B_CONSTRAINT_TEST, "Rot", *xco, *yco-24,60,19, &data->flag, 0, 0, 0, 0, "Chain follows rotation of target");
-                               
                                uiBlockBeginAlign(block);
-                                       uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 19, &data->tar, "Target Object"); 
-                                       
-                                       if (is_armature_target(data->tar)) {
-                                               but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,19, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
-                                               uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
-                                       }
-                                       else if (is_geom_target(data->tar)) {
-                                               but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
-                                               uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
-                                       }
-                                       else {
-                                               strcpy(data->subtarget, "");
-                                       }
+                               uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco, *yco-44, 137, 19, &data->tar, "Target Object"); 
+
+                               if (is_armature_target(data->tar)) {
+                                       but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco, *yco-62,137,19, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+                                       uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+                               }
+                               else if (is_geom_target(data->tar)) {
+                                       but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco, *yco-62,137,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+                                       uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+                               }
+                               else {
+                                       strcpy (data->subtarget, "");
+                               }
+
                                uiBlockEndAlign(block);
-                               
+
+                               /* Settings */
                                uiBlockBeginAlign(block);
-                                       uiDefButBitS(block, TOG, CONSTRAINT_IK_TIP, B_CONSTRAINT_TEST, "Use Tail", *xco, *yco-64, 137, 19, &data->flag, 0, 0, 0, 0, "Include Bone's tail as last element in Chain");
-                                       uiDefButI(block, NUM, B_CONSTRAINT_TEST, "ChainLen:", *xco, *yco-84,137,19, &data->rootbone, 0, 255, 0, 0, "If not zero, the amount of bones in this chain");
-                               uiBlockEndAlign(block);
-                               
+                               uiDefButBitS(block, TOG, CONSTRAINT_IK_TIP, B_CONSTRAINT_TEST, "Use Tail", *xco, *yco-92, 137, 19, &data->flag, 0, 0, 0, 0, "Include Bone's tail als last element in Chain");
+                               uiDefButI(block, NUM, B_CONSTRAINT_TEST, "ChainLen:", *xco, *yco-112,137,19, &data->rootbone, 0, 255, 0, 0, "If not zero, the amount of bones in this chain");
+
                                uiBlockBeginAlign(block);
-                                       uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "PosW ", *xco+147, *yco-64, 137, 19, &data->weight, 0.01, 1.0, 2, 2, "For Tree-IK: weight of position control for this target");
-                                       uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "RotW ", *xco+147, *yco-84, 137, 19, &data->orientweight, 0.01, 1.0, 2, 2, "For Tree-IK: Weight of orientation control for this target");
-                               uiBlockEndAlign(block);
-                               
+                               uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "PosW ", *xco+147, *yco-92, 137, 19, &data->weight, 0.01, 1.0, 2, 2, "For Tree-IK: weight of position control for this target");
+                               uiDefButBitS(block, TOG, CONSTRAINT_IK_ROT, B_CONSTRAINT_TEST, "Rot", *xco+147, *yco-112, 40,19, &data->flag, 0, 0, 0, 0, "Chain follows rotation of target");
+                               uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "W ", *xco+187, *yco-112, 97, 19, &data->orientweight, 0.01, 1.0, 2, 2, "For Tree-IK: Weight of orientation control for this target");
+
                                uiBlockBeginAlign(block);
-                                       uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Iterations:", *xco, *yco-109, 137, 19, &data->iterations, 1, 10000, 0, 0, "Maximum number of solving iterations"); 
-                               uiBlockEndAlign(block);
-                               
+
+                               uiDefButBitS(block, TOG, CONSTRAINT_IK_STRETCH, B_CONSTRAINT_TEST, "Stretch", *xco, *yco-137,137,19, &data->flag, 0, 0, 0, 0, "Enable IK stretching");
                                uiBlockBeginAlign(block);
-                                       uiDefButBitS(block, TOG, CONSTRAINT_IK_STRETCH, B_CONSTRAINT_TEST, "Stretch", *xco+147, *yco-109,137,19, &data->flag, 0, 0, 0, 0, "Enable IK stretching");
+                               uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Iterations:", *xco+147, *yco-137, 137, 19, &data->iterations, 1, 10000, 0, 0, "Maximum number of solving iterations"); 
                                uiBlockEndAlign(block);
+
+                               /* Pole Vector */
+                               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Pole Target:", *xco+147, *yco-24, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
+
+                               uiBlockBeginAlign(block);
+                               uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+147, *yco-44, 137, 19, &data->poletar, "Pole Target Object"); 
+                               if (is_armature_target(data->poletar)) {
+                                       but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+147, *yco-62,137,19, &data->polesubtarget, 0, 24, 0, 0, "Pole Subtarget Bone");
+                                       uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->poletar);
+                               }
+                               else if (is_geom_target(data->poletar)) {
+                                       but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+147, *yco-62,137,18, &data->polesubtarget, 0, 24, 0, 0, "Name of Vertex Group defining pole 'target' points");
+                                       uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->poletar);
+                               }
+                               else {
+                                       strcpy (data->polesubtarget, "");
+                               }
+       
+                               if(data->poletar) {
+                                       uiBlockBeginAlign(block);
+#if 0
+                                       but = uiDefBut(block, BUT, B_CONSTRAINT_TEST, (data->flag & CONSTRAINT_IK_SETANGLE)? "Set Pole Offset": "Clear Pole Offset", *xco, *yco-167, 137, 19, 0, 0.0, 1.0, 0.0, 0.0, "Set the pole rotation offset from the current pose");
+                                       uiButSetFunc(but, con_kinematic_set_pole_angle, ob, con);
+                                       if(!(data->flag & CONSTRAINT_IK_SETANGLE))
+#endif
+                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Pole Offset ", *xco, *yco-167, 137, 19, &data->poleangle, -180.0, 180.0, 0, 0, "Pole rotation offset");
+                               }
                        }
                        break;
                case CONSTRAINT_TYPE_TRACKTO:
@@ -1402,10 +1451,10 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
                                uiBlockEndAlign(block);
                                
                                /* Extra Options Controlling Behaviour */
-                               uiBlockBeginAlign(block);
-                                       uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Options:", *xco, *yco-86, 90, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
-                                       uiDefButBitI(block, TOG, CLAMPTO_CYCLIC, B_CONSTRAINT_TEST, "Cyclic", *xco+((width/2)), *yco-86,60,19, &data->flag2, 0, 0, 0, 0, "Treat curve as cyclic curve (no clamping to curve bounding box)");
-                               uiBlockEndAlign(block);
+                               //uiBlockBeginAlign(block);
+                                       uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Options:", *xco, *yco-88, 90, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
+                                       uiDefButBitI(block, TOG, CLAMPTO_CYCLIC, B_CONSTRAINT_TEST, "Cyclic", *xco+((width/2)), *yco-88,60,19, &data->flag2, 0, 0, 0, 0, "Treat curve as cyclic curve (no clamping to curve bounding box)");
+                               //uiBlockEndAlign(block);
                        }
                        break;
                case CONSTRAINT_TYPE_TRANSFORM:
@@ -1643,7 +1692,7 @@ void do_constraintbuts(unsigned short event)
                {
                        con = add_new_constraint(CONSTRAINT_TYPE_NULL);
                        add_constraint_to_active(ob, con);
-
+                       
                        BIF_undo_push("Add constraint");
                }
                break;
index d61268b20642387de0e6e2d91aa0d55d45eb12bf..c734eac073537708c1ec13d06a74075ca5807cf8 100644 (file)
@@ -1570,12 +1570,14 @@ static void render_panel_stamp(void)
                        
                        /* draw fg/bg next to the scene */
                        yofs -= 25;
-                       uiDefBut(block, LABEL, 0, "Text Color", xofs+110, yofs, 80, 19, 0, 0, 0, 0, 0, "");
-                       uiDefBut(block, LABEL, 0, "Background", xofs+205, yofs, 80, 19, 0, 0, 0, 0, 0, "");
+                       uiDefBut(block, LABEL, B_NOP, "Text Color", xofs+110, yofs, 80, 19, 0, 0, 0, 0, 0, "");
+                       uiDefBut(block, LABEL, B_NOP, "Background", xofs+205, yofs, 80, 19, 0, 0, 0, 0, 0, "");
                        yofs -= 20;
                        uiDefButF(block, COL, B_NOP, "", xofs+110, yofs, 90, 19, G.scene->r.fg_stamp, 0, 0, 0, 0, "Foreground text color");
                        uiDefButF(block, COL, B_NOP, "", xofs+210, yofs, 90, 19, G.scene->r.bg_stamp, 0, 0, 0, 0, "Background color");
-                       yofs += 75;
+                       yofs -= 30;
+                       uiDefButF(block, NUMSLI, B_NOP, "A ", xofs+110, yofs, 190, 19, &G.scene->r.bg_stamp[3], 0, 1.0, 0, 0, "Alpha for text background");
+                       yofs += 105;
                } else {
                        yofs += 30;
                }
index 56c8d60bf5b6e46b6bd184010fd9ec51c7e5ea0f..67ccf78c5f6d3054a1eb161c72fbe30cbac613f5 100644 (file)
@@ -1923,8 +1923,8 @@ void do_worldbuts(unsigned short event)
                        scrarea_queue_winredraw(curarea);
                }
                break;
-       case B_AO_DISTANCES:
-               /* distances option only supports plain */
+       case B_AO_FALLOFF:
+               /* falloff distances option only supports plain */
                wrld= G.buts->lockpoin;
                if(wrld)
                        wrld->aocolor= WO_AOPLAIN;
@@ -2124,54 +2124,88 @@ static void world_panel_mistaph(World *wrld)
 static void world_panel_amb_occ(World *wrld)
 {
        uiBlock *block;
+       short yco=PANEL_YMAX;
        
        block= uiNewBlock(&curarea->uiblocks, "world_panel_amb_oc", UI_EMBOSS, UI_HELV, curarea->win);
        uiNewPanelTabbed("Mist / Stars / Physics", "World");
-       if(uiNewPanel(curarea, block, "Amb Occ", "World", 320, 0, 318, 204)==0) return;
+       if(uiNewPanel(curarea, block, "Amb Occ", "World", PANELX, PANELY, PANELW, PANELH)==0) return;
 
        uiBlockSetCol(block, TH_BUT_SETTING1);
-       uiDefButBitS(block, TOG, WO_AMB_OCC, B_REDR,    "Ambient Occlusion",10,150,300,19, &wrld->mode, 0, 0, 0, 0, "Toggles ambient occlusion (soft shadows)");
+       uiDefButBitS(block, TOG, WO_AMB_OCC, B_REDR, "Ambient Occlusion",
+               X2CLM1, yco-=BUTH, BUTW1, BUTH, &wrld->mode, 0, 0, 0, 0, "Toggles ambient occlusion (soft shadows)");
        uiBlockSetCol(block, TH_AUTO);
+       
+       if(!(wrld->mode & WO_AMB_OCC)) return;
+       
+       yco -= YSPACE;
 
-       if(wrld->mode & WO_AMB_OCC) {
-
-               /* aolight: samples */
-               uiDefButS(block, MENU, B_REDR, "Constant QMC %x2|Adaptive QMC %x1|Constant Jittered %x0",
-                               10, 120, 145, 19, &wrld->ao_samp_method, 0, 0, 0, 0, "Method for generating shadow samples: Constant QMC: best quality, Adaptive QMC: fast in high contrast areas");
-               uiDefButS(block, NUM, B_REDR, "Samples:",
-                               165, 120, 145, 19, &wrld->aosamp, 1.0, 32.0, 100, 0, "Sets the number of samples used for AO  (actual number: squared)");
-               
-               if (wrld->ao_samp_method == WO_AOSAMP_HALTON) {
-                       uiDefButF(block, NUM, B_REDR, "Threshold:",
-                               10, 95, 145, 19, &wrld->ao_adapt_thresh, 0.0, 1.0, 100, 0, "Samples below this threshold will be considered fully shadowed/unshadowed and skipped");
-               }
-               uiDefButF(block, NUM, B_REDR, "Dist:",
-                       165, 95, 145, 19, &wrld->aodist, 0.001, 5000.0, 100, 0, "Sets length of AO rays, defines how far away other faces give occlusion effect");
+       uiDefButS(block, NUM, B_REDR, "Samples:",
+               X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aosamp, 1.0, 32.0, 100, 0, "Sets the number of samples used for AO  (actual number: squared)");
+       
+       yco -= YSPACE;
+       
+       uiDefButF(block, NUM, B_REDR, "Max Dist:",
+               X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aodist, 0.001, 5000.0, 100, 0, "Sets length of AO rays, defines how far away other faces give occlusion effect");
 
+       yco -= YSPACE;
+       
+       uiBlockBeginAlign(block);
+       uiDefButBitS(block, TOG, WO_AODIST, B_AO_FALLOFF, "Use Falloff",
+               X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aomode, 0, 0, 0, 0, "When enabled, distances to objects will be used to attenuate shadows. Only for Plain AO.");
+       if (wrld->aomode & WO_AODIST)
+               uiDefButF(block, NUM, B_REDR, "Strength:",
+                       X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aodistfac, 0.00001, 10.0, 100, 0, "Distance attenuation factor, the higher, the 'shorter' the shadows");
+       uiBlockEndAlign(block);
+       
+       /* column 2 */
+       yco = PANEL_YMAX - BUTH - YSPACE;
+       
+       uiDefButS(block, MENU, B_REDR, "Constant QMC %x2|Adaptive QMC %x1|Constant Jittered %x0",
+               X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_samp_method, 0, 0, 0, 0, "Method for generating shadow samples: Constant QMC: best quality, Adaptive QMC: fast in high contrast areas");
+       
+       yco -= YSPACE;
+       
+       if (wrld->ao_samp_method == WO_AOSAMP_HALTON) { 
                uiBlockBeginAlign(block);
-               uiDefButBitS(block, TOG, WO_AODIST, B_AO_DISTANCES, "Use Distances", 10, 70, 150, 19, &wrld->aomode, 0, 0, 0, 0, "When enabled, distances to objects will be used to attenuate shadows. Only for Plain AO.");
-               /* distance attenuation factor */
-               if (wrld->aomode & WO_AODIST)
-                       uiDefButF(block, NUM, B_REDR, "DistF:", 160, 70, 150, 19, &wrld->aodistfac, 0.00001, 10.0, 100, 0, "Distance factor, the higher, the 'shorter' the shadows");
+               uiDefButF(block, NUM, B_REDR, "Threshold:",
+                       X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_adapt_thresh, 0.0, 1.0, 100, 0, "Samples below this threshold will be considered fully shadowed/unshadowed and skipped");
+               uiDefButF(block, NUMSLI, B_REDR, "Adapt Vec:",
+                       X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_adapt_speed_fac, 0.0, 1.0, 100, 0, "Use the speed vector pass to reduce AO samples in fast moving pixels. The higher the value, the more aggressive the sample reduction. Requires Vec pass enabled.");
+               uiBlockEndAlign(block);
+       } else if (wrld->ao_samp_method == WO_AOSAMP_CONSTANT) {
+               uiDefButF(block, NUMSLI, B_REDR, "Bias:",
+                       X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->aobias, 0.0, 0.5, 10, 0, "Sets bias to prevent smoothed faces to show banding (in radians)");
+       }
 
-               /* result mix modes */
-               uiBlockBeginAlign(block);
-               uiDefButS(block, ROW, B_REDR, "Add", 10, 45, 100, 20, &wrld->aomix, 1.0, (float)WO_AOADD, 0, 0, "adds light/shadows");
-               uiDefButS(block, ROW, B_REDR, "Sub", 110, 45, 100, 20, &wrld->aomix, 1.0, (float)WO_AOSUB, 0, 0, "subtracts light/shadows (needs at least one normal light to make anything visible)");
-               uiDefButS(block, ROW, B_REDR, "Both", 210, 45, 100, 20, &wrld->aomix, 1.0, (float)WO_AOADDSUB, 0, 0, "both lightens & darkens");
 
-               /* color treatment */
-               uiBlockBeginAlign(block);
-               uiDefButS(block, ROW, B_REDR, "Plain", 10, 25, 100, 20, &wrld->aocolor, 2.0, (float)WO_AOPLAIN, 0, 0, "Plain diffuse energy (white)");
-               uiDefButS(block, ROW, B_REDR, "Sky Color", 110, 25, 100, 20, &wrld->aocolor, 2.0, (float)WO_AOSKYCOL, 0, 0, "Use horizon and zenith color for diffuse energy");
-               uiDefButS(block, ROW, B_REDR, "Sky Texture", 210, 25, 100, 20, &wrld->aocolor, 2.0, (float)WO_AOSKYTEX, 0, 0, "Does full Sky texture render for diffuse energy");
-               
-               uiBlockBeginAlign(block);
-               uiDefButF(block, NUMSLI, B_REDR, "Energy:", 10, 0, 150, 19, &wrld->aoenergy, 0.01, 3.0, 100, 0, "Sets global energy scale for AO");
-               if (wrld->ao_samp_method == WO_AOSAMP_CONSTANT)
-                       uiDefButF(block, NUMSLI, B_REDR, "Bias:", 160, 0, 150, 19, &wrld->aobias, 0.0, 0.5, 10, 0, "Sets bias to prevent smoothed faces to show banding (in radians)");
-       }
+       yco = PANEL_YMAX - (5*BUTH+4*YSPACE);
+
+       /* result mix modes */
+       uiBlockBeginAlign(block);
+       uiDefButS(block, ROW, B_REDR, "Add",
+               X3CLM1, yco-=BUTH, BUTW3, BUTH, &wrld->aomix, 1.0, (float)WO_AOADD, 0, 0, "adds light/shadows");
+       uiDefButS(block, ROW, B_REDR, "Sub",
+               X3CLM2, yco, BUTW3, BUTH, &wrld->aomix, 1.0, (float)WO_AOSUB, 0, 0, "subtracts light/shadows (needs at least one normal light to make anything visible)");
+       uiDefButS(block, ROW, B_REDR, "Both",
+               X3CLM3, yco, BUTW3, BUTH, &wrld->aomix, 1.0, (float)WO_AOADDSUB, 0, 0, "both lightens & darkens");
+
+       yco -= YSPACE;
 
+       /* color treatment */
+       uiBlockBeginAlign(block);
+       uiDefButS(block, ROW, B_REDR, "Plain",
+               X3CLM1, yco-=BUTH, BUTW3, BUTH, &wrld->aocolor, 2.0, (float)WO_AOPLAIN, 0, 0, "Plain diffuse energy (white)");
+       uiDefButS(block, ROW, B_REDR, "Sky Color", 
+               X3CLM2, yco, BUTW3, BUTH, &wrld->aocolor, 2.0, (float)WO_AOSKYCOL, 0, 0, "Use horizon and zenith color for diffuse energy");
+       uiDefButS(block, ROW, B_REDR, "Sky Texture", 
+               X3CLM3, yco, BUTW3, BUTH, &wrld->aocolor, 2.0, (float)WO_AOSKYTEX, 0, 0, "Does full Sky texture render for diffuse energy");
+       uiBlockEndAlign(block);
+       
+       yco -= YSPACE;
+       
+       uiDefButF(block, NUMSLI, B_REDR, "Energy:",
+               X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aoenergy, 0.01, 3.0, 100, 0, "Sets global energy scale for AO");
+       
 }
 
 static void world_panel_world(World *wrld)
index b65a34c99728b3eed64d3a6ebc95942af4dacb6b..a64a49a7268d4f921ef0240cb26ad347692f39fc 100644 (file)
@@ -1357,12 +1357,17 @@ void nurbs_foreachScreenVert(void (*func)(void *userData, Nurb *nu, BPoint *bp,
                                BezTriple *bezt = &nu->bezt[i];
 
                                if(bezt->hide==0) {
-                                       view3d_project_short_clip(curarea, bezt->vec[0], s, pmat, vmat);
-                                       func(userData, nu, NULL, bezt, 0, s[0], s[1]);
-                                       view3d_project_short_clip(curarea, bezt->vec[1], s, pmat, vmat);
-                                       func(userData, nu, NULL, bezt, 1, s[0], s[1]);
-                                       view3d_project_short_clip(curarea, bezt->vec[2], s, pmat, vmat);
-                                       func(userData, nu, NULL, bezt, 2, s[0], s[1]);
+                                       if (G.scene->selectmode & SCE_SELECT_CU_HANDLES_HIDE) {
+                                               view3d_project_short_clip(curarea, bezt->vec[1], s, pmat, vmat);
+                                               func(userData, nu, NULL, bezt, 1, s[0], s[1]);
+                                       } else {
+                                               view3d_project_short_clip(curarea, bezt->vec[0], s, pmat, vmat);
+                                               func(userData, nu, NULL, bezt, 0, s[0], s[1]);
+                                               view3d_project_short_clip(curarea, bezt->vec[1], s, pmat, vmat);
+                                               func(userData, nu, NULL, bezt, 1, s[0], s[1]);
+                                               view3d_project_short_clip(curarea, bezt->vec[2], s, pmat, vmat);
+                                               func(userData, nu, NULL, bezt, 2, s[0], s[1]);
+                                       }
                                }
                        }
                }
@@ -1461,7 +1466,7 @@ static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *
                        
                        bglEnd();
                        
-                       glPointSize(size+3);
+                       glPointSize(size);
                        bglBegin(GL_POINTS);
                        bglVertex3fv(co);
                        bglEnd();
@@ -2962,8 +2967,8 @@ static void tekenhandlesN(Nurb *nu, short sel)
        float *fp;
        unsigned int *col;
        int a;
-
-       if(nu->hide) return;
+       
+       if(nu->hide || (G.scene->selectmode & SCE_SELECT_CU_HANDLES_HIDE)) return;
        
        glBegin(GL_LINES); 
        
@@ -3030,9 +3035,13 @@ static void tekenvertsN(Nurb *nu, short sel)
                a= nu->pntsu;
                while(a--) {
                        if(bezt->hide==0) {
-                               if((bezt->f1 & 1)==sel) bglVertex3fv(bezt->vec[0]);
-                               if((bezt->f2 & 1)==sel) bglVertex3fv(bezt->vec[1]);
-                               if((bezt->f3 & 1)==sel) bglVertex3fv(bezt->vec[2]);
+                               if (G.scene->selectmode & SCE_SELECT_CU_HANDLES_HIDE) {
+                                       if((bezt->f2 & 1)==sel) bglVertex3fv(bezt->vec[1]);
+                               } else {
+                                       if((bezt->f1 & 1)==sel) bglVertex3fv(bezt->vec[0]);
+                                       if((bezt->f2 & 1)==sel) bglVertex3fv(bezt->vec[1]);
+                                       if((bezt->f3 & 1)==sel) bglVertex3fv(bezt->vec[2]);
+                               }
                        }
                        bezt++;
                }
@@ -4317,7 +4326,7 @@ void draw_object(Base *base, int flag)
                                ListBase targets = {NULL, NULL};
                                bConstraintTarget *ct;
                                
-                               if ((curcon->flag & CONSTRAINT_EXPAND) && (cti->get_constraint_targets)) {
+                               if ((curcon->flag & CONSTRAINT_EXPAND) && (cti) && (cti->get_constraint_targets)) {
                                        cti->get_constraint_targets(curcon, &targets);
                                        
                                        for (ct= targets.first; ct; ct= ct->next) {
index cac8b0d433e4b57ffa7c6b7e7dcab0563ec438c2..36a857abfe15d15d60364d61a0f34d4254d2081d 100644 (file)
@@ -691,7 +691,7 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq)
        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);
+       is_single_image = (char)check_single_seq(seq);
        
        /* body */
        if(seq->startstill) x1= seq->start;
@@ -901,7 +901,7 @@ static void draw_extra_seqinfo(void)
        }
 
        /* LEN, dont bother with single images */
-       if (check_single_image_seq(last_seq)==0) {
+       if (check_single_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
index 7059c637fc10e4528bc2642bd98ed5a462b9234a..e0588b4c2a0493dff946dde585672bec75ccaa3c 100644 (file)
@@ -223,7 +223,7 @@ bConstraint *add_new_constraint(short type)
        con->type = type;
        con->flag |= CONSTRAINT_EXPAND;
        con->enforce = 1.0F;
-       strcpy (con->name, "Const");
+       strcpy(con->name, "Const");
        
        /* Load the data for it */
        cti = constraint_get_typeinfo(con);
@@ -248,7 +248,7 @@ void add_constraint_to_object(bConstraint *con, Object *ob)
                BLI_addtail(list, con);
                
                con->flag |= CONSTRAINT_ACTIVE;
-               for(con= con->prev; con; con= con->prev)
+               for (con= con->prev; con; con= con->prev)
                        con->flag &= ~CONSTRAINT_ACTIVE;
        }
 }
@@ -256,7 +256,7 @@ void add_constraint_to_object(bConstraint *con, Object *ob)
 /* checks validity of object pointers, and NULLs,
  * if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag 
  */
-static void test_constraints (Object *owner, const char* substring)
+static void test_constraints (Object *owner, const char substring[])
 {
        
        bConstraint *curcon;
@@ -328,7 +328,7 @@ static void test_constraints (Object *owner, const char* substring)
                                {
                                        bActionConstraint *data = curcon->data;
                                        
-                                       if (!exist_object(data->tar)){
+                                       if (!exist_object(data->tar)) {
                                                data->tar = NULL;
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
@@ -346,7 +346,7 @@ static void test_constraints (Object *owner, const char* substring)
                                {
                                        bLocateLikeConstraint *data = curcon->data;
                                        
-                                       if (!exist_object(data->tar)){
+                                       if (!exist_object(data->tar)) {
                                                data->tar = NULL;
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
@@ -364,7 +364,7 @@ static void test_constraints (Object *owner, const char* substring)
                                {
                                        bMinMaxConstraint *data = curcon->data;
                                        
-                                       if (!exist_object(data->tar)){
+                                       if (!exist_object(data->tar)) {
                                                data->tar = NULL;
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
@@ -382,7 +382,7 @@ static void test_constraints (Object *owner, const char* substring)
                                {
                                        bRotateLikeConstraint *data = curcon->data;
                                        
-                                       if (!exist_object(data->tar)){
+                                       if (!exist_object(data->tar)) {
                                                data->tar = NULL;
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
@@ -400,7 +400,7 @@ static void test_constraints (Object *owner, const char* substring)
                                {
                                        bSizeLikeConstraint *data = curcon->data;
                                
-                                       if (!exist_object(data->tar)){
+                                       if (!exist_object(data->tar)) {
                                                data->tar = NULL;
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
@@ -417,18 +417,26 @@ static void test_constraints (Object *owner, const char* substring)
                                case CONSTRAINT_TYPE_KINEMATIC:
                                {
                                        bKinematicConstraint *data = curcon->data;
-                                       if (!exist_object(data->tar)){
+
+                                       if (!exist_object(data->tar)) {
                                                data->tar = NULL;
                                                curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
                                        }
-                                       
-                                       if ( (data->tar == owner) &&
+                                       else if ( (data->tar == owner) &&
                                                 (!get_named_bone(get_armature(owner), 
                                                                                  data->subtarget))) {
                                                curcon->flag |= CONSTRAINT_DISABLE;
-                                               break;
                                        }
+
+                                       if (data->poletar && !exist_object(data->poletar)) {
+                                               data->poletar = NULL;
+                                       }
+                                       else if ( (data->poletar == owner) &&
+                                                (!get_named_bone(get_armature(owner), 
+                                                                                 data->polesubtarget))) {
+                                               curcon->flag |= CONSTRAINT_DISABLE;
+                                       }
+
                                }
                                        break;
                                case CONSTRAINT_TYPE_TRACKTO:
@@ -446,11 +454,11 @@ static void test_constraints (Object *owner, const char* substring)
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
                                        }
-                                       if (data->reserved2==data->reserved1){
+                                       if (data->reserved2==data->reserved1) {
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
                                        }
-                                       if (data->reserved2+3==data->reserved1){
+                                       if (data->reserved2+3==data->reserved1) {
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
                                        }
@@ -460,7 +468,7 @@ static void test_constraints (Object *owner, const char* substring)
                                {
                                        bLockTrackConstraint *data = curcon->data;
                                        
-                                       if (!exist_object(data->tar)){
+                                       if (!exist_object(data->tar)) {
                                                data->tar = NULL;
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
@@ -473,11 +481,11 @@ static void test_constraints (Object *owner, const char* substring)
                                                break;
                                        }
 
-                                       if (data->lockflag==data->trackflag){
+                                       if (data->lockflag==data->trackflag) {
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
                                        }
-                                       if (data->lockflag+3==data->trackflag){
+                                       if (data->lockflag+3==data->trackflag) {
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
                                        }
@@ -487,7 +495,7 @@ static void test_constraints (Object *owner, const char* substring)
                                {
                                        bStretchToConstraint *data = curcon->data;
                                        
-                                       if (!exist_object(data->tar)){
+                                       if (!exist_object(data->tar)) {
                                                data->tar = NULL;
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
@@ -505,21 +513,21 @@ static void test_constraints (Object *owner, const char* substring)
                                {
                                        bFollowPathConstraint *data = curcon->data;
                                        
-                                       if (!exist_object(data->tar)){
+                                       if (!exist_object(data->tar)) {
                                                data->tar = NULL;
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
                                        }
-                                       if (data->tar->type != OB_CURVE){
+                                       if (data->tar->type != OB_CURVE) {
                                                data->tar = NULL;
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
                                        }
-                                       if (data->upflag==data->trackflag){
+                                       if (data->upflag==data->trackflag) {
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
                                        }
-                                       if (data->upflag+3==data->trackflag){
+                                       if (data->upflag+3==data->trackflag) {
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
                                        }
@@ -529,13 +537,13 @@ static void test_constraints (Object *owner, const char* substring)
                                {
                                        bClampToConstraint *data = curcon->data;
                                        
-                                       if (!exist_object(data->tar)){
+                                       if (!exist_object(data->tar)) {
                                                data->tar = NULL;
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
                                        }
                                        
-                                       if (data->tar->type != OB_CURVE){
+                                       if (data->tar->type != OB_CURVE) {
                                                data->tar = NULL;
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
@@ -552,7 +560,7 @@ static void test_constraints (Object *owner, const char* substring)
                                {
                                        bTransformConstraint *data = curcon->data;
                                        
-                                       if (!exist_object(data->tar)){
+                                       if (!exist_object(data->tar)) {
                                                data->tar = NULL;
                                                curcon->flag |= CONSTRAINT_DISABLE;
                                                break;
@@ -816,7 +824,7 @@ void add_constraint(int only_IK)
                set_constraint_nth_target(con, ob, pchansel->name, 0);
        }
        else if(obsel) {
-               set_constraint_nth_target(con, obsel, NULL, 0);
+               set_constraint_nth_target(con, obsel, "", 0);
        }
        else if (ELEM4(nr, 11, 13, 14, 15)==0) {        /* add new empty as target */
                Base *base= BASACT, *newbase;
@@ -838,7 +846,7 @@ void add_constraint(int only_IK)
                else
                        VECCOPY(obt->loc, ob->obmat[3]);
                
-               set_constraint_nth_target(con, obt, NULL, 0);
+               set_constraint_nth_target(con, obt, "", 0);
                
                /* restore, add_object sets active */
                BASACT= base;
index a0c864de0167f4174141976184f90b422ee3b541..c2fc725e941a9f92d76ed5808d4cba1fbd78beed 100644 (file)
@@ -132,9 +132,12 @@ void EM_select_mirrored(void)
 }
 
 void EM_automerge(int update) {
+       int len;
        if  (G.scene->automerge) {
                if (G.obedit && G.obedit->type==OB_MESH) {
-                       if (removedoublesflag(1, 1, G.scene->toolsettings->doublimit)) {
+                       len = removedoublesflag(1, 1, G.scene->toolsettings->doublimit);
+                       if (len) {
+                               G.totvert -= len; /* saves doing a countall */
                                if (update) {
                                        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
                                }
index c8f0dec40fa00a5274cc2635915696411a42e58c..628d1c3b405636a0c9f77d1708bc1360695743de 100644 (file)
@@ -1417,7 +1417,7 @@ void make_parent(void)
                                                
                                                add_constraint_to_object(con, base->object);
                                                
-                                               get_constraint_target_matrix(con, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, G.scene->r.cfra - base->object->sf);
+                                               get_constraint_target_matrix(con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, G.scene->r.cfra - base->object->sf);
                                                VecSubf(vec, base->object->obmat[3], cmat[3]);
                                                
                                                base->object->loc[0] = vec[0];
index 6965faeb0005febdfcfea718902e0be4b33f1e83..88705404965116d68c65e34103a3939dc8f6599b 100644 (file)
@@ -220,9 +220,9 @@ int seq_tx_check_right(Sequence *seq)
 
 /* 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)
+int check_single_seq(Sequence *seq)
 {
-       if (seq->type == SEQ_IMAGE && seq->len == 1 )
+       if ( seq->len==1 && (seq->type == SEQ_IMAGE || seq->type == SEQ_COLOR))
                return 1;
        else
                return 0;
@@ -231,7 +231,7 @@ int check_single_image_seq(Sequence *seq)
 static void fix_single_image_seq(Sequence *seq)
 {
        int left, start, offset;
-       if (!check_single_image_seq(seq))
+       if (!check_single_seq(seq))
                return;
        
        /* make sure the image is always at the start since there is only one,
@@ -1987,6 +1987,19 @@ void change_sequence(void)
 
 }
 
+void reload_sequence(void)
+{
+       Editing *ed= G.scene->ed;
+       Sequence *seq;
+       WHILE_SEQ(ed->seqbasep) {
+               if(seq->flag & SELECT) {
+                       update_changed_seq_and_deps(seq, 0, 1);
+               }
+       }
+       END_SEQ
+       allqueue(REDRAWSEQ, 0);
+}
+
 void reassign_inputs_seq_effect()
 {
        Editing *ed= G.scene->ed;
@@ -2673,7 +2686,7 @@ static void transform_grab_xlimits(Sequence *seq, int leftflag, int rightflag)
                        seq_tx_set_final_left(seq, seq_tx_get_final_right(seq)-1);
                }
                
-               if (check_single_image_seq(seq)==0) {
+               if (check_single_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);
                        }
@@ -2695,7 +2708,7 @@ static void transform_grab_xlimits(Sequence *seq, int leftflag, int rightflag)
                        seq_tx_set_final_right(seq, seq_tx_get_final_left(seq)+1);
                }
                                                                        
-               if (check_single_image_seq(seq)==0) {
+               if (check_single_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);
                        }
@@ -2722,13 +2735,13 @@ void transform_seq(int mode, int context)
        unsigned short event = 0;
        short mval[2], val, xo, yo, xn, yn;
        char str[32];
-       char side; /* for extend mode only - use to know which side to extend on */
+       char side= 'L'; /* 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;
+       char snapskip = 0, snap, snap_old= 0;
        int snapdist_max = seq_get_snaplimit();
        /* at the moment there are only 4 possible snap points,
        -       last_seq (start,end)
@@ -2863,7 +2876,7 @@ void transform_seq(int mode, int context)
                                snapskip = 0;
                        } else {
                                int dist;
-                               int snap_ofs;
+                               int snap_ofs= 0;
                                int snap_dist= snapdist_max;
                                
                                /* Get sequence points to snap to the markers */
index f4a572873d50057311ee64cfcb3e0658ac78564e..0cd8a0dc08db73689facd359970024fbc91aee71 100644 (file)
@@ -812,7 +812,7 @@ static void do_info_filemenu(void *arg, int event)
        switch(event) {
        case 0:
                if (okee("Erase All")) {
-                       if (!BIF_read_homefile(0))
+                       if (!BIF_read_homefile(0, 1))
                                error("No file ~/.B.blend");
                }
                break;
@@ -896,7 +896,7 @@ static void do_info_filemenu(void *arg, int event)
                break;
        case 32:
                if (okee("Erase All")) {
-                       if (!BIF_read_homefile(1))
+                       if (!BIF_read_homefile(1, 1))
                                error("Can't read data from memory!");
                }
                break;
index a0edbdc316f69e9317adfee665863baede60f1e1..4075371108b2275ae9e99444b87297962326b55f 100644 (file)
@@ -432,6 +432,9 @@ static void do_seq_editmenu(void *arg, int event)
        case 16:
                seq_separate_images();
                break;
+       case 17:
+               reload_sequence();
+               break;
        }
 }
 
@@ -497,6 +500,9 @@ static uiBlock *seq_editmenu(void *arg_unused)
                }
        }
        
+       uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reload Strip Data...|Alt R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 17, "");
+       
 
        if(curarea->headertype==HEADERTOP) {
                uiBlockSetDirection(block, UI_DOWN);
index 534c87a093acd461e2d4fd056c734336606c5ba2..099a016c698368271a18c9c3278d3229e3c05602 100644 (file)
@@ -2989,6 +2989,9 @@ static void do_view3d_edit_meshmenu(void *arg, int event)
                if(session) b_verse_push_object(session, G.obedit);
                break;
 #endif
+       case 15:
+               uv_autocalc_tface();
+               break;
        }
        allqueue(REDRAWVIEW3D, 0);
 }
@@ -3027,6 +3030,10 @@ static uiBlock *view3d_edit_meshmenu(void *arg_unused)
        
        uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "UV Unwrap|U",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
+       
+       uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+       
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extrude|E",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Edge/Face|F",                       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
@@ -3248,6 +3255,9 @@ static void do_view3d_edit_curvemenu(void *arg, int event)
                initTransform(TFM_WARP, CTX_NONE);
                Transform();
                break;
+       case 15:
+               uv_autocalc_tface();
+               break;
        }
        allqueue(REDRAWVIEW3D, 0);
 }
@@ -3275,6 +3285,10 @@ static uiBlock *view3d_edit_curvemenu(void *arg_unused)
        
        uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "UV Unwrap|U",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
+       
+       uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+       
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extrude|E",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Segment|F",                 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
@@ -3368,6 +3382,9 @@ static void do_view3d_edit_metaballmenu(void *arg, int event)
                break;
        case 7: /* Transform Properties */
                add_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, 0);
+               break;  
+       case 8:
+               uv_autocalc_tface();
                break;
        }
        allqueue(REDRAWVIEW3D, 0);
@@ -3393,6 +3410,10 @@ static uiBlock *view3d_edit_metaballmenu(void *arg_unused)
        uiDefIconTextBlockBut(block, view3d_edit_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 19, "");
        
        uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+       
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "UV Unwrap|U",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
+       
+       uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete...|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
@@ -3578,6 +3599,9 @@ static void do_view3d_edit_latticemenu(void *arg, int event)
                if(G.scene->proportional) G.scene->proportional= 0;
                else G.scene->proportional= 1;
                break;
+       case 6:
+               uv_autocalc_tface();
+               break;
        }
        allqueue(REDRAWVIEW3D, 0);
 }
@@ -3604,6 +3628,10 @@ static uiBlock *view3d_edit_latticemenu(void *arg_unused)
        
        uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "UV Unwrap|U",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+       
+       uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+       
        if(G.scene->proportional) {
                uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
        } else {
@@ -3734,6 +3762,9 @@ static void do_view3d_edit_armaturemenu(void *arg, int event)
        case 17: /* move to layer */
                pose_movetolayer();
                break;
+       case 18:
+               uv_autocalc_tface();
+               break;
        }
        
        allqueue(REDRAWVIEW3D, 0);
@@ -3819,6 +3850,10 @@ static uiBlock *view3d_edit_armaturemenu(void *arg_unused)
        
        uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "UV Unwrap|U",    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
+       
+       uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+       
        uiDefIconTextBlockBut(block, view3d_edit_armature_parentmenu, NULL, ICON_RIGHTARROW_THIN, "Parent", 0, yco-=20, 120, 19, "");
        
        uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -4932,6 +4967,7 @@ static void view3d_header_pulldowns(uiBlock *block, short *xcoord)
                        uiDefPulldownBut(block, view3d_edit_armaturemenu, NULL, "Armature",     xco,-2, xmax-3, 24, "");
                        xco+= xmax;
                }
+               
        }
        else if (G.f & G_WEIGHTPAINT) {
                xmax= GetButStringLength("Paint");
@@ -5184,7 +5220,7 @@ void view3d_buttons(void)
                        }
                        xco+= 20;
                }
-
+               
                uiDefIconBut(block, BUT, B_VIEWRENDER, ICON_SCENE_DEHLT, xco,0,XIC,YIC, NULL, 0, 1.0, 0, 0, "Render this window (hold CTRL for anim)");
        
                if (ob && (ob->flag & OB_POSEMODE)) {
index 559c74b79956328b4c154db4609e60bec44b9da4..68529d656fcc26ea87987ba8e89eb3b85ce23e50 100644 (file)
@@ -2398,7 +2398,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        }
                                }*/
                                if(G.obedit) {
-                                       if(G.qual==0) {
+                                       if(G.obedit->type==OB_MESH && G.qual==0) {
                                                uv_autocalc_tface();
                                        }
                                }
@@ -3741,7 +3741,10 @@ void drawinfospace(ScrArea *sa, void *spacedata)
                        "Enables automatic saving of preview images in the .blend file");
                
        } else if (U.userpref == 4) { /* system & opengl */
-
+               int memcachemax;
+               if (sizeof(void *) ==8) memcachemax = 1024*16; /* 64bit system, 16 gig of ram would be nice */
+               else                                    memcachemax = 1024; /* 32 bit system, cant address over 2gig anyway */
+               
                uiDefBut(block, LABEL,0,"Solid OpenGL lights:",
                        xpos+edgsp, y6label, mpref, buth,
                        0, 0, 0, 0, 0, "");
@@ -3842,11 +3845,12 @@ void drawinfospace(ScrArea *sa, void *spacedata)
                          (xpos+edgsp+(4*mpref)+(4*midsp)), y6, mpref, buth, 
                          &U.prefetchframes, 0.0, 500.0, 20, 2, 
                          "Number of frames to render ahead during playback.");
-
+               
                uiDefButI(block, NUM, B_MEMCACHELIMIT, "MEM Cache Limit ",
                          (xpos+edgsp+(4*mpref)+(4*midsp)), y5, mpref, buth, 
-                         &U.memcachelimit, 0.0, 1024.0, 30, 2, 
-                         "Memory cache limit in sequencer");
+                          &U.memcachelimit, 0.0, (float)memcachemax, 30, 2, 
+                         "Memory cache limit in sequencer (megabytes)");
+               
                uiDefButS(block, NUM, B_REDR, "Frameserver Port ",
                          (xpos+edgsp+(4*mpref)+(4*midsp)), y4, mpref, buth, 
                          &U.frameserverport, 0.0, 32727.0, 30, 2, 
@@ -4633,9 +4637,11 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                        }
                        break;
                case RKEY:
-                       if((G.qual==LR_SHIFTKEY))
+                       if(G.qual==LR_SHIFTKEY)
                                seq_remap_paths();
-                       else
+                       if(G.qual==LR_ALTKEY)
+                               reload_sequence();
+                       else if (G.qual==0)
                                reassign_inputs_seq_effect();
                        break;
                case SKEY:
index 6464f699d1a80fa16c668d927582982078ef9708..b174abfa873bd70eaeda499d7aa7b2f34a833900 100644 (file)
@@ -942,7 +942,7 @@ int blenderqread(unsigned short event, short val)
                if(textspace==0 && textediting==0) {
                        if(G.qual==LR_CTRLKEY) {
                                if(okee("Erase all")) {
-                                       if( BIF_read_homefile(0)==0) error("No file ~/.B.blend");
+                                       if( BIF_read_homefile(0, 1)==0) error("No file ~/.B.blend");
                                }
                                return 0;
                        }
index 8b6cd987cf88fa216be82a12ad5ad13484ab6860..3928f736f1a24c8199ba3282683ed7b360e0a641 100644 (file)
@@ -483,7 +483,7 @@ static void outliner_242_patch(void)
 }
 
 /* only here settings for fullscreen */
-int BIF_read_homefile(int from_memory)
+int BIF_read_homefile(int from_memory, int do_undo)
 {
        char tstr[FILE_MAXDIR+FILE_MAXFILE], scestr[FILE_MAXDIR];
        char *home= BLI_gethome();
@@ -526,7 +526,9 @@ int BIF_read_homefile(int from_memory)
 
        undo_editmode_clear();
        BKE_reset_undo();
-       BKE_write_undo("original");     /* save current state */
+       
+       if (do_undo)
+               BIF_undo_push("original");
        
        return success;
 }
@@ -896,7 +898,11 @@ void BIF_init(void)
        init_node_butfuncs();
        
        BIF_preview_init_dbase();
-       BIF_read_homefile(0);
+       
+       /* dont set an undo here because this sets the default scene to be the initial
+       undo state when loading blender with a file  a new file, so holding Ctrl+Z will undo to the default
+       scene rather then to the new file */
+       BIF_read_homefile(0, 0);
 
        BIF_resources_init();   /* after homefile, to dynamically load an icon file based on theme settings */
        
index c9474f01b5f2f7ef8c7844c3de0d7e7de39dd6f2..8983582e44a0779671ed06588788f57513ceb3ec 100644 (file)
@@ -702,9 +702,10 @@ int main(int argc, char **argv)
                sce= add_scene("1");
                set_scene(sce);
        }
-
+       
+       BKE_write_undo("original");     /* save current state */
        screenmain();
-
+       
        return 0;
 } /* end of int main(argc,argv)        */