svn merge -r 15688:15908 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorAndre Susano Pinto <andresusanopinto@gmail.com>
Fri, 1 Aug 2008 21:37:36 +0000 (21:37 +0000)
committerAndre Susano Pinto <andresusanopinto@gmail.com>
Fri, 1 Aug 2008 21:37:36 +0000 (21:37 +0000)
195 files changed:
bin/.blender/.Blanguages
intern/boolop/intern/BOP_Edge.cpp
intern/boolop/intern/BOP_Edge.h
intern/boolop/intern/BOP_Face.cpp
intern/boolop/intern/BOP_Face.h
intern/boolop/intern/BOP_Interface.cpp
intern/boolop/intern/BOP_Merge.cpp
intern/boolop/intern/BOP_Merge.h
intern/boolop/intern/BOP_Merge2.cpp [new file with mode: 0644]
intern/boolop/intern/BOP_Merge2.h [new file with mode: 0644]
intern/boolop/intern/BOP_Mesh.cpp
intern/boolop/intern/BOP_Mesh.h
intern/boolop/intern/BOP_Misc.h [new file with mode: 0644]
intern/boolop/intern/BOP_Tag.h
intern/boolop/intern/BOP_Vertex.cpp
intern/boolop/intern/BOP_Vertex.h
projectfiles_vc7/blender/makesdna/DNA_makesdna.vcproj
projectfiles_vc7/blender/src/BL_src.vcproj
projectfiles_vc7/gameengine/blenderhook/KX_blenderhook.vcproj
release/scripts/rvk1_torvk2.py
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_idprop.h
source/blender/blenkernel/BKE_shrinkwrap.h
source/blender/blenkernel/BKE_texture.h
source/blender/blenkernel/bad_level_call_stubs/stubs.c
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/idprop.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenkernel/intern/texture.c
source/blender/blenlib/intern/arithb.c
source/blender/blenlib/intern/freetypefont.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/include/BDR_gpencil.h
source/blender/include/BIF_editaction.h
source/blender/include/BIF_editarmature.h
source/blender/include/BIF_editview.h
source/blender/include/BSE_drawview.h
source/blender/include/butspace.h
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_action_types.h
source/blender/makesdna/DNA_actuator_types.h
source/blender/makesdna/DNA_armature_types.h
source/blender/makesdna/DNA_constraint_types.h
source/blender/makesdna/DNA_customdata_types.h
source/blender/makesdna/DNA_gpencil_types.h
source/blender/makesdna/DNA_meshdata_types.h
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_sequence_types.h
source/blender/nodes/intern/SHD_nodes/SHD_material.c
source/blender/nodes/intern/SHD_util.c
source/blender/nodes/intern/SHD_util.h
source/blender/python/BPY_interface.c
source/blender/python/api2_2x/Armature.c
source/blender/python/api2_2x/Bone.c
source/blender/python/api2_2x/IDProp.c
source/blender/python/api2_2x/doc/Armature.py
source/blender/python/api2_2x/doc/IDProp.py
source/blender/python/api2_2x/doc/Ipo.py
source/blender/python/api2_2x/sceneRender.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_logic.c
source/blender/src/buttons_object.c
source/blender/src/drawaction.c
source/blender/src/drawgpencil.c
source/blender/src/drawnode.c
source/blender/src/drawseq.c
source/blender/src/drawview.c
source/blender/src/editaction.c
source/blender/src/editaction_gpencil.c
source/blender/src/editarmature.c
source/blender/src/editipo.c
source/blender/src/editnode.c
source/blender/src/editobject.c
source/blender/src/editseq.c
source/blender/src/editview.c
source/blender/src/gpencil.c
source/blender/src/header_action.c
source/blender/src/header_ipo.c
source/blender/src/header_view3d.c
source/blender/src/interface.c
source/blender/src/interface_draw.c
source/blender/src/meshlaplacian.c
source/blender/src/outliner.c
source/blender/src/poseobject.c
source/blender/src/sequence.c
source/blender/src/space.c
source/blender/src/transform_conversions.c
source/blender/src/transform_manipulator.c
source/creator/creator.c
source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.cpp [deleted file]
source/gameengine/BlenderRoutines/KX_BlenderPolyMaterial.h [deleted file]
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/Converter/BL_ActionActuator.cpp
source/gameengine/Converter/BL_ArmatureObject.cpp
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/BL_ShapeActionActuator.cpp
source/gameengine/Converter/BL_ShapeActionActuator.h
source/gameengine/Converter/KX_ConvertActuators.cpp
source/gameengine/Converter/KX_ConvertSensors.cpp
source/gameengine/Converter/KX_IpoConvert.cpp
source/gameengine/Converter/KX_IpoConvert.h
source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
source/gameengine/GameLogic/SCA_ActuatorEventManager.h
source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
source/gameengine/GameLogic/SCA_ActuatorSensor.h
source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
source/gameengine/GameLogic/SCA_AlwaysEventManager.h
source/gameengine/GameLogic/SCA_EventManager.cpp
source/gameengine/GameLogic/SCA_EventManager.h
source/gameengine/GameLogic/SCA_IObject.cpp
source/gameengine/GameLogic/SCA_ISensor.cpp
source/gameengine/GameLogic/SCA_ISensor.h
source/gameengine/GameLogic/SCA_JoystickManager.cpp
source/gameengine/GameLogic/SCA_JoystickManager.h
source/gameengine/GameLogic/SCA_KeyboardManager.cpp
source/gameengine/GameLogic/SCA_KeyboardManager.h
source/gameengine/GameLogic/SCA_LogicManager.cpp
source/gameengine/GameLogic/SCA_LogicManager.h
source/gameengine/GameLogic/SCA_MouseManager.cpp
source/gameengine/GameLogic/SCA_MouseManager.h
source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
source/gameengine/GameLogic/SCA_PropertyEventManager.h
source/gameengine/GameLogic/SCA_RandomEventManager.cpp
source/gameengine/GameLogic/SCA_RandomEventManager.h
source/gameengine/GameLogic/SCA_TimeEventManager.cpp
source/gameengine/GameLogic/SCA_TimeEventManager.h
source/gameengine/Ketsji/BL_BlenderShader.cpp
source/gameengine/Ketsji/BL_BlenderShader.h
source/gameengine/Ketsji/BL_Material.h
source/gameengine/Ketsji/BL_Texture.cpp
source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h
source/gameengine/Ketsji/KX_BlenderMaterial.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
source/gameengine/Ketsji/KX_ConstraintActuator.cpp
source/gameengine/Ketsji/KX_ConstraintActuator.h
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_IpoActuator.cpp
source/gameengine/Ketsji/KX_IpoActuator.h
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_MaterialIpoController.cpp
source/gameengine/Ketsji/KX_MaterialIpoController.h
source/gameengine/Ketsji/KX_NearSensor.cpp
source/gameengine/Ketsji/KX_NearSensor.h
source/gameengine/Ketsji/KX_ObjectActuator.cpp
source/gameengine/Ketsji/KX_ObjectActuator.h
source/gameengine/Ketsji/KX_PolygonMaterial.cpp
source/gameengine/Ketsji/KX_PolygonMaterial.h
source/gameengine/Ketsji/KX_PyMath.h
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_RayEventManager.cpp
source/gameengine/Ketsji/KX_RayEventManager.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_TouchEventManager.cpp
source/gameengine/Ketsji/KX_TouchEventManager.h
source/gameengine/Ketsji/KX_TouchSensor.cpp
source/gameengine/Ketsji/KX_TouchSensor.h
source/gameengine/Ketsji/KX_TrackToActuator.cpp
source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
source/gameengine/PyDoc/BL_ShapeActionActuator.py [new file with mode: 0644]
source/gameengine/PyDoc/KX_ActuatorSensor.py [new file with mode: 0644]
source/gameengine/PyDoc/KX_ConstraintActuator.py
source/gameengine/PyDoc/KX_IpoActuator.py
source/gameengine/PyDoc/KX_ObjectActuator.py
source/gameengine/PyDoc/KX_StateActuator.py [new file with mode: 0644]
source/gameengine/PyDoc/SCA_ISensor.py
source/gameengine/Rasterizer/RAS_BucketManager.cpp
source/gameengine/Rasterizer/RAS_BucketManager.h
source/gameengine/Rasterizer/RAS_CameraData.h
source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
source/gameengine/Rasterizer/RAS_IRasterizer.h
source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
source/gameengine/Rasterizer/RAS_MaterialBucket.h
source/gameengine/Rasterizer/RAS_MeshObject.cpp
source/gameengine/Rasterizer/RAS_MeshObject.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
source/gameengine/Rasterizer/RAS_Polygon.cpp

index 0f98ce02247dc87107f9aa8409740cbf25b02788..de8d8c44550e709fa8850792a3ec96331ecc462b 100644 (file)
@@ -20,3 +20,4 @@ Romanian:ro
 Arabic:ar
 Bulgarian:bg
 Greek:el
+Korean:kr
index ac302b530dfa3eefca4d0b7419211de791be1300..44e7d5cb5676c3e00e86ebad220e984be0e96b43 100644 (file)
@@ -75,4 +75,47 @@ void BOP_Edge::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex)
        else if (m_vertexs[1] == oldIndex) m_vertexs[1] = newIndex;
 }
 
+#ifdef BOP_NEW_MERGE
+
+/**
+ * Returns if this edge contains the specified face index.
+ * @param i face index
+ * @return true if this edge contains the specified face index, false otherwise
+ */
+bool BOP_Edge::removeFace(BOP_Index i)
+{
+       int pos=0;
+       for(BOP_IT_Indexs it = m_faces.begin();it!=m_faces.end();pos++,it++) {
+               if ((*it) == i) {
+                       m_faces.erase(it);
+                       return true;
+               }
+       }
+       
+       return false;
+}
+
+#endif
+
+#ifdef BOP_DEBUG
+
+#include <iostream>
+using namespace std;
+
+/**
+ * Implements operator <<.
+ */
+ostream &operator<<(ostream &stream, BOP_Edge *e)
+{
+       stream << "Edge[" << e->getVertex1() << "," << e->getVertex2();
+#ifdef BOP_NEW_MERGE
+       if(e->m_used)
+               stream << "] (used)";
+       else
+               stream << "] (unused)";
+#endif
+       return stream;
+}
+#endif
+
 
index 13426f6e63ce935d69230ff1dc98e233b1d3b846..a817b3d624fde33c1b79d6afb4f298c437bd7237 100644 (file)
 #define BOP_EDGE_H
 
 #include "BOP_Indexs.h"
+#include "BOP_Misc.h"
 
 class BOP_Edge
 {
 private:
        BOP_Index  m_vertexs[2];
        BOP_Indexs m_faces;
+#ifdef BOP_NEW_MERGE
+       bool m_used;
+#endif
 
        bool containsFace(BOP_Index i);
 
@@ -47,6 +51,15 @@ public:
        inline unsigned int getNumFaces(){return m_faces.size();};
        inline BOP_Indexs &getFaces(){return m_faces;};
        void addFace(BOP_Index face);
+#ifdef BOP_NEW_MERGE
+       bool removeFace(BOP_Index i);
+       bool getUsed() { return m_used;};
+       void setUsed(bool setting) { m_used=setting;};
+#endif
+#ifdef BOP_DEBUG
+       friend ostream &operator<<(ostream &stream, BOP_Edge *e);
+#endif
+
 };
 
 #endif
index 12c94624517d3555d791608781d336a84a49ec0d..01308de3e5de50c867287877ec7226eca9195830 100644 (file)
@@ -402,6 +402,7 @@ bool BOP_Face4::getEdgeIndex(BOP_Index v1, BOP_Index v2, unsigned int &e)
        return  true;
 }  
 
+#ifdef BOP_DEBUG
 /**
  * Implements operator <<.
  */
@@ -421,3 +422,4 @@ ostream &operator<<(ostream &stream, BOP_Face *f)
 
        return stream;
 }
+#endif
index e16425f78b320d2f07c84ec9c6ce1749e0817f4d..965882db7320b200654670f49eb2970f7c6da614 100644 (file)
@@ -32,6 +32,7 @@
 #include "MT_Plane3.h"
 #include "BOP_Indexs.h"
 #include "BOP_BBox.h"
+#include "BOP_Misc.h"
 #include <iostream>
 #include <vector>
 using namespace std;
@@ -80,7 +81,9 @@ public:
        virtual void replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex) = 0;
        virtual bool containsVertex(BOP_Index v) = 0;
                
+#ifdef BOP_DEBUG
        friend ostream &operator<<(ostream &stream, BOP_Face *f);
+#endif
 };
 
 class BOP_Face3: public BOP_Face 
index 2a1981039311645d9c2b6ebbad985d564f613639..898ca708204168a097b1a4015fef5f34edda25af 100644 (file)
 #include "BOP_Mesh.h"
 #include "BOP_Face2Face.h"
 #include "BOP_Merge.h"
+#include "BOP_Merge2.h"
 #include "BOP_Chrono.h"
 
-//#define DEBUG
+#if defined(BOP_ORIG_MERGE) && defined(BOP_NEW_MERGE) 
+#include "../../source/blender/blenkernel/BKE_global.h"
+#endif
 
 BoolOpState BOP_intersectionBoolOp(BOP_Mesh*  meshC,
                                                                   BOP_Faces* facesA,
@@ -208,7 +211,32 @@ BoolOpState BOP_intersectionBoolOp(BOP_Mesh*  meshC,
        #endif
 
        // Merge faces
+#ifdef BOP_ORIG_MERGE
+#ifndef BOP_NEW_MERGE
        BOP_Merge::getInstance().mergeFaces(meshC,numVertices);
+#endif
+#endif
+
+#ifdef BOP_NEW_MERGE
+#ifndef BOP_ORIG_MERGE
+       BOP_Merge2::getInstance().mergeFaces(meshC,numVertices);
+#else
+       static int state = -1;
+       if (G.rt == 100) {
+               if( state != 1 ) {
+                       cout << "Boolean code using old merge technique." << endl;
+                       state = 1;
+               }
+               BOP_Merge::getInstance().mergeFaces(meshC,numVertices);
+       } else {
+               if( state != 0 ) {
+                       cout << "Boolean code using new merge technique." << endl;
+                       state = 0;
+               }
+               BOP_Merge2::getInstance().mergeFaces(meshC,numVertices);
+       }
+#endif
+#endif
 
        #ifdef DEBUG
        c = chrono.stamp(); t += c;
index 1e4139ab971318a7914b2c32e27b7554cea00dd8..012d34091877f5648fe913f6309986ba41f5cc4a 100644 (file)
@@ -30,6 +30,7 @@
  
 #include "BOP_Merge.h"
 
+#ifdef BOP_ORIG_MERGE
 
 #ifdef _MSC_VER
 #if _MSC_VER < 1300
@@ -802,3 +803,5 @@ void BOP_Merge::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, B
        }
        }
 }
+
+#endif  /* BOP_ORIG_MERGE */
index 88999b2e734a194b7249dd098fd23f033b8f56ba..ceb8ec10690eecc9ca82ebbb8029ee9d0256770f 100644 (file)
@@ -28,6 +28,9 @@
 #ifndef BOP_MERGE_H
 #define BOP_MERGE_H
 
+#include "BOP_Misc.h"
+
+#ifdef BOP_ORIG_MERGE
 #include "BOP_Mesh.h"
 #include "BOP_Tag.h"
 #include "BOP_MathUtils.h"
@@ -68,4 +71,6 @@ class BOP_Merge {
                void mergeFaces(BOP_Mesh *m, BOP_Index v);
 };
 
+#endif /* BOP_ORIG_MERGE */
+
 #endif
