soc-2008-mxcurioni: merged changes to revision 15705
authorMaxime Curioni <maxime.curioni@gmail.com>
Wed, 23 Jul 2008 06:02:18 +0000 (06:02 +0000)
committerMaxime Curioni <maxime.curioni@gmail.com>
Wed, 23 Jul 2008 06:02:18 +0000 (06:02 +0000)
144 files changed:
CMakeLists.txt
README
intern/bsp/intern/BSP_CSGMesh.cpp
intern/container/CTR_TaggedIndex.h
intern/decimation/intern/LOD_ManMesh2.cpp
intern/elbeem/intern/solver_init.cpp
intern/ghost/intern/GHOST_SystemWin32.cpp
intern/ghost/intern/GHOST_WindowWin32.cpp
projectfiles_vc7/blender/makesdna/DNA_makesdna.vcproj
projectfiles_vc7/blender/src/BL_src.vcproj
projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj
source/blender/blenkernel/BKE_global.h
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenlib/intern/arithb.c
source/blender/blenlib/intern/storage.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/imbuf/intern/openexr/openexr_api.cpp
source/blender/include/BDR_drawaction.h
source/blender/include/BDR_gpencil.h [new file with mode: 0644]
source/blender/include/BIF_drawgpencil.h [new file with mode: 0644]
source/blender/include/BIF_editaction.h
source/blender/include/BIF_resources.h
source/blender/include/BIF_space.h
source/blender/include/BSE_editaction_types.h
source/blender/include/blendef.h
source/blender/include/transform.h
source/blender/makesdna/DNA_action_types.h
source/blender/makesdna/DNA_actuator_types.h
source/blender/makesdna/DNA_gpencil_types.h [new file with mode: 0644]
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesdna/DNA_view3d_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/python/api2_2x/Blender.c
source/blender/python/api2_2x/Library.c
source/blender/python/api2_2x/Particle.c
source/blender/python/api2_2x/doc/Ipo.py
source/blender/python/api2_2x/doc/LibData.py
source/blender/python/api2_2x/doc/Particle.py
source/blender/python/api2_2x/doc/Render.py
source/blender/python/api2_2x/sceneRender.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/shadeoutput.c
source/blender/render/intern/source/zbuf.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_logic.c
source/blender/src/buttons_scene.c
source/blender/src/drawaction.c
source/blender/src/drawgpencil.c [new file with mode: 0644]
source/blender/src/drawnode.c
source/blender/src/drawobject.c
source/blender/src/drawseq.c
source/blender/src/drawview.c
source/blender/src/editaction.c
source/blender/src/editaction_gpencil.c [new file with mode: 0644]
source/blender/src/editmesh.c
source/blender/src/editnode.c
source/blender/src/editobject.c
source/blender/src/editsound.c
source/blender/src/gpencil.c [new file with mode: 0644]
source/blender/src/header_action.c
source/blender/src/header_node.c
source/blender/src/header_seq.c
source/blender/src/header_view3d.c
source/blender/src/interface.c
source/blender/src/poselib.c
source/blender/src/resources.c
source/blender/src/space.c
source/blender/src/transform_conversions.c
source/blender/src/transform_generics.c
source/blender/src/usiblender.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/BL_DeformableGameObject.h
source/gameengine/Converter/BL_ShapeDeformer.cpp
source/gameengine/Converter/BL_SkinDeformer.cpp
source/gameengine/Converter/BL_SkinDeformer.h
source/gameengine/Converter/KX_ConvertActuators.cpp
source/gameengine/Expressions/Value.cpp
source/gameengine/Expressions/Value.h
source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
source/gameengine/GameLogic/SCA_2DFilterActuator.h
source/gameengine/GameLogic/SCA_ILogicBrick.cpp
source/gameengine/GameLogic/SCA_ILogicBrick.h
source/gameengine/GameLogic/SCA_IObject.cpp
source/gameengine/GameLogic/SCA_PropertyActuator.cpp
source/gameengine/GameLogic/SCA_PropertyActuator.h
source/gameengine/GameLogic/SCA_PythonController.cpp
source/gameengine/GamePlayer/common/GPC_Canvas.h
source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
source/gameengine/GamePlayer/common/GPC_RenderTools.h
source/gameengine/GamePlayer/ghost/GPG_Application.cpp
source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
source/gameengine/Ketsji/KX_BulletPhysicsController.h
source/gameengine/Ketsji/KX_CameraActuator.cpp
source/gameengine/Ketsji/KX_CameraActuator.h
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_IPhysicsController.h
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_NearSensor.cpp
source/gameengine/Ketsji/KX_OdePhysicsController.cpp
source/gameengine/Ketsji/KX_OdePhysicsController.h
source/gameengine/Ketsji/KX_ParentActuator.cpp
source/gameengine/Ketsji/KX_ParentActuator.h
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_PythonInit.h
source/gameengine/Ketsji/KX_RadarSensor.cpp
source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/Ketsji/KX_SceneActuator.cpp
source/gameengine/Ketsji/KX_SceneActuator.h
source/gameengine/Ketsji/KX_SoundActuator.cpp
source/gameengine/Ketsji/KX_SumoPhysicsController.cpp
source/gameengine/Ketsji/KX_SumoPhysicsController.h
source/gameengine/Ketsji/KX_TrackToActuator.cpp
source/gameengine/Ketsji/KX_TrackToActuator.h
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.h
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
source/gameengine/PyDoc/KX_GameObject.py
source/gameengine/Rasterizer/CMakeLists.txt
source/gameengine/Rasterizer/Makefile
source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
source/gameengine/Rasterizer/RAS_2DFilterManager.h
source/gameengine/Rasterizer/RAS_ICanvas.h
source/gameengine/Rasterizer/RAS_IRenderTools.h
source/gameengine/Rasterizer/SConscript
source/gameengine/SceneGraph/SG_IObject.cpp
source/gameengine/SceneGraph/SG_IObject.h
source/gameengine/SceneGraph/SG_Node.cpp
source/gameengine/SceneGraph/SG_Node.h

index b58fe9456639abdd060aa9f9f6812e3083a54bbb..5a23e77d9f81fa04100e840f1bab164e442a317f 100644 (file)
@@ -197,10 +197,17 @@ IF(UNIX)
 ENDIF(UNIX)
 
 IF(WIN32)
-  INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake)
 
+  INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake)
+  
   SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/windows)
 
+  # Setup 64bit and 64bit windows systems
+  IF(CMAKE_CL_64)
+    message("64 bit compiler detected.")
+    SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/win64)
+  ENDIF(CMAKE_CL_64)
+
   SET(PYTHON ${LIBDIR}/python)
   SET(PYTHON_VERSION 2.5)
   SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}")
@@ -214,12 +221,20 @@ IF(WIN32)
   SET(OPENAL_LIB openal_static)
   SET(OPENAL_LIBPATH ${OPENAL}/lib)
 
-  SET(PNG_LIB libpng_st)
+  IF(CMAKE_CL_64)
+       SET(PNG_LIB libpng)
+  ELSE(CMAKE_CL_64)
+       SET(PNG_LIB libpng_st)
+  ENDIF(CMAKE_CL_64)
   SET(JPEG_LIB libjpeg)
 
   SET(ZLIB ${LIBDIR}/zlib)
   SET(ZLIB_INC ${ZLIB}/include)
-  SET(ZLIB_LIB libz)
+  IF(CMAKE_CL_64)
+       SET(ZLIB_LIB zlib)
+  ELSE(CMAKE_CL_64)
+       SET(ZLIB_LIB libz)
+  ENDIF(CMAKE_CL_64)
   SET(ZLIB_LIBPATH ${ZLIB}/lib)
   
   SET(PTHREADS ${LIBDIR}/pthreads)
@@ -302,7 +317,11 @@ IF(WIN32)
   
   SET(WINTAB_INC ${LIBDIR}/wintab/include) 
 
-  SET(PLATFORM_LINKFLAGS "/NODEFAULTLIB:libc.lib")
+  IF(CMAKE_CL_64)
+  SET(PLATFORM_LINKFLAGS "/NODEFAULTLIB:libc.lib;MSVCRT.lib ")
+  ELSE(CMAKE_CL_64)
+  SET(PLATFORM_LINKFLAGS "/NODEFAULTLIB:libc.lib ")
+  ENDIF(CMAKE_CL_64)
   SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib;libc.lib ")
 ENDIF(WIN32)
 
diff --git a/README b/README
index d123a90ba486eff7251016859e56a26280b6fb61..1a7964f954e4a2366d58e8295aefff6f92786cfd 100644 (file)
--- a/README
+++ b/README
@@ -24,22 +24,22 @@ dir to one of these locations (your home directory being recommended).
 -------------------------------------Links--------------------------------------
 
 Getting Involved:
-http://www.blender.org/docs/get_involved.html
+http://www.blender.org/community/get-involved
 
 Community:
-http://www.blender3d.org/Community/
+http://www.blender.org/Community
 
 Main blender development site:
-http://www.blender.org/
+http://www.blender.org
 
 The Blender project homepage:
-http://projects.blender.org/projects/bf-blender/
+http://projects.blender.org/projects/bf-blender
 
 Documentation:
-http://www.blender.org/modules.php?op=modload&name=documentation&file=index
+http://www.blender.org/education-help
 
 Bug tracker:
-http://projects.blender.org/tracker/?atid=125&group_id=9&func=browse
+http://www.blender.org/development/report-a-bug
 
 Feature request tracker:
-http://projects.blender.org/tracker/?atid=128&group_id=9&func=browse
+http://wiki.blender.org/index.php/Requests
index 553f39a4642e1a8ae73c3f1f5baeecf51d3fbc10..ca7795b3cf5edea6b29dfa9caab4fd1e6accf674 100644 (file)
@@ -197,7 +197,7 @@ BuildEdges(
 
                for (int vert = 0; vert < vertex_num; ++vert) {
 
-                       BSP_FaceInd fi(f_it - f_it_begin);
+                       BSP_FaceInd fi(size_t (f_it - f_it_begin));
                        InsertEdge(prev_vi,face.m_verts[vert],fi,dummy);
                        prev_vi = face.m_verts[vert];
                }
index 7a7bd85e8902d02347f067f1080babe2548ebef5..68d2536c8793fb37d526295a0ac6d7aa0562cc36 100644 (file)
@@ -93,6 +93,16 @@ public:
        }
 
 
+#if defined(_WIN64)
+       CTR_TaggedIndex(
+               const unsigned __int64 val
+       ) :
+               m_val ( ((unsigned __int64)val & index_mask)
+                               | ( (empty_tag << tag_shift)
+                                       & (~index_mask) ) ) {
+       }
+#endif
+
        CTR_TaggedIndex(
                const CTR_TaggedIndex &my_index
        ):
@@ -124,6 +134,12 @@ public:
                return (long int)(m_val & index_mask);
        }
 
