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:
1  2 
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
source/blender/include/BIF_drawgpencil.h
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
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
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
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
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

diff --cc CMakeLists.txt
@@@ -197,10 -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}")
    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)
    
    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 --cc README
--- 1/README
--- 2/README
+++ b/README
@@@ -24,22 -24,22 +24,22 @@@ dir to one of these locations (your hom
  -------------------------------------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
@@@ -197,7 -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];
                }
@@@ -93,6 -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
        ):
                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 {
@@@ -477,7 -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 +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 +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)) {
                
@@@ -694,7 -694,7 +694,7 @@@ bool LbmFsgrSolver::initializeSolverMem
                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
  
  #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 
  #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;
@@@ -471,6 -471,6 +471,9 @@@ DNA_makesdna.exe dna.
                        <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>
@@@ -21,7 -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 +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>
@@@ -21,7 -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"
@@@ -175,6 -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 -265,3 +266,4 @@@ extern Global G
        
  #endif
  
++
@@@ -1437,6 -1437,6 +1437,9 @@@ CollisionModifierData **get_collisionob
  
                                        if(coll_ob == self)
                                                continue;
++                                      
++                                      if( !collmd->bvhtree)
++                                              continue;
  
                                        if(numobj >= maxobj)
                                        {
@@@ -915,7 -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;
@@@ -2797,7 -2797,7 +2797,10 @@@ void do_effectors(int pa_no, ParticleDa
                                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;
@@@ -60,6 -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 -3800,12 +3801,50 @@@ int RayIntersectsTriangle(float p1[3], 
  
  /* 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);
  /*---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);
                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);
  
        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);
        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;
                }
        }
  
        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);
        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)
@@@ -382,7 -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);
              }
@@@ -69,6 -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 -3698,6 +3699,32 @@@ static void lib_link_screen_sequence_ip
  
  /* ************ 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)
                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 -4081,6 +4108,10 @@@ static void direct_link_screen(FileDat
                                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);
                        }
                        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);
@@@ -112,6 -112,6 +112,7 @@@ Important to know is that 'streaming' h
  #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 -1565,6 +1566,32 @@@ static void write_scenes(WriteData *wd
        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;
                        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);
                                        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;
                                        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;
                        }
@@@ -451,7 -451,7 +451,7 @@@ void IMB_exr_begin_write(void *handle, 
        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);
  }
@@@ -38,6 -38,6 +38,7 @@@ struct bAction
  struct bActionGroup;
  struct Object;
  struct ListBase;
++struct bGPDlayer;
  
  /* ****************************** Base Structs ****************************** */
  
@@@ -82,6 -82,6 +83,7 @@@ void draw_ipo_channel(struct gla2DDrawI
  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 -89,6 +91,7 @@@ void ipo_to_keylist(struct Ipo *ipo, Li
  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 */
  
index 0000000,0000000..d0ebd09
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 */
index 0000000,0000000..4184463
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 */ 
@@@ -48,7 -48,7 +48,8 @@@ enum 
        ACTTYPE_FILLIPO,
        ACTTYPE_FILLCON,
        ACTTYPE_IPO,
--      ACTTYPE_SHAPEKEY
++      ACTTYPE_SHAPEKEY,
++      ACTTYPE_GPLAYER
  };
  
  /* Macros for easier/more consistant state testing */
  #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 -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 -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 -166,6 +173,7 @@@ void deselect_action_channels(short mod
  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 -174,6 +182,24 @@@ void action_add_localmarker(struct bAct
  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);
@@@ -591,6 -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);
  
@@@ -53,6 -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
  #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 -145,3 +150,4 @@@ extern              void mainwindow_close(void)
  
  #endif
  
++
@@@ -38,7 -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 -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
  #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
@@@ -397,6 -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);
@@@ -32,6 -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 -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 -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 */
@@@ -196,9 -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
index 0000000,0000000..eafd886
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 */
@@@ -50,6 -50,6 +50,7 @@@ struct RenderInfo
  struct bNodeTree;
  struct uiBlock;
  struct FileList;
++struct bGPdata;
  
        /**
         * The base structure all the other spaces
@@@ -150,6 -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 -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... */
        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;
  #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 {
@@@ -116,6 -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 {
@@@ -40,6 -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... */
  #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 -63,6 +67,9 @@@
      short xim, yim;
  } BGpic;
  
++/* ********************************* */
++
++/* 3D ViewPort Struct */
  typedef struct View3D {
        struct SpaceLink *next, *prev;
        int spacetype;
        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
  #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
  
  #endif
  
++
@@@ -126,6 -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 -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 */
@@@ -709,7 -708,7 +709,7 @@@ static PyObject *Blender_Save( PyObjec
                                              "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" );
                }
@@@ -1135,9 -1135,9 +1135,78 @@@ static PyObject *M_Library_Load(PyObjec
        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}
  };
  
@@@ -40,6 -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 -799,22 +800,27 @@@ static PyObject *Part_freeEdit( BPy_Par
        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;
        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;
                                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;
        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;
        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;
  
                                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;
        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;
                                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 -1376,11 +1551,8 @@@ static int Part_set2d( BPy_PartSys * se
  {
        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 -1526,7 +1698,7 @@@ static int Part_setRandEmission( BPy_Pa
  
  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 )
                return EXPP_ReturnIntError( PyExc_TypeError, errstr );
        }
  
--      self->psys->part->from = number;
++      self->psys->part->from = (short)number;
  
        Particle_RecalcPsys_distr(self,1);
  
@@@ -1603,7 -1603,7 +1775,7 @@@ static int Part_setDist( BPy_PartSys * 
                return EXPP_ReturnIntError( PyExc_TypeError, errstr );
        }
  
--      self->psys->part->distr = number;
++      self->psys->part->distr = (short)number;
  
        Particle_RecalcPsys_distr(self,1);
  
@@@ -1731,7 -1731,7 +1903,7 @@@ static int Part_setTargetPsys( BPy_Part
  
        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;
@@@ -250,7 -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.
                        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.
@@@ -27,17 -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:
        """
@@@ -56,17 -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
        @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
                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.
                """
@@@ -833,9 -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):
@@@ -987,7 -985,7 +987,7 @@@ PyObject *RenderData_EnableCropping( vo
  /*    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;
  }
  
@@@ -671,8 -671,8 +671,10 @@@ static void atm_tile(RenderPart *pa, Re
        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;
        
        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)
        
        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) {
                                        }
  
                                        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);
                                                
  
                        /* 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);
++                              }
++                      }
                }
        }
  }
@@@ -1379,6 -1379,6 +1379,8 @@@ static void shade_one_light(LampRen *la
                }
                
                /* 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)));
@@@ -3545,7 -3545,7 +3545,7 @@@ void merge_transp_passes(RenderLayer *r
        
        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:
                                col= &shr->mist;
                                pixsize= 1;
                                break;
++                      case SCE_PASS_Z:
++                              col= &shr->z;
++                              pixsize= 1;
++                              break;
                        case SCE_PASS_VECTOR:
                                
                                {
                        
                        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 -3973,7 +3981,7 @@@ unsigned short *zbuffer_transp_shade(Re
  
        /* 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)
@@@ -513,7 -513,7 +513,6 @@@ void do_common_editbuts(unsigned short 
                                } 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;
                                        nu= nu->next;
                                }
                                BIF_undo_push("Select material index");
--                              allqueue(REDRAWVIEW3D, 0);
                        }
++                      allqueue(REDRAWIMAGE, 0);
++                      allqueue(REDRAWVIEW3D, 0);
                }
                countall();
                break;
@@@ -5153,32 -5153,32 +5153,6 @@@ static void verify_posegroup_groupname(
        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;
                        /* 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");
@@@ -2062,7 -2062,7 +2062,7 @@@ static short draw_actuatorbuttons(Objec
                        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, "");
  
                        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");
  
                        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, "");
                        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, "");
                                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;
                }
                
@@@ -137,36 -137,36 +137,42 @@@ static void load_new_sample(char *str)  
        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 -403,7 +409,7 @@@ static void sound_panel_sound(bSound *s
                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 -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) {
@@@ -32,6 -32,6 +32,7 @@@
  
  #include <math.h>
  #include <stdlib.h>
++#include <string.h>
  
  #ifdef HAVE_CONFIG_H
  #include <config.h>
@@@ -56,6 -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 -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 -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 -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 -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) {
                                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 */
                                case ALE_ICU:
                                        draw_icu_channel(di, ale->key_data, y);
                                        break;
++                              case ALE_GPFRAME:
++                                      draw_gpl_channel(di, ale->data, y);
++                                      break;
                        }
                }
                
  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;
++      
        }
  }
  
  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 -976,6 +1122,7 @@@ void drawactionspace(ScrArea *sa, void 
  {
        bAction *act = NULL;
        Key *key = NULL;
++      bGPdata *gpd = NULL;
        void *data;
        short datatype;
        
  
        /* 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 -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 -1429,6 +1601,16 @@@ void draw_action_channel(gla2DDrawInfo 
        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 -1575,3 +1757,26 @@@ void action_to_keylist(bAction *act, Li
        }
  }
  
++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;
++              }
++      }
++}
++
index 0000000,0000000..55d0464
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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);
++}
++
++/* ************************************************** */
@@@ -37,6 -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 -3300,6 +3304,66 @@@ static void node_draw_group(ScrArea *sa
  }
  
  
++
++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;
                }
        }
        
++      /* 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 */
@@@ -1199,7 -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);
                
@@@ -43,6 -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 -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 -98,6 +102,70 @@@ static void draw_seq_text(Sequence *seq
  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 -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 -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;
@@@ -61,6 -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 -2498,7 +2501,7 @@@ static void view3d_panel_background(sho
        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
&