diff --git a/intern/boolop/intern/BOP_Merge2.cpp b/intern/boolop/intern/BOP_Merge2.cpp
new file mode 100644 (file)
index 0000000..bbf3f8b
--- /dev/null
@@ -0,0 +1,944 @@
+/**
+ *
+ * $Id: BOP_Merge22.cpp 14444 2008-04-16 22:40:48Z hos $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Marc Freixas, Ken Hughes
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#include "BOP_Merge2.h"
+
+#ifdef BOP_NEW_MERGE
+
+static void deleteFace(BOP_Mesh *m, BOP_Face *face);
+
+/**
+ * SINGLETON (use method BOP_Merge2.getInstance).
+ */
+BOP_Merge2 BOP_Merge2::SINGLETON;
+
+#ifdef BOP_DEBUG
+void dumpmesh ( BOP_Mesh *m, bool force )
+{
+       unsigned int nonmanifold = 0;
+       {
+       BOP_Edges edges = m->getEdges();
+       int count = 0;
+    for (BOP_IT_Edges edge = edges.begin(); edge != edges.end();
+               ++count, ++edge) {
+               if (!(*edge)->getUsed() && (*edge)->getFaces().size() == 0 ) continue;
+               BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1());
+               BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2());
+
+               if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) {
+                       int fcount = 0;
+                       BOP_Indexs faces = (*edge)->getFaces();
+                       for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) {
+                               BOP_Face *f = m->getFace(*face);
+                               if(f->getTAG()== UNCLASSIFIED) ++fcount;
+                       }
+
+
+                       if(fcount !=0 && fcount !=2 ) {
+                               ++nonmanifold;
+                       }
+               }
+       }
+       if (!force && nonmanifold == 0) return;
+       }
+       if( nonmanifold )
+               cout << nonmanifold << " edges detected" << endl;
+#ifdef DEBUG
+       cout << "---------------------------" << endl;
+
+       BOP_Edges edges = m->getEdges();
+       int count = 0;
+    for (BOP_IT_Edges edge = edges.begin(); edge != edges.end();
+               ++count, ++edge) {
+               BOP_Vertex * v1 = m->getVertex((*edge)->getVertex1());
+               BOP_Vertex * v2 = m->getVertex((*edge)->getVertex2());
+
+               if(v1->getTAG()!= BROKEN || v2->getTAG()!= BROKEN ) {
+                       int fcount = 0;
+                       BOP_Indexs faces = (*edge)->getFaces();
+                       cout << count << ", " << (*edge) << ", " << faces.size() << endl;
+                       for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); face++) {
+                               BOP_Face *f = m->getFace(*face);
+                               if(f->getTAG()== UNCLASSIFIED) ++fcount;
+                               cout << "  face " << f << endl;
+                       }
+
+
+                       if(fcount !=0 && fcount !=2 )
+                               cout << "    NON-MANIFOLD" << endl;
+               }
+       }
+
+       BOP_Faces faces = m->getFaces();
+       count = 0;
+    for (BOP_IT_Faces face = faces.begin(); face != faces.end(); face++) {
+               if( count < 12*2 || (*face)->getTAG() != BROKEN ) {
+                       cout << count << ", " << *face << endl;
+               }
+               ++count;
+       }
+
+       BOP_Vertexs verts = m->getVertexs();
+       count = 0;
+    for (BOP_IT_Vertexs vert = verts.begin(); vert != verts.end(); vert++) {
+               cout << count++ << ", " << *vert << " " << (*vert)->getNumEdges() << endl;
+               BOP_Indexs edges = (*vert)->getEdges();
+           for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) {
+                       BOP_Edge *edge = m->getEdge(*it);
+                       cout << "   " << edge << endl;
+               }
+       }
+       cout << "===========================" << endl;
+#endif
+}
+#endif
+
+/**
+ * Simplifies a mesh, merging its faces.
+ * @param m mesh
+ * @param v index of the first mergeable vertex (can be removed by merge) 
+ */
+
+void BOP_Merge2::mergeFaces(BOP_Mesh *m, BOP_Index v)
+{
+       m_mesh = m;
+
+#ifdef DEBUG
+       cout << "##############################" << endl;
+#endif
+       cleanup( );
+
+       m_firstVertex = v;
+       bool cont = false;
+
+       // Merge faces
+       mergeFaces();   
+
+       do {
+               // Add quads ...
+               cont = createQuads();
+               // ... and merge new faces
+               if( cont ) cont = mergeFaces();
+
+#ifdef DEBUG
+               cout << "called mergeFaces " << cont << endl;
+#endif
+               // ... until the merge is not succesful
+       } while(cont);
+}
+
+void clean_nonmanifold( BOP_Mesh *m )
+{
+       return;
+
+       BOP_Edges nme;
+       BOP_Edges e = m->getEdges();
+       for( BOP_IT_Edges it = e.begin(); it != e.end(); ++it ) {
+               BOP_Indexs faces = (*it)->getFaces();
+               if( faces.size() & ~2 )
+                       nme.push_back(*it);
+       }
+       if (nme.size() == 0) return;
+       for( BOP_IT_Edges it = nme.begin(); it != nme.end(); ++it ) {
+               if( (*it)->getFaces().size() > 1 ) {
+                       BOP_Indexs faces = (*it)->getFaces();
+                       for( BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face ) {
+                               MT_Point3 vertex1 = m->getVertex(m->getFace(*face)->getVertex(0))->getPoint();
+                               MT_Point3 vertex2 = m->getVertex(m->getFace(*face)->getVertex(1))->getPoint();
+                               MT_Point3 vertex3 = m->getVertex(m->getFace(*face)->getVertex(2))->getPoint();
+                               if (BOP_collinear(vertex1,vertex2,vertex3)) // collinear triangle
+                                       deleteFace(m,m->getFace(*face));
+                       }
+                       continue;
+               }
+               BOP_Face *oface1 = m->getFace((*it)->getFaces().front());
+               BOP_Face *oface2, *tmpface;
+               BOP_Index first =(*it)->getVertex1();
+               BOP_Index next =(*it)->getVertex2();
+               BOP_Index last = first;
+               unsigned short facecount = 0;
+               bool found = false;
+               BOP_Indexs vertList;
+#ifdef DEBUG
+               cout << "  first edge is " << (*it) << endl;
+#endif
+               vertList.push_back(first);
+               BOP_Edge *edge;
+               while(true) {
+                       BOP_Vertex *vert = m->getVertex(next);
+                       BOP_Indexs edges = vert->getEdges();
+                       edge = NULL;
+                       for( BOP_IT_Indexs eit = edges.begin(); eit != edges.end(); ++eit) {
+                               edge = m->getEdge(*eit);
+                               if( edge->getFaces().size() > 1) {
+                                       edge = NULL;
+                                       continue;
+                               }
+                               if( edge->getVertex1() == next && edge->getVertex2() != last ) {
+                                       last = next;
+                                       next = edge->getVertex2();
+                                       break;
+                               }
+                               if( edge->getVertex2() == next && edge->getVertex1() != last ) {
+                                       last = next;
+                                       next = edge->getVertex1();
+                                       break;
+                               }
+                               edge = NULL;
+                       }
+                       if( !edge ) break;
+#ifdef DEBUG
+                       cout << "   next edge is " << edge << endl;
+#endif
+                       tmpface = m->getFace(edge->getFaces().front());
+                       if( oface1->getOriginalFace() != tmpface->getOriginalFace() )
+                               oface2 = tmpface;
+                       else
+                               ++facecount;
+                       vertList.push_back(last);
+                       if( vertList.size() > 3 ) break;
+                       if( next == first ) {
+                               found = true;
+                               break;
+                       }
+               }
+               if(found) {
+                       edge = *it;
+#ifdef DEBUG
+                       cout << "   --> found a loop" << endl;
+#endif
+                       if( vertList.size() == 3 ) {
+                               BOP_Face3 *face = (BOP_Face3 *)m->getFace(edge->getFaces().front());
+                               face->getNeighbours(first,last,next);
+                       } else if( vertList.size() == 4 ) {
+                               BOP_Face4 *face = (BOP_Face4 *)m->getFace(edge->getFaces().front());
+                               face->getNeighbours(first,last,next,last);
+                       } else {
+#ifdef DEBUG
+                               cout << "loop has " << vertList.size() << "verts"; 
+#endif
+                               continue;
+                       }
+                       if(facecount == 1) oface1 = oface2;
+                       next = vertList[1];
+                       last = vertList[2];
+                       if( edge->getVertex2() == next ) { 
+                               BOP_Face3 *f = new BOP_Face3(next,first,last,
+                                       oface1->getPlane(),oface1->getOriginalFace());
+                               m->addFace( f );
+#ifdef DEBUG
+                               cout << "   face is backward: " << f << endl;
+#endif
+                               
+                       } else {
+                               BOP_Face3 *f = new BOP_Face3(last,first,next,
+                                       oface1->getPlane(),oface1->getOriginalFace());
+                               m->addFace( f );
+#ifdef DEBUG
+                               cout << "   face is forward: " << f << endl;
+#endif
+                       }
+               }
+       }
+}
+
+/**
+ * Runs through mesh and makes sure vert/face/edge data is consistent.  Most
+ * importantly:
+ * (1) mark edges which are no longer used
+ * (2) remove broken faces from edges
+ * (3) remove faces from mesh which have a single edge belonging to no other
+ *     face (non-manifold edges)
+ */
+
+void BOP_Merge2::cleanup( void )
+{
+       BOP_Edges edges = m_mesh->getEdges();
+       for (BOP_IT_Edges edge = edges.begin(); edge != edges.end(); ++edge) {
+               BOP_Indexs faces = (*edge)->getFaces();
+               for (BOP_IT_Indexs face = faces.begin(); face != faces.end(); ++face) {
+                       BOP_Face *f = m_mesh->getFace(*face);
+                       if(f->getTAG()== UNCLASSIFIED) ;
+                       else (*edge)->removeFace(*face);
+               }
+               if( (*edge)->getFaces().size() == 0) (*edge)->setUsed(false);
+       }
+
+       BOP_Vertexs v = m_mesh->getVertexs();
+       for( BOP_IT_Vertexs it = v.begin(); it != v.end(); ++it ) {
+               if( (*it)->getTAG() != BROKEN) {
+                       BOP_Indexs edges = (*it)->getEdges();
+                       for(BOP_IT_Indexs i = edges.begin();i!=edges.end();i++)
+                               if( m_mesh->getEdge((*i))->getUsed( ) == false) (*it)->removeEdge( *i );
+                       if( (*it)->getEdges().size() == 0 ) (*it)->setTAG(BROKEN);
+               }
+       }
+       // clean_nonmanifold( m_mesh );
+}
+
+/**
+ * Simplifies a mesh, merging its faces.
+ */
+bool BOP_Merge2::mergeFaces()
+{
+       BOP_Indexs mergeVertices;
+       BOP_Vertexs vertices = m_mesh->getVertexs();
+       BOP_IT_Vertexs v = vertices.begin();
+       const BOP_IT_Vertexs verticesEnd = vertices.end();
+
+       // Advance to first mergeable vertex
+       advance(v,m_firstVertex);
+       BOP_Index pos = m_firstVertex;
+
+       // Add unbroken vertices to the list
+       while(v!=verticesEnd) {
+               if ((*v)->getTAG() != BROKEN) {
+                       mergeVertices.push_back(pos);
+               }
+
+               v++;
+               pos++;
+       }
+
+       // Merge faces with that vertices
+       return mergeFaces(mergeVertices);
+}
+
+/**
+ * remove edges from vertices when the vertex is removed
+ */
+void BOP_Merge2::freeVerts(BOP_Index v, BOP_Vertex *vert)
+{
+       BOP_Indexs edges = vert->getEdges();
+       BOP_Vertex *other;
+
+       for( BOP_IT_Indexs it = edges.begin(); it != edges.end(); ++it) {
+               BOP_Edge *edge = m_mesh->getEdge(*it);
+               BOP_Indexs edges2;
+               if( edge->getVertex1() != v )
+                       other = m_mesh->getVertex( edge->getVertex1() );
+               else
+                       other = m_mesh->getVertex( edge->getVertex2() );
+               other->removeEdge(*it);
+               vert->removeEdge(*it);
+       }
+}
+
+/**
+ * Simplifies a mesh, merging the faces with the specified vertices.
+ * @param mergeVertices vertices to test
+ * @return true if a face merge was performed
+ */
+bool BOP_Merge2::mergeFaces(BOP_Indexs &mergeVertices)
+{
+       // Check size > 0!
+       if (mergeVertices.size() == 0) return false;
+       bool didMerge = false;
+
+       for( BOP_Index i = 0; i < mergeVertices.size(); ++i ) {
+               BOP_LFaces facesByOriginalFace;
+               BOP_Index v = mergeVertices[i];
+               BOP_Vertex *vert = m_mesh->getVertex(v);
+#ifdef DEBUG
+               cout << "i = " << i << ", v = " << v << ", vert = " << vert << endl;
+               if (v==48)
+                       cout << "found vert 48" << endl;
+#endif
+               if ( vert->getTAG() != BROKEN ) {
+                       getFaces(facesByOriginalFace,v);
+
+                       switch (facesByOriginalFace.size()) {
+                       case 0:
+                               // v has no unbroken faces (so it's a new BROKEN vertex)
+                               freeVerts( v, vert );
+                               vert->setTAG(BROKEN);
+                               break;
+                       case 2: {
+#ifdef DEBUG
+                               cout << "size of fBOF = " << facesByOriginalFace.size() << endl;
+#endif
+                               BOP_Faces ff = facesByOriginalFace.front();
+                               BOP_Faces fb = facesByOriginalFace.back();
+                               BOP_Index eindexs[2];
+                               int ecount = 0;
+
+                               // look for two edges adjacent to v which contain both ofaces
+                               BOP_Indexs edges = vert->getEdges();
+#ifdef DEBUG
+                               cout << "   ff has " << ff.size() << " faces" << endl;
+                               cout << "   fb has " << fb.size() << " faces" << endl;
+                               cout << "   v  has " << edges.size() << " edges" << endl;
+#endif
+                               for(BOP_IT_Indexs it = edges.begin(); it != edges.end(); 
+                                               ++it ) {
+                                       BOP_Edge *edge = m_mesh->getEdge(*it);
+                                       BOP_Indexs faces = edge->getFaces();
+#ifdef DEBUG
+                                       cout << "  " << edge << " has " << edge->getFaces().size() << " faces" << endl;
+#endif
+                                       if( faces.size() == 2 ) {
+                                               BOP_Face *f0 = m_mesh->getFace(faces[0]);
+                                               BOP_Face *f1 = m_mesh->getFace(faces[1]);
+                                               if( f0->getOriginalFace() != f1->getOriginalFace() ) {
+#ifdef DEBUG
+                                                       cout << "   " << f0 << endl;
+                                                       cout << "   " << f1 << endl;
+#endif
+                                                       eindexs[ecount++] = (*it);
+                                               }
+                                       }
+                               }
+                               if(ecount == 2) {
+#ifdef DEBUG
+                                       cout << "   edge indexes are " << eindexs[0];
+                                       cout << " and " << eindexs[1] << endl;
+#endif
+                                       BOP_Edge *edge = m_mesh->getEdge(eindexs[0]);
+                                       BOP_Index N = edge->getVertex1();
+                                       if(N == v) N = edge->getVertex2();
+#ifdef DEBUG
+                                       cout << "    ## OK, replace "<<v<<" with "<<N << endl;
+#endif
+                                       mergeVertex(ff , v, N );
+                                       mergeVertex(fb , v, N );
+// now remove v and its edges
+                                       vert->setTAG(BROKEN);
+                                       for(BOP_IT_Indexs it = edges.begin(); it != edges.end(); 
+                                                       ++it ) {
+                                               BOP_Edge *edge = m_mesh->getEdge(*it);
+                                               edge->setUsed(false);
+                                       }
+                                       didMerge = true;
+                               }       
+#ifdef DEBUG
+                               else {
+                                       cout << "   HUH: ecount was " << ecount << endl;
+                               }
+#endif
+                               }
+                               break;
+                       default:
+                               break;
+                       }
+               }
+       }
+
+       return didMerge;
+}
+
+void BOP_Merge2::mergeVertex(BOP_Faces &faces, BOP_Index v1, BOP_Index v2)
+{
+       for(BOP_IT_Faces face=faces.begin();face!=faces.end();face++) {
+               if( (*face)->size() == 3)
+                       mergeVertex((BOP_Face3 *) *face, v1, v2);
+               else
+                       mergeVertex((BOP_Face4 *) *face, v1, v2);
+               (*face)->setTAG(BROKEN);
+#ifdef DEBUG
+               cout << "  breaking " << (*face) << endl;
+#endif
+       }
+}
+
+/*
+ * Remove a face from the mesh and from each edges's face list
+ */
+
+static void deleteFace(BOP_Mesh *m, BOP_Face *face)
+{
+       BOP_Index l2 = face->getVertex(0);
+       BOP_Faces faces = m->getFaces();
+       for(int i = face->size(); i-- ; ) {
+               BOP_Indexs edges = m->getVertex(l2)->getEdges();
+               BOP_Index l1 = face->getVertex(i);
+               for(BOP_IT_Indexs it1 = edges.begin(); it1 != edges.end(); ++it1 ) {
+                       BOP_Edge *edge = m->getEdge(*it1);
+                       if( ( edge->getVertex1() == l1 && edge->getVertex2() == l2 ) ||
+                               ( edge->getVertex1() == l2 && edge->getVertex2() == l1 ) ) {
+                               BOP_Indexs ef = edge->getFaces();
+                               for(BOP_IT_Indexs it = ef.begin(); it != ef.end(); ++it ) {
+                                       if( m->getFace(*it) == face) {
+                                               edge->removeFace(*it);
+                                               break;
+                                       }
+                               }
+                               break;
+                       }
+               }
+               l2 = l1;
+       }
+       face->setTAG(BROKEN);
+}
+
+void BOP_Merge2::mergeVertex(BOP_Face3 *face, BOP_Index v1, BOP_Index v2)
+{
+       BOP_Index next, prev;
+       face->getNeighbours(v1,prev,next);
+
+       // if new vertex is not already in the tri, make a new tri
+       if( prev != v2 && next != v2 ) {
+               m_mesh->addFace( new BOP_Face3(prev,v2,next,
+                                       face->getPlane(),face->getOriginalFace()) );
+#ifdef DEBUG
+               cout << "mv3: add " << prev << "," << v2 << "," << next << endl;
+       } else {
+               cout << "mv3: vertex already in tri: doing nothing" << endl;
+#endif
+       }
+       deleteFace(m_mesh, face);
+}
+
+void BOP_Merge2::mergeVertex(BOP_Face4 *face, BOP_Index v1, BOP_Index v2)
+{
+       BOP_Index next, prev, opp;
+       face->getNeighbours(v1,prev,next,opp);
+
+       // if new vertex is already in the quad, replace quad with new tri
+       if( prev == v2 || next == v2 ) {
+               m_mesh->addFace( new BOP_Face3(prev,next,opp,
+                                       face->getPlane(),face->getOriginalFace()) );
+#ifdef DEBUG
+               cout << "mv4a: add " << prev << "," << next << "," << opp << endl;
+#endif
+       }
+       // otherwise make a new quad
+       else {
+               m_mesh->addFace( new BOP_Face4(prev,v2,next,opp,
+                                       face->getPlane(),face->getOriginalFace()) );
+#ifdef DEBUG
+               cout << "mv4b: add "<<prev<<","<<v2<<","<<next<<","<<opp<<endl;
+#endif
+       }
+       deleteFace(m_mesh, face);
+}
+
+// #define OLD_QUAD
+
+/** 
+ * Simplifies the mesh, merging the pairs of triangles that come frome the
+ * same original face and define a quad.
+ * @return true if a quad was added, false otherwise
+ */
+bool BOP_Merge2::createQuads()
+{
+  
+       BOP_Faces quads;
+       
+       // Get mesh faces
+       BOP_Faces faces = m_mesh->getFaces();
+       
+    // Merge mesh triangles
+       const BOP_IT_Faces facesIEnd = (faces.end()-1);
+       const BOP_IT_Faces facesJEnd = faces.end();
+       for(BOP_IT_Faces faceI=faces.begin();faceI!=facesIEnd;faceI++) {
+#ifdef OLD_QUAD
+               if ((*faceI)->getTAG() == BROKEN || (*faceI)->size() != 3) continue;
+               for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) {
+                       if ((*faceJ)->getTAG() == BROKEN || (*faceJ)->size() != 3 ||
+                               (*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue;
+
+
+                       BOP_Face *faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ);
+                       if (faceK != NULL) {
+                               // Set triangles to BROKEN
+                               deleteFace(m_mesh, *faceI);
+                               deleteFace(m_mesh, *faceJ);
+#ifdef DEBUG
+                       cout << "createQuad: del " << *faceI << endl;
+                       cout << "createQuad: del " << *faceJ << endl;
+                       cout << "createQuad: add " << faceK << endl;
+#endif
+                               quads.push_back(faceK);
+                               break;
+                       }
+               }
+#else
+               if ((*faceI)->getTAG() == BROKEN ) continue;
+               for(BOP_IT_Faces faceJ=(faceI+1);faceJ!=facesJEnd;faceJ++) {
+                       if ((*faceJ)->getTAG() == BROKEN ||
+                               (*faceJ)->getOriginalFace() != (*faceI)->getOriginalFace()) continue;
+
+                       BOP_Face *faceK = NULL;
+                       if((*faceI)->size() == 3) {
+                               if((*faceJ)->size() == 3)
+                                       faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face3*)*faceJ);
+                               else
+                                       faceK = createQuad((BOP_Face3*)*faceI,(BOP_Face4*)*faceJ);
+                       } else {
+                               if((*faceJ)->size() == 3)
+                                       faceK = createQuad((BOP_Face3*)*faceJ,(BOP_Face4*)*faceI);
+                               else
+                                       faceK = createQuad((BOP_Face4*)*faceI,(BOP_Face4*)*faceJ);
+                       }
+
+                       if (faceK != NULL) {
+                               // Set triangles to BROKEN
+                               deleteFace(m_mesh, *faceI);
+                               deleteFace(m_mesh, *faceJ);
+#ifdef DEBUG
+                       cout << "createQuad: del " << *faceI << endl;
+                       cout << "createQuad: del " << *faceJ << endl;
+                       cout << "createQuad: add " << faceK << endl;
+#endif
+                               quads.push_back(faceK);
+                               break;
+                       }
+               }
+#endif
+       }
+
+    // Add quads to mesh
+       const BOP_IT_Faces quadsEnd = quads.end();
+       for(BOP_IT_Faces quad=quads.begin();quad!=quadsEnd;quad++) m_mesh->addFace(*quad);
+       return (quads.size() > 0);
+}
+
+/** 
+ * Returns a new quad (convex) from the merge of two triangles that share the
+ * vertex index v.
+ * @param faceI mesh triangle
+ * @param faceJ mesh triangle
+ * @param v vertex index shared by both triangles
+ * @return a new convex quad if the merge is possible
+ */
+BOP_Face* BOP_Merge2::createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ)
+{
+       // Test if both triangles share a vertex index
+       BOP_Index v;
+       unsigned int i;
+       for(i=0;i<3 ;i++) {
+               v = faceI->getVertex(i);
+               if( faceJ->containsVertex(v) ) break;
+       }
+       if (i == 3) return NULL;
+
+       BOP_Face *faceK = NULL;
+
+       // Get faces data
+       BOP_Index prevI, nextI, prevJ, nextJ;
+       faceI->getNeighbours(v,prevI,nextI);
+       faceJ->getNeighbours(v,prevJ,nextJ);
+       MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
+       MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
+       MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
+       MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
+       MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();
+
+       // Quad test
+       if (prevI == nextJ) {
+               if (!BOP_collinear(vNextI,vertex,vPrevJ) && !BOP_collinear(vNextI,vPrevI,vPrevJ) &&
+                       BOP_convex(vertex,vNextI,vPrevI,vPrevJ)) {
+                               faceK = new BOP_Face4(v,nextI,prevI,prevJ,faceI->getPlane(),faceI->getOriginalFace());
+                               faceK->setTAG(faceI->getTAG());
+                               BOP_Index edge;
+                               m_mesh->getIndexEdge(v,prevI,edge);
+                               m_mesh->getVertex(v)->removeEdge(edge);
+                               m_mesh->getVertex(prevI)->removeEdge(edge);
+               }
+       }
+       else if (nextI == prevJ) {
+               if (!BOP_collinear(vPrevI,vertex,vNextJ) && !BOP_collinear(vPrevI,vNextI,vNextJ) &&
+                       BOP_convex(vertex,vNextJ,vNextI,vPrevI)) {
+                               faceK = new BOP_Face4(v,nextJ,nextI,prevI,faceI->getPlane(),faceI->getOriginalFace());
+                               faceK->setTAG(faceI->getTAG());
+                               BOP_Index edge;
+                               m_mesh->getIndexEdge(v,nextI,edge);
+                               m_mesh->getVertex(v)->removeEdge(edge);
+                               m_mesh->getVertex(nextI)->removeEdge(edge);
+                       }
+       }
+       return faceK;
+}
+
+/** 
+ * Returns a new quad (convex) from the merge of two triangles that share the
+ * vertex index v.
+ * @param faceI mesh triangle
+ * @param faceJ mesh triangle
+ * @param v vertex index shared by both triangles
+ * @return a new convex quad if the merge is possible
+ */
+BOP_Face* BOP_Merge2::createQuad(BOP_Face3 *faceI, BOP_Face4 *faceJ)
+{
+       // Test if triangle and quad share a vertex index
+       BOP_Index v;
+       unsigned int i;
+       for(i=0;i<3 ;i++) {
+               v = faceI->getVertex(i);
+               if( faceJ->containsVertex(v) ) break;
+       }
+       if (i == 3) return NULL;
+
+       BOP_Face *faceK = NULL;
+
+       // Get faces data
+       BOP_Index prevI, nextI, prevJ, nextJ, oppJ;
+       faceI->getNeighbours(v,prevI,nextI);
+       faceJ->getNeighbours(v,prevJ,nextJ,oppJ);
+
+       // Quad test
+       BOP_Index edge;
+       if (nextI == prevJ) {
+               if (prevI == nextJ) {   // v is in center
+                       faceK = new BOP_Face3(nextJ,oppJ,prevJ,faceI->getPlane(),faceI->getOriginalFace());
+                       faceK->setTAG(faceI->getTAG());
+                       m_mesh->getIndexEdge(v,prevI,edge);
+                       m_mesh->getVertex(v)->removeEdge(edge);
+                       m_mesh->getVertex(prevI)->removeEdge(edge);
+                       m_mesh->getIndexEdge(v,nextI,edge);
+                       m_mesh->getVertex(v)->removeEdge(edge);
+                       m_mesh->getVertex(nextI)->removeEdge(edge);
+                       freeVerts(v, m_mesh->getVertex(v));
+               } else if (prevI == oppJ) {     // nextI is in center
+                       faceK = new BOP_Face3(v,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace());
+                       faceK->setTAG(faceI->getTAG());
+                       m_mesh->getIndexEdge(v,nextI,edge);
+                       m_mesh->getVertex(v)->removeEdge(edge);
+                       m_mesh->getVertex(nextI)->removeEdge(edge);
+                       m_mesh->getIndexEdge(prevI,nextI,edge);
+                       m_mesh->getVertex(prevI)->removeEdge(edge);
+                       m_mesh->getVertex(nextI)->removeEdge(edge);
+                       freeVerts(nextI, m_mesh->getVertex(nextI));
+               }
+       } else if (nextI == oppJ && prevI == nextJ ) { // prevI is in center
+               faceK = new BOP_Face3(prevJ,v,oppJ,faceI->getPlane(),faceI->getOriginalFace());
+               faceK->setTAG(faceI->getTAG());
+               m_mesh->getIndexEdge(v,prevI,edge);
+               m_mesh->getVertex(v)->removeEdge(edge);
+               m_mesh->getVertex(prevI)->removeEdge(edge);
+               m_mesh->getIndexEdge(nextI,prevI,edge);
+               m_mesh->getVertex(nextI)->removeEdge(edge);
+               m_mesh->getVertex(prevI)->removeEdge(edge);
+               freeVerts(prevI, m_mesh->getVertex(prevI));
+       }
+       return faceK;
+}
+
+/** 
+ * Returns a new quad (convex) from the merge of two triangles that share the
+ * vertex index v.
+ * @param faceI mesh triangle
+ * @param faceJ mesh triangle
+ * @param v vertex index shared by both triangles
+ * @return a new convex quad if the merge is possible
+ */
+BOP_Face* BOP_Merge2::createQuad(BOP_Face4 *faceI, BOP_Face4 *faceJ)
+{
+       BOP_Face *faceK = NULL;
+       //
+       // Test if both quads share a vertex index
+       //
+       BOP_Index v;
+       unsigned int i;
+       for(i=0;i<4 ;i++) {
+               v = faceI->getVertex(i);
+               if( faceJ->containsVertex(v) ) break;
+       }
+       if (i == 3) return NULL;
+
+
+       // Get faces data
+       BOP_Index prevI, nextI, oppI, prevJ, nextJ, oppJ;
+       faceI->getNeighbours(v,prevI,nextI,oppI);
+       faceJ->getNeighbours(v,prevJ,nextJ,oppJ);
+
+       // Quad test
+       BOP_Index edge;
+       if (nextI == prevJ) {
+               if (prevI == nextJ) {   // v is in center
+                       faceK = new BOP_Face4(nextI,oppI,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace());
+                       faceK->setTAG(faceI->getTAG());
+                       m_mesh->getIndexEdge(v,prevI,edge);
+                       m_mesh->getVertex(v)->removeEdge(edge);
+                       m_mesh->getVertex(prevI)->removeEdge(edge);
+                       m_mesh->getIndexEdge(v,nextI,edge);
+                       m_mesh->getVertex(v)->removeEdge(edge);
+                       m_mesh->getVertex(nextI)->removeEdge(edge);
+                       freeVerts(v, m_mesh->getVertex(v));
+               } else if (oppI == oppJ) {      // nextI is in center
+                       faceK = new BOP_Face4(v,nextJ,oppJ,prevI,faceI->getPlane(),faceI->getOriginalFace());
+                       faceK->setTAG(faceI->getTAG());
+                       m_mesh->getIndexEdge(v,nextI,edge);
+                       m_mesh->getVertex(v)->removeEdge(edge);
+                       m_mesh->getVertex(nextI)->removeEdge(edge);
+                       m_mesh->getIndexEdge(prevI,nextI,edge);
+                       m_mesh->getVertex(prevI)->removeEdge(edge);
+                       m_mesh->getVertex(nextI)->removeEdge(edge);
+                       freeVerts(nextI, m_mesh->getVertex(nextI));
+               }
+       } else if (prevI == nextJ && oppI == oppJ) { // prevI is in center
+               faceK = new BOP_Face4(v,nextI,oppJ,prevJ,faceI->getPlane(),faceI->getOriginalFace());
+               faceK->setTAG(faceI->getTAG());
+               m_mesh->getIndexEdge(v,prevI,edge);
+               m_mesh->getVertex(v)->removeEdge(edge);
+               m_mesh->getVertex(prevI)->removeEdge(edge);
+               m_mesh->getIndexEdge(nextI,prevI,edge);
+               m_mesh->getVertex(nextI)->removeEdge(edge);
+               m_mesh->getVertex(prevI)->removeEdge(edge);
+               freeVerts(prevI, m_mesh->getVertex(prevI));
+       }
+       return faceK;
+}
+
+/**
+ * Returns if a index is inside a set of indexs.
+ * @param indexs set of indexs
+ * @param i index
+ * @return true if the index is inside the set, false otherwise
+ */
+bool BOP_Merge2::containsIndex(BOP_Indexs indexs, BOP_Index i)
+{
+  const BOP_IT_Indexs indexsEnd = indexs.end();
+       for(BOP_IT_Indexs it=indexs.begin();it!=indexsEnd;it++) {
+               if (*it == i) return true;
+       }
+       return false;
+}
+
+/**
+ * Creates a list of lists L1, L2, ... LN where
+ *   LX = mesh faces with vertex v that come from the same original face
+ * @param facesByOriginalFace list of faces lists
+ * @param v vertex index
+ */
+void BOP_Merge2::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Index v)
+{
+       // Get edges with vertex v
+
+       BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges();
+       const BOP_IT_Indexs edgeEnd = edgeIndexs.end();
+       for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) {    
+               // For each edge, add its no broken faces to the output list
+               BOP_Edge* edge = m_mesh->getEdge(*edgeIndex);
+               BOP_Indexs faceIndexs = edge->getFaces();
+               const BOP_IT_Indexs faceEnd = faceIndexs.end();
+               for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) {
+                       BOP_Face* face = m_mesh->getFace(*faceIndex);
+                       if (face->getTAG() != BROKEN) {
+                               bool found = false;
+                               // Search if we already have created a list for the 
+                               // faces that come from the same original face
+                               const BOP_IT_LFaces lfEnd = facesByOriginalFace.end();
+                               for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin();
+                               facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) {
+                                       if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) {
+                                               // Search that the face has not been added to the list before
+                                               for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) {
+                                                       if ((*facesByOriginalFaceX)[i] == face) {
+                                                               found = true;
+                                                               break;
+                                                       }
+                                               }
+                                               if (!found) {
+                                                       // Add the face to the list
+                                                 if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face);
+                                                 else facesByOriginalFaceX->push_back(face);
+                                                 found = true;
+                                               }
+                                               break;
+                                       }
+                               }
+                               if (!found) {
+                                       // Create a new list and add the current face
+                                       BOP_Faces facesByOriginalFaceX;
+                                       facesByOriginalFaceX.push_back(face);
+                                       facesByOriginalFace.push_back(facesByOriginalFaceX);
+                               }
+                       }
+               }
+       }
+}
+
+/**
+ * Creates a list of lists L1, L2, ... LN where
+ *   LX = mesh faces with vertex v that come from the same original face
+ *        and without any of the vertices that appear before v in vertices
+ * @param facesByOriginalFace list of faces lists
+ * @param vertices vector with vertices indexs that contains v
+ * @param v vertex index
+ */
+void BOP_Merge2::getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v)
+{
+       // Get edges with vertex v
+       BOP_Indexs edgeIndexs = m_mesh->getVertex(v)->getEdges();
+       const BOP_IT_Indexs edgeEnd = edgeIndexs.end();
+       for(BOP_IT_Indexs edgeIndex = edgeIndexs.begin();edgeIndex != edgeEnd;edgeIndex++) {    
+               // Foreach edge, add its no broken faces to the output list
+               BOP_Edge* edge = m_mesh->getEdge(*edgeIndex);
+               BOP_Indexs faceIndexs = edge->getFaces();
+               const BOP_IT_Indexs faceEnd = faceIndexs.end();
+               for(BOP_IT_Indexs faceIndex=faceIndexs.begin();faceIndex!=faceEnd;faceIndex++) {
+                       BOP_Face* face = m_mesh->getFace(*faceIndex);
+                       if (face->getTAG() != BROKEN) {
+                               // Search if the face contains any of the forbidden vertices
+                               bool found = false;
+                               for(BOP_IT_Indexs vertex = vertices.begin();*vertex!= v;vertex++) {
+                                       if (face->containsVertex(*vertex)) {
+                                               // face contains a forbidden vertex!
+                                               found = true;
+                                               break;
+                               }
+                       }
+                       if (!found) {
+                               // Search if we already have created a list with the 
+                               // faces that come from the same original face
+                         const BOP_IT_LFaces lfEnd = facesByOriginalFace.end();
+                               for(BOP_IT_LFaces facesByOriginalFaceX=facesByOriginalFace.begin();
+                                       facesByOriginalFaceX!=lfEnd; facesByOriginalFaceX++) {
+                                       if (((*facesByOriginalFaceX)[0])->getOriginalFace() == face->getOriginalFace()) {
+                                               // Search that the face has not been added to the list before
+                                               for(unsigned int i = 0;i<(*facesByOriginalFaceX).size();i++) {
+                                                       if ((*facesByOriginalFaceX)[i] == face) {
+                                                               found = true;
+                                                               break;
+                                                       }
+                                               }
+                                               if (!found) {
+                                                 // Add face to the list
+                                                 if (face->getTAG()==OVERLAPPED) facesByOriginalFaceX->insert(facesByOriginalFaceX->begin(),face);
+                                                 else facesByOriginalFaceX->push_back(face);
+                                                 found = true;
+                                               }
+                                               break;
+                                       }
+                               }
+                               if (!found) {
+                                       // Create a new list and add the current face
+                                       BOP_Faces facesByOriginalFaceX;
+                                       facesByOriginalFaceX.push_back(face);
+                                       facesByOriginalFace.push_back(facesByOriginalFaceX);
+                               }
+                       }
+               }
+       }
+       }
+}
+
+#endif  /* BOP_NEW_MERGE */
diff --git a/intern/boolop/intern/BOP_Merge2.h b/intern/boolop/intern/BOP_Merge2.h
new file mode 100644 (file)
index 0000000..1e5945a
--- /dev/null
@@ -0,0 +1,99 @@
+/**
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef BOP_MERGE2_H
+#define BOP_MERGE2_H
+
+#include "BOP_Misc.h"
+
+#ifdef BOP_NEW_MERGE
+
+#include "BOP_Mesh.h"
+#include "BOP_Tag.h"
+#include "BOP_MathUtils.h"
+#include "MEM_SmartPtr.h"
+
+typedef vector< BOP_Faces > BOP_LFaces;
+typedef vector< BOP_Faces >::iterator BOP_IT_LFaces;
+
+class BOP_Merge2 {
+       private:
+               BOP_Mesh* m_mesh;
+               BOP_Index m_firstVertex;
+               static BOP_Merge2 SINGLETON;
+
+               BOP_Merge2() {};
+               bool mergeFaces();
+               bool mergeFaces(BOP_Indexs &mergeVertices);
+               bool mergeFaces(BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v);
+               bool mergeFaces(BOP_Faces &faces, BOP_Faces &oldFaces, BOP_Faces &newFaces, BOP_Indexs &vertices, BOP_Index v);
+               BOP_Face *mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v);
+               BOP_Face *mergeFaces(BOP_Face *faceI, BOP_Face *faceJ, BOP_Indexs &pending, BOP_Index v);
+               BOP_Face *mergeFaces(BOP_Face3 *faceI, BOP_Face3 *faceJ, BOP_Index v);
+               BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Index v);
+               BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Indexs &pending, BOP_Index v);
+               BOP_Face *mergeFaces(BOP_Face4 *faceI, BOP_Face4 *faceJ, BOP_Indexs &pending, BOP_Index v);
+               bool createQuads();
+               bool containsIndex(BOP_Indexs indexs, BOP_Index index);
+               void getFaces(BOP_LFaces &facesByOriginalFace, BOP_Index v);
+               void getFaces(BOP_LFaces &facesByOriginalFace, BOP_Indexs vertices, BOP_Index v);
+               BOP_Face *createQuad(BOP_Face3 *faceI, BOP_Face3 *faceJ);
+               BOP_Face *createQuad(BOP_Face3 *faceI, BOP_Face4 *faceJ);
+               BOP_Face *createQuad(BOP_Face4 *faceI, BOP_Face4 *faceJ);
+
+               bool mergeVertex(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v,
+                               BOP_Indexs &mergeVertices);
+               bool mergeVertex(BOP_Face *faceI, BOP_Face *faceJ, BOP_Index v,
+                               BOP_Indexs &pending, BOP_Faces &oldFaces, BOP_Faces &newFaces );
+               BOP_Face *find3Neighbor(BOP_Face *faceI, BOP_Face *faceJ,
+                               BOP_Index X, BOP_Index I, BOP_Index P, BOP_Index N );
+               BOP_Face *find4Neighbor(BOP_Face *faceI, BOP_Face *faceJ,
+                               BOP_Index X, BOP_Index I, BOP_Index P, BOP_Index N,
+                       BOP_Face **faceL, BOP_Index &O);
+               BOP_Face3 *collapse(BOP_Face4 *faceC, BOP_Index X);
+               void mergeFaces(BOP_Face *A, BOP_Face *B, BOP_Index X,
+                       BOP_Index I, BOP_Index N, BOP_Index P, BOP_Faces &newFaces );
+               void freeVerts(BOP_Index v, BOP_Vertex *vert);
+
+               void mergeVertex(BOP_Faces&, BOP_Index, BOP_Index);
+               void mergeVertex(BOP_Face3 *, BOP_Index, BOP_Index);
+               void mergeVertex(BOP_Face4 *, BOP_Index, BOP_Index);
+               void cleanup( void );
+
+       public:
+
+               static BOP_Merge2 &getInstance() {
+                       return SINGLETON;
+               }
+
+               void mergeFaces(BOP_Mesh *m, BOP_Index v);
+};
+
+void dumpmesh(BOP_Mesh *, bool);
+
+#endif /* BOP_NEW_MERGE2 */
+#endif
index 5659cd62a3ff00f4e5d955e8b7fc388bd8db3eea..075884a19202c4de0b6a81e19ad35b7538419e43 100644 (file)
@@ -449,6 +449,13 @@ bool BOP_Mesh::getIndexEdge(BOP_Index v1, BOP_Index v2, BOP_Index &e)
                        printf ("found edge (%d %d)\n",v1,v2);
 #endif
                        e = edge->index;