+#if defined(_WIN64)
+       operator unsigned __int64 () const {
+                       return (unsigned __int64)(m_val & index_mask);
+               }
+#endif
+
                bool
        IsEmpty(
        ) const {
index eeb497bb09eb1024a003b0ac6fb135d3046de0ce..2fe49b36583c47c756fa1dd498d08908fd7ccb3e 100644 (file)
@@ -477,7 +477,7 @@ DeleteVertex(
                return;
        }
 
-       LOD_VertexInd last = LOD_VertexInd(verts.end() - verts.begin() - 1);
+       LOD_VertexInd last = LOD_VertexInd(size_t(verts.end() - verts.begin() - 1));
 
        if (!(last == v)) {
 
@@ -533,7 +533,7 @@ DeleteEdge(
                return;
        }
 
-       LOD_EdgeInd last = LOD_EdgeInd(edges.end() - edges.begin() - 1);
+       LOD_EdgeInd last = LOD_EdgeInd(size_t(edges.end() - edges.begin() - 1));
 
        if (!(last == e)) {
                vector<LOD_EdgeInd> e_verts;
@@ -573,7 +573,7 @@ DeleteFace(
                return;
        }
 
-       LOD_FaceInd last = LOD_FaceInd(faces.end() - faces.begin() - 1);
+       LOD_FaceInd last = LOD_FaceInd(size_t (faces.end() - faces.begin() - 1));
 
        if (!(last == f)) {
                
index c953d2f47da66979878b645e62bfc1f28aec0679..a873f3c69874587ad84d61382ee1d2dee4f3b26a 100644 (file)
@@ -694,7 +694,7 @@ bool LbmFsgrSolver::initializeSolverMemory()
                double maxDefaultMemChunk = 2.*1024.*1024.*1024.;
                //std::cerr<<" memEstFine "<< memEstFine <<" maxWin:" <<maxWinMemChunk <<" maxMac:" <<maxMacMemChunk ; // DEBUG
 #ifdef WIN32
-               if(memEstFine> maxWinMemChunk) {
+               if(sizeof(void *)==4 && memEstFine>maxWinMemChunk) {
                        memBlockAllocProblem = true;
                }
 #endif // WIN32
index 293f8fc1661d2230ec2f1ff109c5564da92d0ef6..f5c7c08ebfe1d71ec5e68647413009b7485b65a5 100644 (file)
 
 #include "GHOST_SystemWin32.h"
 
+// win64 doesn't define GWL_USERDATA
+#ifdef WIN32
+#ifndef GWL_USERDATA
+#define GWL_USERDATA GWLP_USERDATA
+#define GWL_WNDPROC GWLP_WNDPROC
+#endif
+#endif
+
 /*
  * According to the docs the mouse wheel message is supported from windows 98 
  * upwards. Leaving WINVER at default value, the WM_MOUSEWHEEL message and the 
index 905b2f7ac6349487d6c1b6371690f3db4927ba27..fef58d071a457a3412c72bfbe1344e8875c4d097 100644 (file)
 #define M_PI 3.1415926536
 #endif
 
+// win64 doesn't define GWL_USERDATA
+#ifdef WIN32
+#ifndef GWL_USERDATA
+#define GWL_USERDATA GWLP_USERDATA
+#define GWL_WNDPROC GWLP_WNDPROC
+#endif
+#endif
+
 LPCSTR GHOST_WindowWin32::s_windowClassName = "GHOST_WindowClass";
 const int GHOST_WindowWin32::s_maxTitleLength = 128;
 HGLRC GHOST_WindowWin32::s_firsthGLRc = NULL;
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 6f91aeed8b55f626a67b2e8317b1da437340f851..153d9a90b2392e463b5f86aef8a2f80b3a1c4ef9 100644 (file)
@@ -21,7 +21,7 @@
                        <Tool
                                Name="VCCLCompilerTool"
                                InlineFunctionExpansion="1"
-                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_7\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include"
+                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_7\extern\verse\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include"
                                PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER=1;WITH_QUICKTIME;INTERNATIONAL;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET=1;WITH_FFMPEG"
                                StringPooling="TRUE"
                                RuntimeLibrary="0"
@@ -73,7 +73,7 @@
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_7\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include"
+                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_7\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\build\msvc_7\extern\glew\include"
                                PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER;WITH_QUICKTIME;INTERNATIONAL;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET = 1;WITH_FFMPEG"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
                        <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 31520b0654618e5fd383ed9b51d36e7d395092a1..9d55a7712fc77fdb813237d4bd321d935aa78ad6 100644 (file)
@@ -21,7 +21,7 @@
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5"
                                PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
                        <Tool
                                Name="VCCLCompilerTool"
                                InlineFunctionExpansion="1"
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5"
                                PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"
                                StringPooling="TRUE"
                                RuntimeLibrary="0"
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5"
                                PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
                        <Tool
                                Name="VCCLCompilerTool"
                                InlineFunctionExpansion="1"
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5"
                                PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"
                                StringPooling="TRUE"
                                RuntimeLibrary="0"
index 62289d227c762f74a67d3543f208db45a2c89ef4..8c9634cba06051e5df877e3be8ef539bc14497ec 100644 (file)
@@ -175,6 +175,7 @@ typedef struct Global {
 #define G_WEIGHTPAINT  (1 << 15)       
 #define G_TEXTUREPAINT (1 << 16)
 /* #define G_NOFROZEN  (1 << 17) also removed */
+#define G_GREASEPENCIL         (1 << 17)
 #define G_DRAWEDGES            (1 << 18)
 #define G_DRAWCREASES  (1 << 19)
 #define G_DRAWSEAMS     (1 << 20)
@@ -265,3 +266,4 @@ extern Global G;
        
 #endif
 
+
index 26c5d186d8703b995d22aca66ccd1ede9d293ece..6dfb77504fb3d7cf6babdf2104fc0dd07fc620f0 100644 (file)
@@ -1437,6 +1437,9 @@ CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj)
 
                                        if(coll_ob == self)
                                                continue;
+                                       
+                                       if( !collmd->bvhtree)
+                                               continue;
 
                                        if(numobj >= maxobj)
                                        {
index e8bcae42d5a97764732e1a237d345427747cd5f1..54915058bab7b21778a8c29ff0a3db9d86e04ab2 100644 (file)
@@ -915,7 +915,10 @@ void lattice_calc_modifiers(Object *ob)
                mti->deformVerts(md, ob, NULL, vertexCos, numVerts);
        }
 
-       if (vertexCos) {
+       /* always displist to make this work like derivedmesh */
+       if (!vertexCos) vertexCos = lattice_getVertexCos(ob, &numVerts);
+       
+       {
                DispList *dl = MEM_callocN(sizeof(*dl), "lt_dl");
                dl->type = DL_VERTS;
                dl->parts = 1;
index f70648965f413a5b9474f12cc2ae1150f1ee8c90..7dca87d5c135ad53b2de60acda7a7af89b365e44 100644 (file)
@@ -2797,7 +2797,10 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, P
                                epart= epsys->part;
                                pd= epart->pd;
                                totepart= epsys->totpart;
-
+                               
+                               if(totepart <= 0)
+                                       continue;
+                               
                                if(pd->forcefield==PFIELD_HARMONIC){
                                        /* every particle is mapped to only one harmonic effector particle */
                                        p= pa_no%epsys->totpart;
index c97ca3c6a8abd93c27fa6fab9d58cf60ffa52ac9..b7598ec0c4d1f9fc96d73d6d786fb78188128bf6 100644 (file)
@@ -60,6 +60,7 @@
 #define SMALL_NUMBER   1.e-8
 #define ABS(x) ((x) < 0 ? -(x) : (x))
 #define SWAP(type, a, b)       { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; }
+#define CLAMP(a, b, c)         if((a)<(b)) (a)=(b); else if((a)>(c)) (a)=(c)
 
 
 #if defined(WIN32) || defined(__APPLE__)
@@ -3800,12 +3801,50 @@ int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], flo
 
 /* Adapted from the paper by Kasper Fauerby */
 /* "Improved Collision detection and Response" */
+static int getLowestRoot(float a, float b, float c, float maxR, float* root)
+{
+       // Check if a solution exists
+       float determinant = b*b - 4.0f*a*c;
+
+       // If determinant is negative it means no solutions.
+       if (determinant >= 0.0f)
+       {
+               // calculate the two roots: (if determinant == 0 then
+               // x1==x2 but let’s disregard that slight optimization)
+               float sqrtD = sqrt(determinant);
+               float r1 = (-b - sqrtD) / (2.0f*a);
+               float r2 = (-b + sqrtD) / (2.0f*a);
+               
+               // Sort so x1 <= x2
+               if (r1 > r2)
+                       SWAP( float, r1, r2);
+
+               // Get lowest root:
+               if (r1 > 0.0f && r1 < maxR)
+               {
+                       *root = r1;
+                       return 1;
+               }
+
+               // It is possible that we want x2 - this can happen
+               // if x1 < 0
+               if (r2 > 0.0f && r2 < maxR)
+               {
+                       *root = r2;
+                       return 1;
+               }
+       }
+       // No (valid) solutions
+       return 0;
+}
+
 int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint)
 {
        float e1[3], e2[3], e3[3], point[3], vel[3], /*dist[3],*/ nor[3], temp[3], bv[3];
-       float a, b, c, d, e, x, y, z, t, t0, t1, radius2=radius*radius;
+       float a, b, c, d, e, x, y, z, radius2=radius*radius;
        float elen2,edotv,edotbv,nordotv,vel2;
-       int embedded_in_plane=0, found_by_sweep=0;
+       float newLambda;
+       int found_by_sweep=0;
 
        VecSubf(e1,v1,v0);
        VecSubf(e2,v2,v0);
@@ -3814,44 +3853,41 @@ int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, f
 /*---test plane of tri---*/
        Crossf(nor,e1,e2);
        Normalize(nor);
+
        /* flip normal */
        if(Inpf(nor,vel)>0.0f) VecMulf(nor,-1.0f);
        
        a=Inpf(p1,nor)-Inpf(v0,nor);
-
        nordotv=Inpf(nor,vel);
 
-       if ((nordotv > -0.000001) && (nordotv < 0.000001)) {
-               if(fabs(a)>=1.0f)
+       if (fabs(nordotv) < 0.000001)
+       {
+               if(fabs(a)>=radius)
+               {
                        return 0;
-               else{
-                       embedded_in_plane=1;
-                       t0=0.0f;
-                       t1=1.0f;
                }
        }
-       else{
-               t0=(radius-a)/nordotv;
-               t1=(-radius-a)/nordotv;
-               /* make t0<t1 */
-               if(t0>t1){b=t1; t1=t0; t0=b;}
+       else
+       {
+               float t0=(-a+radius)/nordotv;
+               float t1=(-a-radius)/nordotv;
+
+               if(t0>t1)
+                       SWAP(float, t0, t1);
 
                if(t0>1.0f || t1<0.0f) return 0;
 
                /* clamp to [0,1] */
-               t0=(t0<0.0f)?0.0f:((t0>1.0f)?1.0:t0);
-               t1=(t1<0.0f)?0.0f:((t1>1.0f)?1.0:t1);
-       }
+               CLAMP(t0, 0.0f, 1.0f);
+               CLAMP(t1, 0.0f, 1.0f);
 
-/*---test inside of tri---*/
-       if(embedded_in_plane==0){
+               /*---test inside of tri---*/
                /* plane intersection point */
-               VecCopyf(point,vel);
-               VecMulf(point,t0);
-               VecAddf(point,point,p1);
-               VecCopyf(temp,nor);
-               VecMulf(temp,radius);
-               VecSubf(point,point,temp);
+
+               point[0] = p1[0] + vel[0]*t0 - nor[0]*radius;
+               point[1] = p1[1] + vel[1]*t0 - nor[1]*radius;
+               point[2] = p1[2] + vel[2]*t0 - nor[2]*radius;
+
 
                /* is the point in the tri? */
                a=Inpf(e1,e1);
@@ -3866,14 +3902,19 @@ int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, f
                y=e*a-d*b;
                z=x+y-(a*c-b*b);
 
-               if(( ((unsigned int)z)& ~(((unsigned int)x)|((unsigned int)y)) ) & 0x80000000){
+
+               if( z <= 0.0f && (x >= 0.0f && y >= 0.0f))
+               {
+               //( ((unsigned int)z)& ~(((unsigned int)x)|((unsigned int)y)) ) & 0x80000000){
                        *lambda=t0;
                        VecCopyf(ipoint,point);
                        return 1;
                }
        }
 
+
        *lambda=1.0f;
+
 /*---test points---*/
        a=vel2=Inpf(vel,vel);
 
@@ -3881,73 +3922,42 @@ int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, f
        VecSubf(temp,p1,v0);
        b=2.0f*Inpf(vel,temp);
        c=Inpf(temp,temp)-radius2;
-       d=b*b-4*a*c;
-
-       if(d>=0.0f){
-               if(d==0.0f)
-                       t=-b/2*a;
-               else{
-                       z=sqrt(d);
-                       x=(-b-z)*0.5/a;
-                       y=(-b+z)*0.5/a;
-                       t=x<y?x:y;
-               }
 
-               if(t>0.0 && t < *lambda){
-                       *lambda=t;
-                       VecCopyf(ipoint,v0);
-                       found_by_sweep=1;
-               }
+       if(getLowestRoot(a, b, c, *lambda, lambda))
+       {
+               VecCopyf(ipoint,v0);
+               found_by_sweep=1;
        }
 
        /*v1*/
        VecSubf(temp,p1,v1);
        b=2.0f*Inpf(vel,temp);
        c=Inpf(temp,temp)-radius2;
-       d=b*b-4*a*c;
-
-       if(d>=0.0f){
-               if(d==0.0f)
-                       t=-b/2*a;
-               else{
-                       z=sqrt(d);
-                       x=(-b-z)*0.5/a;
-                       y=(-b+z)*0.5/a;
-                       t=x<y?x:y;
-               }
 
-               if(t>0.0 && t < *lambda){
-                       *lambda=t;
-                       VecCopyf(ipoint,v1);
-                       found_by_sweep=1;
-               }
+       if(getLowestRoot(a, b, c, *lambda, lambda))
+       {
+               VecCopyf(ipoint,v1);
+               found_by_sweep=1;
        }
+       
        /*v2*/
        VecSubf(temp,p1,v2);
        b=2.0f*Inpf(vel,temp);
        c=Inpf(temp,temp)-radius2;
-       d=b*b-4*a*c;
-
-       if(d>=0.0f){
-               if(d==0.0f)
-                       t=-b/2*a;
-               else{
-                       z=sqrt(d);
-                       x=(-b-z)*0.5/a;
-                       y=(-b+z)*0.5/a;
-                       t=x<y?x:y;
-               }
 
-               if(t>0.0 && t < *lambda){
-                       *lambda=t;
-                       VecCopyf(ipoint,v2);
-                       found_by_sweep=1;
-               }
+       if(getLowestRoot(a, b, c, *lambda, lambda))
+       {
+               VecCopyf(ipoint,v2);
+               found_by_sweep=1;
        }
 
 /*---test edges---*/
+       VecSubf(e3,v2,v1); //wasnt yet calculated
+
+
        /*e1*/
        VecSubf(bv,v0,p1);
+
        elen2 = Inpf(e1,e1);
        edotv = Inpf(e1,vel);
        edotbv = Inpf(e1,bv);
@@ -3955,27 +3965,18 @@ int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, f
        a=elen2*(-Inpf(vel,vel))+edotv*edotv;
        b=2.0f*(elen2*Inpf(vel,bv)-edotv*edotbv);
        c=elen2*(radius2-Inpf(bv,bv))+edotbv*edotbv;
-       d=b*b-4*a*c;
-       if(d>=0.0f){
-               if(d==0.0f)
-                       t=-b/2*a;
-               else{
-                       z=sqrt(d);
-                       x=(-b-z)*0.5/a;
-                       y=(-b+z)*0.5/a;
-                       t=x<y?x:y;
-               }
 
-               e=(edotv*t-edotbv)/elen2;
+       if(getLowestRoot(a, b, c, *lambda, &newLambda))
+       {
+               e=(edotv*newLambda-edotbv)/elen2;
 
-               if((e>=0.0f) && (e<=1.0f)){
-                       if(t>0.0 && t < *lambda){
-                               *lambda=t;
-                               VecCopyf(ipoint,e1);
-                               VecMulf(ipoint,e);
-                               VecAddf(ipoint,ipoint,v0);
-                               found_by_sweep=1;
-                       }
+               if(e >= 0.0f && e <= 1.0f)
+               {
+                       *lambda = newLambda;
+                       VecCopyf(ipoint,e1);
+                       VecMulf(ipoint,e);
+                       VecAddf(ipoint,ipoint,v0);
+                       found_by_sweep=1;
                }
        }
 
@@ -3988,32 +3989,27 @@ int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, f
        a=elen2*(-Inpf(vel,vel))+edotv*edotv;
        b=2.0f*(elen2*Inpf(vel,bv)-edotv*edotbv);
        c=elen2*(radius2-Inpf(bv,bv))+edotbv*edotbv;
-       d=b*b-4*a*c;
-       if(d>=0.0f){
-               if(d==0.0f)
-                       t=-b/2*a;
-               else{
-                       z=sqrt(d);
-                       x=(-b-z)*0.5/a;
-                       y=(-b+z)*0.5/a;
-                       t=x<y?x:y;
-               }
 
-               e=(edotv*t-edotbv)/elen2;
+       if(getLowestRoot(a, b, c, *lambda, &newLambda))
+       {
+               e=(edotv*newLambda-edotbv)/elen2;
 
-               if((e>=0.0f) && (e<=1.0f)){
-                       if(t>0.0 && t < *lambda){
-                               *lambda=t;
-                               VecCopyf(ipoint,e2);
-                               VecMulf(ipoint,e);
-                               VecAddf(ipoint,ipoint,v0);
-                               found_by_sweep=1;
-                       }
+               if(e >= 0.0f && e <= 1.0f)
+               {
+                       *lambda = newLambda;
+                       VecCopyf(ipoint,e2);
+                       VecMulf(ipoint,e);
+                       VecAddf(ipoint,ipoint,v0);
+                       found_by_sweep=1;
                }
        }
 
        /*e3*/
-       VecSubf(e3,v2,v1);
+       VecSubf(bv,v0,p1);
+       elen2 = Inpf(e1,e1);
+       edotv = Inpf(e1,vel);
+       edotbv = Inpf(e1,bv);
+
        VecSubf(bv,v1,p1);
        elen2 = Inpf(e3,e3);
        edotv = Inpf(e3,vel);
@@ -4022,30 +4018,22 @@ int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, f
        a=elen2*(-Inpf(vel,vel))+edotv*edotv;
        b=2.0f*(elen2*Inpf(vel,bv)-edotv*edotbv);
        c=elen2*(radius2-Inpf(bv,bv))+edotbv*edotbv;
-       d=b*b-4*a*c;
-       if(d>=0.0f){
-               if(d==0.0f)
-                       t=-b/2*a;
-               else{
-                       z=sqrt(d);
-                       x=(-b-z)*0.5/a;
-                       y=(-b+z)*0.5/a;
-                       t=x<y?x:y;
-               }
 
-               e=(edotv*t-edotbv)/elen2;
+       if(getLowestRoot(a, b, c, *lambda, &newLambda))
+       {
+               e=(edotv*newLambda-edotbv)/elen2;
 
-               if((e>=0.0f) && (e<=1.0f)){
-                       if(t>0.0 && t < *lambda){
-                               *lambda=t;
-                               VecCopyf(ipoint,e3);
-                               VecMulf(ipoint,e);
-                               VecAddf(ipoint,ipoint,v1);
-                               found_by_sweep=1;
-                       }
+               if(e >= 0.0f && e <= 1.0f)
+               {
+                       *lambda = newLambda;
+                       VecCopyf(ipoint,e3);
+                       VecMulf(ipoint,e);
+                       VecAddf(ipoint,ipoint,v1);
+                       found_by_sweep=1;
                }
        }
 
+
        return found_by_sweep;
 }
 int AxialLineIntersectsTriangle(int axis, float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda)
index fbcc56ac21d69cd289de6d3e26080cd1d2a2b0d9..ca7a376d3a2bc96235d1f48e05e183022cbe68ff 100644 (file)
@@ -382,7 +382,6 @@ void BLI_adddirstrings()
                        pwuser = getpwuid(files[num].s.st_uid);
                        if ( pwuser ) {
                        strcpy(files[num].owner, pwuser->pw_name);
-                       free(pwuser);
                        } else {
                                sprintf(files[num].owner, "%d", files[num].s.st_uid);
             }
index 3c629818b2dd0204fe899b1804aeeebd584ae36d..090b1d7c6b6a13f283b798d2af5604c83ab37871 100644 (file)
@@ -69,6 +69,7 @@
 #include "DNA_effect_types.h"
 #include "DNA_fileglobal_types.h"
 #include "DNA_group_types.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_ipo_types.h"
 #include "DNA_image_types.h"
 #include "DNA_key_types.h"
@@ -3698,6 +3699,32 @@ static void lib_link_screen_sequence_ipos(Main *main)
 
 /* ************ READ SCREEN ***************** */
 
+/* relinks grease-pencil data for 3d-view(s) - used for direct_link */
+static void link_gpencil(FileData *fd, bGPdata *gpd)
+{
+       bGPDlayer *gpl;
+       bGPDframe *gpf;
+       bGPDstroke *gps;
+       
+       /* relink layers */
+       link_list(fd, &gpd->layers);
+       
+       for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
+               /* relink frames */
+               link_list(fd, &gpl->frames);
+               gpl->actframe= newdataadr(fd, gpl->actframe);
+               
+               for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
+                       /* relink strokes (and their points) */
+                       link_list(fd, &gpf->strokes);
+                       
+                       for (gps= gpf->strokes.first; gps; gps= gps->next) {
+                               gps->points= newdataadr(fd, gps->points);
+                       }
+               }
+       }
+}
+
 /* note: file read without screens option G_FILE_NO_UI; 
    check lib pointers in call below */
 static void lib_link_screen(FileData *fd, Main *main)
@@ -3709,23 +3736,23 @@ static void lib_link_screen(FileData *fd, Main *main)
                if(sc->id.flag & LIB_NEEDLINK) {
                        sc->id.us= 1;
                        sc->scene= newlibadr(fd, sc->id.lib, sc->scene);
-
+                       
                        sa= sc->areabase.first;
                        while(sa) {
                                SpaceLink *sl;
-
+                               
                                sa->full= newlibadr(fd, sc->id.lib, sa->full);
-
+                               
                                /* space handler scriptlinks */
                                lib_link_scriptlink(fd, &sc->id, &sa->scriptlink);
-
+                               
                                for (sl= sa->spacedata.first; sl; sl= sl->next) {
                                        if(sl->spacetype==SPACE_VIEW3D) {
                                                View3D *v3d= (View3D*) sl;
-
+                                               
                                                v3d->camera= newlibadr(fd, sc->id.lib, v3d->camera);
                                                v3d->ob_centre= newlibadr(fd, sc->id.lib, v3d->ob_centre);
-
+                                               
                                                if(v3d->bgpic) {
                                                        v3d->bgpic->ima= newlibadr_us(fd, sc->id.lib, v3d->bgpic->ima);
                                                }
@@ -4081,6 +4108,10 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                v3d->bgpic= newdataadr(fd, v3d->bgpic);
                                if(v3d->bgpic)
                                        v3d->bgpic->iuser.ok= 1;
+                               if(v3d->gpd) {
+                                       v3d->gpd= newdataadr(fd, v3d->gpd);
+                                       link_gpencil(fd, v3d->gpd);
+                               }
                                v3d->localvd= newdataadr(fd, v3d->localvd);
                                v3d->afterdraw.first= v3d->afterdraw.last= NULL;
                                v3d->clipbb= newdataadr(fd, v3d->clipbb);
@@ -4115,9 +4146,30 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                        }
                        else if(sl->spacetype==SPACE_NODE) {
                                SpaceNode *snode= (SpaceNode *)sl;
+                               
+                               if(snode->gpd) {
+                                       snode->gpd= newdataadr(fd, snode->gpd);
+                                       link_gpencil(fd, snode->gpd);
+                               }
                                snode->nodetree= snode->edittree= NULL;
                                snode->flag |= SNODE_DO_PREVIEW;
                        }
+                       else if(sl->spacetype==SPACE_SEQ) {
+                               SpaceSeq *sseq= (SpaceSeq *)sl;
+                               if(sseq->gpd) {
+                                       sseq->gpd= newdataadr(fd, sseq->gpd);
+                                       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);
index ca91f1dc3461f7bcd4dc7d33737cde89f0d786ea..b59dd851dfe462b4bcb8e3394a0ca905ff3a2257 100644 (file)
@@ -112,6 +112,7 @@ Important to know is that 'streaming' has been added to files, for Blender Publi
 #include "DNA_customdata_types.h"
 #include "DNA_effect_types.h"
 #include "DNA_group_types.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_image_types.h"
 #include "DNA_ipo_types.h"
 #include "DNA_fileglobal_types.h"
@@ -1565,6 +1566,32 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
        mywrite(wd, MYWRITE_FLUSH, 0);
 }
 
+static void write_gpencil(WriteData *wd, bGPdata *gpd)
+{
+       bGPDlayer *gpl;
+       bGPDframe *gpf;
+       bGPDstroke *gps;
+       
+       /* write gpd data block to file */
+       writestruct(wd, DATA, "bGPdata", 1, gpd);
+       
+       /* write grease-pencil layers to file */
+       for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
+               writestruct(wd, DATA, "bGPDlayer", 1, gpl);
+               
+               /* write this layer's frames to file */
+               for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
+                       writestruct(wd, DATA, "bGPDframe", 1, gpf);
+                       
+                       /* write strokes */
+                       for (gps= gpf->strokes.first; gps; gps= gps->next) {
+                               writestruct(wd, DATA, "bGPDstroke", 1, gps);
+                               writestruct(wd, DATA, "bGPDspoint", gps->totpoints, gps->points);                               
+                       }
+               }
+       }
+}
+
 static void write_screens(WriteData *wd, ListBase *scrbase)
 {
        bScreen *sc;
@@ -1610,11 +1637,12 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                        sl= sa->spacedata.first;
                        while(sl) {
                                if(sl->spacetype==SPACE_VIEW3D) {
-                                       View3D *v3d= (View3D*) sl;
+                                       View3D *v3d= (View3D *) sl;
                                        writestruct(wd, DATA, "View3D", 1, v3d);
                                        if(v3d->bgpic) writestruct(wd, DATA, "BGpic", 1, v3d->bgpic);
                                        if(v3d->localvd) writestruct(wd, DATA, "View3D", 1, v3d->localvd);
                                        if(v3d->clipbb) writestruct(wd, DATA, "BoundBox", 1, v3d->clipbb);
+                                       if(v3d->gpd) write_gpencil(wd, v3d->gpd);
                                }
                                else if(sl->spacetype==SPACE_IPO) {
                                        writestruct(wd, DATA, "SpaceIpo", 1, sl);
@@ -1626,7 +1654,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                        writestruct(wd, DATA, "SpaceFile", 1, sl);
                                }
                                else if(sl->spacetype==SPACE_SEQ) {
+                                       SpaceSeq *sseq= (SpaceSeq *)sl;
                                        writestruct(wd, DATA, "SpaceSeq", 1, sl);
+                                       if(sseq->gpd) write_gpencil(wd, sseq->gpd);
                                }
                                else if(sl->spacetype==SPACE_OOPS) {
                                        SpaceOops *so= (SpaceOops *)sl;
@@ -1689,7 +1719,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
                                        writestruct(wd, DATA, "SpaceTime", 1, sl);
                                }
                                else if(sl->spacetype==SPACE_NODE){
+                                       SpaceNode *snode= (SpaceNode *)sl;
                                        writestruct(wd, DATA, "SpaceNode", 1, sl);
+                                       if(snode->gpd) write_gpencil(wd, snode->gpd);
                                }
                                sl= sl->next;
                        }
index fe352610a40cb36fcdd2c4c4103bb3452826a5c2..3e618a483e352ca8b8ebf981b5de9cd84035d941 100644 (file)
@@ -451,7 +451,7 @@ void IMB_exr_begin_write(void *handle, char *filename, int width, int height, in
        openexr_header_compression(&header, compress);
        /* header.lineOrder() = DECREASING_Y; this crashes in windows for file read! */
        
-       header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43"));
+       header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43 and newer"));
        
        data->ofile = new OutputFile(filename, header);
 }
index 91635123cb7e1642a805e4bc6ea2c147c4181c39..7cb0768e83250d45b28b907cde89a994d4992179 100644 (file)
@@ -38,6 +38,7 @@ struct bAction;
 struct bActionGroup;
 struct Object;
 struct ListBase;
+struct bGPDlayer;
 
 /* ****************************** Base Structs ****************************** */
 
@@ -82,6 +83,7 @@ void draw_ipo_channel(struct gla2DDrawInfo *di, struct Ipo *ipo, float ypos);
 void draw_agroup_channel(struct gla2DDrawInfo *di, struct bActionGroup *agrp, float ypos);
 void draw_action_channel(struct gla2DDrawInfo *di, struct bAction *act, float ypos);
 void draw_object_channel(struct gla2DDrawInfo *di, struct Object *ob, float ypos);
+void draw_gpl_channel(struct gla2DDrawInfo *di, struct bGPDlayer *gpl, float ypos);
 
 /* Keydata Generation */
 void icu_to_keylist(struct IpoCurve *icu, ListBase *keys, ListBase *blocks, ActKeysInc *aki);
@@ -89,6 +91,7 @@ void ipo_to_keylist(struct Ipo *ipo, ListBase *keys, ListBase *blocks, ActKeysIn
 void agroup_to_keylist(struct bActionGroup *agrp, ListBase *keys, ListBase *blocks, ActKeysInc *aki);
 void action_to_keylist(struct bAction *act, ListBase *keys, ListBase *blocks, ActKeysInc *aki);
 void ob_to_keylist(struct Object *ob, ListBase *keys, ListBase *blocks, ActKeysInc *aki);
+void gpl_to_keylist(struct bGPDlayer *gpl, ListBase *keys, ListBase *blocks, ActKeysInc *aki);
 
 #endif  /*  BDR_DRAWACTION_H */
 
diff --git a/source/blender/include/BDR_gpencil.h b/source/blender/include/BDR_gpencil.h
new file mode 100644 (file)
index 0000000..d0ebd09
--- /dev/null
@@ -0,0 +1,76 @@
+/**
+ * $Id: BDR_gpencil.h 14444 2008-04-16 22:40:48Z aligorith $
+ *
+ * ***** 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) 2008, Blender Foundation
+ * This is a new part of Blender
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BDR_GPENCIL_H
+#define BDR_GPENCIL_H
+
+struct ListBase;
+struct bScreen;
+struct ScrArea;
+struct View3D;
+struct SpaceNode;
+struct SpaceSeq;
+struct bGPdata;
+struct bGPDlayer;
+struct bGPDframe;
+
+/* ------------ Grease-Pencil API ------------------ */
+
+void free_gpencil_strokes(struct bGPDframe *gpf);
+void free_gpencil_frames(struct bGPDlayer *gpl);
+void free_gpencil_layers(struct ListBase *list);
+void free_gpencil_data(struct bGPdata *gpd);
+
+struct bGPDframe *gpencil_frame_addnew(struct bGPDlayer *gpl, int cframe);
+struct bGPDlayer *gpencil_layer_addnew(struct bGPdata *gpd);
+struct bGPdata *gpencil_data_addnew(void);
+
+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);
+
+struct bGPDframe *gpencil_layer_getframe(struct bGPDlayer *gpl, int cframe, short addnew);
+void gpencil_layer_delframe(struct bGPDlayer *gpl, struct bGPDframe *gpf);
+struct bGPDlayer *gpencil_layer_getactive(struct bGPdata *gpd);
+void gpencil_layer_setactive(struct bGPdata *gpd, struct bGPDlayer *active);
+void gpencil_layer_delactive(struct bGPdata *gpd);
+
+void gpencil_delete_actframe(struct bGPdata *gpd);
+void gpencil_delete_laststroke(struct bGPdata *gpd);
+
+void gpencil_delete_operation(short mode);
+void gpencil_delete_menu(void);
+
+//short gpencil_paint(short mousebutton);
+short gpencil_do_paint(struct ScrArea *sa);
+
+#endif /*  BDR_GPENCIL_H */
diff --git a/source/blender/include/BIF_drawgpencil.h b/source/blender/include/BIF_drawgpencil.h
new file mode 100644 (file)
index 0000000..4184463
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * $Id: BIF_drawgpencil.h 14444 2008-04-16 22:40:48Z aligorith $
+ *
+ * ***** 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) 2008, Blender Foundation
+ * This is a new part of Blender
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BIF_DRAWGPENCIL_H
+#define BIF_DRAWGPENCIL_H
+
+struct ScrArea;
+struct View3D;
+struct SpaceNode;
+struct SpaceSeq;
+struct bGPdata;
+struct uiBlock;
+
+short draw_gpencil_panel(struct uiBlock *block, struct bGPdata *gpd, struct ScrArea *sa); 
+
+void draw_gpencil_2dview(struct ScrArea *sa, short onlyv2d);
+void draw_gpencil_3dview(struct ScrArea *sa, short only3d);
+void draw_gpencil_oglrender(struct View3D *v3d, int winx, int winy);
+
+#endif /*  BIF_DRAWGPENCIL_H */ 
index 2d751f56fc5b18f732961a16d05e7bc0e31bbf3d..9f6751daeffd73ef1ee6cd7832dc57320785738a 100644 (file)
@@ -48,7 +48,8 @@ enum {
        ACTTYPE_FILLIPO,
        ACTTYPE_FILLCON,
        ACTTYPE_IPO,
-       ACTTYPE_SHAPEKEY
+       ACTTYPE_SHAPEKEY,
+       ACTTYPE_GPLAYER
 };
 
 /* Macros for easier/more consistant state testing */
@@ -69,7 +70,10 @@ enum {
 #define EDITABLE_ICU(icu) ((icu->flag & IPO_PROTECT)==0)
 #define SEL_ICU(icu) (icu->flag & IPO_SELECT)
 
-#define NLA_ACTION_SCALED (G.saction->pin==0 && OBACT && OBACT->action)
+#define EDITABLE_GPL(gpl) ((gpl->flag & GP_LAYER_LOCKED)==0)
+#define SEL_GPL(gpl) ((gpl->flag & GP_LAYER_ACTIVE) || (gpl->flag & GP_LAYER_SELECT))
+
+#define NLA_ACTION_SCALED (G.saction->mode==SACTCONT_ACTION && G.saction->pin==0 && OBACT && OBACT->action)
 #define NLA_IPO_SCALED (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname)
 
 /* constants for setting ipo-interpolation type */
@@ -114,6 +118,8 @@ struct BWinEvent;
 struct Key;
 struct ListBase;
 struct TimeMarker;
+struct bGPdata;
+struct bGPDlayer;
 
 /* Key operations */
 void transform_action_keys(int mode, int dummy);
@@ -141,6 +147,7 @@ void paste_actdata(void);
 /* Group/Channel Operations */
 struct bActionGroup *get_active_actiongroup(struct bAction *act);
 void set_active_actiongroup(struct bAction *act, struct bActionGroup *agrp, short select);
+void actionbone_group_copycolors(struct bActionGroup *grp, short init_new);
 void verify_pchan2achan_grouping(struct bAction *act, struct bPose *pose, char name[]);
 void sync_pchan2achan_grouping(void); 
 void action_groups_group(short add_group);
@@ -166,6 +173,7 @@ void deselect_action_channels(short mode);
 void deselect_actionchannels(struct bAction *act, short mode);
 int select_channel(struct bAction *act, struct bActionChannel *achan, int selectmode);
 void select_actionchannel_by_name(struct bAction *act, char *name, int select);
+void select_action_group_channels(struct bAction *act, struct bActionGroup *agrp);
 void selectkeys_leftright (short leftright, short select_mode);
 
 /* Action Markers */
@@ -174,6 +182,24 @@ void action_add_localmarker(struct bAction *act, int frame);
 void action_rename_localmarker(struct bAction *act);
 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);
+
+short is_gplayer_frame_selected(struct bGPDlayer *gpl);
+void set_gplayer_frame_selection(struct bGPDlayer *gpl, short mode);
+void select_gpencil_frames(struct bGPDlayer *gpl, short select_mode);
+void select_gpencil_frame(struct bGPDlayer *gpl, int selx, short select_mode);
+void borderselect_gplayer_frames(struct bGPDlayer *gpl, float min, float max, short select_mode);
+
+void delete_gpencil_layers(void);
+void delete_gplayer_frames(struct bGPDlayer *gpl);
+void duplicate_gplayer_frames(struct bGPDlayer *gpd);
+
+void snap_gplayer_frames(struct bGPDlayer *gpl, short mode);
+void mirror_gplayer_frames(struct bGPDlayer *gpl, short mode);
+
 /* ShapeKey stuff */
 struct Key *get_action_mesh_key(void);
 int get_nearest_key_num(struct Key *key, short *mval, float *x);
index e6cbe7bb69aa1aa02fcfa2c6a03eb2fbc2df60c3..df514190270acb8b7d95e9aac3ecb5fec1be0f62 100644 (file)
@@ -591,6 +591,9 @@ void        BIF_load_ui_colors              (void);
 char   *BIF_ThemeGetColorPtr(struct bTheme *btheme, int spacetype, int colorid);
 char   *BIF_ThemeColorsPup(int spacetype);
 
+/* only for Bone Color sets */
+char *BIF_ThemeColorSetsPup(short inc_custom);
+
 
 void   BIF_def_color                   (BIFColorID colorid, unsigned char r, unsigned char g, unsigned char b);
 
index 37be4a9eafc5c29b8cf7afd1bdd4aae8d40e8d6a..4b2b8e14bb63da606ca3ce8c399d307805ab41be 100644 (file)
@@ -53,6 +53,7 @@ struct SpaceOops;
 #define VIEW3D_HANDLER_PREVIEW         4
 #define VIEW3D_HANDLER_MULTIRES         5
 #define VIEW3D_HANDLER_TRANSFORM       6
+#define VIEW3D_HANDLER_GREASEPENCIL 7
 
 /* ipo handler codes */
 #define IPO_HANDLER_PROPERTIES 20
@@ -73,11 +74,15 @@ struct SpaceOops;
 #define NLA_HANDLER_PROPERTIES 50
 
 /* sequence handler codes */
-#define SEQ_HANDLER_PROPERTIES 60
+#define SEQ_HANDLER_PROPERTIES         60
+#define SEQ_HANDLER_GREASEPENCIL       61
 
 /* imasel handler codes */
 #define IMASEL_HANDLER_IMAGE   70
 
+/* nodes handler codes */
+#define NODES_HANDLER_GREASEPENCIL             80
+
 /* theme codes */
 #define B_ADD_THEME    3301
 #define B_DEL_THEME    3302
@@ -145,3 +150,4 @@ extern               void mainwindow_close(void);
 
 #endif
 
+
index c531383accc8b684b86494136976909c222e9599..be21041597312e29c08f741b02a95e10ef5bebdf 100644 (file)
@@ -38,7 +38,8 @@ typedef enum ALE_KEYTYPE {
        ALE_NONE = 0,
        ALE_IPO,        
        ALE_ICU,
-       ALE_GROUP       
+       ALE_GROUP,
+       ALE_GPFRAME,
 } ALE_KEYTYPE;
 
 /* This struct defines a structure used for quick access */
@@ -78,7 +79,8 @@ typedef enum ACTFILTER_FLAGS {
 typedef enum ACTCONT_TYPES {
        ACTCONT_NONE = 0,
        ACTCONT_ACTION,
-       ACTCONT_SHAPEKEY
+       ACTCONT_SHAPEKEY,
+       ACTCONT_GPENCIL
 } ACTCONT_TYPES;
 
 #endif
index a798224b35b4b20694c3ae08f6bad7e443774c92..6f8b94d7cd177a4be1c4f4226b111ba89ae96c25 100644 (file)
 #define B_ACTCOPYKEYS          710
 #define B_ACTPASTEKEYS         711
 
+#define B_ACTCUSTCOLORS                712
+#define B_ACTCOLSSELECTOR      713
+#define B_ACTGRP_SELALL                714
+#define B_ACTGRP_ADDTOSELF     715
+#define B_ACTGRP_UNGROUP       716
+
 /* TIME: 751 - 800 */
 #define B_TL_REW               751
 #define B_TL_PLAY              752
index 4e3b80134f9e2487c1daa7188127dbd87727b172..720b856a14941e9c31a5ab7911f1960631d88c0d 100644 (file)
@@ -397,6 +397,7 @@ int Align(TransInfo *t, short mval[2]);
 
 /*********************** transform_conversions.c ********** */
 struct ListBase;
+void flushTransGPactionData(TransInfo *t);
 void flushTransIpoData(TransInfo *t);
 void flushTransUVs(TransInfo *t);
 void flushTransParticles(TransInfo *t);
index 18d2a1cb6f3a61c32497ce67855ec007d8253b0d..d7969a7379b19211f42cdcc59d46d8cf2284ef5a 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "DNA_listBase.h"
 #include "DNA_ID.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_view2d_types.h"
 #include "DNA_userdef_types.h"
 
@@ -183,8 +184,11 @@ typedef struct SpaceAction {
        View2D v2d;     
        
        bAction         *action;                /* the currently active action */
-       short flag, autosnap;           /* flag: bitmapped settings; autosnap: automatic keyframe snapping mode */
-       short pin, actnr, lock;         /* pin: keep showing current action; actnr: used for finding chosen action from menu; lock: lock time to other windows */
+       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; */
+       short pin, lock;                        /* pin: keep showing current action; actnr: used for finding chosen action from menu; lock: lock time to other windows */
        short actwidth;                         /* width of the left-hand side name panel (in pixels?) */
        float timeslide;                        /* for Time-Slide transform mode drawing - current frame? */
 } SpaceAction;
@@ -238,6 +242,18 @@ typedef enum SACTION_FLAG {
        SACTION_NODRAWGCOLORS = (1<<7)
 } SACTION_FLAG;        
 
+/* SpaceAction Mode Settings */
+typedef enum SACTCONT_MODES {
+               /* action (default) */
+       SACTCONT_ACTION = 0,
+               /* editing of shapekey's IPO block */
+       SACTCONT_SHAPEKEY,
+               /* editing of gpencil data */
+       SACTCONT_GPENCIL,
+               /* dopesheet (unimplemented... future idea?) */
+       SACTCONT_DOPESHEET
+} SACTCONTEXT_MODES;
+
 /* SpaceAction AutoSnap Settings (also used by SpaceNLA) */
 typedef enum SACTSNAP_MODES {
                /* no auto-snap */
index a467722e8e19d3b3048819fa1a408d82ac17d470..ac9761f165df751684a088809f128ad20126ddb4 100644 (file)
@@ -196,9 +196,7 @@ typedef struct bVisibilityActuator {
 } bVisibilityActuator;
 
 typedef struct bTwoDFilterActuator{
-       char pad[2];
-       /* bitwise flag for enabling or disabling depth(bit 0) and luminance(bit 1) */
-       short texture_flag;
+       char pad[4];
        /* Tells what type of 2D Filter */
        short type;
        /* (flag == 0) means 2D filter is activate and
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
new file mode 100644 (file)
index 0000000..eafd886
--- /dev/null
@@ -0,0 +1,141 @@
+/**
+ * $Id: DNA_gpencil_types.h 8768 2006-11-07 00:10:37Z aligorith $
+ *
+ * ***** 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) 2008, Blender Foundation.
+ * This is a new part of Blender
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef DNA_GPENCIL_TYPES_H
+#define DNA_GPENCIL_TYPES_H
+
+#include "DNA_listBase.h"
+#include "DNA_ID.h"
+
+/* Grease-Pencil Annotations - 'Stroke Point'
+ *     -> Coordinates may either be 2d or 3d depending on settings at the time
+ *     -> Coordinates of point on stroke, in proportions of window size
+ *             (i.e. n/1000). This assumes that the bottom-left corner is (0,0)
+ */
+typedef struct bGPDspoint {
+       float x, y, z;                  /* co-ordinates of point (usually 2d, but can be 3d as well) */                         
+       float pressure;                 /* pressure of input device (from 0 to 1) at this point */
+} bGPDspoint;
+
+/* Grease-Pencil Annotations - 'Stroke'
+ *     -> A stroke represents a (simplified version) of the curve
+ *        drawn by the user in one 'mousedown'->'mouseup' operation
+ */
+typedef struct bGPDstroke {
+       struct bGPDstroke *next, *prev;
+       
+       bGPDspoint *points;             /* array of data-points for stroke */
+       int totpoints;                  /* number of data-points in array */
+       
+       short thickness;                /* thickness of stroke (currently not used) */  
+       short flag;                             /* various settings about this stroke */
+} bGPDstroke;
+
+/* bGPDstroke->flag */
+       /* stroke is in 3d-space */
+#define GP_STROKE_3DSPACE              (1<<0)
+       /* stroke is in 2d-space */
+#define GP_STROKE_2DSPACE              (1<<1)
+
+
+/* Grease-Pencil Annotations - 'Frame'
+ *     -> Acts as storage for the 'image' formed by strokes
+ */
+typedef struct bGPDframe {
+       struct bGPDframe *next, *prev;
+       
+       ListBase strokes;       /* list of the simplified 'strokes' that make up the frame's data */
+       
+       int framenum;           /* frame number of this frame */
+       int flag;                       /* temp settings */
+} bGPDframe;
+
+/* bGPDframe->flag */  
+       /* frame is being painted on */
+#define GP_FRAME_PAINT         (1<<0)
+       /* for editing in Action Editor */
+#define GP_FRAME_SELECT                (1<<1)
+
+
+/* Grease-Pencil Annotations - 'Layer' */
+typedef struct bGPDlayer {
+       struct bGPDlayer *next, *prev;
+       
+       ListBase frames;                /* list of annotations to display for frames (bGPDframe list) */
+       bGPDframe *actframe;    /* active frame (should be the frame that is currently being displayed) */
+       
+       int flag;                               /* settings for layer */                
+       short thickness;                /* current thickness to apply to strokes */
+       short gstep;                    /* max number of frames between active and ghost to show (0=only those on either side) */
+       
+       float color[4];                 /* color that should be used to draw all the strokes in this layer */
+       
+       char info[128];                 /* optional reference info about this layer (i.e. "director's comments, 12/3") */
+} bGPDlayer;
+
+/* bGPDlayer->flag */
+       /* don't display layer */
+#define GP_LAYER_HIDE          (1<<0)
+       /* protected from further editing */
+#define GP_LAYER_LOCKED                (1<<1)  
+       /* layer is 'active' layer being edited */
+#define GP_LAYER_ACTIVE                (1<<2)
+       /* draw points of stroke for debugging purposes */
+#define GP_LAYER_DRAWDEBUG     (1<<3)
+       /* do onionskinning */
+#define GP_LAYER_ONIONSKIN     (1<<4)
+       /* for editing in Action Editor */
+#define GP_LAYER_SELECT                (1<<5)
+
+
+/* Grease-Pencil Annotations - 'DataBlock' */
+typedef struct bGPdata {
+       /* saved Grease-Pencil data */
+       ListBase layers;                /* bGPDlayers */
+       int flag;                               /* settings for this datablock */
+       
+       /* not-saved stroke buffer data (only used during paint-session) 
+        *      - buffer must be initialised before use, but freed after 
+        *        whole paint operation is over
+        */
+       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) */
+} bGPdata;
+
+/* bGPdata->flag */
+       /* draw this datablock's data (not used) */
+#define GP_DATA_DISP           (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)
+       /* is the block overriding all clicks? */
+#define GP_DATA_EDITPAINT      (1<<3)
+       /* new strokes are added in viewport space */
+#define GP_DATA_VIEWALIGN      (1<<4)
+
+#endif /*  DNA_GPENCIL_TYPES_H */
index bc30a12ff274da92425398eeb4a5f83a4bce105f..a8694dfb7f59a9487c7c9a535ff89d708b9ba40c 100644 (file)
@@ -50,6 +50,7 @@ struct RenderInfo;
 struct bNodeTree;
 struct uiBlock;
 struct FileList;
+struct bGPdata;
 
        /**
         * The base structure all the other spaces
@@ -150,6 +151,8 @@ typedef struct SpaceSeq {
        short zebra;
        int flag;
        float zoom;
+       
+       struct bGPdata *gpd;            /* grease-pencil data */
 } SpaceSeq;
 
 typedef struct SpaceFile {
@@ -339,6 +342,8 @@ typedef struct SpaceNode {
        float blockscale;
        struct ScrArea *area;
        
+       short blockhandler[8];
+       
        View2D v2d;
        
        struct ID *id, *from;           /* context, no need to save in file? well... pinning... */
@@ -351,11 +356,13 @@ typedef struct SpaceNode {
        struct bNodeTree *nodetree, *edittree;
        int treetype, pad;                      /* treetype: as same nodetree->type */
        
+       struct bGPdata *gpd;            /* grease-pencil data */
 } SpaceNode;
 
 /* snode->flag */
 #define SNODE_DO_PREVIEW       1
 #define SNODE_BACKDRAW         2
+#define SNODE_DISPGP           4
 
 typedef struct SpaceImaSel {
        SpaceLink *next, *prev;
@@ -657,6 +664,7 @@ typedef struct SpaceImaSel {
 #define SEQ_MARKER_TRANS 2
 #define SEQ_DRAW_COLOR_SEPERATED     4
 #define SEQ_DRAW_SAFE_MARGINS        8
+#define SEQ_DRAW_GPENCIL                       16
 
 /* space types, moved from DNA_screen_types.h */
 enum {
index 3de5b0ff5baf5ba1921159ed09f9ca3f0c7b59c9..cd1c047dac9a24e8b87510ea2ebe759174b6d488 100644 (file)
@@ -116,6 +116,7 @@ typedef struct ThemeWireColor {
 
 /* flags for ThemeWireColor */
 #define TH_WIRECOLOR_CONSTCOLS (1<<0)
+#define TH_WIRECOLOR_TEXTCOLS  (1<<1)
 
 /* A theme */
 typedef struct bTheme {
index c21d629be831668c58c88fe549016dc07b2854dc..135272b9ac244dc1433fe2aa8829fc9e0b5d0061 100644 (file)
@@ -40,6 +40,7 @@ struct Base;
 struct BoundBox;
 struct RenderInfo;
 struct RetopoViewData;
+struct bGPdata;
 
 /* This is needed to not let VC choke on near and far... old
  * proprietary MS extensions... */
@@ -53,9 +54,12 @@ struct RetopoViewData;
 #include "DNA_listBase.h"
 #include "DNA_image_types.h"
 
+/* ******************************** */
+
 /* The near/far thing is a Win EXCEPTION. Thus, leave near/far in the
  * code, and patch for windows. */
-
+/* Background Picture in 3D-View */
 typedef struct BGpic {
     struct Image *ima;
        struct ImageUser iuser;
@@ -63,6 +67,9 @@ typedef struct BGpic {
     short xim, yim;
 } BGpic;
 
+/* ********************************* */
+
+/* 3D ViewPort Struct */
 typedef struct View3D {
        struct SpaceLink *next, *prev;
        int spacetype;
@@ -135,9 +142,10 @@ typedef struct View3D {
        char ndoffilter;                /*filter for 6DOF devices 0 normal, 1 dominant */
        
        void *properties_storage;       /* Nkey panel stores stuff here, not in file */
-
+       struct bGPdata *gpd;            /* Grease-Pencil Data (annotation layers) */
 } View3D;
 
+
 /* View3D->flag (short) */
 #define V3D_MODE                       (16+32+64+128+256+512)
 #define V3D_DISPIMAGE          1
@@ -158,10 +166,12 @@ typedef struct View3D {
 #define V3D_DRAW_CENTERS       32768
 
 /* View3d->flag2 (short) */
+#define V3D_MODE2                      (32)
 #define V3D_OPP_DIRECTION_NAME 1
 #define V3D_FLYMODE                            2
 #define V3D_DEPRECATED                 4 /* V3D_TRANSFORM_SNAP, moved to a scene setting */
 #define V3D_SOLID_TEX                  8
+#define V3D_DISPGP                             16
 
 /* View3D->around */
 #define V3D_CENTER              0
@@ -203,3 +213,4 @@ typedef struct View3D {
 
 #endif
 
+
index 83f4e633fa1670303de53f430d3ebbe1e1eb7e18..3818d66b39ca96ba42b0f966ada09a1a523c2c21 100644 (file)
@@ -126,6 +126,7 @@ char *includefiles[] = {
        "DNA_customdata_types.h",
        "DNA_particle_types.h",
        "DNA_cloth_types.h",
+       "DNA_gpencil_types.h",
        // if you add files here, please add them at the end
        // of makesdna.c (this file) as well
 
@@ -1147,4 +1148,5 @@ int main(int argc, char ** argv)
 #include "DNA_customdata_types.h"
 #include "DNA_particle_types.h"
 #include "DNA_cloth_types.h"
+#include "DNA_gpencil_types.h"
 /* end of list */
index 633badb759d3074b9a16ce02e1e3a729aff03e6c..71675ade60584e3f434594d283e39c8216f397ea 100644 (file)
@@ -709,7 +709,7 @@ static PyObject *Blender_Save( PyObject * self, PyObject * args )
                                              "expected filename and optional int (overwrite flag) as arguments" );
 
        for( li = G.main->library.first; li; li = li->id.next ) {
-               if( BLI_streq( li->name, fname ) ) {
+               if( li->parent==NULL && BLI_streq( li->name, fname ) ) {
                        return EXPP_ReturnPyObjError( PyExc_AttributeError,
                                                      "cannot overwrite used library" );
                }
index 799735c2062fc31aebe2b57bd4d4f8f0140df1d0..468263c420817d107099d5631b9120f0b2ce795b 100644 (file)
@@ -1135,9 +1135,78 @@ static PyObject *M_Library_Load(PyObject *self, PyObject * args)
        return (PyObject *)lib;
 }
 
+static PyObject *M_Library_GetPaths(PyObject *self, PyObject * args)
+{      
+       PyObject *list;
+       PyObject *name;
+       int type=0;
+       Library *lib;
+       
+       if( !PyArg_ParseTuple( args, "|i", &type ) || type < 0 || type > 2 ) {
+               return EXPP_ReturnPyObjError( PyExc_TypeError,
+                       "expected an int between 0 and 2." );
+       }
+       
+       list = PyList_New(0);
+       
+       for(lib= G.main->library.first; lib; lib= lib->id.next) {
+               if (type==0) {
+                       /* any type is ok */
+               } else if (type==1 && lib->parent == 0) {
+                       /* only direct linked */
+               } else if (type==2 && lib->parent != 0) {
+                       /* only indirect */
+               } else {
+                       continue; /* incompatible type */
+               }
+               
+               name = PyString_FromString(lib->name);
+               PyList_Append(list, name);
+               Py_DECREF(name);
+       }
+       return list;
+}
+
+static PyObject *M_Library_ReplacePath(PyObject *self, PyObject * args)
+{
+       char *name_from, *name_to;
+       Library *lib;
+       
+       if( !PyArg_ParseTuple( args, "ss", &name_from, &name_to )) {
+               return EXPP_ReturnPyObjError( PyExc_TypeError,
+                       "expected the name of a library path" );
+       }
+       
+       for(lib= G.main->library.first; lib; lib= lib->id.next) {
+               if (strcmp(lib->name, name_from)==0) {
+                       if (lib->parent) {
+                               return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                                       "path is indirectly linked, cannot be changed." );
+                       }
+                       
+                       if (strlen(name_to) > sizeof(lib->name)) {
+                               return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                                       "string length too long, cannot set path." );
+                       }
+                       
+                       strcpy(lib->name, name_to);
+                       Py_RETURN_NONE;
+               }
+       }
+       
+       return EXPP_ReturnPyObjError( PyExc_ValueError,
+               "path given does not exist as a library" );
+}
+
+
+
 static struct PyMethodDef M_Library_methods[] = {
        {"load", (PyCFunction)M_Library_Load, METH_VARARGS,
        "(string) - declare a .blend file for use as a library"},
+       {"paths", (PyCFunction)M_Library_GetPaths, METH_VARARGS,
+       "(type) - return a list of library paths, type 0 for all, 1 only direct links, 2 only indirect links"},
+       {"replace", (PyCFunction)M_Library_ReplacePath, METH_VARARGS,
+       "(from, to) - replace the path of an existing, directly linked library."},
        {NULL, NULL, 0, NULL}
 };
 
index 95de9757b8709c3f81ea686535841ddcf480ff07..2c2e724129ed7a63b048e6d4e78c6a297a5eaaa9 100644 (file)
@@ -40,6 +40,7 @@
 #include "BKE_material.h"
 #include "BKE_utildefines.h"
 #include "BKE_pointcache.h"
+#include "BKE_DerivedMesh.h"
 #include "BIF_editparticle.h"
 #include "BIF_space.h"
 #include "blendef.h"
@@ -799,22 +800,27 @@ static PyObject *Part_freeEdit( BPy_PartSys * self, PyObject * args ){
        Py_RETURN_NONE;
 }
 
-static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){
+static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args )
+{
        ParticleSystem *psys = 0L;
        Object *ob = 0L;
        PyObject *partlist,*seglist;
-       PyObject* loc = 0L;
        ParticleCacheKey **cache,*path;
+       PyObject* loc = 0L;
        ParticleKey state;
-       float cfra=bsystem_time(ob,(float)CFRA,0.0);
+       DerivedMesh* dm;
+       float cfra;
        int i,j,k;
+       float vm[4][4],wm[4][4];
        int     childexists = 0;
        int all = 0;
        int id = 0;
 
+       cfra = bsystem_time(ob,(float)CFRA,0.0);
+
        if( !PyArg_ParseTuple( args, "|ii", &all,&id ) )
                return EXPP_ReturnPyObjError( PyExc_TypeError,
-                               "expected one optional integer as argument" );
+                               "expected two optional integers as arguments" );
 
        psys = self->psys;
        ob = self->object;
@@ -822,88 +828,118 @@ static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){
        if (!ob || !psys)
                Py_RETURN_NONE;
 
-       if (psys->part->type == 2){
-               cache=psys->pathcache;
+       G.rendering = 1;
 
-               /* little hack to calculate hair steps in render mode */
-               psys->renderdata = (void*)(int)1;
+       /* Just to create a valid rendering context */
+       psys_render_set(ob,psys,vm,wm,0,0,0);
 
-               psys_cache_paths(ob, psys, cfra, 1);
+       dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
+       dm->release(dm);
 
-               psys->renderdata = NULL;
+       if ( !psys_check_enabled(ob,psys) ){
+               G.rendering = 0;
+               psys_render_restore(ob,psys);
+               Particle_Recalc(self,1);
+               Py_RETURN_NONE;
+       }
 
-               partlist = PyList_New( 0 );
-               if( !partlist )
-                       return EXPP_ReturnPyObjError( PyExc_MemoryError, "PyList() failed" );
+       partlist = PyList_New( 0 );
+       if( !partlist ){
+               PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
+               goto error;
+       }
 
-               for(i = 0; i < psys->totpart; i++){
-                       path=cache[i];
-                       seglist = PyList_New( 0 );
-                       k = path->steps+1;
-                       for( j = 0; j < k ; j++){
-                               loc = PyTuple_New(3);
-
-                               PyTuple_SetItem(loc,0,PyFloat_FromDouble((double)path->co[0]));
-                               PyTuple_SetItem(loc,1,PyFloat_FromDouble((double)path->co[1]));
-                               PyTuple_SetItem(loc,2,PyFloat_FromDouble((double)path->co[2]));
-
-                               if ( (PyList_Append(seglist,loc) < 0) ){
-                                       Py_DECREF(seglist);
-                                       Py_DECREF(partlist);
-                                       Py_XDECREF(loc);
-                                       return EXPP_ReturnPyObjError( PyExc_RuntimeError,
-                                                       "Couldn't append item to PyList" );
+       if (psys->part->type == PART_HAIR){
+               cache = psys->pathcache;
+
+               if ( ((self->psys->part->draw & PART_DRAW_PARENT) && (self->psys->part->childtype != 0)) || (self->psys->part->childtype == 0) ){
+
+                       for(i = 0; i < psys->totpart; i++){
+                               seglist = PyList_New( 0 );
+                               if (!seglist){
+                                       PyErr_SetString( PyExc_MemoryError,
+                                                       "PyList_New() failed" );
+                                       goto error;
+                               }
+
+                               path=cache[i];
+                               k = path->steps+1;
+                               for( j = 0; j < k ; j++, path++){
+                                       loc = Py_BuildValue("(fff)",(double)path->co[0],
+                                                       (double)path->co[1], (double)path->co[2]);
+
+                                       if (!loc){
+                                               PyErr_SetString( PyExc_RuntimeError,
+                                                               "Couldn't build tuple" );
+                                               goto error;
+                                       }
+
+                                       if ( (PyList_Append(seglist,loc) < 0) ){
+                                               PyErr_SetString( PyExc_RuntimeError,
+                                                               "Couldn't append item to PyList" );
+                                               goto error;
+                                       }
+                                       Py_DECREF(loc); /* PyList_Append increfs */
+                                       loc = NULL;
                                }
-                               Py_DECREF(loc); /* PyList_Append increfs */
-                               path++;
-                       }
 
-                       if ( PyList_Append(partlist,seglist) < 0 ){
-                               Py_DECREF(seglist);
-                               Py_DECREF(partlist);
-                               return EXPP_ReturnPyObjError( PyExc_RuntimeError,
-                                               "Couldn't append item to PyList" );             
+                               if ( PyList_Append(partlist,seglist) < 0 ){
+                                       PyErr_SetString( PyExc_RuntimeError,
+                                                       "Couldn't append item to PyList" );             
+                                       goto error;
+                               }
+                               Py_DECREF(seglist); /* PyList_Append increfs */
+                               seglist = NULL;
                        }
-                       Py_DECREF(seglist); /* PyList_Append increfs */
                }
 
                cache=psys->childcache;
 
                for(i = 0; i < psys->totchild; i++){
-                       path=cache[i];
                        seglist = PyList_New( 0 );
-                       k = path->steps+1;
-                       for( j = 0; j < k ; j++){
-                               loc = PyTuple_New(3);
+                       if (!seglist){
+                               PyErr_SetString( PyExc_MemoryError,
+                                               "PyList_New() failed" );
+                               goto error;
+                       }
 
-                               PyTuple_SetItem(loc,0,PyFloat_FromDouble((double)path->co[0]));
-                               PyTuple_SetItem(loc,1,PyFloat_FromDouble((double)path->co[1]));
-                               PyTuple_SetItem(loc,2,PyFloat_FromDouble((double)path->co[2]));
+                       path=cache[i];
+                       k = path->steps+1;
+                       for( j = 0; j < k ; j++, path++ ){
+                               loc = Py_BuildValue("(fff)",(double)path->co[0],
+                                               (double)path->co[1], (double)path->co[2]);
+
+                               if (!loc){
+                                       PyErr_SetString( PyExc_RuntimeError,
+                                                       "Couldn't build tuple" );
+                                       goto error;
+                               }
 
                                if ( PyList_Append(seglist,loc) < 0){
-                                       Py_DECREF(partlist);
-                                       Py_XDECREF(loc);
-                                       return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                                       PyErr_SetString( PyExc_RuntimeError,
                                                        "Couldn't append item to PyList" );
+                                       goto error;
                                }
                                Py_DECREF(loc);/* PyList_Append increfs */
-                               path++;
+                               loc = NULL;
                        }
 
                        if ( PyList_Append(partlist,seglist) < 0){
-                               Py_DECREF(partlist);
-                               Py_XDECREF(loc);
-                               return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                               PyErr_SetString( PyExc_RuntimeError,
                                                "Couldn't append item to PyList" );     
+                               goto error;
                        }
                        Py_DECREF(seglist); /* PyList_Append increfs */
+                       seglist = NULL;
                }
-               
        } else {
                int init;
-               partlist = PyList_New( 0 );
-               if( !partlist )
-                       return EXPP_ReturnPyObjError( PyExc_MemoryError, "PyList() failed" );
+               char *fmt = NULL;
+
+               if(id)
+                       fmt = "(fffi)";
+               else
+                       fmt = "(fff)";
 
                if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
                        childexists = 1;
@@ -919,55 +955,67 @@ static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){
                                init = 1;
 
                        if (init){
-                               if (!id)
-                                       loc = PyTuple_New(3);
-                               else
-                                       loc = PyTuple_New(4);
-                               PyTuple_SetItem(loc,0,PyFloat_FromDouble((double)state.co[0]));
-                               PyTuple_SetItem(loc,1,PyFloat_FromDouble((double)state.co[1]));
-                               PyTuple_SetItem(loc,2,PyFloat_FromDouble((double)state.co[2]));
-                               if (id)
-                                       PyTuple_SetItem(loc,3,PyInt_FromLong(i));
+                               loc = Py_BuildValue(fmt,(double)state.co[0],
+                                               (double)state.co[1], (double)state.co[2],i);
+                               
+                               if (!loc){
+                                       PyErr_SetString( PyExc_RuntimeError,
+                                                       "Couldn't build tuple" );
+                                       goto error;
+                               }
 
                                if ( PyList_Append(partlist,loc) < 0 ){
-                                       Py_DECREF(partlist);
-                                       Py_XDECREF(loc);
-                                       return EXPP_ReturnPyObjError( PyExc_RuntimeError,
-                                                               "Couldn't append item to PyList" );
+                                       PyErr_SetString( PyExc_RuntimeError,
+                                                       "Couldn't append item to PyList" );
+                                       goto error;
                                }
-                               Py_DECREF(loc);/* PyList_Append increfs */
-                       }
-                       else {
-                               if ( all ){
-                                       if ( PyList_Append(partlist,Py_None) < 0 ){
-                                               Py_DECREF(partlist);
-                                               return EXPP_ReturnPyObjError( PyExc_RuntimeError,
-                                                                       "Couldn't append item to PyList" );
-                                       }
-                                       Py_DECREF(Py_None); /* PyList_Append increfs */
+                               Py_DECREF(loc);
+                               loc = NULL;
+                       } else {
+                               if ( all && PyList_Append(partlist,Py_None) < 0 ){
+                                       PyErr_SetString( PyExc_RuntimeError,
+                                                       "Couldn't append item to PyList" );
+                                       goto error;
                                }
                        }
                }
        }
+
+       psys_render_restore(ob,psys);
+       G.rendering = 0;
+       Particle_Recalc(self,1);
        return partlist;
+
+error:
+       Py_XDECREF(partlist);
+       Py_XDECREF(seglist);
+       Py_XDECREF(loc);
+       psys_render_restore(ob,psys);
+       G.rendering = 0;
+       Particle_Recalc(self,1);
+       return NULL;
 }
 
-static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args ){
+static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args )
+{
        ParticleSystem *psys = 0L;
        Object *ob = 0L;
        PyObject *partlist = 0L;
        PyObject* loc = 0L;
        ParticleKey state;
+       DerivedMesh* dm;
+       float vm[4][4],wm[4][4];
        int i;
        int childexists = 0;
        int all = 0;
        int id = 0;
+    char *fmt = NULL;
 
        float cfra=bsystem_time(ob,(float)CFRA,0.0);
 
        if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
                return EXPP_ReturnPyObjError( PyExc_TypeError,
-                               "expected one optional integer as argument" );
+                               "expected two optional integers as arguments" );
 
        psys = self->psys;
        ob = self->object;
@@ -975,63 +1023,105 @@ static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args ){
        if (!ob || !psys)
                Py_RETURN_NONE;
 
-       if (psys->part->type != 2){
+       G.rendering = 1;
+
+       /* Just to create a valid rendering context */
+       psys_render_set(ob,psys,vm,wm,0,0,0);
+
+       dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
+       dm->release(dm);
+
+       if ( !psys_check_enabled(ob,psys) ){
+               G.rendering = 0;
+               psys_render_restore(ob,psys);
+               Particle_Recalc(self,1);
+               Py_RETURN_NONE;
+       }
+
+       if (psys->part->type != PART_HAIR){
                partlist = PyList_New( 0 );
 
+               if( !partlist ){
+                       PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
+                       goto error;
+               }
+
                if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
                        childexists = 1;
 
+               if(id)
+                       fmt = "(ffffi)";
+               else
+                       fmt = "(ffff)";
+
                for (i = 0; i < psys->totpart + psys->totchild; i++){
                        if (childexists && (i < psys->totpart))
                                continue;
 
                        state.time = cfra;
                        if(psys_get_particle_state(ob,psys,i,&state,0)==0){
-                               if ( all ){
-                                       PyList_Append(partlist,Py_None);
-                                       Py_DECREF(Py_None); /* PyList_Append increfs */
-                                       continue;
-                               } else {
-                                       continue;
+                               if ( all && PyList_Append(partlist,Py_None) < 0){
+                                       PyErr_SetString( PyExc_RuntimeError,
+                                               "Couldn't append item to PyList" );
+                                       goto error;
+                               }
+                       } else {
+                               loc = Py_BuildValue(fmt,(double)state.rot[0], (double)state.rot[1],
+                                               (double)state.rot[2], (double)state.rot[3], i);
+
+                               if (!loc){
+                                       PyErr_SetString( PyExc_RuntimeError,
+                                                       "Couldn't build tuple" );
+                                       goto error;
+                               }
+                               if (PyList_Append(partlist,loc) < 0){
+                                       PyErr_SetString ( PyExc_RuntimeError,
+                                                       "Couldn't append item to PyList" );
+                                       goto error;
                                }
+                               Py_DECREF(loc); /* PyList_Append increfs */
+                               loc = NULL;
                        }
-                       if (!id)
-                               loc = PyTuple_New(4);
-                       else
-                               loc = PyTuple_New(5);
-                       PyTuple_SetItem(loc,0,PyFloat_FromDouble((double)state.rot[0]));
-                       PyTuple_SetItem(loc,1,PyFloat_FromDouble((double)state.rot[1]));
-                       PyTuple_SetItem(loc,2,PyFloat_FromDouble((double)state.rot[2]));
-                       PyTuple_SetItem(loc,3,PyFloat_FromDouble((double)state.rot[3]));
-                       if (id)
-                               PyTuple_SetItem(loc,4,PyInt_FromLong(i));
-                       PyList_Append(partlist,loc);
-                       Py_DECREF(loc); /* PyList_Append increfs */
                }
+       } else {
+               partlist = EXPP_incr_ret( Py_None );
        }
+
+       psys_render_restore(ob,psys);
+       G.rendering = 0;
+       Particle_Recalc(self,1);
        return partlist;
+
+error:
+       Py_XDECREF(partlist);
+       Py_XDECREF(loc);
+       psys_render_restore(ob,psys);
+       G.rendering = 0;
+       Particle_Recalc(self,1);
+       return NULL;
 }
 
-static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args ){
+static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args )
+{
        ParticleKey state;
        ParticleSystem *psys = 0L;
        ParticleData *data;
        Object *ob = 0L;
        PyObject *partlist,*tuple;
-       PyObject* siz = 0L;
+       DerivedMesh* dm;
+       float vm[4][4],wm[4][4];
        float size;
        int i;
        int childexists = 0;
        int all = 0;
        int id = 0;
+    char *fmt = NULL;
 
        float cfra=bsystem_time(ob,(float)CFRA,0.0);
 
        if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
                return EXPP_ReturnPyObjError( PyExc_TypeError,
-                               "expected one optional integer as argument" );
-
-       data = self->psys->particles;
+                               "expected two optional integers as arguments" );
 
        psys = self->psys;
        ob = self->object;
@@ -1039,13 +1129,39 @@ static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args ){
        if (!ob || !psys)
                Py_RETURN_NONE;
 
-               partlist = PyList_New( 0 );
+       G.rendering = 1;
 
-               if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
-                       childexists = 1;
+       /* Just to create a valid rendering context */
+       psys_render_set(ob,psys,vm,wm,0,0,0);
+
+       dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
+       dm->release(dm);
+       data = self->psys->particles;
+
+       if ( !psys_check_enabled(ob,psys) ){
+               psys_render_restore(ob,psys);
+               G.rendering = 0;
+               Particle_Recalc(self,1);
+               Py_RETURN_NONE;
+       }
+
+       partlist = PyList_New( 0 );
+
+       if( !partlist ){
+               PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
+               goto error;
+       }
+
+       if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
+               childexists = 1;
+
+       if(id)
+               fmt = "(fi)";
+       else
+               fmt = "f";
 
-               for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
-               if (psys->part->type != 2){
+       for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
+               if (psys->part->type != PART_HAIR){
                        if (childexists && (i < psys->totpart))
                                continue;
 
@@ -1061,43 +1177,61 @@ static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args ){
                                ChildParticle *cpa= &psys->child[i-psys->totpart];
                                size = psys_get_child_size(psys,cpa,cfra,0);
                        }
-                       if (id){
-                               tuple = PyTuple_New(2);
-                               PyTuple_SetItem(tuple,0,PyFloat_FromDouble((double)size));
-                               PyTuple_SetItem(tuple,1,PyInt_FromLong(i));
-                               PyList_Append(partlist,tuple);
-                               Py_DECREF(tuple);
-                       } else {
-                               siz = PyFloat_FromDouble((double)size);
-                               PyList_Append(partlist,siz);
-                               Py_DECREF(siz);
+
+                       tuple = Py_BuildValue(fmt,(double)size,i);
+
+                       if (!tuple){
+                               PyErr_SetString( PyExc_RuntimeError,
+                                               "Couldn't build tuple" );
+                               goto error;
+                       }
+
+                       if (PyList_Append(partlist,tuple) < 0){
+                               PyErr_SetString( PyExc_RuntimeError,
+                                               "Couldn't append item to PyList" );
+                               goto error;
                        }
+                       Py_DECREF(tuple);
+                       tuple = NULL;
                }
        }
+
+       psys_render_restore(ob,psys);
+       G.rendering = 0;
+       Particle_Recalc(self,1);
        return partlist;
+
+error:
+       Py_XDECREF(partlist);
+       Py_XDECREF(tuple);
+       psys_render_restore(ob,psys);
+       G.rendering = 0;
+       Particle_Recalc(self,1);
+       return NULL;
 }
 
 
-static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args ){
+static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args )
+{
        ParticleKey state;
        ParticleSystem *psys = 0L;
        ParticleData *data;
        Object *ob = 0L;
        PyObject *partlist,*tuple;
-       PyObject* lif = 0L;
+       DerivedMesh* dm;
+       float vm[4][4],wm[4][4];
        float life;
        int i;
        int childexists = 0;
        int all = 0;
        int id = 0;
+       char *fmt = NULL;
 
        float cfra=bsystem_time(ob,(float)CFRA,0.0);
 
        if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
                return EXPP_ReturnPyObjError( PyExc_TypeError,
-                               "expected one optional integer as argument" );
-
-       data = self->psys->particles;
+                               "expected two optional integers as arguments" );
 
        psys = self->psys;
        ob = self->object;
@@ -1105,13 +1239,37 @@ static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args ){
        if (!ob || !psys)
                Py_RETURN_NONE;
 
-               partlist = PyList_New( 0 );
+       G.rendering = 1;
 
-               if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
-                       childexists = 1;
+       /* Just to create a valid rendering context */
+       psys_render_set(ob,psys,vm,wm,0,0,0);
+
+       dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
+       dm->release(dm);
+       data = self->psys->particles;
+
+       if ( !psys_check_enabled(ob,psys) ){
+               psys_render_restore(ob,psys);
+               G.rendering = 0;
+               Py_RETURN_NONE;
+       }
+
+       partlist = PyList_New( 0 );
+       if( !partlist ){
+               PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
+               goto error;
+       }
+
+       if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
+               childexists = 1;
+
+       if(id)
+               fmt = "(fi)";
+       else
+               fmt = "f";
 
-               for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
-               if (psys->part->type != 2){
+       for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
+               if (psys->part->type != PART_HAIR){
 
                        if (childexists && (i < psys->totpart))
                                continue;
@@ -1128,20 +1286,37 @@ static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args ){
                                ChildParticle *cpa= &psys->child[i-psys->totpart];
                                life = psys_get_child_time(psys,cpa,cfra);
                        }
-                       if (id){
-                               tuple = PyTuple_New(2);
-                               PyTuple_SetItem(tuple,0,PyFloat_FromDouble((double)life));
-                               PyTuple_SetItem(tuple,1,PyInt_FromLong(i));
-                               PyList_Append(partlist,tuple);
-                               Py_DECREF(tuple);
-                       } else {
-                               lif = PyFloat_FromDouble((double)life);
-                               PyList_Append(partlist,lif);
-                               Py_DECREF(lif);
+
+                       tuple = Py_BuildValue(fmt,(double)life,i);
+
+                       if (!tuple){
+                               PyErr_SetString( PyExc_RuntimeError,
+                                               "Couldn't build tuple" );
+                               goto error;
                        }
+
+                       if (PyList_Append(partlist,tuple) < 0){
+                               PyErr_SetString( PyExc_RuntimeError,
+                                               "Couldn't append item to PyList" );
+                               goto error;
+                       }
+                       Py_DECREF(tuple);
+                       tuple = NULL;
                }
        }
+
+       psys_render_restore(ob,psys);
+       G.rendering = 0;
+       Particle_Recalc(self,1);
        return partlist;
+
+error:
+       Py_XDECREF(partlist);
+       Py_XDECREF(tuple);
+       psys_render_restore(ob,psys);
+       G.rendering = 0;
+       Particle_Recalc(self,1);
+       return NULL;
 }
 
 
@@ -1376,11 +1551,8 @@ static int Part_set2d( BPy_PartSys * self, PyObject * args )
 {
        int number;
 
-       if( !PyInt_Check( args ) ) {
-               char errstr[128];
-               sprintf ( errstr, "expected int argument" );
-               return EXPP_ReturnIntError( PyExc_TypeError, errstr );
-       }
+       if( !PyInt_Check( args ) )
+               return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
 
        number = PyInt_AS_LONG( args );
 
@@ -1526,7 +1698,7 @@ static int Part_setRandEmission( BPy_PartSys * self, PyObject * args )
 
 static PyObject *Part_getRandEmission( BPy_PartSys * self )
 {
-       return PyInt_FromLong( ((long)( self->psys->part->flag & PART_BOIDS_2D )) > 0 );
+       return PyInt_FromLong( ((long)( self->psys->part->flag & PART_TRAND )) > 0 );
 }
 
 static int Part_setParticleDist( BPy_PartSys * self, PyObject * args )
@@ -1546,7 +1718,7 @@ static int Part_setParticleDist( BPy_PartSys * self, PyObject * args )
                return EXPP_ReturnIntError( PyExc_TypeError, errstr );
        }
 
-       self->psys->part->from = number;
+       self->psys->part->from = (short)number;
 
        Particle_RecalcPsys_distr(self,1);
 
@@ -1603,7 +1775,7 @@ static int Part_setDist( BPy_PartSys * self, PyObject * args )
                return EXPP_ReturnIntError( PyExc_TypeError, errstr );
        }
 
-       self->psys->part->distr = number;
+       self->psys->part->distr = (short)number;
 
        Particle_RecalcPsys_distr(self,1);
 
@@ -1731,7 +1903,7 @@ static int Part_setTargetPsys( BPy_PartSys * self, PyObject * args ){
 
        res = EXPP_setIValueRange( args, &self->psys->target_psys, 0, tottpsys, 'h' );
 
-       if((psys=psys_get_current(ob))){
+       if( ( psys = psys_get_current(ob) ) ){
                if(psys->keyed_ob==ob || psys->target_ob==ob){
                        if(psys->keyed_ob==ob)
                                psys->keyed_ob=NULL;
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 47bd7fdb763efafd334438c4eea7bfe24f2efff2..daa6a186531958a3e555b90671efe661bdc7034c 100644 (file)
@@ -27,17 +27,37 @@ Example::
 """
 
 def load(filename,relative=False):
-  """
-  Select an existing .blend file for use as a library.  Unlike the 
-  Library module, multiple libraries can be defined at the same time.  
-  
-  @type filename: string
-  @param filename: The filename of a Blender file. Filenames starting with "//" will be loaded relative to the blend file's location.
-  @type relative: boolean
-  @param relative: Convert relative paths to absolute paths (default).  Setting this parameter to True will leave paths relative.
-  @rtype: Library
-  @return: return a L{Library} object.
-  """
+       """
+       Select an existing .blend file for use as a library.  Unlike the 
+       Library module, multiple libraries can be defined at the same time.  
+       
+       @type filename: string
+       @param filename: The filename of a Blender file. Filenames starting with "//" will be loaded relative to the blend file's location.
+       @type relative: boolean
+       @param relative: Convert relative paths to absolute paths (default).  Setting this parameter to True will leave paths relative.
+       @rtype: Library
+       @return: return a L{Library} object.
+       """
+
+def paths(link=0):
+       """
+       Returns a list of paths used in the current blend file.
+       
+       @type link: int
+       @param link: 0 (default if no args given) for all library paths, 1 for directly linked library paths only, 2 for indirectly linked library paths only.
+       @rtype: List
+       @return: return a list of path strings.
+       """
+
+def replace(pathFrom, pathTo):
+       """
+       Replaces an existing directly linked path.
+       
+       @type pathFrom: string
+       @param pathFrom: An existing library path.
+       @type pathTo: string
+       @param pathTo: A new library path.
+       """
 
 class Libraries:
        """
index 192ecd5355b3a92383239d16e8a0efdd7b00b28e..511ad81b45f0ccc5fe51ed305e6ca2f084e25f60 100644 (file)
@@ -56,17 +56,17 @@ class Particle:
        @type type: int
        @ivar resolutionGrid: The resolution of the particle grid.
        @type resolutionGrid: int
-       @ivar startFrame: Frame # to start emitting particles.
+       @ivar startFrame: Frame number to start emitting particles.
        @type startFrame: float
-       @ivar endFrame: Frame # to stop emitting particles.
+       @ivar endFrame: Frame number to stop emitting particles.
        @type endFrame: float
        @ivar editable: Finalize hair to enable editing in particle mode.
        @type editable: int
        @ivar amount: The total number of particles.
        @type amount: int
-       @ivar multireact: React multiple times ( Paricle.REACTON[ 'NEAR' | 'COLLISION' | 'DEATH' ] ).
+       @ivar multireact: React multiple times ( Particle.REACTON[ 'NEAR' | 'COLLISION' | 'DEATH' ] ).
        @type multireact: int
-       @ivar reactshape: Power of reaction strength dependence on distance to target.
+       @ivar reactshape: Power of reaction strength, dependent on distance to target.
        @type reactshape: float
        @ivar hairSegments: Amount of hair segments.
        @type hairSegments: int
@@ -74,13 +74,13 @@ class Particle:
        @type lifetime: float
        @ivar randlife: Give the particle life a random variation.
        @type randlife: float
-       @ivar randemission: Give the particle life a random variation
+       @ivar randemission: Emit particles in random order.
        @type randemission: int
-       @ivar particleDistribution: Where to emit particles from  Paricle.EMITFROM[ 'PARTICLE' | 'VOLUME' | 'FACES' | 'VERTS' ] )
+       @ivar particleDistribution: Where to emit particles from  ( Particle.EMITFROM[ 'PARTICLE' | 'VOLUME' | 'FACES' | 'VERTS' ] )
        @type particleDistribution: int
        @ivar evenDistribution: Use even distribution from faces based on face areas or edge lengths.
        @type evenDistribution: int
-       @ivar distribution: How to distribute particles on selected element Paricle.DISTRIBUTION[ 'GRID' | 'RANDOM' | 'JITTERED' ] ).
+       @ivar distribution: How to distribute particles on selected element ( Particle.DISTRIBUTION[ 'GRID' | 'RANDOM' | 'JITTERED' ] ).
        @type distribution: int
        @ivar jitterAmount: Amount of jitter applied to the sampling.
        @type jitterAmount: float
@@ -131,237 +131,56 @@ class Particle:
                Get the particles locations.
                A list of tuple is returned in particle mode.
                A list of list of tuple is returned in hair mode.
-               The tuple is a vector list of 3 or 4 floats in world space (x,y,z, optionnaly the particle's id).
+               The tuple is a vector of 3 or 4 floats in world space (x,y,z,
+optionally the particle's id).
                @type all: int
                @param all: if not 0 export all particles (uninitialized (unborn or died)particles exported as None).
                @type id: int
                @param id: add the particle id in the end of the vector tuple
-               @rtype: list of vectors (tuple of 3 floats and optionnaly the id) or list of list of vectors
-               @return: list of vectors or list of list of vectors (hair mode)
+               @rtype: list of vectors (tuple of 3 floats and optionally the id) or list of list of vectors
+               @return: list of vectors or list of list of vectors (hair mode) or None if system is disabled
                """
        def getRot(all=0,id=0):
                """
-               Get the particles rotations as quaternion.
+               Get the particles' rotations as quaternion.
                A list of tuple is returned in particle mode.
-               The tuple is a vector list of 4 or 5 floats (x,y,z,w, optionnaly the id of the particle).
+               The tuple is vector of 4 or 5 floats (x,y,z,w, optionally the id of the particle).
                
                @type all: int
-               @param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None).
+               @param all: if not 0, export all particles (uninitialized (unborn or died) particles exported as None).
                @type id: int
                @param id: add the particle id in the return tuple
                @rtype: list of tuple of 4 or 5 elements (if id is not zero)
-               @return: list of 4-tuples
+               @return: list of 4-tuples or None if system is disabled
                """
                
        def getMat():
                """
-               Get the particles material.
+               Get the particles' material.
                @rtype: Blender Material
-               @return: The marterial assigned to particles
+               @return: The material assigned to particles
                """
                
        def getSize(all=0,id=0):
                """
-               Get the particles size.
+               Get the particles' size.
                A list of float or list of tuple (particle's size,particle's id).
                @type all: int
-               @param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None).
+               @param all: if not 0, export all particles (uninitialized (unborn or died) particles exported as None).
                @type id: int
                @param id: add the particle id in the return tuple
                @rtype: list of floats
-               @return: list of floats or list of tuples if id is not zero (size,id).
+               @return: list of floats or list of tuples if id is not zero (size,id) or None if system is disabled.
                """
                
        def getAge(all=0,id=0):
                """
-               Get the particles age.
-               A list of float or list of tuple (particle's age,particle's id).
+               Get the particles' age.
+               A list of float or list of tuple (particle's age, particle's id).
                @type all: int
-               @param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None).
+               @param all: if not 0, export all particles (uninitialized (unborn or died) particles exported as None).
                @type id: int
                @param id: add the particle id in the return tuple
                @rtype: list of floats
-               @return: list of floats or list of tuples if id is not zero (size,id).
-               """
-# Blender.Object module and the Object PyType object
-
-"""
-The Blender.Particle submodule
-
-
-Particle
-========
-
-This module provides access to the B{Particle} in Blender.
-
-@type TYPE: readonly dictionary
-@var TYPE: Constant dict used for with L{Particle.TYPE}
-               - HAIR: set particle system to hair mode.
-               - REACTOR: set particle system to reactor mode.
-               - EMITTER: set particle system to emitter mode.
-@type DISTRIBUTION: readonly dictionary
-@var DISTRIBUTION: Constant dict used for with L{Particle.DISTRIBUTION}
-               - GRID: set grid distribution.
-               - RANDOM: set random distribution.
-               - JITTERED: set jittered distribution.
-@type EMITFROM: readonly dictionary
-@var EMITFROM: Constant dict used for with L{Particle.EMITFROM}
-               - VERTS: set particles emit from vertices
-               - FACES: set particles emit from faces
-               - VOLUME: set particles emit from volume
-               - PARTICLE: set particles emit from particles
-@type REACTON: readonly dictionary
-@var REACTON: Constant dict used for with L{Particle.REACTON}
-               - NEAR: react on near
-               - COLLISION: react on collision
-               - DEATH: react on death
-@type DRAWAS: readonly dictionary
-@var DRAWAS: Constant dict used for with L{Particle.DRAWAS}
-               - NONE: Don't draw
-               - POINT: Draw as point
-               - CIRCLE: Draw as circles
-               - CROSS: Draw as crosses
-               - AXIS: Draw as axis
-               - LINE: Draw as lines
-               - PATH: Draw pathes
-               - OBJECT: Draw object
-               - GROUP: Draw goup
-               - BILLBOARD: Draw as billboard 
-"""
-
-def Get(name):
-               """
-               Get the particle system of the object "name".
-               @type name: string
-               @return: The particle system of the object.
-               """
-def New(name):
-               """
-               Assign a new particle system to the object "name".
-               @type name: string
-               @return: The newly created particle system.
-               """
-
-class Particle:
-       """
-       The Particle object
-       ===================
-               This object gives access to paticles data.
-               
-       @ivar seed: Set an offset in the random table.
-       @type seed: int
-       @ivar type: Type of particle system ( Particle.TYPE[ 'HAIR' | 'REACTOR' | 'EMITTER' ] ).
-       @type type: int
-       @ivar resolutionGrid: The resolution of the particle grid.
-       @type resolutionGrid: int
-       @ivar startFrame: Frame # to start emitting particles.
-       @type startFrame: float
-       @ivar endFrame: Frame # to stop emitting particles.
-       @type endFrame: float
-       @ivar editable: Finalize hair to enable editing in particle mode.
-       @type editable: int
-       @ivar amount: The total number of particles.
-       @type amount: int
-       @ivar multireact: React multiple times ( Paricle.REACTON[ 'NEAR' | 'COLLISION' | 'DEATH' ] ).
-       @type multireact: int
-       @ivar reactshape: Power of reaction strength dependence on distance to target.
-       @type reactshape: float
-       @ivar hairSegments: Amount of hair segments.
-       @type hairSegments: int
-       @ivar lifetime: Specify the life span of the particles.
-       @type lifetime: float
-       @ivar randlife: Give the particle life a random variation.
-       @type randlife: float
-       @ivar randemission: Give the particle life a random variation
-       @type randemission: int
-       @ivar particleDistribution: Where to emit particles from  Paricle.EMITFROM[ 'PARTICLE' | 'VOLUME' | 'FACES' | 'VERTS' ] )
-       @type particleDistribution: int
-       @ivar evenDistribution: Use even distribution from faces based on face areas or edge lengths.
-       @type evenDistribution: int
-       @ivar distribution: How to distribute particles on selected element Paricle.DISTRIBUTION[ 'GRID' | 'RANDOM' | 'JITTERED' ] ).
-       @type distribution: int
-       @ivar jitterAmount: Amount of jitter applied to the sampling.
-       @type jitterAmount: float
-       @ivar pf: Emission locations / face (0 = automatic).
-       @type pf:int
-       @ivar invert: Invert what is considered object and what is not.
-       @type invert: int
-       @ivar targetObject: The object that has the target particle system (empty if same object).
-       @type targetObject: Blender object
-       @ivar targetpsys: The target particle system number in the object.
-       @type targetpsys: int
-       @ivar 2d: Constrain boids to a surface.
-       @type 2d: float
-       @ivar maxvel: Maximum velocity.
-       @type maxvel: float
-       @ivar avvel: The usual speed % of max velocity.
-       @type avvel: float
-       @ivar latacc: Lateral acceleration % of max velocity
-       @type latacc: float
-       @ivar tanacc: Tangential acceleration % of max velocity
-       @type tanacc: float
-       @ivar groundz: Default Z value.
-       @type groundz: float
-       @ivar object: Constrain boids to object's surface.
-       @type object: Blender Object
-       @ivar renderEmitter: Render emitter object.
-       @type renderEmitter: int
-       @ivar displayPercentage: Particle display percentage.
-       @type displayPercentage: int
-       @ivar hairDisplayStep: How many steps paths are drawn with (power of 2) in visu mode.
-       @type hairDisplayStep: int
-       @ivar hairRenderStep: How many steps paths are rendered with (power of 2) in render mode."
-       @type hairRenderStep: int
-       @ivar duplicateObject: Get the duplicate object.
-       @type duplicateObject: Blender Object
-       @ivar drawAs: Get draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ]).
-       @type drawAs: int
-       """
-       def freeEdit():
-               """
-               Free edit mode.
-               @return: None
-               """
-
-       def getLoc(all=0,id=0):
-               """
-               Get the particles locations.
-               A list of tuple is returned in particle mode.
-               A list of list of tuple is returned in hair mode.
-               The tuple is a vector list of 3 floats in world space.
-               @type all: int
-               @param all: if not 0 export all particles (uninitialized (unborn or died)particles exported as None).
-               @type id: int
-               @param id: add the particle id in the end of the vector tuple
-               @rtype: list of vectors (tuple of 3 floats and optionnaly the id) or list of list of vectors
-               @return: list of vectors or list of list of vectors (hair mode)
-               """
-       def getRot(all=0,id=0):
-               """
-               Get the particles rotations as quaternion.
-               A list of tuple is returned in particle mode.
-               The tuple is a vector list of 4 floats (quaternion).
-               @type all: int
-               @param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None).
-               @type id: int
-               @param id: add the particle id in the return tuple
-               @rtype: list of tuple of 4 or 5 elements (if id is not zero)
-               @return: list of 4-tuples
-               """
-       def getMat():
-               """
-               Get the particles material.
-               @rtype: Blender Material
-               @return: The marterial assigned to particles
-               """
-       def getSize(all=0,id=0):
-               """
-               Get the particles size.
-               A list of float.
-               @type all: int
-               @param all: if not 0 export all particles (uninitialized (unborn or died) particles exported as None).
-               @type id: int
-               @param id: add the particle id in the return tuple
-               @rtype: list of floats
-               @return: list of floats or list of tuples if id is not zero (size,id).
+               @return: list of floats or list of tuples if id is not zero (size,id) or None if system is disabled.
                """
index 475a4fc5b10c902cbf5dc9078d0b9c3b7dff98f8..d4dc83e84a039491b9c8e9c24e8b07b4eaf83893 100644 (file)
@@ -833,9 +833,7 @@ class RenderData:
 
   def enableCropping(toggle):
     """
-    Enable/disable exclusion of border rendering from total image.
-    @type toggle: int
-    @param toggle: pass 1 for on / 0 for off
+    Deprecated: see the L{crop} attribute.
     """
 
   def setImageType(type):
index a6f35bf4d5d81c58506f7440e2133cad75ef06eb..6fc3a2b18d12ec9bc67b2e0d7e1af0d3b6c169af 100644 (file)
@@ -987,7 +987,7 @@ PyObject *RenderData_EnableCropping( void )
 /*     return M_Render_BitToggleInt( args, R_MOVIECROP,
                                      &self->renderContext->mode );
 */
-       printf("cropping option is now default, obsolete\n");
+       printf("obsolete: movie cropping option is now default\n");
        Py_RETURN_NONE;
 }
 
index 67be0ce4c005f62ff24583887429bd85cf1c3fb8..4520e4c10bb3f6f42b9f6fb5cfddc8e483342062 100644 (file)
@@ -671,8 +671,10 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
        RenderPass *zpass;
        GroupObject *go;
        LampRen *lar;
-       
-       int x, y;
+       RenderLayer *rlpp[RE_MAX_OSA];
+
+       int totsample, fullsample, sample;
+       int x, y,od;
        short first_lamp;
        float *zrect;
        float *rgbrect;
@@ -683,7 +685,10 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
        
        fac = 0.5;
        facm = 1.0 - fac;
-       
+
+       totsample= get_sample_layers(pa, rl, rlpp);
+       fullsample= (totsample > 1);
+
        /* check that z pass is enabled */
        if(pa->rectz==NULL) return;
        for(zpass= rl->passes.first; zpass; zpass= zpass->next)
@@ -708,9 +713,10 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
        
        zrect = zpass->rect;
        rgbrect = rl->rectf;
+       od=0;
        /* for each x,y and sun lamp*/
        for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
-               for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, zrect++, rgbrect+=4) {
+               for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, zrect++, od++) {
                        
                        first_lamp = 1;
                        for(go=R.lights.first; go; go= go->next) {
@@ -724,7 +730,7 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
                                        }
 
                                        if(lar->sunsky->effect_type & LA_SUN_EFFECT_AP){        
-                                               VECCOPY(tmp_rgb, rgbrect);
+                                               VECCOPY(tmp_rgb, (float*)(rgbrect+4*od));
 
                                                shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect);
                                                
@@ -743,7 +749,16 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
 
                        /* if at least for one sun lamp aerial perspective was applied*/
                        if(first_lamp==0)
-                               VECCOPY(rgbrect, rgb);
+                       {
+                               if(fullsample) {
+                                       for(sample=0; sample<totsample; sample++) {
+                                               VECCOPY((float*)(rlpp[sample]->rectf + od*4), rgb);
+                                       }
+                               }
+                               else {
+                                       VECCOPY((float*)(rgbrect+4*od), rgb);
+                               }
+                       }
                }
        }
 }
index 0928042729a5c65a26cf3fb467e3246e43fbb567..5b69323667edce2188c09b7045d5431f0c430a8b 100644 (file)
@@ -1379,6 +1379,8 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
                }
                
                /* specularity */
+               shadfac[3]*= phongcorr; /* note, shadfac not allowed to be stored nonlocal */
+               
                if(shadfac[3]>0.0f && shi->spec!=0.0f && !(lar->mode & LA_NO_SPEC) && !(lar->mode & LA_ONLYSHADOW)) {
                        
                        if(!(passflag & (SCE_PASS_COMBINED|SCE_PASS_SPEC)));
index 579905315bb4c46d06e15b3b2f337cd33cf502cf..c91c9e2f799fb42121e2b58c4cf16b72374b3069 100644 (file)
@@ -3545,7 +3545,7 @@ void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
        
        for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
                float *col= NULL;
-               int pixsize= 0;
+               int pixsize= 3;
                
                switch(rpass->passtype) {
                        case SCE_PASS_RGBA:
@@ -3580,6 +3580,10 @@ void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
                                col= &shr->mist;
                                pixsize= 1;
                                break;
+                       case SCE_PASS_Z:
+                               col= &shr->z;
+                               pixsize= 1;
+                               break;
                        case SCE_PASS_VECTOR:
                                
                                {
@@ -3612,14 +3616,18 @@ void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
                        
                        for(samp= 1; samp<R.osa; samp++, fp+=delta) {
                                col[0]+= fp[0];
-                               col[1]+= fp[1];
-                               col[2]+= fp[2];
-                               if(pixsize) col[3]+= fp[3];
+                               if(pixsize>1) {
+                                       col[1]+= fp[1];
+                                       col[2]+= fp[2];
+                                       if(pixsize==4) col[3]+= fp[3];
+                               }
                        }
                        col[0]*= weight;
-                       col[1]*= weight;
-                       col[2]*= weight;
-                       if(pixsize) col[3]*= weight;
+                       if(pixsize>1) {
+                               col[1]*= weight;
+                               col[2]*= weight;
+                               if(pixsize==4) col[3]*= weight;
+                       }
                }
        }
                                
@@ -3973,7 +3981,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
 
        /* general shader info, passes */
        shade_sample_initialize(&ssamp, pa, rl);
-       addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
+       addpassflag= rl->passflag & ~(SCE_PASS_COMBINED);
        addzbuf= rl->passflag & SCE_PASS_Z;
        
        if(R.osa)
index 7eff79fec88da0348d371a04e5bea787ab80792e..529a795a101e90c7167b07838b04ae01e5d1e48f 100644 (file)
@@ -513,7 +513,6 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
                                } else {
                                        editmesh_deselect_by_material(G.obedit->actcol-1);
                                }
-                               allqueue(REDRAWVIEW3D, 0);
                        }
                        else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
                                nu= editNurb.first;
@@ -553,8 +552,9 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
                                        nu= nu->next;
                                }
                                BIF_undo_push("Select material index");
-                               allqueue(REDRAWVIEW3D, 0);
                        }
+                       allqueue(REDRAWIMAGE, 0);
+                       allqueue(REDRAWVIEW3D, 0);
                }
                countall();
                break;
@@ -5153,32 +5153,6 @@ static void verify_posegroup_groupname(void *arg1, void *arg2)
        BLI_uniquename(&pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32);
 }
 
-static char *build_colorsets_menustr ()
-{
-       DynStr *pupds= BLI_dynstr_new();
-       char *str;
-       char buf[48];
-       int i;
-       
-       /* add title first (and the "default" entry) */
-       BLI_dynstr_append(pupds, "Bone Color Set%t|Default Colors%x0|");
-       
-       /* loop through set indices, adding them */
-       for (i=1; i<21; i++) {
-               sprintf(buf, "%d - Theme Color Set%%x%d|", i, i);
-               BLI_dynstr_append(pupds, buf);
-       }
-       
-       /* add the 'custom' entry */
-       BLI_dynstr_append(pupds, "Custom Set %x-1");
-       
-       /* convert to normal MEM_malloc'd string */
-       str= BLI_dynstr_get_cstring(pupds);
-       BLI_dynstr_free(pupds);
-       
-       return str;
-}
-
 static void editing_panel_links(Object *ob)
 {
        uiBlock *block;
@@ -5338,32 +5312,14 @@ static void editing_panel_links(Object *ob)
                        /* color set for 'active' group */
                        if (pose->active_group && grp) {
                                uiBlockBeginAlign(block);
-                                       menustr= build_colorsets_menustr();
+                                       menustr= BIF_ThemeColorSetsPup(1);
                                        uiDefButI(block, MENU,B_POSEGRP_RECALC, menustr, xco,85,140,19, &grp->customCol, -1, 20, 0.0, 0.0, "Index of set of Custom Colors to shade Group's bones with. 0 = Use Default Color Scheme, -1 = Use Custom Color Scheme");                                            
                                        MEM_freeN(menustr);
                                        
                                        /* show color-selection/preview */
                                        if (grp->customCol) {
-                                               if (grp->customCol > 0) {
-                                                       /* copy theme colors on-to group's custom color in case user tries to edit color */
-                                                       bTheme *btheme= U.themes.first;
-                                                       ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)];
-                                                       
-                                                       memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
-                                               }
-                                               else {
-                                                       /* init custom colors with a generic multi-color rgb set, if not initialised already */
-                                                       if (grp->cs.solid[0] == 0) {
-                                                               /* define for setting colors in theme below */
-                                                               #define SETCOL(col, r, g, b, a)  col[0]=r; col[1]=g; col[2]= b; col[3]= a;
-                                                               
-                                                               SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
-                                                               SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
-                                                               SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
-                                                               
-                                                               #undef SETCOL
-                                                       }
-                                               }
+                                               /* do color copying/init (to stay up to date) */
+                                               actionbone_group_copycolors(grp, 1);
                                                
                                                /* color changing */
                                                uiDefButC(block, COL, B_POSEGRP_MCUSTOM, "",            xco, 65, 30, 19, grp->cs.solid, 0, 0, 0, 0, "Color to use for surface of bones");
index cc4df06e22d49f306bfacbd6409c01525dcaf6b9..6b29a05bd22145dcfce622b0d4e46a5d2b14e142 100644 (file)
@@ -2062,7 +2062,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,7 +2084,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|-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");
 
@@ -2124,7 +2124,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 +2133,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, "");
@@ -2536,11 +2538,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
                                break;
                        case ACT_2DFILTER_CUSTOMFILTER:
                                uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30,yco-44,width-60,19,&tdfa->int_arg,0.0,MAX_RENDER_PASS-1,0.0,0.0,"Set motion blur value");
-                               uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width/2-32, 19, &tdfa->text, "");
-                               uiDefButS(block, TOG|BIT|0, B_REDR, "Depth", xco+width/2+2 , yco - 64, width/4-16 , 19,
-                                               &tdfa->texture_flag, 0.0, 0.0, 0, 0, "Includes Depth Texture (bgl_DepthTexture)");
-                               uiDefButS(block, TOG|BIT|1, B_REDR, "Luminance", xco+3*width/4-14 , yco - 64, width/4-16 , 19,
-                                               &tdfa->texture_flag, 0.0, 0.0, 0, 0, "Includes Luminance Texture (bgl_LuminanceTexture)");
+                               uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width-60, 19, &tdfa->text, "");
                                break;
                }
                
index a58d44538a27a78816910566a5faeefba5e35a23..8b35f90ea9d4d96a68a3e27aaaa68be7ad10f431 100644 (file)
@@ -137,36 +137,42 @@ static void load_new_sample(char *str)    /* called from fileselect */
        bSample *sample, *newsample;
 
        sound = G.buts->lockpoin;
+       
+       /* No Sound or Selected the same sample as we alredy have, just ignore */
+       if (sound==NULL || str==sound->name)
+               return;
+               
+       if (sizeof(sound->sample->name) < strlen(str)) {
+               error("Path too long: %s", str);
+               return;
+       }
+               
+       // save values
+       sample = sound->sample;
+       strcpy(name, sound->sample->name);      
+       strcpy(sound->name, str);
+       sound_set_sample(sound, NULL);
+       sound_initialize_sample(sound);
 
-       if (sound) {
-               // save values
-               sample = sound->sample;
-               strcpy(name, sound->sample->name);
-
-               strcpy(sound->name, str);
-               sound_set_sample(sound, NULL);
-               sound_initialize_sample(sound);
-
-               if (sound->sample->type == SAMPLE_INVALID) {
-                       error("Not a valid sample: %s", str);
+       if (sound->sample->type == SAMPLE_INVALID) {
+               error("Not a valid sample: %s", str);
 
-                       newsample = sound->sample;
+               newsample = sound->sample;
 
-                       // restore values
-                       strcpy(sound->name, name);
-                       sound_set_sample(sound, sample);
+               // restore values
+               strcpy(sound->name, name);
+               sound_set_sample(sound, sample);
 
-                       // remove invalid sample
+               // remove invalid sample
 
-                       sound_free_sample(newsample);
-                       BLI_remlink(samples, newsample);
-                       MEM_freeN(newsample);
-               }
+               sound_free_sample(newsample);
+               BLI_remlink(samples, newsample);
+               MEM_freeN(newsample);
+               return;
        }
-
+       
        BIF_undo_push("Load new audio file");
        allqueue(REDRAWBUTSSCENE, 0);
-
 }
 
 
@@ -403,7 +409,7 @@ static void sound_panel_sound(bSound *sound)
                sample = sound->sample;
 
                /* info string */
-               if (sound->sample && sound->sample->len) {
+               if (sound->sample && sound->sample->len && sound->sample->channels && sound->sample->bits) {
                        char *tmp;
                        if (sound->sample->channels == 1) tmp= "Mono";
                        else if (sound->sample->channels == 2) tmp= "Stereo";
@@ -1174,18 +1180,18 @@ static void seq_panel_proxy()
                             130,140,120,19, &last_seq->flag, 
                             0.0, 21.0, 100, 0, 
                             "Use a custom directory to store data");
-       }
 
-       if (last_seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
-               uiDefIconBut(block, BUT, B_SEQ_SEL_PROXY_DIR, 
-                            ICON_FILESEL, 10, 120, 20, 20, 0, 0, 0, 0, 0, 
-                            "Select the directory/name for "
-                            "the proxy storage");
+               if (last_seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
+                       uiDefIconBut(block, BUT, B_SEQ_SEL_PROXY_DIR, 
+                                    ICON_FILESEL, 10, 120, 20, 20, 0, 0, 0, 0, 0, 
+                                    "Select the directory/name for "
+                                    "the proxy storage");
 
-               uiDefBut(block, TEX, 
-                        B_SEQ_BUT_RELOAD, "Dir: ", 
-                        30,120,220,20, last_seq->strip->proxy->dir, 
-                        0.0, 160.0, 100, 0, "");
+                       uiDefBut(block, TEX, 
+                                B_SEQ_BUT_RELOAD, "Dir: ", 
+                                30,120,220,20, last_seq->strip->proxy->dir, 
+                                0.0, 160.0, 100, 0, "");
+               }
        }
 
        if (last_seq->flag & SEQ_USE_PROXY) {
index 89466151a39f9216e6cbdac597c95587ae4b35e5..9b1af3f1a065b7eb588a01ed07d4693435528c3a 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <math.h>
 #include <stdlib.h>
+#include <string.h>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -56,6 +57,8 @@
 #include "DNA_space_types.h"
 #include "DNA_constraint_types.h"
 #include "DNA_key_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_gpencil_types.h"
 
 #include "BKE_action.h"
 #include "BKE_depsgraph.h"
@@ -72,6 +75,7 @@
 #include "BIF_editnla.h"
 #include "BIF_interface.h"
 #include "BIF_interface_icons.h"
+#include "BIF_drawgpencil.h"
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
 #include "BIF_resources.h"
@@ -81,6 +85,7 @@
 
 #include "BDR_drawaction.h"
 #include "BDR_editcurve.h"
+#include "BDR_gpencil.h"
 
 #include "BSE_drawnla.h"
 #include "BSE_drawipo.h"
@@ -620,6 +625,28 @@ static void draw_channel_names(void)
                                        sprintf(name, "Constraint");
                                }
                                        break;
+                               case ACTTYPE_GPLAYER: /* gpencil layer */
+                               {
+                                       bGPDlayer *gpl = (bGPDlayer *)ale->data;
+                                       
+                                       indent = 0;
+                                       special = -1;
+                                       expand = -1;
+                                               
+                                       if (EDITABLE_GPL(gpl))
+                                               protect = ICON_UNLOCKED;
+                                       else
+                                               protect = ICON_LOCKED;
+                                               
+                                       if (gpl->flag & GP_LAYER_HIDE)
+                                               mute = ICON_MUTE_IPO_ON;
+                                       else
+                                               mute = ICON_MUTE_IPO_OFF;
+                                       
+                                       sel = SEL_GPL(gpl);
+                                       BLI_snprintf(name, 32, gpl->info);
+                               }
+                                       break;
                        }       
 
                        /* now, start drawing based on this information */
@@ -825,6 +852,12 @@ static void draw_channel_strips(void)
                                        sel = SEL_ICU(icu);
                                }
                                        break;
+                               case ACTTYPE_GPLAYER:
+                               {
+                                       bGPDlayer *gpl = (bGPDlayer *)ale->data;
+                                       sel = SEL_GPL(gpl);
+                               }
+                                       break;
                        }
                        
                        if (datatype == ACTCONT_ACTION) {
@@ -863,6 +896,19 @@ static void draw_channel_strips(void)
                                glColor4ub(col2[0], col2[1], col2[2], 0x44);
                                glRectf(frame1_x, channel_y-CHANNELHEIGHT/2, G.v2d->hor.xmax,  channel_y+CHANNELHEIGHT/2);
                        }
+                       else if (datatype == ACTCONT_GPENCIL) {
+                               gla2DDrawTranslatePt(di, G.v2d->cur.xmin, y, &frame1_x, &channel_y);
+                               
+                               /* frames less than one get less saturated background */
+                               if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22);
+                               else glColor4ub(col2[0], col2[1], col2[2], 0x22);
+                               glRectf(0, channel_y-CHANNELHEIGHT/2, frame1_x, channel_y+CHANNELHEIGHT/2);
+                               
+                               /* frames one and higher get a saturated background */
+                               if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x44);
+                               else glColor4ub(col2[0], col2[1], col2[2], 0x44);
+                               glRectf(frame1_x, channel_y-CHANNELHEIGHT/2, G.v2d->hor.xmax,  channel_y+CHANNELHEIGHT/2);
+                       }
                }
                
                /*      Increment the step */
@@ -897,6 +943,9 @@ static void draw_channel_strips(void)
                                case ALE_ICU:
                                        draw_icu_channel(di, ale->key_data, y);
                                        break;
+                               case ALE_GPFRAME:
+                                       draw_gpl_channel(di, ale->data, y);
+                                       break;
                        }
                }
                
@@ -928,12 +977,55 @@ static void draw_channel_strips(void)
 void do_actionbuts(unsigned short event)
 {
        switch(event) {
+               /* general */
        case REDRAWVIEW3D:
                allqueue(REDRAWVIEW3D, 0);
                break;
        case B_REDR:
                allqueue(REDRAWACTION, 0);
                break;
+               
+               /* action-groups */
+       case B_ACTCUSTCOLORS:   /* only when of the color wells is edited */
+       {
+               bActionGroup *agrp= get_active_actiongroup(G.saction->action);
+               
+               if (agrp)
+                       agrp->customCol= -1;
+                       
+               allqueue(REDRAWACTION, 0);
+       }
+               break;
+       case B_ACTCOLSSELECTOR: /* sync color set after using selector */
+       {
+               bActionGroup *agrp= get_active_actiongroup(G.saction->action);
+               
+               if (agrp) 
+                       actionbone_group_copycolors(agrp, 1);
+                       
+               allqueue(REDRAWACTION, 0);
+       }
+               break;
+       case B_ACTGRP_SELALL: /* select all grouped channels */
+       {
+               bAction *act= G.saction->action;
+               bActionGroup *agrp= get_active_actiongroup(act);
+               
+               /* select all in group, then reselect/activate group as the previous operation clears that */
+               select_action_group_channels(act, agrp);
+               agrp->flag |= (AGRP_ACTIVE|AGRP_SELECTED);
+               
+               allqueue(REDRAWACTION, 0);
+       }
+               break;
+       case B_ACTGRP_ADDTOSELF: /* add all selected action channels to self */
+               action_groups_group(0);
+               break;
+       case B_ACTGRP_UNGROUP: /* remove channels from active group */
+               // FIXME: todo...
+               printf("FIXME: remove achans from active Action-Group not implemented yet! \n");
+               break;
+       
        }
 }
 
@@ -941,14 +1033,68 @@ void do_actionbuts(unsigned short event)
 static void action_panel_properties(short cntrl)       // ACTION_HANDLER_PROPERTIES
 {
        uiBlock *block;
-
+       void *data;
+       short datatype;
+       
        block= uiNewBlock(&curarea->uiblocks, "action_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
        uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
        uiSetPanelHandler(ACTION_HANDLER_PROPERTIES);  // for close and esc
-       if (uiNewPanel(curarea, block, "Transform Properties", "Action", 10, 230, 318, 204)==0) 
+       
+       /* get datatype */
+       data= get_action_context(&datatype);
+       //if (data == NULL) return;
+       
+       if (uiNewPanel(curarea, block, "Active Channel Properties", "Action", 10, 230, 318, 204)==0) 
                return;
-
-       uiDefBut(block, LABEL, 0, "test text",          10,180,300,19, 0, 0, 0, 0, 0, "");
+       
+       /* currently, only show data for actions */
+       if (datatype == ACTCONT_ACTION) {
+               bActionGroup *agrp= get_active_actiongroup(data);
+               //bActionChannel *achan= get_hilighted_action_channel(data);
+               char *menustr;
+               
+               /* only for action-groups */
+               if (agrp) {
+                       /* general stuff */
+                       uiDefBut(block, LABEL, 1, "Action Group:",                                      10, 180, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
+                       
+                       uiDefBut(block, TEX, B_REDR, "Name: ",  10,160,150,20, agrp->name, 0.0, 31.0, 0, 0, "");
+                       uiBlockBeginAlign(block);
+                               uiDefButBitI(block, TOG, AGRP_EXPANDED, B_REDR, "Expanded", 170, 160, 75, 20, &agrp->flag, 0, 0, 0, 0, "Action Group is expanded");
+                               uiDefButBitI(block, TOG, AGRP_PROTECTED, B_REDR, "Protected", 245, 160, 75, 20, &agrp->flag, 0, 0, 0, 0, "Action Group is protected");
+                       uiBlockEndAlign(block);
+                       
+                       /* color stuff */
+                       uiDefBut(block, LABEL, 1, "Group Colors:",      10, 107, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
+                       uiBlockBeginAlign(block);
+                               menustr= BIF_ThemeColorSetsPup(1);
+                               uiDefButI(block, MENU,B_ACTCOLSSELECTOR, menustr, 10,85,150,19, &agrp->customCol, -1, 20, 0.0, 0.0, "Index of set of Custom Colors to shade Group's bones with. 0 = Use Default Color Scheme, -1 = Use Custom Color Scheme");                                           
+                               MEM_freeN(menustr);
+                               
+                               /* show color-selection/preview */
+                               if (agrp->customCol) {
+                                       /* do color copying/init (to stay up to date) */
+                                       actionbone_group_copycolors(agrp, 1);
+                                       
+                                       /* color changing */
+                                       uiDefButC(block, COL, B_ACTCUSTCOLORS, "",              10, 65, 50, 19, agrp->cs.active, 0, 0, 0, 0, "Color to use for 'top-level' channels");
+                                       uiDefButC(block, COL, B_ACTCUSTCOLORS, "",              60, 65, 50, 19, agrp->cs.select, 0, 0, 0, 0, "Color to use for '2nd-level' channels");
+                                       uiDefButC(block, COL, B_ACTCUSTCOLORS, "",              110, 65, 50, 19, agrp->cs.solid, 0, 0, 0, 0, "Color to use for '3rd-level' channels");
+                               }
+                       uiBlockEndAlign(block);
+                       
+                       /* commands for active group */
+                       uiDefBut(block, BUT, B_ACTGRP_SELALL, "Select Grouped", 170,85,150,20, 0, 21, 0, 0, 0, "Select all action-channels belonging to this group (same as doing Ctrl-Shift-LMB)");
+                       
+                       uiBlockBeginAlign(block);
+                               uiDefBut(block, BUT, B_ACTGRP_ADDTOSELF, "Add to Group",        170,60,150,20, 0, 21, 0, 0, 0, "Add selected action-channels to this group");
+                               uiDefBut(block, BUT, B_ACTGRP_UNGROUP, "Un-Group",      170,40,150,20, 0, 21, 0, 0, 0, "Remove selected action-channels from this group (unimplemented)");
+                       uiBlockEndAlign(block);
+               }
+       }
+       else {
+               /* Currently, there isn't anything to display for these types ... */
+       }
 }
 
 static void action_blockhandlers(ScrArea *sa)
@@ -976,6 +1122,7 @@ void drawactionspace(ScrArea *sa, void *spacedata)
 {
        bAction *act = NULL;
        Key *key = NULL;
+       bGPdata *gpd = NULL;
        void *data;
        short datatype;
        
@@ -991,18 +1138,38 @@ void drawactionspace(ScrArea *sa, void *spacedata)
 
        /* only try to refresh action that's displayed if not pinned */
        if (G.saction->pin==0) {
-               if (OBACT)
-                       G.saction->action = OBACT->action;
-               else
-                       G.saction->action= NULL;
+               /* depends on mode */
+               switch (G.saction->mode) {
+                       case SACTCONT_ACTION:
+                       {
+                               if (OBACT)
+                                       G.saction->action = OBACT->action;
+                               else
+                                       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;
+               }
        }
        
        /* get data */
        data = get_action_context(&datatype);
-       if (datatype == ACTCONT_ACTION)
-               act = data;
-       else if (datatype == ACTCONT_SHAPEKEY)
-               key = data;
+       switch (datatype) {
+               case ACTCONT_ACTION:
+                       act = data;
+                       break;
+               case ACTCONT_SHAPEKEY:
+                       key = data;
+                       break;
+               case ACTCONT_GPENCIL:
+                       gpd = data;
+                       break;
+       }
        
        /* Lets make sure the width of the left hand of the screen
         * is set to an appropriate value based on whether sliders
@@ -1351,10 +1518,15 @@ static ActKeysInc *init_aki_data()
        static ActKeysInc aki;
        
        /* init data of static struct here */
-       if ((curarea->spacetype == SPACE_ACTION) && NLA_ACTION_SCALED)
+       if ((curarea->spacetype == SPACE_ACTION) && NLA_ACTION_SCALED &&
+               (G.saction->mode == SACTCONT_ACTION))
+       {
                aki.ob= OBACT;
+       }
        else if (curarea->spacetype == SPACE_NLA)
+       {
                aki.ob= NULL; // FIXME
+       }
        else
                aki.ob= NULL;
                
@@ -1429,6 +1601,16 @@ void draw_action_channel(gla2DDrawInfo *di, bAction *act, float ypos)
        BLI_freelistN(&keys);
 }
 
+void draw_gpl_channel(gla2DDrawInfo *di, bGPDlayer *gpl, float ypos)
+{
+       ListBase keys = {0, 0};
+       ActKeysInc *aki = init_aki_data();
+       
+       gpl_to_keylist(gpl, &keys, NULL, aki);
+       draw_keylist(di, &keys, NULL, ypos);
+       BLI_freelistN(&keys);
+}
+
 /* --------------- Conversion: data -> keyframe list ------------------ */
 
 void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
@@ -1575,3 +1757,26 @@ void action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks, ActKeysIn
        }
 }
 
+void gpl_to_keylist(bGPDlayer *gpl, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
+{
+       bGPDframe *gpf;
+       ActKeyColumn *ak;
+       
+       if (gpl && keys) {
+               /* loop over frames, converting directly to 'keyframes' (should be in order too) */
+               for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
+                       ak= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
+                       BLI_addtail(keys, ak);
+                       
+                       ak->cfra= gpf->framenum;
+                       ak->modified = 1;
+                       ak->handle_type= 0; 
+                       
+                       if (gpf->flag & GP_FRAME_SELECT)
+                               ak->sel = SELECT;
+                       else
+                               ak->sel = 0;
+               }
+       }
+}
+
diff --git a/source/blender/src/drawgpencil.c b/source/blender/src/drawgpencil.c
new file mode 100644 (file)
index 0000000..55d0464
--- /dev/null
@@ -0,0 +1,653 @@
+/**
+ * $Id: drawgpencil.c 14881 2008-05-18 10:41:42Z aligorith $
+ *
+ * ***** 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) 2008, Blender Foundation
+ * This is a new part of Blender
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <math.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "BMF_Api.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+
+#include "DNA_listBase.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+#include "BKE_blender.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+#include "BIF_butspace.h"
+#include "BIF_graphics.h"
+#include "BIF_interface.h"
+#include "BIF_mywindow.h"
+#include "BIF_resources.h"
+#include "BIF_space.h"
+#include "BIF_screen.h"
+#include "BIF_toolbox.h"
+#include "BIF_toets.h"
+
+#include "BDR_gpencil.h"
+#include "BIF_drawgpencil.h"
+
+#include "BSE_drawipo.h"
+#include "BSE_headerbuttons.h"
+#include "BSE_view.h"
+
+#include "blendef.h"
+#include "butspace.h"
+
+#include "PIL_time.h"                  /* sleep                                */
+#include "mydevice.h"
+
+/* ************************************************** */
+/* GREASE PENCIL PANEL-UI DRAWING */
+
+/* Every space which implements Grease-Pencil functionality should have a panel
+ * for the settings. All of the space-dependent parts should be coded in the panel
+ * code for that space, but the rest is all handled by generic panel here.
+ */
+
+/* ------- Callbacks ----------- */
+/* These are just 'dummy wrappers' around gpencil api calls */
+
+/* make layer active one after being clicked on */
+void gp_ui_activelayer_cb (void *gpd, void *gpl)
+{
+       gpencil_layer_setactive(gpd, gpl);
+}
+
+/* rename layer and set active */
+void gp_ui_renamelayer_cb (void *gpd_arg, void *gpl_arg)
+{
+       bGPdata *gpd= (bGPdata *)gpd_arg;
+       bGPDlayer *gpl= (bGPDlayer *)gpl_arg;
+       
+       BLI_uniquename(&gpd->layers, gpl, "GP_Layer", offsetof(bGPDlayer, info[0]), 128);
+       gpencil_layer_setactive(gpd, gpl);
+}
+
+/* add a new layer */
+void gp_ui_addlayer_cb (void *gpd, void *dummy)
+{
+       gpencil_layer_addnew(gpd);
+}
+
+/* delete active layer */
+void gp_ui_dellayer_cb (void *gpd, void *dummy)
+{
+       gpencil_layer_delactive(gpd);
+}
+
+/* delete last stroke of active layer */
+void gp_ui_delstroke_cb (void *gpd, void *gpl)
+{
+       bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0);
+       
+       gpencil_layer_setactive(gpd, gpl);
+       gpencil_frame_delete_laststroke(gpf);
+}
+
+/* delete active frame of active layer */
+void gp_ui_delframe_cb (void *gpd, void *gpl)
+{
+       bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0);
+       
+       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);
+}
+
+
+/* ------- 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 width= 314;
+       short height;
+       int rb_col;
+       
+       /* unless button has own callback, it adds this callback to button */
+       uiBlockSetFunc(block, gp_ui_activelayer_cb, gpd, gpl);
+       
+       /* draw header */
+       {
+               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, ""); 
+               
+               /* 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 */
+       if (gpl->flag & (GP_LAYER_LOCKED|GP_LAYER_HIDE)) {
+               height= 26;
+               
+               /* 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)");
+               }
+               
+               /* draw backdrop */
+               uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
+               
+               /* draw settings... (i.e. just warning for this one) */
+               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, "");
+               else
+                       uiDefBut(block, LABEL, 1, "Grease Pencil Layer Locked", *xco+60, *yco-26, 205, 20, NULL, 0.0, 0.0, 0, 0, "");
+                       
+               uiBlockSetEmboss(block, UI_EMBOSS);
+       }
+       else {
+               height= 100;
+               
+               /* draw rest of header */
+               {
+                       /* visibility button */
+                       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");
+                       
+                       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)");
+                       uiButSetFunc(but, gp_ui_renamelayer_cb, gpd, gpl);
+                       
+                       /* delete 'button' */
+                       uiBlockSetEmboss(block, UI_EMBOSSN);
+                       
+                       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);
+               }
+               
+               /* draw backdrop */
+               uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
+               
+               /* draw settings */
+               {
+                       /* color */
+                       uiBlockBeginAlign(block);
+                               uiDefButF(block, COL, B_REDR, "",               *xco, *yco-26, 150, 19, gpl->color, 0, 0, 0, 0, "Color to use for all strokes on this Grease Pencil Layer");
+                               uiDefButF(block, NUMSLI, B_REDR, "Opacity: ",           *xco,*yco-45,150,19, &gpl->color[3], 0.3, 1.0, 0, 0, "Visibility of stroke (0.3 to 1.0)");
+                       uiBlockEndAlign(block);
+                       
+                       /* stroke thickness */
+                       uiDefButS(block, NUMSLI, B_REDR, "Thickness:",  *xco, *yco-75, 150, 20, &gpl->thickness, 1, 10, 0, 0, "Thickness of strokes (in pixels)");
+                       
+                       
+                       /* 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)");
+                       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");
+               }
+       }
+       
+       /* adjust height for new to start */
+       (*yco) -= (height + 27); 
+} 
+
+/* 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)
+ * 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;
+       
+       /* 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");
+               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)");
+               
+               /* '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");
+               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 */
+       for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
+               gp_drawui_layer(block, gpd, gpl, &xco, &yco);
+       }
+       
+       /* return new height if necessary */
+       return (yco < 0) ? (204 - yco) : 204;
+}      
+
+/* ************************************************** */
+/* GREASE PENCIL DRAWING */
+
+/* flags for sflag */
+enum {
+       GP_DRAWDATA_NOSTATUS    = (1<<0),       /* don't draw status info */
+       GP_DRAWDATA_ONLY3D              = (1<<1),       /* only draw 3d-strokes */
+       GP_DRAWDATA_ONLYV2D             = (1<<2),       /* only draw 'canvas' strokes */
+};
+
+/* 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)
+{
+       bGPDspoint *pt;
+       int i;
+       
+       /* error checking */
+       if ((points == NULL) || (totpoints <= 0))
+               return;
+       
+       /* check if stroke can be drawn */
+       if ((dflag & GP_DRAWDATA_ONLY3D) && !(sflag & GP_STROKE_3DSPACE))
+               return;
+       if (!(dflag & GP_DRAWDATA_ONLY3D) && (sflag & GP_STROKE_3DSPACE))
+               return;
+       if ((dflag & GP_DRAWDATA_ONLYV2D) && !(sflag & GP_STROKE_2DSPACE))
+               return;
+       if (!(dflag & GP_DRAWDATA_ONLYV2D) && (sflag & GP_STROKE_2DSPACE))
+               return;
+       
+       /* if drawing a single point, draw it larger */
+       if (totpoints == 1) {           
+               /* draw point */
+               if (sflag & GP_STROKE_3DSPACE) {
+                       glBegin(GL_POINTS);
+                               glVertex3f(points->x, points->y, points->z);
+                       glEnd();
+               }
+               else if (sflag & GP_STROKE_2DSPACE) {
+                       glBegin(GL_POINTS);
+                               glVertex2f(points->x, points->y);
+                       glEnd();
+               }
+               else {
+                       const float x= (points->x / 1000 * winx);
+                       const float y= (points->y / 1000 * winy);
+                       
+                       glBegin(GL_POINTS);
+                               glVertex2f(x, y);
+                       glEnd();
+               }
+       }
+       else {
+               float oldpressure = 0.0f;
+               
+               /* draw stroke curve */
+               glBegin(GL_LINE_STRIP);
+               for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
+                       float x, y, z;
+                       
+                       if (sflag & GP_STROKE_3DSPACE) {
+                               x= pt->x;
+                               y= pt->y;
+                               z= pt->z;
+                       }
+                       else if (sflag & GP_STROKE_2DSPACE) {
+                               x= pt->x;
+                               y= pt->y;
+                               z= 0;
+                       }
+                       else {
+                               x= (pt->x / 1000 * winx);
+                               y= (pt->y / 1000 * winy);
+                               z= 0;
+                       }
+                       
+                       if (fabs(pt->pressure - oldpressure) > 0.2f) {
+                               glEnd();
+                               glLineWidth(pt->pressure * thickness);
+                               glBegin(GL_LINE_STRIP);
+                               
+                               if (sflag & GP_STROKE_3DSPACE) 
+                                       glVertex3f(x, y, z);
+                               else
+                                       glVertex2f(x, y);
+                               
+                               oldpressure = pt->pressure;
+                       }
+                       else {
+                               if (sflag & GP_STROKE_3DSPACE) 
+                                       glVertex3f(x, y, z);
+                               else
+                                       glVertex2f(x, y);
+                       }
+               }
+               glEnd();
+               
+               /* draw debug points of curve on top? */
+               if (debug) {
+                       glBegin(GL_POINTS);
+                       for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
+                               if (sflag & GP_STROKE_3DSPACE) {
+                                       glVertex3f(pt->x, pt->y, pt->z);
+                               }
+                               else if (sflag & GP_STROKE_2DSPACE) {
+                                       glVertex2f(pt->x, pt->y);
+                               }
+                               else {
+                                       const float x= (pt->x / 1000 * winx);
+                                       const float y= (pt->y / 1000 * winy);
+                                       
+                                       glVertex2f(x, y);
+                               }
+                       }
+                       glEnd();
+               }
+       }
+}
+
+/* draw grease-pencil datablock */
+static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
+{
+       bGPDlayer *gpl, *actlay=NULL;
+       
+       /* turn on smooth lines (i.e. anti-aliasing) */
+       glEnable(GL_LINE_SMOOTH);
+       
+       /* turn on alpha-blending */
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       glEnable(GL_BLEND);
+               
+       /* 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];
+               
+               /* don't draw layer if hidden */
+               if (gpl->flag & GP_LAYER_HIDE) 
+                       continue;
+               
+               /* if layer is active one, store pointer to it */
+               if (gpl->flag & GP_LAYER_ACTIVE)
+                       actlay= gpl;
+               
+               /* get frame to draw */
+               gpf= gpencil_layer_getframe(gpl, CFRA, 0);
+               if (gpf == NULL) 
+                       continue;
+               
+               /* set color, stroke thickness, and point size */
+               glLineWidth(lthick);
+               QUATCOPY(color, gpl->color); // just for copying 4 array elements
+               glColor4f(color[0], color[1], color[2], color[3]);
+               glPointSize(gpl->thickness + 2);
+               
+               /* draw 'onionskins' (frame left + right) */
+               if (gpl->flag & GP_LAYER_ONIONSKIN) {
+                       /* drawing method - only immediately surrounding (gstep = 0), or within a frame range on either side (gstep > 0)*/                      
+                       if (gpl->gstep) {
+                               bGPDframe *gf;
+                               short i;
+                               
+                               /* draw previous frames first */
+                               for (gf=gpf->prev, i=0; gf; gf=gf->prev, i++) {
+                                       /* 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);
+                                               }
+                                       }
+                                       else 
+                                               break;
+                               }
+                               
+                               /* now draw next frames */
+                               for (gf= gpf->next, i=0; gf; gf=gf->next, i++) {
+                                       /* 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);
+                                               }
+                                       }
+                                       else 
+                                               break;
+                               }       
+                               
+                               /* restore alpha */
+                               glColor4f(color[0], color[1], color[2], color[3]);
+                       }
+                       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);
+                                       }
+                               }
+                               
+                               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);
+                                       }
+                               }
+                               
+                               /* restore alpha */
+                               glColor4f(color[0], color[1], color[2], color[3]);
+                       }
+               }
+               
+               /* 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);
+               }
+               
+               /* 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)
+                */
+               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);
+               }
+       }
+       
+       /* turn off alpha blending, then smooth lines */
+       glDisable(GL_BLEND); // alpha blending
+       glDisable(GL_LINE_SMOOTH); // smooth lines
+       
+       /* show info for debugging the status of gpencil */
+       if ( ((dflag & GP_DRAWDATA_NOSTATUS)==0) && (gpd->flag & GP_DATA_DISPINFO) ) {
+               char printable[256];
+               short xmax;
+               
+               /* get text to display */
+               if (actlay) {
+                       if (gpd->flag & GP_DATA_EDITPAINT)
+                               BIF_ThemeColor(TH_BONE_POSE); // should be blue-ish
+                       else if (actlay->actframe == NULL)
+                               BIF_ThemeColor(TH_REDALERT);
+                       else if (actlay->actframe->framenum == CFRA)
+                               BIF_ThemeColor(TH_VERTEX_SELECT); // should be yellow
+                       else
+                               BIF_ThemeColor(TH_TEXT_HI);
+                       
+                       if (actlay->actframe) {
+                               sprintf(printable, "GPencil: Layer ('%s'), Frame (%d) %s", 
+                                       actlay->info, actlay->actframe->framenum,
+                                       ((gpd->flag & GP_DATA_EDITPAINT)?", Draw Mode On":"") );
+                       }
+                       else {
+                               sprintf(printable, "GPencil: Layer ('%s'), Frame <None> %s", 
+                                       actlay->info, ((gpd->flag & GP_DATA_EDITPAINT)?", Draw Mode On":"") );
+                       }
+               }
+               else {
+                       BIF_ThemeColor(TH_REDALERT);
+                       sprintf(printable, "GPencil: Layer <None>");
+               }
+               xmax= GetButStringLength(printable);
+               
+               /* only draw it if view is wide enough (assume padding of 20 is enough for now) */
+               if (winx > (xmax + 20)) { 
+                       glRasterPos2i(winx-xmax, winy-20);
+                       BMF_DrawString(G.fonts, printable);
+               }
+       }
+       
+       /* restore initial gl conditions */
+       glLineWidth(1.0);
+       glPointSize(1.0);
+       glColor4f(0, 0, 0, 1);
+}
+
+/* ----------- */
+
+/* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly 
+ * Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes, second time with onlyv2d=0 for screen-aligned strokes
+ */
+void draw_gpencil_2dview (ScrArea *sa, short onlyv2d)
+{
+       bGPdata *gpd;
+       int dflag = 0;
+       
+       /* check that we have grease-pencil stuff to draw */
+       if (sa == NULL) return;
+       gpd= gpencil_data_getactive(sa);
+       if (gpd == NULL) return;
+       
+       /* draw it! */
+       if (onlyv2d) dflag |= (GP_DRAWDATA_ONLYV2D|GP_DRAWDATA_NOSTATUS);
+       gp_draw_data(gpd, sa->winx, sa->winy, dflag);
+}
+
+/* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly 
+ * Note: this gets called twice - first time with only3d=1 to draw 3d-strokes, second time with only3d=0 for screen-aligned strokes
+ */
+void draw_gpencil_3dview (ScrArea *sa, short only3d)
+{
+       bGPdata *gpd;
+       int dflag = 0;
+       
+       /* check that we have grease-pencil stuff to draw */
+       gpd= gpencil_data_getactive(sa);
+       if (gpd == NULL) return;
+       
+       /* draw it! */
+       if (only3d) dflag |= (GP_DRAWDATA_ONLY3D|GP_DRAWDATA_NOSTATUS);
+       gp_draw_data(gpd, sa->winx, sa->winy, dflag);
+}
+
+/* draw grease-pencil sketches to opengl render window assuming that matrices are already set correctly */
+void draw_gpencil_oglrender (View3D *v3d, int winx, int winy)
+{
+       bGPdata *gpd;
+       
+       /* assume gpencil data comes from v3d */
+       if (v3d == NULL) return;
+       gpd= v3d->gpd;
+       if (gpd == NULL) return;
+       
+       /* pass 1: draw 3d-strokes ------------ > */
+       gp_draw_data(gpd, winx, winy, (GP_DRAWDATA_NOSTATUS|GP_DRAWDATA_ONLY3D));
+       
+       /* pass 2: draw 2d-strokes ------------ > */
+               /* adjust view matrices */
+       myortho2(-0.375, (float)(winx)-0.375, -0.375, (float)(winy)-0.375);
+       glLoadIdentity();
+       
+               /* draw it! */
+       gp_draw_data(gpd, winx, winy, GP_DRAWDATA_NOSTATUS);
+}
+
+/* ************************************************** */
index 1169062fdd05da18e27a2018abf03f2233fec91e..3a73ee84ead109793e78bfe1de1102a82c8a327f 100644 (file)
@@ -37,6 +37,7 @@
 #include "DNA_action_types.h"
 #include "DNA_color_types.h"
 #include "DNA_customdata_types.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_ipo_types.h"
 #include "DNA_ID.h"
 #include "DNA_image_types.h"
 #include "CMP_node.h"
 #include "SHD_node.h"
 
+#include "BDR_gpencil.h"
+
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
+#include "BIF_drawgpencil.h"
 #include "BIF_interface.h"
 #include "BIF_interface_icons.h"
 #include "BIF_language.h"
@@ -3300,6 +3304,66 @@ static void node_draw_group(ScrArea *sa, SpaceNode *snode, bNode *gnode)
 }
 
 
+
+static void nodes_panel_gpencil(short cntrl)   // NODES_HANDLER_GREASEPENCIL
+{
+       uiBlock *block;
+       SpaceNode *snode;
+       
+       snode= curarea->spacedata.first;
+
+       block= uiNewBlock(&curarea->uiblocks, "nodes_panel_gpencil", UI_EMBOSS, UI_HELV, curarea->win);
+       uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE  | cntrl);
+       uiSetPanelHandler(NODES_HANDLER_GREASEPENCIL);  // for close and esc
+       if (uiNewPanel(curarea, block, "Grease Pencil", "SpaceNode", 100, 30, 318, 204)==0) return;
+       
+       /* we can only really draw stuff if there are nodes (otherwise no events are handled */
+       if (snode->nodetree == NULL)
+               return;
+       
+       /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */
+       if (snode->flag & SNODE_DISPGP) {
+               if (snode->gpd == NULL)
+                       gpencil_data_setactive(curarea, gpencil_data_addnew());
+       }
+       
+       if (snode->flag & SNODE_DISPGP) {
+               bGPdata *gpd= snode->gpd;
+               short newheight;
+               
+               /* this is a variable height panel, newpanel doesnt force new size on existing panels */
+               /* so first we make it default height */
+               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");
+               
+               /* extend the panel if the contents won't fit */
+               newheight= draw_gpencil_panel(block, gpd, curarea); 
+               uiNewPanelHeight(block, newheight);
+       }
+       else {
+               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");
+               uiDefBut(block, LABEL, 1, " ",  160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
+       }
+}
+
+static void nodes_blockhandlers(ScrArea *sa)
+{
+       SpaceNode *snode= sa->spacedata.first;
+       short a;
+       
+       for(a=0; a<SPACE_MAXHANDLER; a+=2) {
+               /* clear action value for event */
+               switch(snode->blockhandler[a]) {
+                       case NODES_HANDLER_GREASEPENCIL:
+                               nodes_panel_gpencil(snode->blockhandler[a+1]);
+                               break;
+               }
+       }
+       uiDrawBlocksPanels(sa, 0);
+}
+
 void drawnodespace(ScrArea *sa, void *spacedata)
 {
        SpaceNode *snode= sa->spacedata.first;
@@ -3354,13 +3418,26 @@ void drawnodespace(ScrArea *sa, void *spacedata)
                }
        }
        
+       /* draw grease-pencil ('canvas' strokes) */
+       if ((snode->flag & SNODE_DISPGP) && (snode->nodetree))
+               draw_gpencil_2dview(sa, 1);
+       
        /* restore viewport (not needed yet) */
        mywinset(sa->win);
 
        /* ortho at pixel level curarea */
        myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
+       
+       /* draw grease-pencil (screen strokes) */
+       if ((snode->flag & SNODE_DISPGP) && (snode->nodetree))
+               draw_gpencil_2dview(sa, 0);
 
        draw_area_emboss(sa);
+       
+       /* it is important to end a view in a transform compatible with buttons */
+       bwin_scalematrix(sa->win, snode->blockscale, snode->blockscale, snode->blockscale);
+       nodes_blockhandlers(sa);
+       
        curarea->win_swap= WIN_BACK_OK;
        
        /* in the end, this is a delayed previewrender test, to allow buttons to be first */
index 045bf292446225718cd1e6bad03250c3d716d32c..1a469e8b3660b29e2e6b22008a13e6f6efb94ebb 100644 (file)
@@ -1199,7 +1199,12 @@ static void drawlattice(Object *ob)
        int use_wcol= 0;
 
        lt= (ob==G.obedit)?editLatt:ob->data;
+       
+       /* now we default make displist, this will modifiers work for non animated case */
+       if(ob->disp.first==NULL)
+               lattice_calc_modifiers(ob);
        dl= find_displist(&ob->disp, DL_VERTS);
+       
        if(ob==G.obedit) {
                cpack(0x004000);
                
index e554b91dd52a03bb400bdb845ebf57b3c16313b0..c8c74ad827940cebf1762dbc01d9bbd9f7f048bb 100644 (file)
@@ -43,6 +43,7 @@
 
 #include "IMB_imbuf_types.h"
 
+#include "DNA_gpencil_types.h"
 #include "DNA_sequence_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
@@ -67,6 +68,9 @@
 #include "BIF_space.h"
 #include "BIF_interface.h"
 
+#include "BIF_drawgpencil.h"
+#include "BDR_gpencil.h"
+
 #include "BSE_view.h"
 #include "BSE_drawipo.h"
 #include "BSE_sequence.h"
@@ -98,6 +102,70 @@ static void draw_seq_text(Sequence *seq, float x1, float x2, float y1, float y2)
 static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float x2, float y2);
 static void draw_seq_strip(struct Sequence *seq, struct ScrArea *sa, struct SpaceSeq *sseq, int outline_tint, float pixelx);
 
+
+static void seq_panel_gpencil(short cntrl)     // SEQ_HANDLER_GREASEPENCIL
+{
+       uiBlock *block;
+       SpaceSeq *sseq;
+       
+       sseq= curarea->spacedata.first;
+
+       block= uiNewBlock(&curarea->uiblocks, "seq_panel_gpencil", UI_EMBOSS, UI_HELV, curarea->win);
+       uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE  | cntrl);
+       uiSetPanelHandler(SEQ_HANDLER_GREASEPENCIL);  // for close and esc
+       if (uiNewPanel(curarea, block, "Grease Pencil", "SpaceSeq", 100, 30, 318, 204)==0) return;
+       
+       /* only draw settings if right mode */
+       if (sseq->mainb == 0)
+               return;
+       
+       /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */
+       if (sseq->flag & SEQ_DRAW_GPENCIL) {
+               if (sseq->gpd == NULL)
+                       gpencil_data_setactive(curarea, gpencil_data_addnew());
+       }
+       
+       if (sseq->flag & SEQ_DRAW_GPENCIL) {
+               bGPdata *gpd= sseq->gpd;
+               short newheight;
+               
+               /* this is a variable height panel, newpanel doesnt force new size on existing panels */
+               /* so first we make it default height */
+               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");
+               
+               /* extend the panel if the contents won't fit */
+               newheight= draw_gpencil_panel(block, gpd, curarea); 
+               uiNewPanelHeight(block, newheight);
+       }
+       else {
+               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");
+               uiDefBut(block, LABEL, 1, " ",  160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
+       }
+}
+
+static void seq_blockhandlers(ScrArea *sa)
+{
+       SpaceSeq *sseq= sa->spacedata.first;
+       short a;
+
+       /* warning; blocks need to be freed each time, handlers dont remove (for ipo moved to drawipospace) */
+       uiFreeBlocksWin(&sa->uiblocks, sa->win);
+
+       for(a=0; a<SPACE_MAXHANDLER; a+=2) {
+               switch(sseq->blockhandler[a]) {
+                       case SEQ_HANDLER_GREASEPENCIL:
+                               seq_panel_gpencil(sseq->blockhandler[a+1]);
+                               break;
+               }
+       }
+       uiDrawBlocksPanels(sa, 0);
+
+}
+
+
 static void draw_cfra_seq(void)
 {
        glColor3ub(0x30, 0x90, 0x50);
@@ -907,6 +975,17 @@ static void draw_image_seq(ScrArea *sa)
        if (free_ibuf) {
                IMB_freeImBuf(ibuf);
        } 
+       
+       /* draw grease-pencil (screen aligned) */
+       if (sseq->flag & SEQ_DRAW_GPENCIL)
+               draw_gpencil_2dview(sa, 0);
+       
+       /* ortho at pixel level sa */
+       myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
+       
+       /* it is important to end a view in a transform compatible with buttons */
+       bwin_scalematrix(sa->win, sseq->blockscale, sseq->blockscale, sseq->blockscale);
+       seq_blockhandlers(sa);
 
        sa->win_swap= WIN_BACK_OK;
 }
@@ -1023,24 +1102,6 @@ void seq_viewmove(SpaceSeq *sseq)
        window_set_cursor(win, oldcursor);
 }
 
-
-
-static void seq_blockhandlers(ScrArea *sa)
-{
-       SpaceSeq *sseq= sa->spacedata.first;
-       short a;
-
-       /* warning; blocks need to be freed each time, handlers dont remove (for ipo moved to drawipospace) */
-       uiFreeBlocksWin(&sa->uiblocks, sa->win);
-
-       for(a=0; a<SPACE_MAXHANDLER; a+=2) {
-               /* clear action value for event */
-               sseq->blockhandler[a+1]= 0;
-       }
-       uiDrawBlocksPanels(sa, 0);
-
-}
-
 void drawprefetchseqspace(ScrArea *sa, void *spacedata)
 {
        SpaceSeq *sseq= sa->spacedata.first;
index f595a101f63e3484a069430faa44f09bf2de62f8..14434504e7aa8338fc0b1682ea2b38f31d3db327 100644 (file)
@@ -61,6 +61,7 @@
 #include "DNA_constraint_types.h"
 #include "DNA_curve_types.h"
 #include "DNA_group_types.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_image_types.h"
 #include "DNA_key_types.h"
 #include "DNA_lattice_types.h"
 
 #include "BIF_butspace.h"
 #include "BIF_drawimage.h"
+#include "BIF_drawgpencil.h"
 #include "BIF_editgroup.h"
 #include "BIF_editarmature.h"
 #include "BIF_editmesh.h"
 #include "BDR_editobject.h"
 #include "BDR_vpaint.h"
 #include "BDR_sculptmode.h"
+#include "BDR_gpencil.h"
 
 #include "BSE_drawview.h"
 #include "BSE_filesel.h"
@@ -2498,7 +2501,7 @@ static void view3d_panel_background(short cntrl)  // VIEW3D_HANDLER_BACKGROUND
        uiSetPanelHandler(VIEW3D_HANDLER_BACKGROUND);  // for close and esc
        if(uiNewPanel(curarea, block, "Background Image", "View3d", 340, 10, 318, 204)==0) return;
 
-       if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT || G.f & G_TEXTUREPAINT) {
+       if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT || G.f & G_TEXTUREPAINT || G.f & G_GREASEPENCIL) {
                uiBlockSetFlag(block, UI_BLOCK_FRONTBUFFER);    // force old style frontbuffer draw
        }
        
@@ -2546,7 +2549,7 @@ static void view3d_panel_properties(short cntrl)  // VIEW3D_HANDLER_SETTINGS
        /* to force height */
        uiNewPanelHeight(block, 264);
 
-       if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) {
+       if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT|G_GREASEPENCIL)) {
                uiBlockSetFlag(block, UI_BLOCK_FRONTBUFFER);    // force old style frontbuffer draw
        }
 
@@ -2620,6 +2623,49 @@ static void view3d_panel_preview(ScrArea *sa, short cntrl)       // VIEW3D_HANDLER_PRE
        }
 }
 
+static void view3d_panel_gpencil(short cntrl)  // VIEW3D_HANDLER_GREASEPENCIL
+{
+       uiBlock *block;
+       View3D *vd;
+       
+       vd= G.vd;
+
+       block= uiNewBlock(&curarea->uiblocks, "view3d_panel_gpencil", UI_EMBOSS, UI_HELV, curarea->win);
+       uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE  | cntrl);
+       uiSetPanelHandler(VIEW3D_HANDLER_GREASEPENCIL);  // for close and esc
+       if (uiNewPanel(curarea, block, "Grease Pencil", "View3d", 100, 30, 318, 204)==0) return;
+
+       if (G.f & (G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT|G_GREASEPENCIL)) {
+               uiBlockSetFlag(block, UI_BLOCK_FRONTBUFFER);    // force old style frontbuffer draw
+       }
+       
+       /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */
+       if (vd->flag2 & V3D_DISPGP) {
+               if (vd->gpd == NULL)
+                       gpencil_data_setactive(curarea, gpencil_data_addnew());
+       }
+       
+       if (vd->flag2 & V3D_DISPGP) {
+               bGPdata *gpd= vd->gpd;
+               short newheight;
+               
+               /* this is a variable height panel, newpanel doesnt force new size on existing panels */
+               /* so first we make it default height */
+               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");
+               
+               /* extend the panel if the contents won't fit */
+               newheight= draw_gpencil_panel(block, gpd, curarea); 
+               uiNewPanelHeight(block, newheight);
+       }
+       else {
+               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");
+               uiDefBut(block, LABEL, 1, " ",  160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
+       }
+}
+
 
 static void view3d_blockhandlers(ScrArea *sa)
 {
@@ -2634,9 +2680,7 @@ static void view3d_blockhandlers(ScrArea *sa)
        glDisable(GL_DEPTH_TEST); 
        
        for(a=0; a<SPACE_MAXHANDLER; a+=2) {
-       
                switch(v3d->blockhandler[a]) {
-
                case VIEW3D_HANDLER_PROPERTIES:
                        view3d_panel_properties(v3d->blockhandler[a+1]);
                        break;
@@ -2651,7 +2695,10 @@ static void view3d_blockhandlers(ScrArea *sa)
                        break;                  
                case VIEW3D_HANDLER_TRANSFORM:
                        view3d_panel_transform_spaces(v3d->blockhandler[a+1]);
-                       break;                  
+                       break;
+               case VIEW3D_HANDLER_GREASEPENCIL:
+                       view3d_panel_gpencil(v3d->blockhandler[a+1]);
+                       break;
                }
                /* clear action value for event */
                v3d->blockhandler[a+1]= 0;
@@ -3169,7 +3216,11 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
                v3d->zbuf= FALSE;
                glDisable(GL_DEPTH_TEST);
        }
-
+       
+       /* draw grease-pencil stuff */
+       if (v3d->flag2 & V3D_DISPGP)
+               draw_gpencil_3dview(sa, 1);
+       
        persp(PERSP_WIN);  // set ortho
 
        /* Draw Sculpt Mode brush */
@@ -3211,6 +3262,11 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
 
        if(v3d->persp>1) drawviewborder();
        if(v3d->flag2 & V3D_FLYMODE) drawviewborder_flymode();
+       
+       /* draw grease-pencil stuff */
+       if (v3d->flag2 & V3D_DISPGP)
+               draw_gpencil_3dview(sa, 0);
+       
        if(!(G.f & G_PLAYANIM)) drawcursor(v3d);
        if(U.uiflag & USER_SHOW_ROTVIEWICON)
                draw_view_axis();
@@ -3311,16 +3367,15 @@ void drawview3d_render(struct View3D *v3d, int winx, int winy, float winmat[][4]
 
        /* first draw set */
        if(G.scene->set) {
-       
                for(SETLOOPER(G.scene->set, base)) {
                        if(v3d->lay & base->lay) {
                                if ELEM3(base->object->type, OB_LAMP, OB_CAMERA, OB_LATTICE);
                                else {
                                        where_is_object(base->object);
-       
+                                       
                                        BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
                                        draw_object(base, DRAW_CONSTCOLOR|DRAW_SCENESET);
-       
+                                       
                                        if(base->object->transflag & OB_DUPLI) {
                                                draw_dupli_objects(v3d, base);
                                        }
@@ -3377,6 +3432,13 @@ void drawview3d_render(struct View3D *v3d, int winx, int winy, float winmat[][4]
                glDisable(GL_DEPTH_TEST);
        }
        
+       if(v3d->gpd) {
+               /* draw grease-pencil overlays 
+                * WARNING: view matrices are altered here!
+                */
+               draw_gpencil_oglrender(v3d, winx, winy);
+       }
+       
        G.f &= ~G_SIMULATION;
 
        glFlush();
index f93a1526e3cb891d53a389e24115595736f4531a..3251cb33b53766716d15bcc9fc69108fd8670664 100644 (file)
@@ -52,6 +52,7 @@
 #include "DNA_mesh_types.h"
 #include "DNA_nla_types.h"
 #include "DNA_lattice_types.h"
+#include "DNA_gpencil_types.h"
 
 #include "BKE_action.h"
 #include "BKE_armature.h"
@@ -90,6 +91,7 @@
 
 #include "BDR_drawaction.h"
 #include "BDR_editobject.h"
+#include "BDR_gpencil.h"
 
 #include "mydevice.h"
 #include "blendef.h"
@@ -296,6 +298,16 @@ bActListElem *make_new_actlistelem (void *data, short datatype, void *owner, sho
                                ale->datatype= ALE_IPO;
                        }
                                break;
+                       case ACTTYPE_GPLAYER:
+                       {
+                               bGPDlayer *gpl= (bGPDlayer *)data;
+                               
+                               ale->flag= gpl->flag;
+                               
+                               ale->key_data= NULL;
+                               ale->datatype= ALE_GPFRAME;
+                       }
+                               break;
                }
        }
        
@@ -505,6 +517,29 @@ 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)
+{
+       bActListElem *ale;
+       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);
+                               }
+                       }
+               }
+       }
+}
 /* This function filters the active data source to leave only the desired
  * data types. 'Public' api call.
  *     *act_data: is a pointer to a ListBase, to which the filtered action data 
@@ -525,6 +560,9 @@ void actdata_filter (ListBase *act_data, int filter_mode, void *data, short data
                        case ACTCONT_SHAPEKEY:
                                actdata_filter_shapekey(act_data, data, filter_mode);
                                break;
+                       case ACTCONT_GPENCIL:
+                               actdata_filter_gpencil(act_data, data, filter_mode);
+                               break;
                }
                        
                /* remove any weedy entries */
@@ -743,6 +781,10 @@ static void *get_nearest_action_key (float *selx, short *sel, short *ret_type, b
                                bActionGroup *agrp= (bActionGroup *)ale->data;
                                agroup_to_keylist(agrp, &act_keys, NULL, NULL);
                        }
+                       else if (ale->type == ACTTYPE_GPLAYER) {
+                               bGPDlayer *gpl= (bGPDlayer *)ale->data;
+                               gpl_to_keylist(gpl, &act_keys, NULL, NULL);
+                       }
                        
                        /* loop through keyframes, finding one that was clicked on */
                        for (ak= act_keys.first; ak; ak= ak->next) {
@@ -766,6 +808,10 @@ static void *get_nearest_action_key (float *selx, short *sel, short *ret_type, b
                                data = ale->key_data;
                                *ret_type= ACTTYPE_ICU;
                        }
+                       else if (datatype == ACTCONT_GPENCIL) {
+                               data = ale->data;
+                               *ret_type= ACTTYPE_GPLAYER;
+                       }
                        
                        /* cleanup tempolary lists */
                        BLI_freelistN(&act_keys);
@@ -795,17 +841,43 @@ void *get_action_context (short *datatype)
        act = (G.saction)? G.saction->action: NULL;
        key = get_action_mesh_key();
        
-       if (act) {
-               *datatype= ACTCONT_ACTION;
-               return act;
-       }
-       else if (key) {
-               *datatype= ACTCONT_SHAPEKEY;
-               return key;
+       /* check mode selector */
+       if (G.saction) {
+               switch (G.saction->mode) {
+                       case SACTCONT_ACTION: 
+                               *datatype= ACTCONT_ACTION;
+                               return act;
+                               
+                       case SACTCONT_SHAPEKEY:
+                               *datatype= ACTCONT_SHAPEKEY;
+                               return key;
+                               
+                       case SACTCONT_GPENCIL:
+                               *datatype= ACTCONT_GPENCIL;
+                               if (G.saction->pin)
+                                       return G.saction->gpd;
+                               else
+                                       return gpencil_data_getetime(G.curscreen);
+                       
+                       default: /* includes SACTCONT_DOPESHEET for now */
+                               *datatype= ACTCONT_NONE;
+                               return NULL;
+               }
        }
        else {
-               *datatype= ACTCONT_NONE;
-               return NULL;
+               /* resort to guessing based on what is available */
+               if (act) {
+                       *datatype= ACTCONT_ACTION;
+                       return act;
+               }
+               else if (key) {
+                       *datatype= ACTCONT_SHAPEKEY;
+                       return key;
+               }
+               else {
+                       *datatype= ACTCONT_NONE;
+                       return NULL;
+               }
        }
 }
 
@@ -1114,6 +1186,38 @@ void action_groups_ungroup (void)
        allqueue(REDRAWACTION, 0);
 }
 
+/* Copy colors from a specified theme's color set to an Action/Bone Group */
+void actionbone_group_copycolors (bActionGroup *grp, short init_new)
+{
+       /* error checking */
+       if (grp == NULL)
+               return;
+       
+       /* only do color copying if using a custom color */
+       if (grp->customCol) {
+               if (grp->customCol > 0) {
+                       /* copy theme colors on-to group's custom color in case user tries to edit color */
+                       bTheme *btheme= U.themes.first;
+                       ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)];
+                       
+                       memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
+               }
+               else if (init_new) {
+                       /* init custom colors with a generic multi-color rgb set, if not initialised already (and allowed to do so) */
+                       if (grp->cs.solid[0] == 0) {
+                               /* define for setting colors in theme below */
+                               #define SETCOL(col, r, g, b, a)  col[0]=r; col[1]=g; col[2]= b; col[3]= a;
+                               
+                               SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
+                               SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
+                               SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
+                               
+                               #undef SETCOL
+                       }
+               }
+       }
+}
+
 /* This function is used when inserting keyframes for pose-channels. It assigns the
  * action-channel with the nominated name to a group with the same name as that of 
  * the pose-channel with the nominated name.
@@ -1160,34 +1264,9 @@ void verify_pchan2achan_grouping (bAction *act, bPose *pose, char name[])
                        /* copy name */
                        sprintf(grp->name, agrp->name);
                        
-                       /* deal with group-color copying */
-                       if (agrp->customCol) {
-                               if (agrp->customCol > 0) {
-                                       /* copy theme colors on-to group's custom color in case user tries to edit color */
-                                       bTheme *btheme= U.themes.first;
-                                       ThemeWireColor *col_set= &btheme->tarm[(agrp->customCol - 1)];
-                                       
-                                       memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
-                               }
-                               else {
-                                       /* init custom colors with a generic multi-color rgb set, if not initialised already */
-                                       if (agrp->cs.solid[0] == 0) {
-                                               /* define for setting colors in theme below */
-                                               #define SETCOL(col, r, g, b, a)  col[0]=r; col[1]=g; col[2]= b; col[3]= a;
-                                               
-                                               SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
-                                               SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
-                                               SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
-                                               
-                                               #undef SETCOL
-                                       }
-                                       else {
-                                               /* just copy color set specified */
-                                               memcpy(&grp->cs, &agrp->cs, sizeof(ThemeWireColor));
-                                       }
-                               }
-                       }
-                       grp->customCol= agrp->customCol;
+                       /* deal with group-color copying (grp is destination, agrp is source) */
+                       memcpy(grp, agrp, sizeof(bActionGroup));
+                       actionbone_group_copycolors(grp, 1);
                        
                        BLI_addtail(&act->groups, grp);
                }
@@ -1300,12 +1379,18 @@ void duplicate_action_keys (void)
        if (data == NULL) return;
        
        /* filter data */
-       filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+       if (datatype == ACTCONT_GPENCIL)
+       filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT);
+       else
+               filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
        actdata_filter(&act_data, filter, data, datatype);
        
        /* loop through filtered data and duplicate selected keys */
        for (ale= act_data.first; ale; ale= ale->next) {
-               duplicate_ipo_keys((Ipo *)ale->key_data);
+               if (ale->type == ACTTYPE_GPLAYER)
+                       duplicate_gplayer_frames(ale->data);
+               else
+                       duplicate_ipo_keys((Ipo *)ale->key_data);
        }
        
        /* free filtered list */
@@ -1391,7 +1476,10 @@ void snap_action_keys(short mode)
        }
        
        /* filter data */
-       filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+       if (datatype == ACTCONT_GPENCIL)
+               filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT);
+       else
+               filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
        actdata_filter(&act_data, filter, data, datatype);
        
        /* snap to frame */
@@ -1401,6 +1489,8 @@ void snap_action_keys(short mode)
                        snap_ipo_keys(ale->key_data, mode);
                        actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
                }
+               else if (ale->type == ACTTYPE_GPLAYER)
+                       snap_gplayer_frames(ale->data, mode);
                else 
                        snap_ipo_keys(ale->key_data, mode);
        }
@@ -1414,6 +1504,7 @@ void snap_action_keys(short mode)
        allqueue(REDRAWACTION, 0);
        allqueue(REDRAWIPO, 0);
        allqueue(REDRAWNLA, 0);
+       allqueue(REDRAWVIEW3D, 0);
 }
 
 /* this function is responsible for snapping keyframes to frame-times */
@@ -1449,7 +1540,10 @@ void mirror_action_keys(short mode)
        }
        
        /* filter data */
-       filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+       if (datatype == ACTCONT_GPENCIL)
+               filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT);
+       else
+               filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
        actdata_filter(&act_data, filter, data, datatype);
        
        /* mirror */
@@ -1459,6 +1553,8 @@ void mirror_action_keys(short mode)
                        mirror_ipo_keys(ale->key_data, mode);
                        actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
                }
+               else if (ale->type == ACTTYPE_GPLAYER)
+                       mirror_gplayer_frames(ale->data, mode);
                else 
                        mirror_ipo_keys(ale->key_data, mode);
        }
@@ -1543,6 +1639,10 @@ void insertkey_action(void)
                        }
                }
        }
+       else {
+               /* this tool is not supported in this mode */
+               return;
+       }
        
        BIF_undo_push("Insert Key");
        allspace(REMAKEIPO, 0);
@@ -1566,12 +1666,18 @@ void delete_action_keys (void)
        if (data == NULL) return;
        
        /* filter data */
-       filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+       if (datatype == ACTCONT_GPENCIL)
+               filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT);
+       else
+               filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
        actdata_filter(&act_data, filter, data, datatype);
        
        /* loop through filtered data and delete selected keys */
        for (ale= act_data.first; ale; ale= ale->next) {
-               delete_ipo_keys((Ipo *)ale->key_data);
+               if (ale->type == ACTTYPE_GPLAYER)
+                       delete_gplayer_frames((bGPDlayer *)ale->data);
+               else
+                       delete_ipo_keys((Ipo *)ale->key_data);
        }
        
        /* free filtered list */
@@ -1692,6 +1798,7 @@ void clean_action (void)
                                0.0000001f, 1.0, 0.001, 0.1,
                                "Clean Threshold");
        if (!ok) return;
+       if (datatype == ACTCONT_GPENCIL) return;
        
        /* filter data */
        filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_SEL | ACTFILTER_ONLYICU);
@@ -1730,6 +1837,7 @@ void sample_action_keys (void)
        /* sanity checks */
        data= get_action_context(&datatype);
        if (data == NULL) return;
+       if (datatype == ACTCONT_GPENCIL) return;
        
        /* filter data */
        filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_ONLYICU);
@@ -2089,6 +2197,7 @@ void action_set_ipo_flags (short mode, short event)
        /* determine what type of data we are operating on */
        data = get_action_context(&datatype);
        if (data == NULL) return;
+       if (datatype == ACTCONT_GPENCIL) return;
        
        /* determine which set of processing we are doing */
        switch (mode) {
@@ -2187,6 +2296,7 @@ void sethandles_action_keys (int code)
        /* determine what type of data we are operating on */
        data = get_action_context(&datatype);
        if (data == NULL) return;
+       if (datatype == ACTCONT_GPENCIL) return;
        
        /* filter data */
        filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
@@ -2225,11 +2335,12 @@ static void numbuts_action ()
        bConstraintChannel *conchan= NULL;
        IpoCurve *icu= NULL;
        KeyBlock *kb= NULL;
+       bGPDlayer *gpl= NULL;
        
        short mval[2];
        
        int but=0;
-    char str[64];
+    char str[128];
        short expand, protect, mute;
        float slidermin, slidermax;
        
@@ -2338,6 +2449,18 @@ static void numbuts_action ()
                add_numbut(but++, TOG|SHO, "Expanded", 0, 24, &expand, "Action Group is Expanded");
                add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Group is Protected");
        }
+       else if (chantype == ACTTYPE_GPLAYER) {
+               /* Grease-Pencil Layer */
+               gpl= (bGPDlayer *)act_channel;
+               
+               strcpy(str, gpl->info);
+               protect= (gpl->flag & GP_LAYER_LOCKED);
+               mute = (gpl->flag & GP_LAYER_HIDE);
+               
+               add_numbut(but++, TEX, "GP-Layer: ", 0, 128, str, "Name of Grease Pencil Layer");
+               add_numbut(but++, TOG|SHO, "Hide", 0, 24, &mute, "Grease Pencil Layer is Visible");
+               add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Grease Pencil Layer is Protected");
+       }
        else {
                /* nothing under-cursor */
                return;
@@ -2386,6 +2509,16 @@ static void numbuts_action ()
                        if (protect) agrp->flag |= AGRP_PROTECTED;
                        else agrp->flag &= ~AGRP_PROTECTED;
                }
+               else if (gpl) {
+                       strcpy(gpl->info, str);
+                       BLI_uniquename(&( ((bGPdata *)data)->layers ), gpl, "GP_Layer", offsetof(bGPDlayer, info), 128);
+                       
+                       if (mute) gpl->flag |= GP_LAYER_HIDE;
+                       else gpl->flag &= ~GP_LAYER_HIDE;;
+                       
+                       if (protect) gpl->flag |= GP_LAYER_LOCKED;
+                       else gpl->flag &= ~GP_LAYER_LOCKED;
+               }
                
         allqueue(REDRAWACTION, 0);
                allspace(REMAKEIPO, 0);
@@ -2517,6 +2650,31 @@ void setflag_action_channels (short mode)
                                }
                        }
                                break;
+                       case ACTTYPE_GPLAYER:
+                       {
+                               bGPDlayer *gpl= (bGPDlayer *)ale->data;
+                               
+                               /* 'protect' and 'mute' */
+                               if (val == 2) {
+                                       /* mute */
+                                       if (mode == 2)
+                                               gpl->flag &= ~GP_LAYER_HIDE;
+                                       else if (mode == 1)
+                                               gpl->flag |= GP_LAYER_HIDE;
+                                       else
+                                               gpl->flag ^= GP_LAYER_HIDE;
+                               }
+                               else if (val == 1) {
+                                       /* protected */
+                                       if (mode == 2)
+                                               gpl->flag &= ~GP_LAYER_LOCKED;
+                                       else if (mode == 1)
+                                               gpl->flag |= GP_LAYER_LOCKED;
+                                       else
+                                               gpl->flag ^= GP_LAYER_LOCKED;
+                               }
+                       }
+                               break;
                }
        }
        BLI_freelistN(&act_data);
@@ -2557,7 +2715,7 @@ static void select_action_group (bAction *act, bActionGroup *agrp, int selectmod
        set_active_actiongroup(act, agrp, select);
 }
 
-static void hilight_channel(bAction *act, bActionChannel *achan, short select)
+static void hilight_channel (bAction *act, bActionChannel *achan, short select)
 {
        bActionChannel *curchan;
 
@@ -2630,7 +2788,7 @@ void select_actionchannel_by_name (bAction *act, char *name, int select)
 
 /* exported for outliner (ton) */
 /* apparently within active object context */
-int select_channel(bAction *act, bActionChannel *achan, int selectmode) 
+int select_channel (bAction *act, bActionChannel *achan, int selectmode) 
 {
        /* Select the channel based on the selection mode */
        int flag;
@@ -2654,9 +2812,9 @@ int select_channel(bAction *act, bActionChannel *achan, int selectmode)
        return flag;
 }
 
-static int select_constraint_channel(bAction *act, 
-                                     bConstraintChannel *conchan, 
-                                     int selectmode) 
+static int select_constraint_channel (bAction *act, 
+                                      bConstraintChannel *conchan, 
+                                      int selectmode) 
 {
        /* Select the constraint channel based on the selection mode */
        int flag;
@@ -2677,7 +2835,7 @@ static int select_constraint_channel(bAction *act,
        return flag;
 }
 
-int select_icu_channel(bAction *act, IpoCurve *icu, int selectmode) 
+int select_icu_channel (bAction *act, IpoCurve *icu, int selectmode) 
 {
        /* Select the channel based on the selection mode */
        int flag;
@@ -2697,6 +2855,51 @@ int select_icu_channel(bAction *act, IpoCurve *icu, int selectmode)
        return flag;
 }
 
+int select_gplayer_channel (bGPdata *gpd, bGPDlayer *gpl, int selectmode) 
+{
+       /* Select the channel based on the selection mode */
+       int flag;
+
+       switch (selectmode) {
+       case SELECT_ADD:
+               gpl->flag |= GP_LAYER_SELECT;
+               break;
+       case SELECT_SUBTRACT:
+               gpl->flag &= ~GP_LAYER_SELECT;
+               break;
+       case SELECT_INVERT:
+               gpl->flag ^= GP_LAYER_SELECT;
+               break;
+       }
+       flag = (gpl->flag & GP_LAYER_SELECT) ? 1 : 0;
+
+       gpencil_layer_setactive(gpd, gpl);
+
+       return flag;
+}
+
+
+/* select only the active action-group's action channels */
+void select_action_group_channels (bAction *act, bActionGroup *agrp)
+{
+       bActionChannel *achan;
+       
+       /* error checking */
+       if (ELEM(NULL, act, agrp))
+               return;
+       
+       /* deselect all other channels */
+       deselect_actionchannels(act, 0);
+       
+       /* only select channels in group */
+       for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+               select_channel(act, achan, SELECT_ADD);
+               
+               /* messy... set active bone */
+               select_poseelement_by_name(achan->name, 1);
+       }
+}
+
 /* ----------------------------------------- */
 
 /* De-selects or inverts the selection of Channels in a given Action 
@@ -2819,6 +3022,8 @@ void deselect_action_channels (short mode)
        /* based on type */
        if (datatype == ACTCONT_ACTION)
                deselect_actionchannels(data, mode);
+       else if (datatype == ACTCONT_GPENCIL)
+               deselect_gpencil_layers(data, mode);
        // should shapekey channels be allowed to do this? 
 }