+#ifdef BOP_NEW_MERGE
+                       if( m_edges[e]->getUsed() == false ) {
+                               m_edges[e]->setUsed(true);
+                               m_vertexs[v1]->addEdge(e);
+                               m_vertexs[v2]->addEdge(e);
+                       }
+#endif
                        return true;
                }
 #ifdef HASH_PRINTF_DEBUG
@@ -794,7 +801,8 @@ bool BOP_Mesh::isClosedMesh()
 }
 
 
-/** ***************************************************************************
+#ifdef BOP_DEBUG
+/******************************************************************************
  * DEBUG METHODS                                                              * 
  * This functions are used to test the mesh state and debug program errors.   *
  ******************************************************************************/
@@ -1075,3 +1083,4 @@ void BOP_Mesh::updatePlanes()
        }
 }
 
+#endif
index 9abff52545fe8457dd009cfc41e901f3cda7463c..46c8fa53d2086fbb26d7c77c6d187f6e3ec34f30 100644 (file)
@@ -1,10 +1,3 @@
-/*
- * TEMPORARY defines to enable hashing support
- */
-
-#define HASH(x) ((x) >> 5)             /* each "hash" covers 32 indices */
-// #define HASH_PRINTF_DEBUG   /* uncomment to enable debug output */
-
 /**
  *
  * $Id$
diff --git a/intern/boolop/intern/BOP_Misc.h b/intern/boolop/intern/BOP_Misc.h
new file mode 100644 (file)
index 0000000..d021579
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ *
+ * $Id: BOP_Misc.h 14444 2008-04-16 22:40:48Z khughes $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Ken Hughes
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+/*
+ * This file contains various definitions used across the modules
+ */
+
+/*
+ * define operator>> for faces, edges and vertices, and also add some
+ * debugging functions for displaying various internal data structures
+ */
+
+// #define     BOP_DEBUG
+
+#define HASH(x) ((x) >> 5)             /* each "hash" covers 32 indices */
+// #define HASH_PRINTF_DEBUG   /* uncomment to enable debug output */
+
+/*
+ * temporary: control which method is used to merge final triangles and
+ * quads back together after an operation.  If both methods are included,
+ * the "rt" debugging button on the Scene panel (F10) is used to control
+ * which is active.  Setting it to 100 enables the original method, any
+ * other value enables the new method.
+ */
+
+#define BOP_ORIG_MERGE                 /* include original merge code */
+#define BOP_NEW_MERGE                  /* include new merge code */
index 705f4885866b2147000425dde613c3a824dc19bd..ead10fa60402b32a5b7a5e0fe908b53e165d3520 100644 (file)
@@ -39,7 +39,7 @@
 #define OUTON_TAG        0x11  // Above and on the plane  
 #define UNCLASSIFIED_TAG 0x0F  // Expecting to be classified
 
-#define PHANTOM_TAG      0x0C  // Phantom face
+#define PHANTOM_TAG      0x0C  // Phantom face: verts form collinear triangle
 #define OVERLAPPED_TAG   0x0D  // Overlapped face
 #define BROKEN_TAG       0x0B  // Splitted and unused ... 
 
index a429c26d204bc94b775fd0ef5fd132b694c8dc53..edb53ea6a59c06da697530ee8690827c0fc48604 100644 (file)
@@ -89,3 +89,22 @@ bool BOP_Vertex::containsEdge(BOP_Index i)
        
        return false;
 }
+
+#ifdef BOP_DEBUG
+/**
+ * Implements operator <<.
+ */
+#include <iomanip>
+
+ostream &operator<<(ostream &stream, BOP_Vertex *v)
+{
+       char aux[20];
+       BOP_stringTAG(v->m_tag,aux);
+       MT_Point3 point = v->getPoint();
+       stream << setprecision(6) << showpoint << fixed;
+       stream << "Vertex[" << point[0] << "," << point[1] << ",";
+       stream << point[2] << "] ("  <<  aux  <<  ")";
+       return stream;
+}
+#endif
+
index 3a9895df6d3abb28cfcb0b231a3ac823c74f32a2..18b2f168f8c0f710401dff67b4411882dd4720e9 100644 (file)
@@ -31,6 +31,7 @@
 #include "BOP_Tag.h"
 #include "BOP_Indexs.h"
 #include "MT_Point3.h"
+#include "BOP_Misc.h"
 
 class BOP_Vertex 
 {
@@ -52,6 +53,10 @@ public:
        inline MT_Point3 getPoint() const { return m_point;};
        inline BOP_TAG getTAG() { return m_tag;};
        inline void setTAG(BOP_TAG t) { m_tag = t;};
+#ifdef BOP_DEBUG
+       friend ostream &operator<<(ostream &stream, BOP_Vertex *v);
+#endif
+
 };
 
 #endif
index 04d964ba657b3c69d8545264ab22428330aff27e..6ad16dec52c102c11471f2909b18423f894598d3 100644 (file)
@@ -471,6 +471,9 @@ DNA_makesdna.exe dna.c
                        <File
                                RelativePath="..\..\..\source\blender\makesdna\DNA_fileglobal_types.h">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\makesdna\DNA_gpencil_types.h">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\makesdna\DNA_group_types.h">
                        </File>
index 226bedbbfd8567241622b0a864aa9d750ff6c74a..153d9a90b2392e463b5f86aef8a2f80b3a1c4ef9 100644 (file)
                        <File
                                RelativePath="..\..\..\source\blender\src\drawdeps.c">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\src\drawgpencil.c">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\src\drawimage.c">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\src\editaction.c">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\src\editaction_gpencil.c">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\src\editarmature.c">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\src\glutil.c">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\src\gpencil.c">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\src\hddaudio.c">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\include\BDR_editobject.h">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\include\BDR_gpencil.h">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\include\BDR_imagepaint.h">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\include\BIF_cursors.h">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\include\BIF_drawgpencil.h">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\include\BIF_drawimage.h">
                        </File>
index b020d88b2b36570c1a249197e5fa84efd0ab7882..edf0faf4ab7d5117459bd16096ce46236fc0ab1f 100644 (file)
                        <File
                                RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderMouseDevice.cpp">
                        </File>
-                       <File
-                               RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderPolyMaterial.cpp">
-                       </File>
                        <File
                                RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderRenderTools.cpp">
                        </File>
                        <File
                                RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderMouseDevice.h">
                        </File>
-                       <File
-                               RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderPolyMaterial.h">
-                       </File>
                        <File
                                RelativePath="..\..\..\source\gameengine\BlenderRoutines\KX_BlenderRenderTools.h">
                        </File>
index c723efb61a7df2e0be3395e3ab850e061a5163d5..a48d065813a51e62b5cfeef0eecc347ed345ba19 100644 (file)
@@ -14,7 +14,7 @@ __url__ = ("blender", "blenderartists.org",
 __version__ = "2007/04/27"
 
 __bpydoc__ = """\
-"DEFORM to RVK2" copies deform data (except EDGESPLIT,DECIMATE,SUBSURF,BOOLEAN, 
+"DEFORM to RVK2" copies deform data (except EDGESPLIT,DECIMATE,SUBSURF,BOOLEAN,
 BUILD,MIRROR,ARRAY) of the active object to the RVK (relative vertex key) of
 the other selected object.
 
@@ -25,7 +25,7 @@ key.
 The new version of this scrit (Blender 2.43) manages the modifier changes.
 There are a lot of modifiers but only the ones which just deforms the shape
 can be used : LATTICE, CURVE, WAVE, ARMATURE. You can unset these modifiers
-from the script. 
+from the script.
 
 Usage:
 
@@ -35,7 +35,7 @@ the 3d View.  If the active object has subsurf turned on and nonzero subdiv
 level, the script will ask if it should change that.  Before copying data to
 the rvk it will also ask whether it should replace or add a new vertex group.
 
+
 """
 
 #----------------------------------------------
@@ -70,7 +70,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 """
 # Copy the rvk (1, or armature, lattice, or
 # any mesh deformation except surface
@@ -83,7 +83,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 # download the script :
 # http://jmsoler.free.fr/util/blenderfile/py/rvk1_torvk2.py
 # Communicate upon problems or errors:
-# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender 
+# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
 #----------------------------------------------
 # Page officielle :
 #   http://jmsoler.free.fr/util/blenderfile/py/rvk1_torvk2.py
@@ -101,22 +101,22 @@ def Value(t):
        exec "t=Modifier.Types.%s"%t
        return t
 
-def deform2rvk():  
+def deform2rvk():
        POSSMOD_list=['EDGESPLIT',
                                                                'DECIMATE',
-                                                               'SUBSURF', 
-                                                               'BOOLEAN', 
+                                                               'SUBSURF',
+                                                               'BOOLEAN',
                                                                'BUILD',
-                                                               'MIRROR', 
+                                                               'MIRROR',
                                                                'ARRAY']
 
        AUTHMOD_list=['LATTICE',
-                     'CURVE', 
+                     'CURVE',
                      'WAVE',
                      'ARMATURE']
 
        MODIFIERS=0
-       
+
        BMOD=[['Possible Modifiers'],
                                ['Allowed Modifiers']]
 
@@ -129,8 +129,8 @@ def deform2rvk():
                # =============================================================
                # must be 2 meshes ============================================
                # =============================================================
-               if RVK1.getType()=='Mesh' and RVK2.getType()=='Mesh': 
-                       FRAME=Blender.Get('curframe') 
+               if RVK1.getType()=='Mesh' and RVK2.getType()=='Mesh':
+                       FRAME=Blender.Get('curframe')
                        DATA2=RVK2.getData()
                        if DEBUG: print DATA2.getKey()
                        # ============================================================
@@ -151,7 +151,7 @@ def deform2rvk():
                                        # ===  Bloc Menu Modifiers ===1 doc =================
                                        # ===================================================
                                        m=0
-                                       for mod in  MODRVK1: 
+                                       for mod in  MODRVK1:
                                                if DEBUG: print mod.type
                                                if mod.type in POSSMOD:
                                                        BMOD[0].append([Draw.Create(0),mod.type,
@@ -183,7 +183,7 @@ def deform2rvk():
                                        retval = Blender.Draw.PupBlock("MESH 2 RVK", block)
                                        # ===================================================
                                        # ===  unset Modifiers  =============================
-                                       # ===================================================   
+                                       # ===================================================
                                        for     B in BMOD[0][1:]:
                                                if DEBUG: print B[2]
                                                MODRVK1[B[2]][Modifier.Settings.RENDER]=0
@@ -193,12 +193,12 @@ def deform2rvk():
                                        # ===================================================
                                        # ===  update Modifiers =============================
                                        # ===================================================
-                                       RVK1.makeDisplayList()                                                                  
+                                       #RVK1.makeDisplayList()
                                # =======================================================
                                # ===  get deformed mesh ================================
                                # =======================================================
                                RVK1NAME=Object.GetSelected()[0].getName()
-                               meshrvk1=NMesh.GetRawFromObject(RVK1NAME)  
+                               meshrvk1=NMesh.GetRawFromObject(RVK1NAME)
                                if DEBUG: print len(meshrvk1.verts)
                                # =======================================================
                                # ===  get normal mesh for vertex group =================
@@ -209,18 +209,18 @@ def deform2rvk():
                                # =======================================================
                                DATA2=RVK2.getData()
                                if DEBUG: print len(meshrvk1.verts)
-                               if DEBUG: print len(DATA2.verts)                                                        
+                               if DEBUG: print len(DATA2.verts)
                                # ========================================================
                                # ===== is there the same number of vertices =============
                                # ========================================================
-                               if len(meshrvk1.verts)==len(DATA2.verts): 
-                                       name = "Do you want to replace or add vertex groups ? %t| YES %x1| NO ? %x2 " 
+                               if len(meshrvk1.verts)==len(DATA2.verts):
+                                       name = "Do you want to replace or add vertex groups ? %t| YES %x1| NO ? %x2 "
                                        result = Draw.PupMenu(name)
-                                       if result==1:       
+                                       if result==1:
                                                # =====================================================
                                                # ===== Do we save vertex groups ?  ===================
                                                # =====================================================
-                                               GROUPNAME2=DATA2.getVertGroupNames() 
+                                               GROUPNAME2=DATA2.getVertGroupNames()
                                                if len(GROUPNAME2)!=0:
                                                        for GROUP2 in GROUPNAME2:
                                                                DATA2.removeVertGroup(GROUP2)
@@ -233,11 +233,11 @@ def deform2rvk():
                                        # ===== now copy the vertices coords =====================
                                        # ========================================================
                                        for v in meshrvk1.verts:
-                                               i= meshrvk1.verts.index(v) 
+                                               i= meshrvk1.verts.index(v)
                                                v1=DATA2.verts[i]
                                                for n in [0,1,2]:
                                                        v1.co[n]=v.co[n]
-                                       DATA2.update() 
+                                       DATA2.update()
                                        DATA2.insertKey(FRAME,'relative')
                                        DATA2.update()
                                        RVK2.makeDisplayList()
@@ -251,23 +251,23 @@ def deform2rvk():
                                                        if not B[1]:
                                                                MODRVK1[B[2]][Modifier.Settings.RENDER]|=B[-2]
                                else:
-                                       name = "Meshes Objects must the same number of vertices %t| Ok. %x1" 
+                                       name = "Meshes Objects must the same number of vertices %t| Ok. %x1"
                                        result = Draw.PupMenu(name)
                                        return
                        else:
-                               name = "Second Object must have  at least a shape key %t| Ok. %x1" 
+                               name = "Second Object must have  at least a shape key %t| Ok. %x1"
                                result = Draw.PupMenu(name)
                                return
-               else:   
-                       name = "Object must be Meshes %t| Ok. %x1" 
+               else:
+                       name = "Object must be Meshes %t| Ok. %x1"
                        result = Draw.PupMenu(name)
-                       return 
+                       return
        else :
-               name = "At least 2 Meshes as to be selected %t| Ok. %x1" 
+               name = "At least 2 Meshes as to be selected %t| Ok. %x1"
                result = Draw.PupMenu(name)
                return
-       Blender.Redraw()  
+       Blender.Redraw()
 EDITMODE=Blender.Window.EditMode()
 Blender.Window.EditMode(0)
 deform2rvk()
-Blender.Window.EditMode(EDITMODE)
+Blender.Window.EditMode(EDITMODE)
\ No newline at end of file
index f61b300f708e09dd3870a86f56a257d40a6742ed..7dc10c53e22909e1a3548259879112b2de818a03 100644 (file)
@@ -437,5 +437,7 @@ void weight_to_rgb(float input, float *fr, float *fg, float *fb);
 /* determines required DerivedMesh data according to view and edit modes */
 CustomDataMask get_viewedit_datamask();
 
+void DM_add_tangent_layer(DerivedMesh *dm);
+
 #endif
 
index f76cdbc64b7081778938a51de291a3a0fe2e66c9..d951c8401e3b27a60bbaa5f9109ff0d979f4cb8c 100644 (file)
@@ -41,7 +41,7 @@ struct ListBase;
 struct MemFile;
 
 #define BLENDER_VERSION                        246
-#define BLENDER_SUBVERSION             0
+#define BLENDER_SUBVERSION             1
 
 #define BLENDER_MINVERSION             245
 #define BLENDER_MINSUBVERSION  15
index 2d7d0e9286fceda6c1a1c8c83a6d7ac3ebf66da5..2274c54ad3bdea8a58207d1b4ac33e0901c5fc9c 100644 (file)
@@ -46,6 +46,7 @@ struct ID;
 typedef union {
        int i;
        float f;
+       double d;
        char *str;
        struct ID *id;
        struct {
index 739027fc95fafa1dcdc46f9911834490911915f9..1b07ce5074143f91e385ef585b78cb25583b6ae5 100644 (file)
 #ifndef BKE_SHRINKWRAP_H
 #define BKE_SHRINKWRAP_H
 
+/* mesh util */
+//TODO move this somewhere else
+#include "BKE_customdata.h"
+struct DerivedMesh;
+struct Object;
+struct DerivedMesh *object_get_derived_final(struct Object *ob, CustomDataMask dataMask);
+
 /* bitset stuff */
 //TODO: should move this to other generic lib files?
 typedef char* BitSet;
index 78a8f60caeb70cb8b40b33e41dddffeb877dc280..fade0f8cbaa4a1b1555b7c85894c2658e076a859 100644 (file)
@@ -62,6 +62,7 @@ struct Tex *copy_texture(struct Tex *tex);
 void make_local_texture(struct Tex *tex);
 void autotexname(struct Tex *tex);
 struct Tex *give_current_texture(struct Object *ob, int act);
+struct Tex *give_current_world_texture(void);
 
 struct TexMapping *add_mapping(void);
 void init_mapping(struct TexMapping *texmap);
index c913820205b4ac8cadb66fb6174f2b40414fe355..3ad11a61de33125e6a08cc76b2ae8805c6cfb462 100644 (file)
@@ -1,4 +1,3 @@
-
 /**
  * $Id$
  *
@@ -355,7 +354,8 @@ TimeMarker *get_frame_marker(int frame){return 0;};
 
 /* editseq.c */
 Sequence *get_forground_frame_seq(int frame){return 0;};
-void set_last_seq(Sequence *seq){};
+void clear_last_seq(Sequence *seq){};
+    
 
 /* modifier.c stub */
 void harmonic_coordinates_bind(struct MeshDeformModifierData *mmd,
index 4d3f9143b851699cb13e45f61795e768542895d7..67cf89d5ee26de6b964e499eedfd6975b05a9e83 100644 (file)
@@ -59,6 +59,7 @@
 #include "BLI_edgehash.h"
 #include "BLI_editVert.h"
 #include "BLI_linklist.h"
+#include "BLI_memarena.h"
 
 #include "BKE_cdderivedmesh.h"
 #include "BKE_customdata.h"
@@ -2844,6 +2845,127 @@ int editmesh_get_first_deform_matrices(float (**deformmats)[3][3], float (**defo
        return numleft;
 }
 
+void DM_add_tangent_layer(DerivedMesh *dm)
+{
+       /* mesh vars */
+       MTFace *mtface, *tf;
+       MFace *mface, *mf;
+       MVert *mvert, *v1, *v2, *v3, *v4;
+       MemArena *arena= NULL;
+       VertexTangent **vtangents= NULL;
+       float (*orco)[3]= NULL, (*tangent)[3];
+       float *uv1, *uv2, *uv3, *uv4, *vtang;
+       float fno[3], tang[3], uv[4][2];
+       int i, j, len, mf_vi[4], totvert, totface;
+
+       if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1)
+               return;
+
+       /* check we have all the needed layers */
+       totvert= dm->getNumVerts(dm);
+       totface= dm->getNumFaces(dm);
+
+       mvert= dm->getVertArray(dm);
+       mface= dm->getFaceArray(dm);
+       mtface= dm->getFaceDataArray(dm, CD_MTFACE);
+
+       if(!mtface) {
+               orco= dm->getVertDataArray(dm, CD_ORCO);
+               if(!orco)
+                       return;
+       }
+       
+       /* create tangent layer */
+       DM_add_face_layer(dm, CD_TANGENT, CD_CALLOC, NULL);
+       tangent= DM_get_face_data_layer(dm, CD_TANGENT);
+       
+       /* allocate some space */
+       arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+       BLI_memarena_use_calloc(arena);
+       vtangents= MEM_callocN(sizeof(VertexTangent*)*totvert, "VertexTangent");
+       
+       /* sum tangents at connected vertices */
+       for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++) {
+               v1= &mvert[mf->v1];
+               v2= &mvert[mf->v2];
+               v3= &mvert[mf->v3];
+
+               if (mf->v4) {
+                       v4= &mvert[mf->v4];
+                       CalcNormFloat4(v4->co, v3->co, v2->co, v1->co, fno);
+               }
+               else {
+                       v4= NULL;
+                       CalcNormFloat(v3->co, v2->co, v1->co, fno);
+               }
+               
+               if(mtface) {
+                       uv1= tf->uv[0];
+                       uv2= tf->uv[1];
+                       uv3= tf->uv[2];
+                       uv4= tf->uv[3];
+               }
+               else {
+                       uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3];
+                       spheremap(orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2], &uv[0][0], &uv[0][1]);
+                       spheremap(orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2], &uv[1][0], &uv[1][1]);
+                       spheremap(orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2], &uv[2][0], &uv[2][1]);
+                       if(v4)
+                               spheremap(orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2], &uv[3][0], &uv[3][1]);
+               }
+               
+               tangent_from_uv(uv1, uv2, uv3, v1->co, v2->co, v3->co, fno, tang);
+               sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1);
+               sum_or_add_vertex_tangent(arena, &vtangents[mf->v2], tang, uv2);
+               sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3);
+               
+               if(mf->v4) {
+                       v4= &mvert[mf->v4];
+                       
+                       tangent_from_uv(uv1, uv3, uv4, v1->co, v3->co, v4->co, fno, tang);
+                       sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1);
+                       sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3);
+                       sum_or_add_vertex_tangent(arena, &vtangents[mf->v4], tang, uv4);
+               }
+       }
+       
+       /* write tangent to layer */
+       for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++, tangent+=4) {
+               len= (mf->v4)? 4 : 3; 
+               
+               if(mtface) {
+                       uv1= tf->uv[0];
+                       uv2= tf->uv[1];
+                       uv3= tf->uv[2];
+                       uv4= tf->uv[3];
+               }
+               else {
+                       uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3];
+                       spheremap(orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2], &uv[0][0], &uv[0][1]);
+                       spheremap(orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2], &uv[1][0], &uv[1][1]);
+                       spheremap(orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2], &uv[2][0], &uv[2][1]);
+                       if(len==4)
+                               spheremap(orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2], &uv[3][0], &uv[3][1]);
+               }
+               
+               mf_vi[0]= mf->v1;
+               mf_vi[1]= mf->v2;
+               mf_vi[2]= mf->v3;
+               mf_vi[3]= mf->v4;
+               
+               for(j=0; j<len; j++) {
+                       vtang= find_vertex_tangent(vtangents[mf_vi[j]], mtface ? tf->uv[j] : uv[j]);
+
+                       VECCOPY(tangent[j], vtang);
+                       Normalize(tangent[j]);
+               }
+       }
+       
+       BLI_memarena_free(arena);
+       MEM_freeN(vtangents);
+}
+
+
 /* ************************* fluidsim bobj file handling **************************** */
 
 #ifndef DISABLE_ELBEEM
index 6dfb77504fb3d7cf6babdf2104fc0dd07fc620f0..5b3cec2577258b6282bc514c3fe893be87f47a34 100644 (file)
@@ -1547,7 +1547,7 @@ int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, f
 {
        Cloth *cloth=NULL;
        BVHTree *cloth_bvh=NULL;
-       long i=0, numfaces = 0, numverts = 0;
+       int i=0, numfaces = 0, numverts = 0;
        int rounds = 0; // result counts applied collisions; ic is for debug output;
        ClothVertex *verts = NULL;
        int ret = 0, ret2 = 0;
index 068501780bced5d66ca6816daa008425ac1c3e93..93ba30f8c9b9fb694cb406a02085fe47b4d307c4 100644 (file)
@@ -40,6 +40,7 @@
 
 #include "DNA_armature_types.h"
 #include "DNA_constraint_types.h"
+#include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_action_types.h"
 #include "DNA_curve_types.h"
@@ -63,6 +64,7 @@
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_idprop.h"
+#include "BKE_shrinkwrap.h"
 
 
 #include "BPY_extern.h"
@@ -457,7 +459,6 @@ void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4
                                                        Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
                                                        VECCOPY(offs_bone[3], pchan->bone->head);
                                                        offs_bone[3][1]+= pchan->bone->parent->length;
-                                                       
                                                        if (pchan->bone->flag & BONE_HINGE) {
                                                                /* pose_mat = par_pose-space_location * chan_mat */
                                                                float tmat[4][4];
@@ -558,8 +559,8 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
        if (dgroup < 0) return;
        
        /* get DerivedMesh */
-       if (G.obedit && G.editMesh) {
-               /* we are in editmode, so get a special derived mesh */
+       if ((G.obedit == ob) && (G.editMesh)) {
+               /* target is in editmode, so get a special derived mesh */
                dm = CDDM_from_editmesh(G.editMesh, ob->data);
        }
        else {
@@ -3228,6 +3229,140 @@ static bConstraintTypeInfo CTI_TRANSFORM = {
        transform_evaluate /* evaluate */
 };
 
+/* ---------- Shrinkwrap Constraint ----------- */
+static void shrinkwrap_new_data (void *cdata)
+{
+       bShrinkwrapConstraint *data= (bShrinkwrapConstraint *)cdata;
+
+       data->target = NULL;
+       data->dist = 0.0f;
+       data->shrinkType = MOD_SHRINKWRAP_NEAREST_SURFACE;
+}
+
+static int shrinkwrap_get_tars (bConstraint *con, ListBase *list)
+{
+       if (con && list) {
+               bShrinkwrapConstraint *data = con->data;
+               bConstraintTarget *ct;
+               
+               SINGLETARGETNS_GET_TARS(con, data->target, ct, list)
+               
+               return 1;
+       }
+       
+       return 0;
+}
+
+static void shrinkwrap_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+       if (con && list) {
+               bShrinkwrapConstraint *data = con->data;
+               bConstraintTarget *ct= list->first;
+               
+               SINGLETARGETNS_FLUSH_TARS(con, data->target, ct, list, nocopy)
+       }
+}
+
+static void shrinkwrap_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
+{
+       if (ct)
+               Mat4One(ct->matrix);
+}
+
+static void shrinkwrap_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+       bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *) con->data;
+       bConstraintTarget *ct = targets->first;
+       
+       if( VALID_CONS_TARGET(ct) && (ct->tar->type == OB_MESH) )
+       {
+               float co[3] = {0.0f, 0.0f, 0.0f};
+               float no[3] = {0.0f, 0.0f, 1.0f};
+               float dist;
+
+               SpaceTransform transform;
+               DerivedMesh *target = CDDM_copy( object_get_derived_final(ct->tar, CD_MASK_BAREMESH) );
+               BVHTreeRayHit hit;
+               BVHTreeNearest nearest;
+
+               //TODO
+               //Its stupid to create a bvhtree.. if we are only going to project one vertex
+               //But lets do it this way.. (so that in future maybe bvhtree gets a cache system and then the tree would already be build)
+               BVHTreeFromMesh treeData;
+               memset( &treeData, 0, sizeof(treeData) );
+
+               nearest.index = -1;
+               nearest.dist = 100000.0f; //TODO should use FLT_MAX.. but normal projection doenst yet supports it
+
+               if(target != NULL)
+               {
+
+                       space_transform_from_matrixs(&transform, cob->matrix, ct->matrix);
+
+                       space_transform_apply(&transform, co);
+                       space_transform_apply_normal(&transform, no);
+
+
+                       switch(scon->shrinkType)
+                       {
+                               case MOD_SHRINKWRAP_NEAREST_SURFACE:
+                                       if(bvhtree_from_mesh_faces(&treeData, target, 0.0, 2, 6) == NULL) return;
+                                       BLI_bvhtree_find_nearest(treeData.tree, co, &nearest, treeData.nearest_callback, &treeData);
+                                       VECCOPY(co, nearest.co);
+                                       
+                                       dist = VecLenf(co, nearest.co);
+                                       VecLerpf(co, co, nearest.co, (dist - scon->dist)/dist); //linear interpolation
+                               break;
+
+                               case MOD_SHRINKWRAP_NEAREST_VERTEX:
+                                       if(bvhtree_from_mesh_verts(&treeData, target, 0.0, 2, 6) == NULL) return;
+                                       BLI_bvhtree_find_nearest(treeData.tree, co, &nearest, treeData.nearest_callback, &treeData);
+                                       VECCOPY(co, nearest.co);
+
+                                       dist = VecLenf(co, nearest.co);
+                                       VecLerpf(co, co, nearest.co, (dist - scon->dist)/dist); //linear interpolation
+                               break;
+
+                               case MOD_SHRINKWRAP_NORMAL:
+                                       if(bvhtree_from_mesh_faces(&treeData, target, scon->dist, 4, 6) == NULL) return;
+                                       if(normal_projection_project_vertex(0, co, no, &transform, treeData.tree, &hit, treeData.raycast_callback, &treeData) == FALSE)
+                                               return;
+
+                                       VECCOPY(co, hit.co);
+                               break;
+                       }
+
+                       space_transform_invert(&transform, co);
+                       VECADD(cob->matrix[3], cob->matrix[3], co);
+
+
+                       if(treeData.tree)
+                               BLI_bvhtree_free(treeData.tree);
+
+                       target->release(target);
+               }
+               
+
+       }
+}
+
+static bConstraintTypeInfo CTI_SHRINKWRAP = {
+       CONSTRAINT_TYPE_SHRINKWRAP, /* type */
+       sizeof(bShrinkwrapConstraint), /* size */
+       "Shrinkwrap", /* name */
+       "bShrinkwrapConstraint", /* struct name */
+       NULL, /* free data */
+       NULL, /* relink data */
+       NULL, /* copy data */
+       shrinkwrap_new_data, /* new data */
+       shrinkwrap_get_tars, /* get constraint targets */
+       shrinkwrap_flush_tars, /* flush constraint targets */
+       shrinkwrap_get_tarmat, /* get a target matrix */
+       shrinkwrap_evaluate /* evaluate */
+};
+
+
+
 /* ************************* Constraints Type-Info *************************** */
 /* All of the constraints api functions use bConstraintTypeInfo structs to carry out
  * and operations that involve constraint specifc code.
@@ -3259,6 +3394,7 @@ static void constraints_init_typeinfo () {
        constraintsTypeInfo[17]= &CTI_RIGIDBODYJOINT;   /* RigidBody Constraint */
        constraintsTypeInfo[18]= &CTI_CLAMPTO;                  /* ClampTo Constraint */        
        constraintsTypeInfo[19]= &CTI_TRANSFORM;                /* Transformation Constraint */
+       constraintsTypeInfo[20]= &CTI_SHRINKWRAP;               /* Shrinkwrap Constraint */
 }
 
 /* This function should be used for getting the appropriate type-info when only
index 501293ecd814970d8ddc9a4e2a64cd4edc08a439..9012adb09b7a4c428cd8c375bfd7533304b615f0 100644 (file)
@@ -532,13 +532,14 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
        {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
        {sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
        {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL},
-       {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol} 
+       {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
+       {sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}
 };
 
 const char *LAYERTYPENAMES[CD_NUMTYPES] = {
        "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
        "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
-       "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol"};
+       "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent"};
 
 const CustomDataMask CD_MASK_BAREMESH =
        CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
@@ -552,7 +553,7 @@ const CustomDataMask CD_MASK_EDITMESH =
 const CustomDataMask CD_MASK_DERIVEDMESH =
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
        CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
-       CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO;
+       CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT;
 const CustomDataMask CD_MASK_BMESH = 
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
 const CustomDataMask CD_MASK_FACECORNERS =
index 2ef2f3a1b770ba095633b7ed5707a39811e5ffdc..b16f52571f63bbedb006f52154537ebdfa86ba29 100644 (file)
@@ -54,7 +54,8 @@ static char idp_size_table[] = {
        sizeof(float)*16, /*Matrix type, deprecated*/
        0, /*arrays don't have a fixed size*/
        sizeof(ListBase), /*Group type*/
-       sizeof(void*)
+       sizeof(void*),
+       sizeof(double)
 };
 
 
@@ -365,10 +366,14 @@ IDProperty *IDP_New(int type, IDPropertyTemplate val, char *name)
                        prop = MEM_callocN(sizeof(IDProperty), "IDProperty float");
                        *(float*)&prop->data.val = val.f;
                        break;
+               case IDP_DOUBLE:
+                       prop = MEM_callocN(sizeof(IDProperty), "IDProperty float");
+                       *(double*)&prop->data.val = val.d;
+                       break;          
                case IDP_ARRAY:
                {
-                       /*for now, we only support float and int arrays*/
-                       if (val.array.type == IDP_FLOAT || val.array.type == IDP_INT) {
+                       /*for now, we only support float and int and double arrays*/
+                       if (val.array.type == IDP_FLOAT || val.array.type == IDP_INT || val.array.type == IDP_DOUBLE) {
                                prop = MEM_callocN(sizeof(IDProperty), "IDProperty array");
                                prop->len = prop->totallen = val.array.len;
                                prop->subtype = val.array.type;
@@ -411,6 +416,10 @@ IDProperty *IDP_New(int type, IDPropertyTemplate val, char *name)
 
        prop->type = type;
        strncpy(prop->name, name, MAX_IDPROP_NAME);
+       
+       /*security null byte*/
+       prop->name[MAX_IDPROP_NAME-1] = 0;
+       
        return prop;
 }
 
index 2898dca767c66406703d4f706d96bd5318885f47..553107dd2648aa782251243f34a72664ebcec1bb 100644 (file)
@@ -303,7 +303,7 @@ void set_scene_bg(Scene *sce)
        int flag;
        
        // Note: this here is defined in editseq.c (BIF_editseq.h), NOT in blenkernel! 
-       set_last_seq(NULL);
+       clear_last_seq();
        
        G.scene= sce;
        
index 9005db1312fa47c1c680033d9676bda0d94b993b..d5b5ab6d63e65eb5dd61bee4a794948b5be0897c 100644 (file)
@@ -2053,7 +2053,6 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int
        
        /* check conditions for various options */
        do_deflector= query_external_colliders(ob);
-       do_effector= pdInitEffectors(ob,NULL);
        do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
        do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
        do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
@@ -2061,9 +2060,10 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int
        iks  = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
        bproot= sb->bpoint; /* need this for proper spring addressing */
        
-
-       
        if (do_springcollision || do_aero)  scan_for_ext_spring_forces(ob,timenow);
+       /* after spring scan because it uses Effoctors too */
+       do_effector= pdInitEffectors(ob,NULL);
+
        if (do_deflector) {
                float defforce[3];
                do_deflector = sb_detect_aabb_collisionCached(defforce,ob->lay,ob,timenow);
index 37804bf68ac84ad20b934dee4dd8a6d680bb6d9b..ad139220785679c33887bf8f297e34c7a4c9f8be 100644 (file)
@@ -53,6 +53,7 @@
 #include "DNA_world_types.h"
 #include "DNA_brush_types.h"
 #include "DNA_node_types.h"
+#include "DNA_scene_types.h"
 
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
@@ -731,7 +732,7 @@ Tex *give_current_texture(Object *ob, int act)
        bNode *node;
        
        if(ob==0) return 0;
-       if(ob->totcol==0) return 0;
+       if(ob->totcol==0 && !(ob->type==OB_LAMP)) return 0;
        
        if(ob->type==OB_LAMP) {
                la=(Lamp *)ob->data;
@@ -775,6 +776,18 @@ Tex *give_current_texture(Object *ob, int act)
        return tex;
 }
 
+Tex *give_current_world_texture(void)
+{
+       MTex *mtex = 0;
+       Tex *tex = 0;
+       
+       if(!(G.scene->world)) return 0;
+       
+       mtex= G.scene->world->mtex[(int)(G.scene->world->texact)];
+       if(mtex) tex= mtex->tex;
+       
+       return tex;
+}
 
 /* ------------------------------------------------------------------------- */
 
index a31c769a5b34f1978491b3846963a82c204cc5b2..c1edb7d3ac18b44c36a79f523b61832b0efd0524 100644 (file)
@@ -2535,11 +2535,6 @@ int IsectPQ2Df(float pt[2], float v1[2], float v2[2], float v3[2], float v4[2])
 }
 
 
-
-                       /* copied from Geometry.c - todo - move to arithb.c or some other generic place we can reuse */
-#define SIDE_OF_LINE(pa,pb,pp) ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
-#define POINT_IN_TRI(p0,p1,p2,p3)      ((SIDE_OF_LINE(p1,p2,p0)>=0) && (SIDE_OF_LINE(p2,p3,p0)>=0) && (SIDE_OF_LINE(p3,p1,p0)>=0))
-
 /**
  * 
  * @param min 
index 8b979f9ed2330f6e6a012d0e9bf922077925c313..74f152ac635ffb206158edf5d551be5e6a0a883c 100644 (file)
@@ -405,7 +405,7 @@ static VFontData *objfnt_to_ftvfontdata(PackedFile * pf)
                lcode = charcode;
        }
        
-       err = FT_Set_Charmap( face, (FT_CharMap) FT_ENCODING_UNICODE );
+       err = FT_Select_Charmap( face, FT_ENCODING_UNICODE );
 
        return vfd;     
 }
index 090b1d7c6b6a13f283b798d2af5604c83ab37871..ad19cde3c9ba963ad5700bd4cdb848b396056286 100644 (file)
@@ -1347,8 +1347,14 @@ void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, void *fd)
        prop->data.pointer = newdataadr(fd, prop->data.pointer);
 
        if (switch_endian) {
-               for (i=0; i<prop->len; i++) {
-                       SWITCH_INT(((int*)prop->data.pointer)[i]);
+               if (prop->subtype != IDP_DOUBLE) {
+                       for (i=0; i<prop->len; i++) {
+                               SWITCH_INT(((int*)prop->data.pointer)[i]);
+                       }
+               } else {
+                       for (i=0; i<prop->len; i++) {
+                               SWITCH_LONGINT(((double*)prop->data.pointer)[i]);
+                       }
                }
        }
 }
@@ -1384,6 +1390,24 @@ void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd)
                        break;
                case IDP_ARRAY:
                        IDP_DirectLinkArray(prop, switch_endian, fd);
+                       break;
+               case IDP_DOUBLE:
+                       /*erg, stupid doubles.  since I'm storing them
+                        in the same field as int val; val2 in the
+                        IDPropertyData struct, they have to deal with
+                        endianness specifically
+                        
+                        in theory, val and val2 would've already been swapped
+                        if switch_endian is true, so we have to first unswap
+                        them then reswap them as a single 64-bit entity.
+                        */
+                       
+                       if (switch_endian) {
+                               SWITCH_INT(prop->data.val);
+                               SWITCH_INT(prop->data.val2);
+                               SWITCH_LONGINT(prop->data.val);
+                       }
+                       
                        break;
        }
 }
@@ -4161,15 +4185,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                        link_gpencil(fd, sseq->gpd);
                                }
                        }
-                       else if(sl->spacetype==SPACE_ACTION) {
-                               SpaceAction *sact= (SpaceAction *)sl;
-                               
-                               /* WARNING: action-editor doesn't have it's own gpencil data! 
-                                * so only adjust pointer, but DON'T LINK
-                                */
-                               if (sact->gpd) 
-                                       sact->gpd= newdataadr(fd, sact->gpd);
-                       }
                }
 
                sa->v1= newdataadr(fd, sa->v1);
@@ -4855,6 +4870,49 @@ void idproperties_fix_group_lengths(ListBase idlist)
        }
 }
 
+void alphasort_version_246(FileData *fd, Library *lib, Mesh *me)
+{
+       Material *ma;
+       MFace *mf;
+       MTFace *tf;
+       int a, b, texalpha;
+
+       /* verify we have a tface layer */
+       for(b=0; b<me->fdata.totlayer; b++)
+               if(me->fdata.layers[b].type == CD_MTFACE)
+                       break;
+       
+       if(b == me->fdata.totlayer)
+               return;
+
+       /* if we do, set alpha sort if the game engine did it before */
+       for(a=0, mf=me->mface; a<me->totface; a++, mf++) {
+               if(mf->mat_nr < me->totcol) {
+                       ma= newlibadr(fd, lib, me->mat[mf->mat_nr]);
+                       texalpha = 0;
+
+                       for(b=0; ma && b<MAX_MTEX; b++)
+                               if(ma->mtex && ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA)
+                                       texalpha = 1;
+               }
+               else {
+                       ma= NULL;
+                       texalpha = 0;
+               }
+
+               for(b=0; b<me->fdata.totlayer; b++) {
+                       if(me->fdata.layers[b].type == CD_MTFACE) {
+                               tf = ((MTFace*)me->fdata.layers[b].data) + a;
+
+                               tf->mode &= ~TF_ALPHASORT;
+                               if(ma && (ma->mode & MA_ZTRA))
+                                       if(ELEM(tf->transp, TF_ALPHA, TF_ADD) || (texalpha && (tf->transp != TF_CLIP)))
+                                               tf->mode |= TF_ALPHASORT;
+                       }
+               }
+       }
+}
+
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
        /* WATCH IT!!!: pointers from libdata have not been converted */
@@ -7699,8 +7757,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        }
 
        /* sun/sky */
-       if ((main->versionfile < 246) ){
+       if(main->versionfile < 246) {
                Lamp *la;
+
                for(la=main->lamp.first; la; la= la->id.next) {
                        la->sun_effect_type = 0;
                        la->horizon_brightness = 1.0;
@@ -7716,6 +7775,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
 
+       if(main->versionfile <= 246 && main->subversionfile < 1){
+               Mesh *me;
+
+               for(me=main->mesh.first; me; me= me->id.next)
+                       alphasort_version_246(fd, lib, me);
+       }
+
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
 
index b59dd851dfe462b4bcb8e3394a0ca905ff3a2257..73abf362d12d9d0875c8660ac76f01f488fab08b 100644 (file)
@@ -533,6 +533,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
                if(part->id.us>0 || wd->current) {
                        /* write LibData */
                        writestruct(wd, ID_PA, "ParticleSettings", 1, part);
+                       if (part->id.properties) IDP_WriteProperty(part->id.properties, wd);
                        writestruct(wd, DATA, "PartDeflect", 1, part->pd);
                }
                part= part->id.next;
index d0ebd096ecba44b7c37e729f0f15d6356e13f2cf..eb749cf28ec656d8953fa2c72738529b6df79ac0 100644 (file)
@@ -38,6 +38,15 @@ struct bGPdata;
 struct bGPDlayer;
 struct bGPDframe;
 
+/* ------------- Grease-Pencil Helpers -------------- */
+
+/* Temporary 'Stroke Point' data */
+typedef struct tGPspoint {
+       short x, y;                             /* x and y coordinates of cursor (in relative to area) */
+       float xf, yf;                   /* same as x and y, but as floats */
+       float pressure;                 /* pressure of tablet at this point */
+} tGPspoint;
+
 /* ------------ Grease-Pencil API ------------------ */
 
 void free_gpencil_strokes(struct bGPDframe *gpf);
@@ -53,8 +62,6 @@ struct bGPdata *gpencil_data_duplicate(struct bGPdata *gpd);
 
 struct bGPdata *gpencil_data_getactive(struct ScrArea *sa);
 short gpencil_data_setactive(struct ScrArea *sa, struct bGPdata *gpd);
-struct bGPdata *gpencil_data_getetime(struct bScreen *sc);
-void gpencil_data_setetime(struct bScreen *sc, struct bGPdata *gpd);
 
 void gpencil_frame_delete_laststroke(struct bGPDframe *gpf);
 
@@ -71,6 +78,6 @@ void gpencil_delete_operation(short mode);
 void gpencil_delete_menu(void);
 
 //short gpencil_paint(short mousebutton);
-short gpencil_do_paint(struct ScrArea *sa);
+short gpencil_do_paint(struct ScrArea *sa, short mousebutton);
 
 #endif /*  BDR_GPENCIL_H */
index 9f6751daeffd73ef1ee6cd7832dc57320785738a..77c2f19bb9b524ded1bc61b7e998721be855218d 100644 (file)
@@ -49,7 +49,9 @@ enum {
        ACTTYPE_FILLCON,
        ACTTYPE_IPO,
        ACTTYPE_SHAPEKEY,
-       ACTTYPE_GPLAYER
+       ACTTYPE_GPDATABLOCK,
+       ACTTYPE_GPLAYER,
+       ACTTYPE_SPECIALDATA
 };
 
 /* Macros for easier/more consistant state testing */
@@ -70,6 +72,8 @@ enum {
 #define EDITABLE_ICU(icu) ((icu->flag & IPO_PROTECT)==0)
 #define SEL_ICU(icu) (icu->flag & IPO_SELECT)
 
+#define EXPANDED_GPD(gpd) (gpd->flag & GP_DATA_EXPAND) 
+
 #define EDITABLE_GPL(gpl) ((gpl->flag & GP_LAYER_LOCKED)==0)
 #define SEL_GPL(gpl) ((gpl->flag & GP_LAYER_ACTIVE) || (gpl->flag & GP_LAYER_SELECT))
 
@@ -185,7 +189,7 @@ void action_remove_localmarkers(struct bAction *act);
 /* Grease-Pencil Data */
 void gplayer_make_cfra_list(struct bGPDlayer *gpl, ListBase *elems, short onlysel);
 
-void deselect_gpencil_layers(struct bGPdata *gpd, short select_mode);
+void deselect_gpencil_layers(void *data, short select_mode);
 
 short is_gplayer_frame_selected(struct bGPDlayer *gpl);
 void set_gplayer_frame_selection(struct bGPDlayer *gpl, short mode);
@@ -204,7 +208,7 @@ void mirror_gplayer_frames(struct bGPDlayer *gpl, short mode);
 struct Key *get_action_mesh_key(void);
 int get_nearest_key_num(struct Key *key, short *mval, float *x);
 
-void *get_nearest_act_channel(short mval[], short *ret_type);
+void *get_nearest_act_channel(short mval[], short *ret_type, void **owner);
 
 /* Action */
 struct bActionChannel *get_hilighted_action_channel(struct bAction* action);
index 24112c7f11afd2664d69804428f2748f19aaa5e5..da98eb3d4f1a8beb122345ccf11669cdaf6aad36 100644 (file)
@@ -134,6 +134,7 @@ void        transform_armature_mirror_update(void);
 void   hide_selected_armature_bones(void);
 void   hide_unselected_armature_bones(void);
 void   show_all_armature_bones(void);
+void   set_locks_armature_bones(short lock);
 
 #define        BONESEL_ROOT    0x10000000
 #define        BONESEL_TIP             0x20000000
index 4ed3d0df367fc9eb8b2b9b05506a9e4a7f13a0a6..d2c6c56d01a2da3258b2c4fbfc82e9a33d317ebd 100644 (file)
@@ -34,9 +34,12 @@ struct Base;
 struct Object;
 struct Camera;
 struct View3D;
+struct rcti;
 
 void   arrows_move_cursor(unsigned short event);
+void   lasso_select_boundbox(struct rcti *rect, short mcords[][2], short moves);
 int            lasso_inside(short mcords[][2], short moves, short sx, short sy);
+int    lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1);
 void   borderselect(void);
 void   circle_select(void);
 void   deselectall(void);
index 83031ff3bad8158d16ddb174fb09cd8c93ff7527..e6f22a4fb67af534c163ca9d2c15074df54c7d35 100644 (file)
@@ -76,6 +76,7 @@ void inner_play_anim_loop(int init, int mode);
 int play_anim(int mode);
 
 void make_axis_color(char *col, char *col2, char axis);
+char *view3d_get_name(struct View3D *v3d);
 
 /* SMOOTHVIEW */
 void smooth_view(struct View3D *v3d, float *ofs, float *quat, float *dist, float *lens);
index c0542e3f34c17ca11a4bffaa1b89eabdf3258dd6..af74946f0e684c3fdfe4a3943d310dd869a059b5 100644 (file)
@@ -721,7 +721,8 @@ enum {
        B_CONSTRAINT_ADD_PYTHON,
        B_CONSTRAINT_ADD_CLAMPTO,
        B_CONSTRAINT_ADD_TRANSFORM,
-       B_CONSTRAINT_INF
+       B_CONSTRAINT_INF,
+       B_CONSTRAINT_ADD_SHRINKWRAP
 };
 
 /* *********************** */
index 60050ea010ec4d84158f24dc7c562e22a4318d0a..3054e038ba2b114bc67937c499113001a11642a5 100644 (file)
@@ -46,7 +46,7 @@ struct ID;
 typedef struct IDPropertyData {
        void *pointer;
        ListBase group;
-       int val, pad;
+       int val, val2; /*note, we actually fit a double into these two ints*/
 } IDPropertyData;
 
 typedef struct IDProperty {
@@ -77,6 +77,7 @@ typedef struct IDProperty {
 /*the ID link property type hasn't been implemented yet, this will require
   some cleanup of blenkernel, most likely.*/
 #define IDP_ID         7
+#define IDP_DOUBLE     8
 
 /*add any future new id property types here.*/
 
index d7969a7379b19211f42cdcc59d46d8cf2284ef5a..2e8d95335cca72ac8bb6ce8b29ffa4d6af67a7b5 100644 (file)
@@ -184,7 +184,6 @@ typedef struct SpaceAction {
        View2D v2d;     
        
        bAction         *action;                /* the currently active action */
-       bGPdata         *gpd;           /* the currently active gpencil block (for editing) */
        
        char  mode, autosnap;           /* mode: editing context; autosnap: automatic keyframe snapping mode   */
        short flag, actnr;                      /* flag: bitmapped settings; */
index ac9761f165df751684a088809f128ad20126ddb4..7444ce95f56a47de24e3e868b6290d48bfc805ba 100644 (file)
@@ -368,9 +368,9 @@ typedef struct FreeCamera {
 #define ACT_CONST_DIRPX                1
 #define ACT_CONST_DIRPY                2
 #define ACT_CONST_DIRPZ                4
-#define ACT_CONST_DIRMX                8
-#define ACT_CONST_DIRMY                16
-#define ACT_CONST_DIRMZ                32
+#define ACT_CONST_DIRNX                8
+#define ACT_CONST_DIRNY                16
+#define ACT_CONST_DIRNZ                32
 
 /* constraint type */
 #define ACT_CONST_TYPE_LOC     0
index 673855a6932009f7c3da12ede50fdc5acdd42260..0648c53535374c2190a9967463c25132924e260e 100644 (file)
@@ -154,7 +154,8 @@ typedef enum eBone_Flag {
        BONE_NO_SCALE                           = (1<<15),      /* No parent scale */
        BONE_HIDDEN_PG                          = (1<<16),      /* hidden bone when drawing PoseChannels (for ghost drawing) */
        BONE_DRAWWIRE                           = (1<<17),      /* bone should be drawn as OB_WIRE, regardless of draw-types of view+armature */
-       BONE_NO_CYCLICOFFSET            = (1<<18)       /* when no parent, bone will not get cyclic offset */
+       BONE_NO_CYCLICOFFSET            = (1<<18),      /* when no parent, bone will not get cyclic offset */
+       BONE_EDITMODE_LOCKED            = (1<<19),      /* bone transforms are locked in EditMode */
 } eBone_Flag;
 
 #endif
index 0fe0dace016d6dc45af43fce8f0c9106270d86f8..e78855b8de69065df36c7c3cd06fc4d1ef88dc47 100644 (file)
@@ -317,6 +317,13 @@ typedef struct bDistLimitConstraint {
        int             pad;
 } bDistLimitConstraint;
 
+typedef struct bShrinkwrapConstraint {
+       Object          *target;
+       float           dist;                   /* distance to kept from target */
+       short           shrinkType;             /* shrink type (look on MOD shrinkwrap for values) */
+       short           pad[5];
+} bShrinkwrapConstraint;
+
 /* ------------------------------------------ */
 
 /* bConstraint->type 
@@ -344,10 +351,9 @@ typedef enum B_CONSTAINT_TYPES {
        CONSTRAINT_TYPE_RIGIDBODYJOINT,         /* rigidbody constraint */
        CONSTRAINT_TYPE_CLAMPTO,                        /* clampto constraint */        
        CONSTRAINT_TYPE_TRANSFORM,                      /* transformation (loc/rot/size -> loc/rot/size) constraint */  
+       CONSTRAINT_TYPE_SHRINKWRAP,                     /* shrinkwrap (loc/rot) constraint */
        
-       
-       /* NOTE: everytime a new constraint is added, update this */
-       NUM_CONSTRAINT_TYPES= CONSTRAINT_TYPE_TRANSFORM
+       NUM_CONSTRAINT_TYPES
 } B_CONSTRAINT_TYPES; 
 
 /* bConstraint->flag */
@@ -375,11 +381,13 @@ typedef enum B_CONSTRAINT_SPACETYPES {
                /* for objects (relative to parent/without parent influence), 
                 * for bones (along normals of bone, without parent/restpositions) 
                 */
-       CONSTRAINT_SPACE_LOCAL,
+       CONSTRAINT_SPACE_LOCAL, /* = 1 */
                /* for posechannels - pose space  */
-       CONSTRAINT_SPACE_POSE,
-               /* for posechannels - local with parent  */
-       CONSTRAINT_SPACE_PARLOCAL,
+       CONSTRAINT_SPACE_POSE, /* = 2 */
+               /* for posechannels - local with parent  */
+       CONSTRAINT_SPACE_PARLOCAL, /* = 3 */
+               /* for files from between 2.43-2.46 (should have been parlocal) */
+       CONSTRAINT_SPACE_INVALID, /* = 4. do not exchange for anything! */
 } B_CONSTRAINT_SPACETYPES;
 
 /* bConstraintChannel.flag */
index 72557145270427b75c28c44365355b576224311f..6c098e220bbbd316e6f9579461eacbcadfa789a0 100644 (file)
@@ -71,7 +71,8 @@ typedef struct CustomData {
 #define CD_MTEXPOLY            15
 #define CD_MLOOPUV             16
 #define CD_MLOOPCOL            17
-#define CD_NUMTYPES            18
+#define CD_TANGENT             18
+#define CD_NUMTYPES            19
 
 /* Bits for CustomDataMask */
 #define CD_MASK_MVERT          (1 << CD_MVERT)
@@ -92,6 +93,7 @@ typedef struct CustomData {
 #define CD_MASK_MTEXPOLY       (1 << CD_MTEXPOLY)
 #define CD_MASK_MLOOPUV                (1 << CD_MLOOPUV)
 #define CD_MASK_MLOOPCOL       (1 << CD_MLOOPCOL)
+#define CD_MASK_TANGENT                (1 << CD_TANGENT)
 
 
 /* CustomData.flag */
index eafd886981b0032b89ddb85812d9585dc7f7105c..dca4e28688dcab1991234abc616807fa542d6a8f 100644 (file)
@@ -59,6 +59,8 @@ typedef struct bGPDstroke {
 #define GP_STROKE_3DSPACE              (1<<0)
        /* stroke is in 2d-space */
 #define GP_STROKE_2DSPACE              (1<<1)
+       /* stroke is an "eraser" stroke */
+#define GP_STROKE_ERASER               (1<<2)
 
 
 /* Grease-Pencil Annotations - 'Frame'
@@ -123,16 +125,16 @@ typedef struct bGPdata {
         */
        short sbuffer_size;                     /* number of elements currently in cache */
        short sbuffer_sflag;            /* flags for stroke that cache represents */
-       bGPDspoint *sbuffer;            /* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */
+       void *sbuffer;                          /* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */
 } bGPdata;
 
 /* bGPdata->flag */
-       /* draw this datablock's data (not used) */
-#define GP_DATA_DISP           (1<<0)
+       /* don't allow painting to occur at all */
+#define GP_DATA_LMBPLOCK       (1<<0)
        /* show debugging info in viewport (i.e. status print) */
 #define GP_DATA_DISPINFO       (1<<1)
-       /* is the block being shown in Action Editor */
-#define GP_DATA_EDITTIME       (1<<2)
+       /* in Action Editor, show as expanded channel */
+#define GP_DATA_EXPAND         (1<<2)
        /* is the block overriding all clicks? */
 #define GP_DATA_EDITPAINT      (1<<3)
        /* new strokes are added in viewport space */
index 6d025839ac8bc5e324ecac9824de743de0f1574f..4e427ed733ce1dfb5682f3fcf33647f5ae627526 100644 (file)
@@ -228,7 +228,7 @@ typedef struct PartialVisibility {
 
 /* mtface->mode */
 #define TF_DYNAMIC             1
-#define TF_DEPRECATED  2
+#define TF_ALPHASORT   2
 #define TF_TEX                 4
 #define TF_SHAREDVERT  8
 #define TF_LIGHT               16
index c4e8cb4925b83aeff9bace19c457583f853a626e..85c49a03569b2f8c330dac2b9a8ec6165d4c449a 100644 (file)
@@ -466,9 +466,11 @@ extern Object workob;
 #define OB_LOCK_ROTX   8
 #define OB_LOCK_ROTY   16
 #define OB_LOCK_ROTZ   32
+#define OB_LOCK_ROT            56
 #define OB_LOCK_SCALEX 64
 #define OB_LOCK_SCALEY 128
 #define OB_LOCK_SCALEZ 256
+#define OB_LOCK_SCALE  448
 
 /* ob->softflag in DNA_object_force.h */
 
index c0b9a6b95907fbc52be8ff4d94b2f7bdd7633f5f..7bad8ec3b44397461e990b5d94106fadc00fc721 100644 (file)
@@ -257,6 +257,7 @@ typedef struct SpeedControlVars {
 #define SEQ_USE_CROP                           131072
 #define SEQ_USE_COLOR_BALANCE                  262144
 #define SEQ_USE_PROXY_CUSTOM_DIR               524288
+#define SEQ_ACTIVE                            1048576
 
 #define SEQ_COLOR_BALANCE_INVERSE_GAIN 1
 #define SEQ_COLOR_BALANCE_INVERSE_GAMMA 2
index bdceb134c0d15acb4360378180343ba08965583d..9396410f850ec2db7a7e8cca018163668f98db56 100644 (file)
@@ -54,7 +54,6 @@ static bNodeSocketType sh_node_material_ext_in[]= {
        {       SOCK_VALUE, 1, "Refl",          0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
        {       SOCK_VECTOR, 1, "Normal",       0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
        {       SOCK_RGBA, 1, "Mirror",         0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
-       {       SOCK_RGBA, 1, "AmbCol",         0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
        {       SOCK_VALUE, 1, "Ambient",       0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
        {       SOCK_VALUE, 1, "Emit",          0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
        {       SOCK_VALUE, 1, "SpecTra",       0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
@@ -117,8 +116,6 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in,
                if (node->type == SH_NODE_MATERIAL_EXT) {
                        if(in[MAT_IN_MIR]->hasinput)
                                nodestack_get_vec(&shi->mirr, SOCK_VECTOR, in[MAT_IN_MIR]);
-                       if(in[MAT_IN_AMBCOL]->hasinput)
-                               nodestack_get_vec(&shi->ambr, SOCK_VECTOR, in[MAT_IN_AMBCOL]);
                        if(in[MAT_IN_AMB]->hasinput)
                                nodestack_get_vec(&shi->amb, SOCK_VALUE, in[MAT_IN_AMB]);
                        if(in[MAT_IN_EMIT]->hasinput)
index c9f58fbce492c6bfeb96f455c1a130b278df0ecb..f673834d2b77280fa83bc34f89660aa8b08d417a 100644 (file)
@@ -164,7 +164,7 @@ void nodeShaderSynchronizeID(bNode *node, int copyto)
                                                case MAT_IN_MIR:
                                                        VECCOPY(&ma->mirr, sock->ns.vec); break;
                                                case MAT_IN_AMB:
-                                                       VECCOPY(&ma->ambr, sock->ns.vec); break;
+                                                       ma->amb= sock->ns.vec[0]; break;
                                                case MAT_IN_EMIT:
                                                        ma->emit= sock->ns.vec[0]; break;
                                                case MAT_IN_SPECTRA:
@@ -188,7 +188,7 @@ void nodeShaderSynchronizeID(bNode *node, int copyto)
                                                case MAT_IN_MIR:
                                                        VECCOPY(sock->ns.vec, &ma->mirr); break;
                                                case MAT_IN_AMB:
-                                                       VECCOPY(sock->ns.vec, &ma->ambr); break;
+                                                       sock->ns.vec[0]= ma->amb; break;
                                                case MAT_IN_EMIT:
                                                        sock->ns.vec[0]= ma->emit; break;
                                                case MAT_IN_SPECTRA:
index f75802b7c15759e10ca4fbcd39c0ac68e8e420d9..bdb2bb3707dbbd04169649a6bb18fabdd078d12a 100644 (file)
@@ -117,13 +117,12 @@ typedef struct ShaderCallData {
 #define MAT_IN_REFL            2
 #define MAT_IN_NORMAL  3
 #define MAT_IN_MIR             4
-#define MAT_IN_AMBCOL  5
-#define MAT_IN_AMB             6
-#define MAT_IN_EMIT    7
-#define MAT_IN_SPECTRA 8
-#define MAT_IN_RAY_MIRROR      9
-#define MAT_IN_ALPHA   10
-#define MAT_IN_TRANSLUCENCY    11
+#define MAT_IN_AMB             5
+#define MAT_IN_EMIT    6
+#define MAT_IN_SPECTRA 7
+#define MAT_IN_RAY_MIRROR      8
+#define MAT_IN_ALPHA   9
+#define MAT_IN_TRANSLUCENCY    10
 
 /* output socket defines */
 #define MAT_OUT_COLOR          0
index 226657655fabb06ab053fe3044518b9193c35e3b..7120e97a62f44d1e1b958ea178c67b2821df515f 100644 (file)
@@ -410,12 +410,14 @@ void BPY_rebuild_syspath( void )
        mod = PyImport_ImportModule( "sys" );   
        if (!mod) {
                printf("error: could not import python sys module. some modules may not import.\n");
+               PyGILState_Release(gilstate);
                return;
        }
        
        if (!bpy_orig_syspath_List) { /* should never happen */
                printf("error refershing python path\n");
                Py_DECREF(mod);
+               PyGILState_Release(gilstate);
                return;
        }
        
index e9dff0987738138bbbc088583ecce5e050a03a97..0db87c00dd24c1709544c02f96e1af5bbd09c212 100644 (file)
@@ -1469,6 +1469,8 @@ PyObject *Armature_Init(void)
                PyConstant_NewInt("BONE_SELECTED", BONE_SELECTED));
        PyModule_AddObject(module, "TIP_SELECTED", 
                PyConstant_NewInt("TIP_SELECTED", BONE_TIPSEL));
+       PyModule_AddObject(module, "LOCKED_EDIT", 
+               PyConstant_NewInt("LOCKED_EDIT", BONE_EDITMODE_LOCKED));
 
        PyModule_AddObject(module, "OCTAHEDRON", 
                PyConstant_NewInt("OCTAHEDRON", ARM_OCTA));
index 84faf416c5f726304138f48f9ea50472272518f7..948eb007803d25bb3e07ac249fe98d04f5f2ab74 100644 (file)
@@ -368,6 +368,10 @@ static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure)
                        if (PyList_Append(list, 
                                EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
                                goto RuntimeError;
+               if(self->editbone->flag & BONE_EDITMODE_LOCKED)
+                       if (PyList_Append(list, 
+                               EXPP_GetModuleConstant("Blender.Armature", "LOCKED_EDIT")) == -1)
+                               goto RuntimeError;
        }else{
                if(self->flag & BONE_CONNECTED)
                        if (PyList_Append(list, 
@@ -401,6 +405,10 @@ static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure)
                        if (PyList_Append(list, 
                                EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
                                goto RuntimeError;
+               if(self->flag & BONE_EDITMODE_LOCKED)
+                       if (PyList_Append(list, 
+                               EXPP_GetModuleConstant("Blender.Armature", "LOCKED_EDIT")) == -1)
+                               goto RuntimeError;
        }
 
        return list;
@@ -422,7 +430,7 @@ static int EditBone_CheckValidConstant(PyObject *constant)
                                return 0;
                        if (!STREQ3(PyString_AsString(name), "CONNECTED", "HINGE", "NO_DEFORM") &&
                                !STREQ3(PyString_AsString(name), "ROOT_SELECTED", "BONE_SELECTED", "TIP_SELECTED")      &&
-                               !STREQ2(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT"))
+                               !STREQ3(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT", "LOCKED_EDIT"))
                                return 0;
                        else
                                return 1;
index f60ebf8dee1991addbe82a1364b61edb7547ed93..4a51619aec417bbb45fed56aa52c3811ae094ebe 100644 (file)
@@ -60,6 +60,8 @@ PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop )
                        return PyInt_FromLong( (long)prop->data.val );
                case IDP_FLOAT:
                        return PyFloat_FromDouble( (double)(*(float*)(&prop->data.val)) );
+               case IDP_DOUBLE:
+                       return PyFloat_FromDouble( (*(double*)(&prop->data.val)) );
                case IDP_GROUP:
                        /*blegh*/
                        {
@@ -128,7 +130,19 @@ int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject *value)
                        Py_XDECREF(value);
                        break;
                }
-
+               case IDP_DOUBLE:
+               {
+                       double dvalue;
+                       if (!PyNumber_Check(value))
+                               return EXPP_ReturnIntError(PyExc_TypeError, "expected a float!");
+                       value = PyNumber_Float(value);
+                       if (!value)
+                               return EXPP_ReturnIntError(PyExc_TypeError, "expected a float!");
+                       dvalue = (float) PyFloat_AsDouble(value);
+                       *(double*)&self->prop->data.val = dvalue;
+                       Py_XDECREF(value);
+                       break;
+               }
                default:
                        return EXPP_ReturnIntError(PyExc_AttributeError, "attempt to set read-only attribute!");
        }
@@ -204,8 +218,8 @@ char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObje
        IDPropertyTemplate val = {0};
        
        if (PyFloat_Check(ob)) {
-               val.f = (float) PyFloat_AsDouble(ob);
-               prop = IDP_New(IDP_FLOAT, val, name);
+               val.d = PyFloat_AsDouble(ob);
+               prop = IDP_New(IDP_DOUBLE, val, name);
        } else if (PyInt_Check(ob)) {
                val.i = (int) PyInt_AsLong(ob);
                prop = IDP_New(IDP_INT, val, name);
@@ -223,7 +237,7 @@ char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObje
                val.array.len = PySequence_Length(ob);
                for (i=0; i<val.array.len; i++) {
                        item = PySequence_GetItem(ob, i);
-                       if (PyFloat_Check(item)) val.array.type = IDP_FLOAT;
+                       if (PyFloat_Check(item)) val.array.type = IDP_DOUBLE;
                        else if (!PyInt_Check(item)) return "only floats and ints are allowed in ID property arrays";
                        Py_XDECREF(item);
                }
@@ -236,7 +250,7 @@ char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObje
                                ((int*)prop->data.pointer)[i] = (int)PyInt_AsLong(item);
                        } else {
                                item = PyNumber_Float(item);
-                               ((float*)prop->data.pointer)[i] = (float)PyFloat_AsDouble(item);
+                               ((double*)prop->data.pointer)[i] = (float)PyFloat_AsDouble(item);
                        }
                        Py_XDECREF(item);
                }
@@ -334,6 +348,9 @@ PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
                case IDP_FLOAT:
                        return PyFloat_FromDouble(*((float*)&prop->data.val));
                        break;
+               case IDP_DOUBLE:
+                       return PyFloat_FromDouble(*((double*)&prop->data.val));
+                       break;
                case IDP_INT:
                        return PyInt_FromLong( (long)prop->data.val );
                        break;
@@ -347,12 +364,15 @@ PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
                                           "PyList_New() failed" );
                        
                        for (i=0; i<prop->len; i++) {
-                               if (prop->subtype == IDP_FLOAT)
+                               if (prop->subtype == IDP_FLOAT) {
                                                PyList_SetItem(seq, i,
                                                PyFloat_FromDouble(((float*)prop->data.pointer)[i]));
-                               
-                               else    PyList_SetItem(seq, i,
-                                               PyInt_FromLong(((int*)prop->data.pointer)[i]));
+                               } else if (prop->subtype == IDP_DOUBLE) {
+                                               PyList_SetItem(seq, i,
+                                               PyFloat_FromDouble(((double*)prop->data.pointer)[i]));                          
+                               } else  { PyList_SetItem(seq, i,
+                                                 PyInt_FromLong(((int*)prop->data.pointer)[i]));
+                               }
                        }
                        return seq;
                }
@@ -451,7 +471,7 @@ PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self)
                /*set correct group length*/
                self->prop->len = i;
                
-               /*free the old list*/
+               /*free the list*/
                Py_DECREF(seq);
                
                /*call self again*/
@@ -688,6 +708,9 @@ PyObject *BPy_IDArray_GetItem(BPy_IDArray *self, int index)
                case IDP_FLOAT:
                        return PyFloat_FromDouble( (double)(((float*)self->prop->data.pointer)[index]));
                        break;
+               case IDP_DOUBLE:
+                       return PyFloat_FromDouble( (((double*)self->prop->data.pointer)[index]));
+                       break;          
                case IDP_INT:
                        return PyInt_FromLong( (long)((int*)self->prop->data.pointer)[index] );
                        break;
@@ -700,7 +723,8 @@ int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *val)
 {
        int i;
        float f;
-
+       double d;
+       
        if (index < 0 || index >= self->prop->len)
                return EXPP_ReturnIntError( PyExc_RuntimeError,
                                "index out of range!");
@@ -717,6 +741,17 @@ int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *val)
                        ((float*)self->prop->data.pointer)[index] = f;
                        Py_XDECREF(val);
                        break;
+               case IDP_DOUBLE:
+                       if (!PyNumber_Check(val)) return EXPP_ReturnIntError( PyExc_TypeError,
+                               "expected a float");
+                       val = PyNumber_Float(val);
+                       if (!val) return EXPP_ReturnIntError( PyExc_TypeError,
+                               "expected a float");
+
+                       d = (double) PyFloat_AsDouble(val);
+                       ((double*)self->prop->data.pointer)[index] = d;
+                       Py_XDECREF(val);
+                       break;
                case IDP_INT:
                        if (!PyNumber_Check(val)) return EXPP_ReturnIntError( PyExc_TypeError,
                                "expected an int");
index 68916af6166e16c944e96abeca49259027b5844d..9aceb0105e36c86adba576d637a0f80687719692 100644 (file)
@@ -89,6 +89,8 @@ Example::
 @type BONE_SELECTED: Constant
 @var TIP_SELECTED: Tip of the Bone is selected
 @type TIP_SELECTED: Constant
+@var LOCKED_EDIT: Prevents the bone from being transformed in editmode
+@type LOCKED_EDIT: Constant
 @var OCTAHEDRON: Bones drawn as octahedrons
 @type OCTAHEDRON: Constant
 @var STICK: Bones drawn as a line
@@ -286,6 +288,7 @@ class Bone:
                         - Armature.ROOT_SELECTED: Selection of root ball of bone
                         - Armature.BONE_SELECTED: Selection of bone
                         - Armature.TIP_SELECTED: Selection of tip ball of bone
+                        - Armature.LOCKED_EDIT: Prevents the bone from being transformed in editmode
        @type options: List of Constants
        @ivar subdivision: The number of bone subdivisions.
        @type subdivision: Int
index 0a0df335fa3e76f6c68935a0a1cd5976b332cad9..01d5136cd70bd921c0305fc051cb94df111d5529 100644 (file)
@@ -18,7 +18,9 @@ class IDGroup:
        
        Note that for arrays, the array type defaults to int unless a float is found
        while scanning the template list; if any floats are found, then the whole
-       array is float.
+       array is float.  Note that double-precision floating point numbers are used for
+       python-created float ID properties and arrays (though the internal C api does 
+       support single-precision floats, and the python code will read them).
        
        You can also delete properties with the del operator.  For example:
        
index c479926ccf3a915713d9513642a6d8a763cadc99..d1c72f8cb86cfb06c5751336546463e0011a9426 100644 (file)
@@ -250,7 +250,7 @@ class Ipo:
                        OfsZ, SizeX, SizeY, SizeZ, texR, texG, texB, DefVar, Col, Nor, Var,
                        Disp.
                        3. Object Ipo: LocX, LocY, LocZ, dLocX, dLocY, dLocZ, RotX, RotY, RotZ,
-                       dRotX, dRotY, dRotZ, SizeX, SizeY, SizeZ, dSizeX, dSizeY, dSizeZ,
+                       dRotX, dRotY, dRotZ, ScaleX, ScaleY, ScaleZ, dScaleX, dScaleY, dScaleZ,
                        Layer, Time, ColR, ColG, ColB, ColA, FStreng, FFall, Damping,
                        RDamp, Perm.
                        4. Lamp Ipo: Energ, R, G, B, Dist, SpoSi, SpoBl, Quad1, Quad2, HaInt.
@@ -289,7 +289,7 @@ class Ipo:
                        OfsZ, SizeX, SizeY, SizeZ, texR, texG, texB, DefVar, Col, Nor, Var,
                        Disp.
                        3. Object Ipo: LocX, LocY, LocZ, dLocX, dLocY, dLocZ, RotX, RotY, RotZ,
-                       dRotX, dRotY, dRotZ, SizeX, SizeY, SizeZ, dSizeX, dSizeY, dSizeZ,
+                       dRotX, dRotY, dRotZ, ScaleX, ScaleY, ScaleZ, dScaleX, dScaleY, dScaleZ,
                        Layer, Time, ColR, ColG, ColB, ColA, FStreng, FFall, Damping,
                        RDamp, Perm.
                        4. Lamp Ipo: Energ, R, G, B, Dist, SpoSi, SpoBl, Quad1, Quad2, HaInt.
index d382d4509703321dd5ce1e039c57c09dd1671224..22e165cbe9fc96b31bb3d909bd6f738d73d99ecc 100644 (file)
@@ -56,6 +56,7 @@ struct View3D; /* keep me up here */
 #include "gen_utils.h"
 #include "gen_library.h"
 
+#include "../BPY_extern.h" /* for BPY_do_all_scripts() */
 #include "Scene.h"
 #include "Group.h"
 
@@ -469,19 +470,20 @@ PyObject *M_Render_EnableDispWin( PyObject * self )
 PyObject *RenderData_Render( BPy_RenderData * self )
 {
        Scene *oldsce;
+       /* unlock to prevent a deadlock when there are pynodes: */
+       PyThreadState *tstate = NULL;
 
        if (!G.background) {
                oldsce = G.scene;
                set_scene( self->scene );
+               tstate = PyEval_SaveThread();
                BIF_do_render( 0 );
                set_scene( oldsce );
        }
-
        else { /* background mode (blender -b file.blend -P script) */
+               int slink_flag = 0;
                Render *re= RE_NewRender(G.scene->id.name);
 
-
-
                int end_frame = G.scene->r.efra;
 
                if (G.scene != self->scene)
@@ -490,11 +492,25 @@ PyObject *RenderData_Render( BPy_RenderData * self )
 
                G.scene->r.efra = G.scene->r.sfra;
 
+               if (G.f & G_DOSCRIPTLINKS) {
+                       BPY_do_all_scripts(SCRIPT_RENDER);
+                       G.f &= ~G_DOSCRIPTLINKS; /* avoid FRAMECHANGED events*/
+                       slink_flag = 1;
+               }
+
+               tstate = PyEval_SaveThread();
+
                RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra);
 
+               if (slink_flag) {
+                       G.f |= G_DOSCRIPTLINKS;
+                       BPY_do_all_scripts(SCRIPT_POSTRENDER);
+               }
+
                G.scene->r.efra = end_frame;
        }
 
+       PyEval_RestoreThread(tstate);
        Py_RETURN_NONE;
 }
 
@@ -565,10 +581,13 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args )
 PyObject *RenderData_RenderAnim( BPy_RenderData * self )
 {
        Scene *oldsce;
-
+       /* unlock to prevent a deadlock when there are pynodes: */
+       PyThreadState *tstate = NULL;
+               
        if (!G.background) {
                oldsce = G.scene;
                set_scene( self->scene );
+               tstate = PyEval_SaveThread();
                BIF_do_render( 1 );
                set_scene( oldsce );
        }
@@ -582,9 +601,18 @@ PyObject *RenderData_RenderAnim( BPy_RenderData * self )
                if (G.scene->r.sfra > G.scene->r.efra)
                        return EXPP_ReturnPyObjError (PyExc_RuntimeError,
                                "start frame must be less or equal to end frame");
-               
+
+               if (G.f & G_DOSCRIPTLINKS)
+                       BPY_do_all_scripts(SCRIPT_RENDER);
+
+               tstate = PyEval_SaveThread();
                RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra);
+
+               if (G.f & G_DOSCRIPTLINKS)
+                       BPY_do_all_scripts(SCRIPT_POSTRENDER);
        }
+
+       PyEval_RestoreThread(tstate);
        Py_RETURN_NONE;
 }
 
index 252350ea72b99689b8777d3b5a2ae8704aec10dd..31f4596c2640b90189a536a61070fdd8b7c49283 100644 (file)
@@ -2013,7 +2013,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
                        uiBlockBeginAlign(block);
                        uiDefButF(block, NUM, B_MODIFIER_RECALC, "Width: ",
                                          lx, (cy -= 19), buttonWidth, 19, &bmd->value,
-                                         0.0, 0.5, 5, 2,
+                                         0.0, 0.5, 5, 4,
                                          "Bevel value/amount");
                        /*uiDefButI(block, NUM, B_MODIFIER_RECALC, "Recurs",
                                          lx, (cy -= 19), buttonWidth, 19, &bmd->res,
@@ -4518,11 +4518,12 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm)
                        uiDefButF(block, NUM,B_ARM_RECALCDATA, "Weight:", 225, by-19,105, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight");
                        
                        /* bone types */
-                       uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge",         -10,by-38,80,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
-                       uiDefButBitI(block, TOG, BONE_NO_SCALE, B_ARM_RECALCDATA, "S",          70,by-38,20,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit scale from parent Bone");
-                       uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform",   90, by-38, 80, 18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry");
-                       uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 170,by-38,80,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup");
-                       uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide",   250,by-38,80,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode");
+                       uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge",         -10,by-38,60,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
+                       uiDefButBitI(block, TOG, BONE_NO_SCALE, B_ARM_RECALCDATA, "S",          50,by-38,20,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit scale from parent Bone");
+                       uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform",   70, by-38, 80, 18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry");
+                       uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 150,by-38,60,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup");
+                       uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide",   210,by-38,60,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode");
+                       uiDefButBitI(block, TOG, BONE_EDITMODE_LOCKED, REDRAWVIEW3D, "Lock",    270,by-38,60,18, &curBone->flag, 0, 0, 0, 0, "Prevents this bone from being transformed in Edit Mode");
                        
                        /* layers */
                        uiBlockBeginAlign(block);
@@ -6335,6 +6336,7 @@ static void editing_panel_mesh_texface(void)
                uiDefButBitS(block, TOG, TF_BILLBOARD2, B_TFACE_BILLB, "Billboard",660,110,60,19, &tf->mode, 0, 0, 0, 0, "Billboard with Z-axis constraint");
                uiDefButBitS(block, TOG, TF_SHADOW, REDRAWVIEW3D, "Shadow", 720,110,60,19, &tf->mode, 0, 0, 0, 0, "Face is used for shadow");
                uiDefButBitS(block, TOG, TF_BMFONT, REDRAWVIEW3D, "Text", 780,110,60,19, &tf->mode, 0, 0, 0, 0, "Enable bitmap text on face");
+               uiDefButBitS(block, TOG, TF_ALPHASORT, REDRAWVIEW3D, "Sort", 840,110,60,19, &tf->mode, 0, 0, 0, 0, "Enable sorting of faces for correct alpha drawing (slow, use Clip Alpha instead when possible)");
 
                uiBlockBeginAlign(block);
                uiBlockSetCol(block, TH_BUT_SETTING1);
index 441d00ffc30cc9d173a833ec50eb8d63c253a9b3..5cf1958678e5ad99cb6c22efebac2c517becf380 100644 (file)
@@ -1654,53 +1654,66 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
                        wval = (width-100)/3;
                        if (oa->type == ACT_OBJECT_NORMAL)
                        {
-                               ysize= 175;
-                               
+                               if ( ob->gameflag & OB_DYNAMIC )
+                               {
+                                       ysize= 175;
+                               }
+                               else
+                               {
+                                       ysize= 72;
+                               }
+
                                glRects(xco, yco-ysize, xco+width, yco);
                                uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
                                
-                               uiDefBut(block, LABEL, 0, "Force",      xco, yco-45, 55, 19, NULL, 0, 0, 0, 0, "Sets the force");
-                               uiDefButF(block, NUM, 0, "",            xco+45, yco-45, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, "");
-                               uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-45, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, "");
-                               uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-45, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, "");
-                               
-                               uiDefBut(block, LABEL, 0, "Torque", xco, yco-64, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
-                               uiDefButF(block, NUM, 0, "",            xco+45, yco-64, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
-                               uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-64, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
-                               uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-64, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");
+                               uiDefBut(block, LABEL, 0, "Loc",        xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, "Sets the location");
+                               uiDefButF(block, NUM, 0, "",            xco+45, yco-45, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
+                               uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-45, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
+                               uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-45, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
                                
-                               uiDefBut(block, LABEL, 0, "dLoc",       xco, yco-87, 45, 19, NULL, 0, 0, 0, 0, "Sets the dLoc");
-                               uiDefButF(block, NUM, 0, "",            xco+45, yco-87, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
-                               uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-87, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
-                               uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-87, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
-                               
-                               uiDefBut(block, LABEL, 0, "dRot",       xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Sets the dRot");
-                               uiDefButF(block, NUM, 0, "",            xco+45, yco-106, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
-                               uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-106, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
-                               uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-106, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
+                               uiDefBut(block, LABEL, 0, "Rot",        xco, yco-64, 45, 19, NULL, 0, 0, 0, 0, "Sets the rotation");
+                               uiDefButF(block, NUM, 0, "",            xco+45, yco-64, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
+                               uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-64, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
+                               uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-64, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
+
+                               uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L",                xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+                               uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L",                xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+       
+                               if ( ob->gameflag & OB_DYNAMIC )
+                               {
+                                       uiDefBut(block, LABEL, 0, "Force",      xco, yco-87, 55, 19, NULL, 0, 0, 0, 0, "Sets the force");
+                                       uiDefButF(block, NUM, 0, "",            xco+45, yco-87, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, "");
+                                       uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-87, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, "");
+                                       uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-87, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, "");
                                
-                               uiDefBut(block, LABEL, 0, "linV",       xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity");
-                               uiDefButF(block, NUM, 0, "",            xco+45, yco-129, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
-                               uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
-                               uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
+                                       uiDefBut(block, LABEL, 0, "Torque", xco, yco-106, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
+                                       uiDefButF(block, NUM, 0, "",            xco+45, yco-106, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
+                                       uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-106, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
+                                       uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-6106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");                               
+                               }
                                
-                               uiDefBut(block, LABEL, 0, "angV",       xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity");
-                               uiDefButF(block, NUM, 0, "",            xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, "");
-                               uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, "");
-                               uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, "");
+                               if ( ob->gameflag & OB_DYNAMIC )
+                               {
+                                       uiDefBut(block, LABEL, 0, "LinV",       xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity");
+                                       uiDefButF(block, NUM, 0, "",            xco+45, yco-129, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
+                                       uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
+                                       uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
                                
-                               uiDefBut(block, LABEL, 0, "damp",       xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity");
-                               uiDefButS(block, NUM, 0, "",            xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, "");
-
-                               uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L",               xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
-                               uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L",              xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
-                               uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L",                xco+45+3*wval, yco-87, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
-                               uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L",                xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
-                               uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L",             xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
-                               uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L",             xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+                                       uiDefBut(block, LABEL, 0, "AngV",       xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity");
+                                       uiDefButF(block, NUM, 0, "",            xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, "");
+                                       uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, "");
+                                       uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, "");
                                
-                               uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV");
+                                       uiDefBut(block, LABEL, 0, "Damp",       xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity");
+                                       uiDefButS(block, NUM, 0, "",            xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, "");
+
+                                       uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L",               xco+45+3*wval, yco-87, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+                                       uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L",              xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+                                       uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L",             xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+                                       uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L",             xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
                                
+                                       uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV");
+                               }                               
                        } else if (oa->type == ACT_OBJECT_SERVO)
                        {
                                ysize= 172;
@@ -2062,7 +2075,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
                        coa->time = 0;
                        uiDefButS(block, MENU, 1, str,          xco+10, yco-65, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, "");
                
-                       uiDefButS(block, NUM,           0, "Damp:",     xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "");
+                       uiDefButS(block, NUM,           0, "damp",      xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter");
                        uiDefBut(block, LABEL,                  0, "Min",       xco+80, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
                        uiDefBut(block, LABEL,                  0, "Max",       xco+80+(width-90)/2, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
 
@@ -2084,12 +2097,12 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
                        str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32";
                        uiDefButS(block, MENU, B_REDR, str,             xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray");
                
-                       uiDefButS(block, NUM,           0, "Damp:",     xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "");
+                       uiDefButS(block, NUM,           0, "damp",      xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter");
                        uiDefBut(block, LABEL,                  0, "Range",     xco+80, yco-45, (width-115)/2, 19, NULL, 0.0, 0.0, 0, 0, "Set the maximum length of ray");
                        uiDefButBitS(block, TOG, ACT_CONST_DISTANCE, B_REDR, "Dist",    xco+80+(width-115)/2, yco-45, (width-115)/2, 19, &coa->flag, 0.0, 0.0, 0, 0, "Force distance of object to point of impact of ray");
 
-                       if(coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRMX)) fp= coa->minloc;
-                       else if(coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRMY)) fp= coa->minloc+1;
+                       if(coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc;
+                       else if(coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1;
                        else fp= coa->minloc+2;
 
                        uiDefButF(block, NUM, 0, "",            xco+80, yco-65, (width-115)/2, 19, fp+3, 0.0, 2000.0, 10, 0, "Maximum length of ray");
@@ -2124,7 +2137,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
                        str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4";
                        uiDefButS(block, MENU, B_REDR, str,             xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Select the axis to be aligned along the reference direction");
                
-                       uiDefButS(block, NUM,           0, "Damp:",     xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "");
+                       uiDefButS(block, NUM,           0, "damp",      xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter");
                        uiDefBut(block, LABEL,                  0, "X", xco+80, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
                        uiDefBut(block, LABEL,                  0, "Y", xco+80+(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
                        uiDefBut(block, LABEL,                  0, "Z", xco+80+2*(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
@@ -2133,7 +2146,9 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
                        uiDefButF(block, NUM, 0, "",            xco+80+(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[1], -2000.0, 2000.0, 10, 0, "Y component of reference direction");
                        uiDefButF(block, NUM, 0, "",            xco+80+2*(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[2], -2000.0, 2000.0, 10, 0, "Z component of reference direction");
 
-                       uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 70+(width-115)/3, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited");
+                       uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 70, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited");
+                       uiDefButF(block, NUM, 0, "min", xco+80, yco-84, (width-115)/2, 19, &(coa->minloc[0]), 0.0, 180.0, 10, 1, "Minimum angle (in degree) to maintain with target direction. No correction is done if angle with target direction is between min and max");
+                       uiDefButF(block, NUM, 0, "max", xco+80+(width-115)/2, yco-84, (width-115)/2, 19, &(coa->maxloc[0]), 0.0, 180.0, 10, 1, "Maximum angle (in degree) allowed with target direction. No correction is done if angle with target direction is between min and max");
                }
                str= "Constraint Type %t|Location %x0|Distance %x1|Orientation %x2";
                but = uiDefButS(block, MENU, B_REDR, str,               xco+40, yco-23, (width-80), 19, &coa->type, 0.0, 0.0, 0, 0, "");
index ebe770c89e77de2cc8c1546d8c00a7d2e61becdd..c2643aa479b9437e2e53b7ada0f855bdf6b6fc42 100644 (file)
@@ -480,7 +480,7 @@ static void draw_constraint_spaceselect (uiBlock *block, bConstraint *con, short
        
        /* Target-Space */
        if (target == 1) {
-               uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1", 
+               uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Pose Space %x2|Local with Parent %x3|Local Space %x1", 
                                                                                                tarx, yco, bwidth, 18, &con->tarspace, 0, 0, 0, 0, "Choose space that target is evaluated in"); 
        }
        else if (target == 0) {
@@ -490,7 +490,7 @@ static void draw_constraint_spaceselect (uiBlock *block, bConstraint *con, short
        
        /* Owner-Space */
        if (owner == 1) {
-               uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Owner Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1", 
+               uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Owner Space %t|World Space %x0|Pose Space %x2|Local with Parent %x3|Local Space %x1", 
                                                                                                ownx, yco, bwidth, 18, &con->ownspace, 0, 0, 0, 0, "Choose space that owner is evaluated in");  
        }
        else if (owner == 0) {
@@ -1739,6 +1739,16 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
                        }
                        break;
+
+               case CONSTRAINT_TYPE_SHRINKWRAP:
+                       {
+                               bShrinkwrapConstraint *data = con->data;
+
+                               height = 44;
+                               uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->target, "Target Object");
+                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "dist", *xco+120, *yco-44, 135, 18, &data->dist, 0.0f, 100.0f, 1.0f, 0.0f, "Distance to target"); 
+                       }
+                       break;
                default:
                        height = 0;
                        break;
@@ -1800,6 +1810,7 @@ static uiBlock *add_constraintmenu(void *arg_unused)
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_MINMAX, "Floor", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCKTRACK, "Locked Track", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_FOLLOWPATH, "Follow Path", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+       uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SHRINKWRAP, "Shrinkwrap" , 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
                
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
        
@@ -2035,6 +2046,14 @@ void do_constraintbuts(unsigned short event)
                        BIF_undo_push("Add constraint");
                }
                break;
+       case B_CONSTRAINT_ADD_SHRINKWRAP:
+               {
+                       con = add_new_constraint(CONSTRAINT_TYPE_SHRINKWRAP);
+                       add_constraint_to_active(ob, con);
+                       
+                       BIF_undo_push("Add constraint");
+               }
+               break;
 
        default:
                break;
index 9b1af3f1a065b7eb588a01ed07d4693435528c3a..0782ccfc7ee1ab0fdf000637c9519d6bc043deee 100644 (file)
@@ -89,6 +89,7 @@
 
 #include "BSE_drawnla.h"
 #include "BSE_drawipo.h"
+#include "BSE_drawview.h"
 #include "BSE_editaction_types.h"
 #include "BSE_editipo.h"
 #include "BSE_time.h"
@@ -467,7 +468,7 @@ static void draw_channel_names(void)
                        bActionGroup *grp = NULL;
                        short indent= 0, offset= 0, sel= 0, group=0;
                        int expand= -1, protect = -1, special= -1, mute = -1;
-                       char name[32];
+                       char name[64];
                        
                        /* determine what needs to be drawn */
                        switch (ale->type) {
@@ -625,6 +626,72 @@ static void draw_channel_names(void)
                                        sprintf(name, "Constraint");
                                }
                                        break;
+                               case ACTTYPE_GPDATABLOCK: /* gpencil datablock */
+                               {
+                                       bGPdata *gpd = (bGPdata *)ale->data;
+                                       ScrArea *sa = (ScrArea *)ale->owner;
+                                       
+                                       indent = 0;
+                                       group= 3;
+                                       
+                                       /* only show expand if there are any channels */
+                                       if (gpd->layers.first) {
+                                               if (gpd->flag & GP_DATA_EXPAND)
+                                                       expand = ICON_TRIA_DOWN;
+                                               else
+                                                       expand = ICON_TRIA_RIGHT;
+                                       }
+                                       
+                                       switch (sa->spacetype) {
+                                               case SPACE_VIEW3D:
+                                               {
+                                                       /* this shouldn't cause any overflow... */
+                                                       sprintf(name, "3DView: %s", view3d_get_name(sa->spacedata.first));
+                                                       special= ICON_VIEW3D;
+                                               }
+                                                       break;
+                                               case SPACE_NODE:
+                                               {
+                                                       SpaceNode *snode= sa->spacedata.first;
+                                                       char treetype[12];
+                                                       
+                                                       if (snode->treetype == 1)
+                                                               sprintf(treetype, "Composite");
+                                                       else
+                                                               sprintf(treetype, "Material");
+                                                       sprintf(name, "Nodes: %s", treetype);
+                                                       
+                                                       special= ICON_NODE;
+                                               }
+                                                       break;
+                                               case SPACE_SEQ:
+                                               {
+                                                       SpaceSeq *sseq= sa->spacedata.first;
+                                                       char imgpreview[10];
+                                                       
+                                                       switch (sseq->mainb) {
+                                                               case 1:         sprintf(imgpreview, "Image...");        break;
+                                                               case 2:         sprintf(imgpreview, "Luma...");         break;
+                                                               case 3:         sprintf(imgpreview, "Chroma...");       break;
+                                                               case 4:         sprintf(imgpreview, "Histogram");       break;
+                                                               
+                                                               default:        sprintf(imgpreview, "Sequence");        break;
+                                                       }
+                                                       sprintf(name, "Sequencer: %s", imgpreview);
+                                                       
+                                                       special= ICON_SEQUENCE;
+                                               }
+                                                       break;
+                                               
+                                               default:
+                                               {
+                                                       sprintf(name, "<Unknown GP-Data Source>");
+                                                       special= -1;
+                                               }
+                                                       break;
+                                       }
+                               }
+                                       break;
                                case ACTTYPE_GPLAYER: /* gpencil layer */
                                {
                                        bGPDlayer *gpl = (bGPDlayer *)ale->data;
@@ -632,7 +699,8 @@ static void draw_channel_names(void)
                                        indent = 0;
                                        special = -1;
                                        expand = -1;
-                                               
+                                       group = 1;
+                                       
                                        if (EDITABLE_GPL(gpl))
                                                protect = ICON_UNLOCKED;
                                        else
@@ -651,8 +719,19 @@ static void draw_channel_names(void)
 
                        /* now, start drawing based on this information */
                        /* draw backing strip behind channel name */
-                       if (group == 2) {
-                               /* only for group-channels */
+                       if (group == 3) {
+                               /* only for gp-data channels */
+                               if (ale->owner == curarea) // fixme... currently useless
+                                       BIF_ThemeColorShade(TH_GROUP_ACTIVE, 10);
+                               else
+                                       BIF_ThemeColorShade(TH_GROUP, 20);
+                               uiSetRoundBox((expand == ICON_TRIA_DOWN)? (1):(1|8));
+                               gl_round_box(GL_POLYGON, x,  yminc, (float)NAMEWIDTH, ymaxc, 8);
+                               
+                               offset = 0;
+                       }
+                       else if (group == 2) {
+                               /* only for action group channels */
                                if (ale->flag & AGRP_ACTIVE)
                                        BIF_ThemeColorShade(TH_GROUP_ACTIVE, 10);
                                else
@@ -698,13 +777,19 @@ static void draw_channel_names(void)
                                offset += 17;
                        }
                        
-                       /* draw special icon indicating type of ipo-blocktype? 
-                        *      only for expand widgets for Ipo and Constraint Channels 
-                        */
-                       if (special > 0) {
-                               offset = (group) ? 29 : 24;
-                               BIF_icon_draw(x+offset, yminc, special);
-                               offset += 17;
+                       /* draw special icon indicating certain data-types */
+                       if (special > -1) {
+                               if (group == 3) {
+                                       /* for gpdatablock channels */
+                                       BIF_icon_draw(x+offset, yminc, special);
+                                       offset += 17;
+                               }
+                               else {
+                                       /* for ipo/constraint channels */
+                                       offset = (group) ? 29 : 24;
+                                       BIF_icon_draw(x+offset, yminc, special);
+                                       offset += 17;
+                               }
                        }
                                
                        /* draw name */
@@ -720,13 +805,13 @@ static void draw_channel_names(void)
                        offset = 0;
                        
                        /* draw protect 'lock' */
-                       if (protect > 0) {
+                       if (protect > -1) {
                                offset = 16;
                                BIF_icon_draw(NAMEWIDTH-offset, yminc, protect);
                        }
                        
                        /* draw mute 'eye' */
-                       if (mute > 0) {
+                       if (mute > -1) {
                                offset += 16;
                                BIF_icon_draw(NAMEWIDTH-offset, yminc, mute);
                        }
@@ -1148,12 +1233,6 @@ void drawactionspace(ScrArea *sa, void *spacedata)
                                        G.saction->action= NULL;
                        }
                                break;
-                       case SACTCONT_GPENCIL:
-                       {
-                               /* this searching could be slow (so users should pin after this is found) */
-                               G.saction->gpd= gpencil_data_getetime(G.curscreen);
-                       }
-                               break;
                }
        }
        
index 55d0464b9af1a47764d4ae7244044b395d68dc47..733310bfda7c61b74956ba1ea345660d4cf71380 100644 (file)
@@ -94,6 +94,7 @@
 void gp_ui_activelayer_cb (void *gpd, void *gpl)
 {
        gpencil_layer_setactive(gpd, gpl);
+       allqueue(REDRAWACTION, 0);
 }
 
 /* rename layer and set active */
@@ -104,18 +105,21 @@ void gp_ui_renamelayer_cb (void *gpd_arg, void *gpl_arg)
        
        BLI_uniquename(&gpd->layers, gpl, "GP_Layer", offsetof(bGPDlayer, info[0]), 128);
        gpencil_layer_setactive(gpd, gpl);
+       allqueue(REDRAWACTION, 0);
 }
 
 /* add a new layer */
 void gp_ui_addlayer_cb (void *gpd, void *dummy)
 {
        gpencil_layer_addnew(gpd);
+       allqueue(REDRAWACTION, 0);
 }
 
 /* delete active layer */
 void gp_ui_dellayer_cb (void *gpd, void *dummy)
 {
        gpencil_layer_delactive(gpd);
+       allqueue(REDRAWACTION, 0);
 }
 
 /* delete last stroke of active layer */
@@ -134,28 +138,17 @@ void gp_ui_delframe_cb (void *gpd, void *gpl)
        
        gpencil_layer_setactive(gpd, gpl);
        gpencil_layer_delframe(gpl, gpf);
-}
-
-
-/* set this set of gpencil data for editing in action editor */
-void gp_ui_dotime_cb (void *gpd_arg, void *dummy)
-{
-       bGPdata *gpd= (bGPdata *)gpd_arg;
        
-       /* check if setting or clearing (note: setting was just set...) */
-       if (gpd->flag & GP_DATA_EDITTIME)
-               gpencil_data_setetime(G.curscreen, gpd);
-       else    
-               gpencil_data_setetime(G.curscreen, NULL);
+       allqueue(REDRAWACTION, 0);
 }
 
-
 /* ------- Drawing Code ------- */
 
 /* draw the controls for a given layer */
 static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short *xco, short *yco)
 {
        uiBut *but;
+       short active= (gpl->flag & GP_LAYER_ACTIVE);
        short width= 314;
        short height;
        int rb_col;
@@ -168,40 +161,41 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
                uiBlockSetEmboss(block, UI_EMBOSSN);
                
                /* rounded header */
-               rb_col= (gpl->flag & GP_LAYER_ACTIVE)?50:20;
-               uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-2, width, 24, NULL, 5.0, 0.0, 15 , rb_col-20, ""); 
+               if (active) uiBlockSetCol(block, TH_BUT_ACTION);
+                       rb_col= (active)?-20:20;
+                       uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-2, width, 24, NULL, 5.0, 0.0, 15 , rb_col-20, ""); 
+               if (active) uiBlockSetCol(block, TH_AUTO);
                
                /* lock toggle */
                uiDefIconButBitI(block, ICONTOG, GP_LAYER_LOCKED, B_REDR, ICON_UNLOCKED,        *xco-7, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Layer cannot be modified");
        }
        
-       /* when layer is locked or hidden, don't draw the rest of its settings */
+       /* when layer is locked or hidden, only draw header */
        if (gpl->flag & (GP_LAYER_LOCKED|GP_LAYER_HIDE)) {
-               height= 26;
+               char name[256]; /* gpl->info is 128, but we need space for 'locked/hidden' as well */
                
-               /* draw rest of header */
-               {
-                       /* visibility button (only if hidden but not locked!) */
-                       if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED))
-                               uiDefIconButBitI(block, ICONTOG, GP_LAYER_HIDE, B_REDR, ICON_RESTRICT_VIEW_OFF, *xco+12, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Visibility of layer");
-                       
-                       /* name */
-                       uiDefBut(block, LABEL, 1, gpl->info,    *xco+35, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "Short description of what this layer is for (optional)");
-               }
+               height= 26;
                
-               /* draw backdrop */
-               uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
+               /* visibility button (only if hidden but not locked!) */
+               if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED))
+                       uiDefIconButBitI(block, ICONTOG, GP_LAYER_HIDE, B_REDR, ICON_RESTRICT_VIEW_OFF, *xco+12, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Visibility of layer");
                
-               /* draw settings... (i.e. just warning for this one) */
+               /* name */
                if (gpl->flag & GP_LAYER_HIDE)
-                       uiDefBut(block, LABEL, 1, "Grease Pencil Layer Hidden", *xco+60, *yco-26, 205, 20, NULL, 0.0, 0.0, 0, 0, "");
+                       sprintf(name, "%s (Hidden)", gpl->info);
                else
-                       uiDefBut(block, LABEL, 1, "Grease Pencil Layer Locked", *xco+60, *yco-26, 205, 20, NULL, 0.0, 0.0, 0, 0, "");
+                       sprintf(name, "%s (Locked)", gpl->info);
+               uiDefBut(block, LABEL, 1, name, *xco+35, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "Short description of what this layer is for (optional)");
                        
+               /* delete button (only if hidden but not locked!) */
+               if ((gpl->flag & GP_LAYER_HIDE) & !(gpl->flag & GP_LAYER_LOCKED)) {
+                       but= uiDefIconBut(block, BUT, B_REDR, ICON_X, *xco+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer");
+                       uiButSetFunc(but, gp_ui_dellayer_cb, gpd, NULL);
+               }       
                uiBlockSetEmboss(block, UI_EMBOSS);
        }
        else {
-               height= 100;
+               height= 97;
                
                /* draw rest of header */
                {
@@ -211,7 +205,7 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
                        uiBlockSetEmboss(block, UI_EMBOSS);
                        
                        /* name */
-                       but= uiDefButC(block, TEX, B_REDR, "Info:",     *xco+35, *yco, 240, 20, gpl->info, 0, 127, 0, 0, "Short description of what this layer is for (optional)");
+                       but= uiDefButC(block, TEX, B_REDR, "Info:",     *xco+36, *yco, 240, 19, gpl->info, 0, 127, 0, 0, "Short description of what this layer is for (optional)");
                        uiButSetFunc(but, gp_ui_renamelayer_cb, gpd, gpl);
                        
                        /* delete 'button' */
@@ -224,7 +218,9 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
                }
                
                /* draw backdrop */
-               uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
+               if (active) uiBlockSetCol(block, TH_BUT_ACTION);
+                       uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
+               if (active) uiBlockSetCol(block, TH_AUTO);
                
                /* draw settings */
                {
@@ -237,21 +233,25 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
                        /* stroke thickness */
                        uiDefButS(block, NUMSLI, B_REDR, "Thickness:",  *xco, *yco-75, 150, 20, &gpl->thickness, 1, 10, 0, 0, "Thickness of strokes (in pixels)");
                        
+                       /* debugging options */
+                       if (G.f & G_DEBUG) {
+                               uiDefButBitI(block, TOG, GP_LAYER_DRAWDEBUG, B_REDR, "Show Points", *xco, *yco-95, 150, 20, &gpl->flag, 0, 0, 0, 0, "Show points which form the strokes");
+                       }
                        
                        /* onion-skinning */
                        uiBlockBeginAlign(block);
                                uiDefButBitI(block, TOG, GP_LAYER_ONIONSKIN, B_REDR, "Onion-Skin", *xco+160, *yco-26, 140, 20, &gpl->flag, 0, 0, 0, 0, "Ghost frames on either side of frame");
-                               uiDefButS(block, NUMSLI, B_REDR, "GStep:",      *xco+160, *yco-46, 140, 20, &gpl->gstep, 0, 120, 0, 0, "Maximum frame range on either side of active frame to show (0 = just 'first' available frame on either side)");
+                               uiDefButS(block, NUMSLI, B_REDR, "GStep:",      *xco+160, *yco-46, 140, 20, &gpl->gstep, 0, 120, 0, 0, "Max number of frames on either side of active frame to show (0 = just 'first' available sketch on either side)");
                        uiBlockEndAlign(block);
                        
                        /* options */
-                       but= uiDefBut(block, BUT, B_REDR, "Del Active Frame", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Erases the the active frame for this layer");
-                       uiButSetFunc(but, gp_ui_delframe_cb, gpd, gpl);
-                       
-                       but= uiDefBut(block, BUT, B_REDR, "Del Last Stroke", *xco+160, *yco-95, 140, 20, NULL, 0, 0, 0, 0, "Erases the last stroke from the active frame");
-                       uiButSetFunc(but, gp_ui_delstroke_cb, gpd, gpl);
-                       
-                       //uiDefButBitI(block, TOG, GP_LAYER_DRAWDEBUG, B_REDR, "Show Points", *xco+160, *yco-75, 130, 20, &gpl->flag, 0, 0, 0, 0, "Show points which form the strokes");
+                       uiBlockBeginAlign(block);
+                               but= uiDefBut(block, BUT, B_REDR, "Del Active Frame", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Erases the the active frame for this layer (Hotkey = Alt-XKEY/DEL)");
+                               uiButSetFunc(but, gp_ui_delframe_cb, gpd, gpl);
+                               
+                               but= uiDefBut(block, BUT, B_REDR, "Del Last Stroke", *xco+160, *yco-95, 140, 20, NULL, 0, 0, 0, 0, "Erases the last stroke from the active frame (Hotkey = Alt-XKEY/DEL)");
+                               uiButSetFunc(but, gp_ui_delstroke_cb, gpd, gpl);
+                       uiBlockEndAlign(block);
                }
        }
        
@@ -262,36 +262,40 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
 /* Draw the contents for a grease-pencil panel. This assumes several things:
  *     - that panel has been created, is 318 x 204. max yco is 225
  *     - that a toggle for turning on/off gpencil drawing is 150 x 20, starting from (10,225)
+ *             which is basically the top left-hand corner
  * It will return the amount of extra space to extend the panel by
  */
 short draw_gpencil_panel (uiBlock *block, bGPdata *gpd, ScrArea *sa)
 {
        uiBut *but;
        bGPDlayer *gpl;
-       short xco= 10, yco= 155;
+       short xco= 10, yco= 170;
        
        /* draw gpd settings first */
        {
-               /* show status info button */
-               uiDefButBitI(block, TOG, GP_DATA_DISPINFO, B_REDR, "Show Status Info", 10, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "Display status info about current status of Grease Pencil");
-               
-               /* add new/duplicate layer buttons */
-               but= uiDefBut(block, BUT, B_REDR, "Add New Layer", 10,182,150,20, 0, 0, 0, 0, 0, "Adds a new Grease Pencil Layer");
+               /* add new layer buttons */
+               but= uiDefBut(block, BUT, B_REDR, "Add New Layer", 10,205,150,20, 0, 0, 0, 0, 0, "Adds a new Grease Pencil Layer");
                uiButSetFunc(but, gp_ui_addlayer_cb, gpd, NULL);
                
                
-               /* show override lmb-clicks button */
-               uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 150, 20, &gpd->flag, 0, 0, 0, 0, "Interpret LMB-click as new strokes (same as holding Shift-Key per stroke)");
+               /* show override lmb-clicks button + painting lock */
+               uiBlockBeginAlign(block);
+                       if ((gpd->flag & GP_DATA_EDITPAINT)==0) {
+                               uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 130, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes");
+                               
+                               uiBlockSetCol(block, TH_BUT_SETTING);
+                                       uiDefIconButBitI(block, ICONTOG, GP_DATA_LMBPLOCK, B_REDR, ICON_UNLOCKED,       300, 225, 20, 20, &gpd->flag, 0.0, 0.0, 0, 0, "Painting cannot occur with Shift-LMB (when making selections)");
+                               uiBlockSetCol(block, TH_AUTO);
+                       }
+                       else
+                               uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 150, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes");
+               uiBlockEndAlign(block);
                
                /* 'view align' button (naming depends on context) */
                if (sa->spacetype == SPACE_VIEW3D)
-                       uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Draw in 3D", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added in 3D-space");
+                       uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Sketch in 3D", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added in 3D-space");
                else if (sa->spacetype != SPACE_SEQ) /* not available for sequencer yet */
                        uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Stick to View", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added on 2d-canvas");
-               
-               /* show edit-in-action button */
-               but= uiDefButBitI(block, TOG, GP_DATA_EDITTIME, B_REDR, "Edit Timing", 170, 182, 150, 20, &gpd->flag, 0, 0, 0, 0, "Edit timing of frames for the Grease Pencil block");
-               uiButSetFunc(but, gp_ui_dotime_cb, gpd, NULL);
        }
        
        /* draw for each layer */
@@ -313,6 +317,66 @@ enum {
        GP_DRAWDATA_ONLYV2D             = (1<<2),       /* only draw 'canvas' strokes */
 };
 
+/* draw stroke in buffer */
+static void gp_draw_stroke_buffer (tGPspoint *points, int totpoints, short thickness, short dflag, short sflag)
+{
+       tGPspoint *pt;
+       int i;
+       
+       /* error checking */
+       if ((points == NULL) || (totpoints <= 0))
+               return;
+       
+       /* check if buffer can be drawn */
+       if (dflag & (GP_DRAWDATA_ONLY3D|GP_DRAWDATA_ONLYV2D))
+               return;
+       
+       /* if drawing a single point, draw it larger */ 
+       if (totpoints == 1) {           
+               /* draw point */
+               glBegin(GL_POINTS);
+                       glVertex2f(points->x, points->y);
+               glEnd();
+       }
+       else if (sflag & GP_STROKE_ERASER) {
+               /* draw stroke curve - just standard thickness */
+               setlinestyle(4);
+               glLineWidth(1.0f);
+               
+               glBegin(GL_LINE_STRIP);
+               for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
+                       glVertex2f(pt->x, pt->y);
+               }
+               glEnd();
+               
+               setlinestyle(0);
+       }
+       else {
+               float oldpressure = 0.0f;
+               
+               /* draw stroke curve */
+               setlinestyle(2);
+               
+               glBegin(GL_LINE_STRIP);
+               for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
+                       if (fabs(pt->pressure - oldpressure) > 0.2f) {
+                               glEnd();
+                               glLineWidth(pt->pressure * thickness);
+                               glBegin(GL_LINE_STRIP);
+                               
+                               glVertex2f(pt->x, pt->y);
+                               
+                               oldpressure = pt->pressure;
+                       }
+                       else
+                               glVertex2f(pt->x, pt->y);
+               }
+               glEnd();
+               
+               setlinestyle(0);
+       }
+}
+
 /* draw a given stroke */
 static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, short debug, int winx, int winy)
 {
@@ -422,6 +486,21 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness,
        }
 }
 
+/* draw a set of strokes */
+static void gp_draw_strokes (bGPDframe *gpf, int winx, int winy, int dflag, short debug, 
+                                                        short lthick, float color[4])
+{
+       bGPDstroke *gps;
+       
+       /* set color first (may need to reset it again later too) */
+       glColor4f(color[0], color[1], color[2], color[3]);
+       
+       for (gps= gpf->strokes.first; gps; gps= gps->next) {    
+               /* just draw the stroke once */
+               gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
+       }
+}
+
 /* draw grease-pencil datablock */
 static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
 {
@@ -437,11 +516,10 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
        /* loop over layers, drawing them */
        for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
                bGPDframe *gpf;
-               bGPDstroke *gps;
                
                short debug = (gpl->flag & GP_LAYER_DRAWDEBUG) ? 1 : 0;
                short lthick= gpl->thickness;
-               float color[4];
+               float color[4], tcolor[4];
                
                /* don't draw layer if hidden */
                if (gpl->flag & GP_LAYER_HIDE) 
@@ -459,6 +537,7 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
                /* set color, stroke thickness, and point size */
                glLineWidth(lthick);
                QUATCOPY(color, gpl->color); // just for copying 4 array elements
+               QUATCOPY(tcolor, gpl->color); // additional copy of color (for ghosting)
                glColor4f(color[0], color[1], color[2], color[3]);
                glPointSize(gpl->thickness + 2);
                
@@ -474,11 +553,8 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
                                        /* check if frame is drawable */
                                        if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
                                                /* alpha decreases with distance from curframe index */
-                                               glColor4f(color[0], color[1], color[2], (color[3]-(i*0.7)));
-                                               
-                                               for (gps= gf->strokes.first; gps; gps= gps->next) {     
-                                                       gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
-                                               }
+                                               tcolor[3] = color[3] - (i/gpl->gstep);
+                                               gp_draw_strokes(gf, winx, winy, dflag, debug, lthick, tcolor);
                                        }
                                        else 
                                                break;
@@ -489,11 +565,8 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
                                        /* check if frame is drawable */
                                        if ((gf->framenum - gpf->framenum) <= gpl->gstep) {
                                                /* alpha decreases with distance from curframe index */
-                                               glColor4f(color[0], color[1], color[2], (color[3]-(i*0.7)));
-                                               
-                                               for (gps= gf->strokes.first; gps; gps= gps->next) {                                                             
-                                                       gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
-                                               }
+                                               tcolor[3] = color[3] - (i/gpl->gstep);
+                                               gp_draw_strokes(gf, winx, winy, dflag, debug, lthick, tcolor);
                                        }
                                        else 
                                                break;
@@ -504,19 +577,14 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
                        }
                        else {
                                /* draw the strokes for the ghost frames (at half of the alpha set by user) */
-                               glColor4f(color[0], color[1], color[2], (color[3] / 7));
-                               
                                if (gpf->prev) {
-                                       for (gps= gpf->prev->strokes.first; gps; gps= gps->next) {
-                                               gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
-                                       }
+                                       tcolor[3] = (color[3] / 7);
+                                       gp_draw_strokes(gpf->prev, winx, winy, dflag, debug, lthick, tcolor);
                                }
                                
-                               glColor4f(color[0], color[1], color[2], (color[3] / 4));
                                if (gpf->next) {
-                                       for (gps= gpf->next->strokes.first; gps; gps= gps->next) {      
-                                               gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
-                                       }
+                                       tcolor[3] = (color[3] / 4);
+                                       gp_draw_strokes(gpf->next, winx, winy, dflag, debug, lthick, tcolor);
                                }
                                
                                /* restore alpha */
@@ -525,20 +593,17 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
                }
                
                /* draw the strokes already in active frame */
-               for (gps= gpf->strokes.first; gps; gps= gps->next) {    
-                       gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
-               }
+               tcolor[3]= color[3];
+               gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
                
                /* Check if may need to draw the active stroke cache, only if this layer is the active layer
-                * that is being edited. (Stroke cache is currently stored in gp-data)
+                * that is being edited. (Stroke buffer is currently stored in gp-data)
                 */
                if ((G.f & G_GREASEPENCIL) && (gpl->flag & GP_LAYER_ACTIVE) &&
                        (gpf->flag & GP_FRAME_PAINT)) 
                {
                        /* Buffer stroke needs to be drawn with a different linestyle to help differentiate them from normal strokes. */
-                       setlinestyle(2);
-                       gp_draw_stroke(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag, debug, winx, winy);
-                       setlinestyle(0);
+                       gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag);
                }
        }
        
index 3a73ee84ead109793e78bfe1de1102a82c8a327f..853df3bedfcb380571023360668720562f5e71c5 100644 (file)
@@ -3336,7 +3336,7 @@ static void nodes_panel_gpencil(short cntrl)      // NODES_HANDLER_GREASEPENCIL
                uiNewPanelHeight(block, 204);
                
                /* draw button for showing gpencil settings and drawings */
-               uiDefButBitS(block, TOG, SNODE_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &snode->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Node Editor");
+               uiDefButBitS(block, TOG, SNODE_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &snode->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Node Editor (draw using Shift-LMB)");
                
                /* extend the panel if the contents won't fit */
                newheight= draw_gpencil_panel(block, gpd, curarea); 
index c8c74ad827940cebf1762dbc01d9bbd9f7f048bb..cc431c73a2ec45a97780062bc191475d3596e25a 100644 (file)
@@ -134,7 +134,7 @@ static void seq_panel_gpencil(short cntrl)  // SEQ_HANDLER_GREASEPENCIL
                uiNewPanelHeight(block, 204);
                
                /* draw button for showing gpencil settings and drawings */
-               uiDefButBitI(block, TOG, SEQ_DRAW_GPENCIL, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sseq->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Sequencer View");
+               uiDefButBitI(block, TOG, SEQ_DRAW_GPENCIL, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sseq->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Sequencer View (draw using Shift-LMB)");
                
                /* extend the panel if the contents won't fit */
                newheight= draw_gpencil_panel(block, gpd, curarea); 
index 14434504e7aa8338fc0b1682ea2b38f31d3db327..2030eb658dec077dec3cf7a64dc6498f16876bb7 100644 (file)
@@ -1502,44 +1502,52 @@ static void draw_view_icon(void)
        glDisable(GL_BLEND);
 }
 
-static void draw_viewport_name(ScrArea *sa)
+char *view3d_get_name(View3D *v3d)
 {
        char *name = NULL;
-       char *printable = NULL;
        
-       switch(G.vd->view) {
+       switch (v3d->view) {
                case 1:
-                       if (G.vd->persp == V3D_ORTHO)
-                               name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Back Ortho" : "Front Ortho";
+                       if (v3d->persp == V3D_ORTHO)
+                               name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Back Ortho" : "Front Ortho";
                        else
-                               name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Back Persp" : "Front Persp";
+                               name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Back Persp" : "Front Persp";
                        break;
                case 3:
-                       if (G.vd->persp == V3D_ORTHO)
-                               name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Left Ortho" : "Right Ortho";
+                       if (v3d->persp == V3D_ORTHO)
+                               name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Left Ortho" : "Right Ortho";
                        else
-                               name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Left Persp" : "Right Persp";
+                               name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Left Persp" : "Right Persp";
                        break;
                case 7:
-                       if (G.vd->persp == V3D_ORTHO)
-                               name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Bottom Ortho" : "Top Ortho";
+                       if (v3d->persp == V3D_ORTHO)
+                               name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Bottom Ortho" : "Top Ortho";
                        else
-                               name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Bottom Persp" : "Top Persp";
+                               name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Bottom Persp" : "Top Persp";
                        break;
                default:
-                       if (G.vd->persp==V3D_CAMOB) {
-                               if ((G.vd->camera) && (G.vd->camera->type == OB_CAMERA)) {
+                       if (v3d->persp==V3D_CAMOB) {
+                               if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
                                        Camera *cam;
-                                       cam = G.vd->camera->data;
+                                       cam = v3d->camera->data;
                                        name = (cam->type != CAM_ORTHO) ? "Camera Persp" : "Camera Ortho";
                                } else {
                                        name = "Object as Camera";
                                }
                        } else { 
-                               name = (G.vd->persp == V3D_ORTHO) ? "User Ortho" : "User Persp";
+                               name = (v3d->persp == V3D_ORTHO) ? "User Ortho" : "User Persp";
                        }
+                       break;
        }
        
+       return name;
+}
+
+static void draw_viewport_name(ScrArea *sa)
+{
+       char *name = view3d_get_name(sa->spacedata.first);
+       char *printable = NULL;
+       
        if (G.vd->localview) {
                printable = malloc(strlen(name) + strlen(" (Local)_")); /* '_' gives space for '\0' */
                strcpy(printable, name);
@@ -1987,6 +1995,8 @@ static void v3d_editarmature_buts(uiBlock *block, Object *ob, float lim)
        tfp->ob_eul[0]= 180.0*ebone->roll/M_PI;
        uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:",        10, 100, 140, 19, tfp->ob_eul, -lim, lim, 1000, 3, "");
 
+       uiDefButBitI(block, TOG, BONE_EDITMODE_LOCKED, REDRAWVIEW3D, "Lock", 160, 100, 140, 19, &(ebone->flag), 0, 0, 0, 0, "Prevents bone from being transformed in edit mode");
+       
        uiBlockBeginAlign(block);
        uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailRadius:",  10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, "");
        if (ebone->parent && ebone->flag & BONE_CONNECTED )
@@ -2654,7 +2664,7 @@ static void view3d_panel_gpencil(short cntrl)     // VIEW3D_HANDLER_GREASEPENCIL
                uiNewPanelHeight(block, 204);
                
                /* draw button for showing gpencil settings and drawings */
-               uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &vd->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View");
+               uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &vd->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View (draw using Shift-LMB)");
                
                /* extend the panel if the contents won't fit */
                newheight= draw_gpencil_panel(block, gpd, curarea); 
index 3251cb33b53766716d15bcc9fc69108fd8670664..c454715b1df3115b2ea57f0c8a20c0dd3ce92a7b 100644 (file)
@@ -517,23 +517,43 @@ static void actdata_filter_shapekey (ListBase *act_data, Key *key, int filter_mo
        }
 }
  
-static void actdata_filter_gpencil (ListBase *act_data, bGPdata *gpd, int filter_mode)
+
+static void actdata_filter_gpencil (ListBase *act_data, bScreen *sc, int filter_mode)
 {
        bActListElem *ale;
+       ScrArea *sa;
+       bGPdata *gpd;
        bGPDlayer *gpl;
        
        /* check if filtering types are appropriate */
        if ( !(filter_mode & (ACTFILTER_IPOKEYS|ACTFILTER_ONLYICU|ACTFILTER_ACTGROUPED)) ) 
        {
-               /* loop over layers as the conditions are acceptable */
-               for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
-                       /* only if selected */
-                       if (!(filter_mode & ACTFILTER_SEL) || SEL_GPL(gpl)) {
-                               /* only if editable */
-                               if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_GPL(gpl)) {
-                                       /* add to list */
-                                       ale= make_new_actlistelem(gpl, ACTTYPE_GPLAYER, NULL, ACTTYPE_NONE);
-                                       if (ale) BLI_addtail(act_data, ale);
+               /* loop over spaces in current screen, finding gpd blocks (could be slow!) */
+               for (sa= sc->areabase.first; sa; sa= sa->next) {
+                       /* try to get gp data */
+                       gpd= gpencil_data_getactive(sa);
+                       if (gpd == NULL) continue;
+                       
+                       /* add gpd as channel too (if for drawing, and it has layers) */
+                       if ((filter_mode & ACTFILTER_FORDRAWING) && (gpd->layers.first)) {
+                               /* add to list */
+                               ale= make_new_actlistelem(gpd, ACTTYPE_GPDATABLOCK, sa, ACTTYPE_SPECIALDATA);
+                               if (ale) BLI_addtail(act_data, ale);
+                       }
+                       
+                       /* only add layers if they will be visible (if drawing channels) */
+                       if ( !(filter_mode & ACTFILTER_VISIBLE) || (EXPANDED_GPD(gpd)) ) {
+                               /* loop over layers as the conditions are acceptable */
+                               for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
+                                       /* only if selected */
+                                       if (!(filter_mode & ACTFILTER_SEL) || SEL_GPL(gpl)) {
+                                               /* only if editable */
+                                               if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_GPL(gpl)) {
+                                                       /* add to list */
+                                                       ale= make_new_actlistelem(gpl, ACTTYPE_GPLAYER, gpd, ACTTYPE_GPDATABLOCK);
+                                                       if (ale) BLI_addtail(act_data, ale);
+                                               }
+                                       }
                                }
                        }
                }
@@ -637,11 +657,8 @@ int get_nearest_key_num (Key *key, short *mval, float *x)
     return (num + 1);
 }
 
-/* this function is used to get a pointer to an action or shapekey 
- * datablock, thus simplying that process.
- */
-/* this function is intended for use */
-void *get_nearest_act_channel (short mval[], short *ret_type)
+/* this function finds the channel that mouse is floating over */
+void *get_nearest_act_channel (short mval[], short *ret_type, void **owner)
 {
        ListBase act_data = {NULL, NULL};
        bActListElem *ale;
@@ -652,6 +669,9 @@ void *get_nearest_act_channel (short mval[], short *ret_type)
        int clickmin, clickmax;
        float x,y;
        
+       /* init 'owner' return val */
+       *owner= NULL;
+       
        /* determine what type of data we are operating on */
        data = get_action_context(&datatype);
        if (data == NULL) {
@@ -679,6 +699,7 @@ void *get_nearest_act_channel (short mval[], short *ret_type)
                        /* found match */
                        *ret_type= ale->type;
                        data= ale->data;
+                       *owner= ale->owner;
                        
                        BLI_freelistN(&act_data);
                        
@@ -854,10 +875,7 @@ void *get_action_context (short *datatype)
                                
                        case SACTCONT_GPENCIL:
                                *datatype= ACTCONT_GPENCIL;
-                               if (G.saction->pin)
-                                       return G.saction->gpd;
-                               else
-                                       return gpencil_data_getetime(G.curscreen);
+                               return G.curscreen; // FIXME: add that dopesheet type thing here!
                        
                        default: /* includes SACTCONT_DOPESHEET for now */
                                *datatype= ACTCONT_NONE;
@@ -2327,7 +2345,7 @@ static void numbuts_action ()
        void *data;
        short datatype;
        
-       void *act_channel;
+       void *act_channel, *channel_owner;
        short chantype;
        
        bActionGroup *agrp= NULL;
@@ -2335,6 +2353,7 @@ static void numbuts_action ()
        bConstraintChannel *conchan= NULL;
        IpoCurve *icu= NULL;
        KeyBlock *kb= NULL;
+       bGPdata *gpd= NULL;
        bGPDlayer *gpl= NULL;
        
        short mval[2];
@@ -2353,7 +2372,7 @@ static void numbuts_action ()
        getmouseco_areawin(mval);
        if (mval[0] > NAMEWIDTH) 
                return;
-       act_channel= get_nearest_act_channel(mval, &chantype);
+       act_channel= get_nearest_act_channel(mval, &chantype, &channel_owner);
        
        /* create items for clever-numbut */
        if (chantype == ACTTYPE_ACHAN) {
@@ -2451,6 +2470,7 @@ static void numbuts_action ()
        }
        else if (chantype == ACTTYPE_GPLAYER) {
                /* Grease-Pencil Layer */
+               gpd= (bGPdata *)channel_owner;
                gpl= (bGPDlayer *)act_channel;
                
                strcpy(str, gpl->info);
@@ -2511,7 +2531,7 @@ static void numbuts_action ()
                }
                else if (gpl) {
                        strcpy(gpl->info, str);
-                       BLI_uniquename(&( ((bGPdata *)data)->layers ), gpl, "GP_Layer", offsetof(bGPDlayer, info), 128);
+                       BLI_uniquename(&gpd->layers, gpl, "GP_Layer", offsetof(bGPDlayer, info), 128);
                        
                        if (mute) gpl->flag |= GP_LAYER_HIDE;
                        else gpl->flag &= ~GP_LAYER_HIDE;;
@@ -2871,9 +2891,10 @@ int select_gplayer_channel (bGPdata *gpd, bGPDlayer *gpl, int selectmode)
                gpl->flag ^= GP_LAYER_SELECT;
                break;
        }
+       
        flag = (gpl->flag & GP_LAYER_SELECT) ? 1 : 0;
-
-       gpencil_layer_setactive(gpd, gpl);
+       if (flag)
+               gpencil_layer_setactive(gpd, gpl);
 
        return flag;
 }
@@ -3100,11 +3121,11 @@ void selectall_action_keys (short mval[], short mode, short select_mode)
        switch (mode) {
                case 0: /* all in channel*/
                {
-                       void *act_channel;
+                       void *act_channel, *channel_owner;
                        short chantype;
                        
                        /* get channel, and act according to type */
-                       act_channel= get_nearest_act_channel(mval, &chantype);
+                       act_channel= get_nearest_act_channel(mval, &chantype, &channel_owner);
                        switch (chantype) {
                                case ACTTYPE_GROUP:     
                                {
@@ -3939,8 +3960,7 @@ static void mouse_action (int selectmode)
 static void mouse_actionchannels (short mval[])
 {
        bAction *act= G.saction->action;
-       bGPdata *gpd= G.saction->gpd;
-       void *data, *act_channel;
+       void *data, *act_channel, *channel_owner;
        short datatype, chantype;
        
        /* determine what type of data we are operating on */
@@ -3948,7 +3968,7 @@ static void mouse_actionchannels (short mval[])
        if (data == NULL) return;
        
        /* get channel to work on */
-       act_channel= get_nearest_act_channel(mval, &chantype);
+       act_channel= get_nearest_act_channel(mval, &chantype, &channel_owner);
        
        /* action to take depends on what channel we've got */
        switch (chantype) {
@@ -4086,8 +4106,17 @@ static void mouse_actionchannels (short mval[])
                                }
                        }
                                break;
+               case ACTTYPE_GPDATABLOCK:
+                       {
+                               bGPdata *gpd= (bGPdata *)act_channel;
+                  &nb