merge with trunk (15330 -> 15566)

This commit is contained in:
Martin Poirier 2008-07-14 14:09:36 +00:00
commit 84ae0fc000
261 changed files with 8786 additions and 2878 deletions

@ -197,10 +197,17 @@ IF(UNIX)
ENDIF(UNIX) ENDIF(UNIX)
IF(WIN32) 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) 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 ${LIBDIR}/python)
SET(PYTHON_VERSION 2.5) SET(PYTHON_VERSION 2.5)
SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}") SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}")
@ -214,12 +221,20 @@ IF(WIN32)
SET(OPENAL_LIB openal_static) SET(OPENAL_LIB openal_static)
SET(OPENAL_LIBPATH ${OPENAL}/lib) 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(JPEG_LIB libjpeg)
SET(ZLIB ${LIBDIR}/zlib) SET(ZLIB ${LIBDIR}/zlib)
SET(ZLIB_INC ${ZLIB}/include) 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(ZLIB_LIBPATH ${ZLIB}/lib)
SET(PTHREADS ${LIBDIR}/pthreads) SET(PTHREADS ${LIBDIR}/pthreads)
@ -302,7 +317,11 @@ IF(WIN32)
SET(WINTAB_INC ${LIBDIR}/wintab/include) 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 ") SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib;libc.lib ")
ENDIF(WIN32) ENDIF(WIN32)

14
README

@ -24,22 +24,22 @@ dir to one of these locations (your home directory being recommended).
-------------------------------------Links-------------------------------------- -------------------------------------Links--------------------------------------
Getting Involved: Getting Involved:
http://www.blender.org/docs/get_involved.html http://www.blender.org/community/get-involved
Community: Community:
http://www.blender3d.org/Community/ http://www.blender.org/Community
Main blender development site: Main blender development site:
http://www.blender.org/ http://www.blender.org
The Blender project homepage: The Blender project homepage:
http://projects.blender.org/projects/bf-blender/ http://projects.blender.org/projects/bf-blender
Documentation: Documentation:
http://www.blender.org/modules.php?op=modload&name=documentation&file=index http://www.blender.org/education-help
Bug tracker: 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: 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 @@ BuildEdges(
for (int vert = 0; vert < vertex_num; ++vert) { 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); InsertEdge(prev_vi,face.m_verts[vert],fi,dummy);
prev_vi = face.m_verts[vert]; prev_vi = face.m_verts[vert];
} }

@ -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( CTR_TaggedIndex(
const CTR_TaggedIndex &my_index const CTR_TaggedIndex &my_index
): ):
@ -124,6 +134,12 @@ public:
return (long int)(m_val & index_mask); return (long int)(m_val & index_mask);
} }
#if defined(_WIN64)
operator unsigned __int64 () const {
return (unsigned __int64)(m_val & index_mask);
}
#endif
bool bool
IsEmpty( IsEmpty(
) const { ) const {

@ -477,7 +477,7 @@ DeleteVertex(
return; 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)) { if (!(last == v)) {
@ -533,7 +533,7 @@ DeleteEdge(
return; 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)) { if (!(last == e)) {
vector<LOD_EdgeInd> e_verts; vector<LOD_EdgeInd> e_verts;
@ -573,7 +573,7 @@ DeleteFace(
return; 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)) { if (!(last == f)) {

@ -694,7 +694,7 @@ bool LbmFsgrSolver::initializeSolverMemory()
double maxDefaultMemChunk = 2.*1024.*1024.*1024.; double maxDefaultMemChunk = 2.*1024.*1024.*1024.;
//std::cerr<<" memEstFine "<< memEstFine <<" maxWin:" <<maxWinMemChunk <<" maxMac:" <<maxMacMemChunk ; // DEBUG //std::cerr<<" memEstFine "<< memEstFine <<" maxWin:" <<maxWinMemChunk <<" maxMac:" <<maxMacMemChunk ; // DEBUG
#ifdef WIN32 #ifdef WIN32
if(memEstFine> maxWinMemChunk) { if(sizeof(void *)==4 && memEstFine>maxWinMemChunk) {
memBlockAllocProblem = true; memBlockAllocProblem = true;
} }
#endif // WIN32 #endif // WIN32

@ -42,6 +42,14 @@
#include "GHOST_SystemWin32.h" #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 * 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 * upwards. Leaving WINVER at default value, the WM_MOUSEWHEEL message and the
@ -302,6 +310,15 @@ GHOST_TSuccess GHOST_SystemWin32::init()
{ {
GHOST_TSuccess success = GHOST_System::init(); GHOST_TSuccess success = GHOST_System::init();
/* Disable scaling on high DPI displays on Vista */
HMODULE user32 = ::LoadLibraryA("user32.dll");
typedef BOOL (WINAPI * LPFNSETPROCESSDPIAWARE)();
LPFNSETPROCESSDPIAWARE SetProcessDPIAware =
(LPFNSETPROCESSDPIAWARE)GetProcAddress(user32, "SetProcessDPIAware");
if (SetProcessDPIAware)
SetProcessDPIAware();
FreeLibrary(user32);
// Determine whether this system has a high frequency performance counter. */ // Determine whether this system has a high frequency performance counter. */
m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER*)&m_freq) == TRUE; m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER*)&m_freq) == TRUE;
if (m_hasPerformanceCounter) { if (m_hasPerformanceCounter) {

@ -48,6 +48,14 @@
#define M_PI 3.1415926536 #define M_PI 3.1415926536
#endif #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"; LPCSTR GHOST_WindowWin32::s_windowClassName = "GHOST_WindowClass";
const int GHOST_WindowWin32::s_maxTitleLength = 128; const int GHOST_WindowWin32::s_maxTitleLength = 128;
HGLRC GHOST_WindowWin32::s_firsthGLRc = NULL; HGLRC GHOST_WindowWin32::s_firsthGLRc = NULL;

@ -74,7 +74,7 @@ public:
virtual bool PositionTask() const { return false; } virtual bool PositionTask() const { return false; }
virtual void Scale(float scale) {} virtual void Scale(float) {}
protected: protected:
int m_id; int m_id;

@ -82,6 +82,24 @@ public:
} }
return 0; return 0;
} }
Key* getKey(int index) {
int count=0;
for (int i=0;i<m_num_buckets;i++)
{
Entry* bucket = m_buckets[i];
while(bucket)
{
if (count==index)
{
return &bucket->m_key;
}
bucket = bucket->m_next;
count++;
}
}
return 0;
}
void clear() { void clear() {
for (int i = 0; i < m_num_buckets; ++i) { for (int i = 0; i < m_num_buckets; ++i) {

@ -31,10 +31,10 @@
#include <limits.h> #include <limits.h>
#define MT_RAND_MAX ULONG_MAX #define MT_RAND_MAX UINT_MAX
extern void MT_srand(unsigned long); extern void MT_srand(unsigned int);
extern unsigned long MT_rand(); extern unsigned int MT_rand();
#endif #endif

@ -76,11 +76,11 @@
#define TEMPERING_SHIFT_T(y) (y << 15) #define TEMPERING_SHIFT_T(y) (y << 15)
#define TEMPERING_SHIFT_L(y) (y >> 18) #define TEMPERING_SHIFT_L(y) (y >> 18)
static unsigned long mt[N]; /* the array for the state vector */ static unsigned int mt[N]; /* the array for the state vector */
static int mti = N+1; /* mti==N+1 means mt[N] is not initialized */ static int mti = N+1; /* mti==N+1 means mt[N] is not initialized */
/* initializing the array with a NONZERO seed */ /* initializing the array with a NONZERO seed */
void MT_srand(unsigned long seed) void MT_srand(unsigned int seed)
{ {
/* setting initial seeds to mt[N] using */ /* setting initial seeds to mt[N] using */
/* the generator Line 25 of Table 1 in */ /* the generator Line 25 of Table 1 in */
@ -91,12 +91,12 @@ void MT_srand(unsigned long seed)
mt[mti] = (69069 * mt[mti-1]) & 0xffffffff; mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
} }
unsigned long MT_rand() unsigned int MT_rand()
{ {
static unsigned long mag01[2] = { 0x0, MATRIX_A }; static unsigned int mag01[2] = { 0x0, MATRIX_A };
/* mag01[x] = x * MATRIX_A for x=0,1 */ /* mag01[x] = x * MATRIX_A for x=0,1 */
unsigned long y; unsigned int y;
if (mti >= N) { /* generate N words at one time */ if (mti >= N) { /* generate N words at one time */
int kk; int kk;

@ -358,6 +358,9 @@
<File <File
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_memarena.c"> RelativePath="..\..\..\source\blender\blenlib\intern\BLI_memarena.c">
</File> </File>
<File
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_mempool.c">
</File>
<File <File
RelativePath="..\..\..\source\blender\blenlib\intern\boxpack2d.c"> RelativePath="..\..\..\source\blender\blenlib\intern\boxpack2d.c">
</File> </File>
@ -473,6 +476,9 @@
<File <File
RelativePath="..\..\..\source\blender\blenlib\BLI_memarena.h"> RelativePath="..\..\..\source\blender\blenlib\BLI_memarena.h">
</File> </File>
<File
RelativePath="..\..\..\source\blender\blenlib\BLI_mempool.h">
</File>
<File <File
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_scanfill.h"> RelativePath="..\..\..\source\blender\blenlib\intern\BLI_scanfill.h">
</File> </File>

@ -74,7 +74,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging" AdditionalIncludeDirectories="..\..\..\..\lib\windows\sdl\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\yafray;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\python;..\..\..\source\blender\blenkernel;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\blender\render\intern\include;..\..\..\source\blender\render\extern\include;..\..\..\source\kernel;..\..\..\source\kernel\gen_messaging"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR" PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR;_USE_MATH_DEFINES"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="1"
DefaultCharIsUnsigned="TRUE" DefaultCharIsUnsigned="TRUE"
@ -175,6 +175,9 @@
<File <File
RelativePath="..\..\..\source\blender\render\intern\source\strand.c"> RelativePath="..\..\..\source\blender\render\intern\source\strand.c">
</File> </File>
<File
RelativePath="..\..\..\source\blender\render\intern\source\sunsky.c">
</File>
<File <File
RelativePath="..\..\..\source\blender\render\intern\source\texture.c"> RelativePath="..\..\..\source\blender\render\intern\source\texture.c">
</File> </File>
@ -245,6 +248,9 @@
<File <File
RelativePath="..\..\..\source\blender\render\intern\include\strand.h"> RelativePath="..\..\..\source\blender\render\intern\include\strand.h">
</File> </File>
<File
RelativePath="..\..\..\source\blender\render\intern\include\sunsky.h">
</File>
<File <File
RelativePath="..\..\..\source\blender\render\intern\include\texture.h"> RelativePath="..\..\..\source\blender\render\intern\include\texture.h">
</File> </File>

@ -21,7 +21,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
InlineFunctionExpansion="1" 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" PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER=1;WITH_QUICKTIME;INTERNATIONAL;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET=1;WITH_FFMPEG"
StringPooling="TRUE" StringPooling="TRUE"
RuntimeLibrary="0" RuntimeLibrary="0"
@ -73,7 +73,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" 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" PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER;WITH_QUICKTIME;INTERNATIONAL;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET = 1;WITH_FFMPEG"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="1"

@ -332,6 +332,12 @@
<File <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_2DFilterActuator.cpp"> RelativePath="..\..\..\source\gameengine\GameLogic\SCA_2DFilterActuator.cpp">
</File> </File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ActuatorEventManager.cpp">
</File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ActuatorSensor.cpp">
</File>
<File <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_AlwaysEventManager.cpp"> RelativePath="..\..\..\source\gameengine\GameLogic\SCA_AlwaysEventManager.cpp">
</File> </File>
@ -395,6 +401,12 @@
<File <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_MouseSensor.cpp"> RelativePath="..\..\..\source\gameengine\GameLogic\SCA_MouseSensor.cpp">
</File> </File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_NANDController.cpp">
</File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_NORController.cpp">
</File>
<File <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ORController.cpp"> RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ORController.cpp">
</File> </File>
@ -425,6 +437,12 @@
<File <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_TimeEventManager.cpp"> RelativePath="..\..\..\source\gameengine\GameLogic\SCA_TimeEventManager.cpp">
</File> </File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_XNORController.cpp">
</File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_XORController.cpp">
</File>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"
@ -432,6 +450,12 @@
<File <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_2DFilterActuator.h"> RelativePath="..\..\..\source\gameengine\GameLogic\SCA_2DFilterActuator.h">
</File> </File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ActuatorEventManager.h">
</File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ActuatorSensor.h">
</File>
<File <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_AlwaysEventManager.h"> RelativePath="..\..\..\source\gameengine\GameLogic\SCA_AlwaysEventManager.h">
</File> </File>
@ -498,6 +522,12 @@
<File <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_MouseSensor.h"> RelativePath="..\..\..\source\gameengine\GameLogic\SCA_MouseSensor.h">
</File> </File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_NANDController.h">
</File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_NORController.h">
</File>
<File <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ORController.h"> RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ORController.h">
</File> </File>
@ -528,6 +558,12 @@
<File <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_TimeEventManager.h"> RelativePath="..\..\..\source\gameengine\GameLogic\SCA_TimeEventManager.h">
</File> </File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_XNORController.h">
</File>
<File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_XORController.h">
</File>
</Filter> </Filter>
</Files> </Files>
<Globals> <Globals>

@ -462,6 +462,9 @@
<File <File
RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_AddObjectActuator.cpp"> RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_AddObjectActuator.cpp">
</File> </File>
<File
RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_DynamicActuator.cpp">
</File>
<File <File
RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_EndObjectActuator.cpp"> RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_EndObjectActuator.cpp">
</File> </File>
@ -686,6 +689,9 @@
<File <File
RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_AddObjectActuator.h"> RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_AddObjectActuator.h">
</File> </File>
<File
RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_DynamicActuator.h">
</File>
<File <File
RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_EndObjectActuator.h"> RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_EndObjectActuator.h">
</File> </File>

@ -21,7 +21,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" 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" PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="1"
@ -125,7 +125,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
InlineFunctionExpansion="1" 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" PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"
StringPooling="TRUE" StringPooling="TRUE"
RuntimeLibrary="0" RuntimeLibrary="0"
@ -229,7 +229,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" 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" PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="1"
@ -281,7 +281,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
InlineFunctionExpansion="1" 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" PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"
StringPooling="TRUE" StringPooling="TRUE"
RuntimeLibrary="0" RuntimeLibrary="0"

@ -9,8 +9,8 @@ Fillename: 'Bake_Constraint.py'
""" """
__author__ = "Roger Wickes (rogerwickes(at)yahoo.com)" __author__ = "Roger Wickes (rogerwickes(at)yahoo.com)"
__script__ = "Bake Constraints" __script__ = "Animation Bake Constraints"
__version__ = "0.6" __version__ = "0.7"
__url__ = ["Communicate problems and errors, http://www.blenderartists.com/forum/private.php?do=newpm to PapaSmurf"] __url__ = ["Communicate problems and errors, http://www.blenderartists.com/forum/private.php?do=newpm to PapaSmurf"]
__email__= ["Roger Wickes, rogerwickes@yahoo.com", "scripts"] __email__= ["Roger Wickes, rogerwickes@yahoo.com", "scripts"]
__bpydoc__ = """\ __bpydoc__ = """\
@ -28,58 +28,62 @@ Developed for use with MoCap data, where a bone is constrained to point at an em
moving through space and time. This records the actual locrot of the armature moving through space and time. This records the actual locrot of the armature
so that the motion can be edited, reoriented, scaled, and used as NLA Actions so that the motion can be edited, reoriented, scaled, and used as NLA Actions
see also wiki Scripts/Manual/ Sandbox/Animation/Bake_Constraints (tbd) see also wiki Scripts/Manual/ Tutorial/Motion Capture <br>
Usage:<br> Usage: <br>
- Select the reference Object(s) you want to bake <br> - Select the reference Object(s) you want to bake <br>
- Set the frame range to bake in the Anim Panel <br> - Set the frame range to bake in the Anim Panel <br>
- Set the test code (if you want a self-test) in the RT field in the Anim Panel <br> - Set the test code (if you want a self-test) in the RT field in the Anim Panel <br>
-- Set RT:1 in the Anim panel to create a test armature <br> -- Set RT:1 to create a test armature <br>
-- Set RT: up to 100 for more debug messages and status updates <br>
<br> <br>
- Run the script <br> - Run the script <br>
- The clone copy of the object is created and it has an IPO curve assigned to it. - The clone copy of the object is created and it has an IPO curve assigned to it. <br>
- The clone shadows the object by an offset locrot (see usrDelta) - The clone shadows the object by an offset locrot (see usrDelta) <br>
- That Ipo has Location and Rotation curves that make the shadow mimic the movement of the selected object, - That Object has Ipo Location and Rotation curves that make the clone mimic the movement <br>
but without using constraints. Bones move identically in relation to the armature as the reference object of the selected object, but without using constraints. <br>
- If the object was an Armature, the clone's bones move identically in relation to the <br>
original armature, and an Action is created that drives the bone movements. <br>
Version History: Version History:
0.1: bakes Loc Rot for a constrained object 0.1: bakes Loc Rot for a constrained object
0.2: bakes Loc and Rot for the bones within Armature object 0.2: bakes Loc and Rot for the bones within Armature object
0.3: UI for setting options 0.3: UI for setting options
0.3.1 add manual to script library 0.3.1 add manual to script library
0.4: bake multiple objects 0.4: bake multiple objects
0.5: root bone worldspace rotation 0.5: root bone worldspace rotation
0.6: re-integration with BPyArmature 0.6: re-integration with BPyArmature
0.7: bakes parents and leaves clones selected
License, Copyright, and Attribution: License, Copyright, and Attribution:
by Roger WICKES May 2008, released under Blender Artistic Licence to Public Domain by Roger WICKES May 2008, released under Blender Artistic Licence to Public Domain
feel free to add to any Blender Python Scripts Bundle. feel free to add to any Blender Python Scripts Bundle.
Thanks to Jean-Baptiste PERIN, IdeasMan42 (Campbell Barton?), Basil_Fawlty/Cage_drei (Andrew Cruse) Thanks to Jean-Baptiste PERIN, IdeasMan42 (Campbell Barton), Basil_Fawlty/Cage_drei (Andrew Cruse)
much lifted/learned from blender.org/documentation/245PytonDoc and wiki much lifted/learned from blender.org/documentation/245PytonDoc and wiki
some modules based on c3D_Import.py, PoseLib16.py and IPO/Armature code examples e.g. camera jitter some modules based on c3D_Import.py, PoseLib16.py and IPO/Armature code examples e.g. camera jitter
Pseudocode (planned versions): Pseudocode:
Initialize Initialize
If at least one object is selected If at least one object is selected
For each selected object, For each selected object,
create a shadow object create a cloned object
remove any constraints on the clone remove any constraints on the clone
create or reset an ipo curve named like the object create or reset an ipo curve named like the object
for each frame for each frame
set the clone's locrot key based on the reference object set the clone's locrot key based on the reference object
if it's an armature, if it's an armature,
create an action (which is an Ipo for each bone) create an action (which is an Ipo for each bone)
for each frame of the animation for each frame of the animation
for each bone in the armature for each bone in the armature
set the key set the key
Else you're a smurf Else you're a smurf
Test Conditions and Regressions: Test Conditions and Regressions:
1. (v0.1) Non-armatures (the cube), with ipo curve and constraints at the object level 1. (v0.1) Non-armatures (the cube), with ipo curve and constraints at the object level
2. armatures, with ipo curve and constraints at the object level 2. armatures, with ipo curve and constraints at the object level
3. armatures, with bones that have ipo curves and constraints 3. armatures, with bones that have ipo curves and constraints
4. objects without parents, children with unselected parents, select children first.
Naming conventions: Naming conventions:
arm = a specific objec type armature arm = a specific objec type armature
bone = bones that make up the skeleton of an armature bone = bones that make up the skeleton of an armature
@ -89,19 +93,6 @@ Naming conventions:
pbone = pose bone, a posed bone in an object pbone = pose bone, a posed bone in an object
tst = testing, self-test routines tst = testing, self-test routines
usr = user-entered or designated stuff usr = user-entered or designated stuff
Pattern Notes (let me know if I've violated any):
Bergin Starting,Designing, Programming, Coding
Bergin 23 Indent for Structure - I don't like only 2, but the editor is set up that way
Bergin 26 Be Spacey Not Tabby - personal frustraion here. workaround is to Format->convert to whitespace
Bergin 27 Consistent Capitalization - except Blender, because I love it.
Bergin 28 Name Your Constants - not for those I plan on making variable
Python 01 Return Everything - I made this one up, all functions and methods end in return
even though it is decoration in Python, it helps Python throw an indentation error for typing mistakes
Wickes 01 Decorate Your Code - for visual appeal and to ease maintenance, include separators like #########
to visually distinquish and separate functions, making it quicker to scan through code for methods
Wickes 02 Whitespace helps readability - include blanks around = # and lines (after def, after return) to make it stand out and pretty
""" """
######################################## ########################################
@ -131,8 +122,8 @@ POSE_XFORM= [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT]
# set senstitivity for displaying debug/console messages. 0=none, 100=max # set senstitivity for displaying debug/console messages. 0=none, 100=max
# then call debug(num,string) to conditionally display status/info in console window # then call debug(num,string) to conditionally display status/info in console window
MODE=Blender.Get('rt') #execution mode: 0=run normal, x=self-test (test error trapping etc) MODE=Blender.Get('rt') #execution mode: 0=run normal, 1=make test armature
DEBUG=100 #how much detail on internal processing for big brother to see DEBUG=Blender.Get('rt') #how much detail on internal processing for user to see. range 0-100
BATCH=False #called from command line? is someone there? Would you like some cake? BATCH=False #called from command line? is someone there? Would you like some cake?
#there are two coordinate systems, the real, or absolute 3D space, #there are two coordinate systems, the real, or absolute 3D space,
@ -143,13 +134,11 @@ COORD_REAL = 1
# User Settings - Change these options manually or via GUI (future TODO) # User Settings - Change these options manually or via GUI (future TODO)
usrCoord = COORD_REAL # what the user wants usrCoord = COORD_REAL # what the user wants
usrParent = False # True=keep parent (if exists), False = breakaway (usually with Real) usrParent = False # True=clone keeps original parent, False = clone's parent is the clone of the original parent (if cloned)
usrFreeze = 2 #2=yes, 0=no. Freezes shadow object in place at current frame as origin usrFreeze = 2 #2=yes, 0=no. Freezes shadow object in place at current frame as origin
#TODO - i wonder if usrFreeze means we should set Delta to the the difference between the original object and parent?
# delta is amount to offset/change from the reference object. future set in a ui, so technically not a constant # delta is amount to offset/change from the reference object. future set in a ui, so technically not a constant
usrDelta = [10,10,0,0,0,0] #order specific - Loc xyz Rot xyz usrDelta = [10,10,0,0,0,0] #order specific - Loc xyz Rot xyz
usrACTION = True # Offset baked Action frames to start at frame 1 usrACTION = True # Offset baked Action frames to start at frame 1
usrBAKEobjIPO = False # bake the object Ipo? it is useless for MoCap, as we only want the Action, and the Object does not move
CURFRAME = 'curframe' #keyword to use when getting the frame number that the scene is presently on CURFRAME = 'curframe' #keyword to use when getting the frame number that the scene is presently on
ARMATURE = 'Armature' #en anglais ARMATURE = 'Armature' #en anglais
@ -159,7 +148,7 @@ BONE_SPACES = ['ARMATURESPACE','BONESPACE']
#Ipo curves created are prefixed with a name, like Ipo_ or Bake_ followed by the object/bone name #Ipo curves created are prefixed with a name, like Ipo_ or Bake_ followed by the object/bone name
#bakedArmName = "b." #used for both the armature class and object instance #bakedArmName = "b." #used for both the armature class and object instance
#ipoObjectNamePrefix= "" usrObjectNamePrefix= ""
#ipoBoneNamePrefix = "" #ipoBoneNamePrefix = ""
# for example, if on entry an armature named Man was selected, and the object prefix was "a." # for example, if on entry an armature named Man was selected, and the object prefix was "a."
# on exit an armature and an IPO curve named a.Man exists for the object as a whole # on exit an armature and an IPO curve named a.Man exists for the object as a whole
@ -177,7 +166,6 @@ scn = Blender.Scene.GetCurrent()
#================= #=================
######################################## ########################################
def debug(num,msg): #use log4j or just console here. def debug(num,msg): #use log4j or just console here.
if DEBUG >= num: if DEBUG >= num:
if BATCH == False: if BATCH == False:
print 'debug: '[:num/10+7]+msg print 'debug: '[:num/10+7]+msg
@ -201,9 +189,26 @@ def getRenderInfo():
debug(90,'Scene is on frame %i and frame range is %i to %i' % (curframe,staframe,endframe)) debug(90,'Scene is on frame %i and frame range is %i to %i' % (curframe,staframe,endframe))
return (staframe,endframe,curframe) return (staframe,endframe,curframe)
########################################
def sortObjects(obs): #returns a list of objects sorted based on parent dependency
obClones= []
while len(obClones) < len(obs):
for ob in obs:
if not ob in obClones:
par= ob.getParent()
#if no parent, or the parent is not scheduled to be cloned
if par==None:
obClones.append(ob) # add the independent
elif par not in obs: # parent will not be cloned
obClones.append(ob) # add the child
elif par in obClones: # is it on the list?
obClones.append(ob) # add the child
# parent may be a child, so it will be caught next time thru
debug(100,'clone object order: \n%s' % obClones)
return obClones # ordered list of (ob, par) tuples
######################################## ########################################
def sortBones(xbones): #returns a sorted list of bones that should be added,sorted based on parent dependency def sortBones(xbones): #returns a sorted list of bones that should be added,sorted based on parent dependency
print ('My suggestion would be:')
# while there are bones to add, # while there are bones to add,
# look thru the list of bones we need to add # look thru the list of bones we need to add
# if we have not already added this bone # if we have not already added this bone
@ -215,7 +220,7 @@ def sortBones(xbones): #returns a sorted list of bones that should be added,sort
# else #we need to keep cycling and catch its parent # else #we need to keep cycling and catch its parent
# else it is a root bone # else it is a root bone
# add it # add it
# else skip it, it's prego # else skip it, it's already in there
# endfor # endfor
# endwhile # endwhile
xboneNames=[] xboneNames=[]
@ -240,7 +245,6 @@ def sortBones(xbones): #returns a sorted list of bones that should be added,sort
######################################## ########################################
def dupliArmature(ob): #makes a copy in current scn of the armature used by ob and its bones def dupliArmature(ob): #makes a copy in current scn of the armature used by ob and its bones
ob_mat = ob.matrixWorld ob_mat = ob.matrixWorld
ob_data = ob.getData() ob_data = ob.getData()
debug(49,'Reference object uses %s' % ob_data) debug(49,'Reference object uses %s' % ob_data)
@ -261,8 +265,6 @@ def dupliArmature(ob): #makes a copy in current scn of the armature used by ob a
#when creating a child, we cannot link to a parent if it does not yet exist in our armature #when creating a child, we cannot link to a parent if it does not yet exist in our armature
ebones = [] #list of the bones I want to create for my arm ebones = [] #list of the bones I want to create for my arm
if BLENDER_VERSION > 245: debug(0,'WARNING: Programmer check for Bone updates in dupliArmature')
eboneNames = sortBones(xbones) eboneNames = sortBones(xbones)
i=0 i=0
@ -306,13 +308,13 @@ def dupliArmature(ob): #makes a copy in current scn of the armature used by ob a
print myob.matrix print myob.matrix
return myob return myob
########################################
def scrub(): # scrubs to startframe def scrub(): # scrubs to startframe
staFrame,endFrame,curFrame = getRenderInfo() staFrame,endFrame,curFrame = getRenderInfo()
# eye-candy, go from current to start, fwd or back # eye-candy, go from current to start, fwd or back
if not BATCH: if not BATCH:
print "Positioning to start..." debug(100, "Positioning to start...")
frameinc=(staFrame-curFrame)/10 frameinc=(staFrame-curFrame)/10
if abs(frameinc) >= 1: if abs(frameinc) >= 1:
for i in range(10): for i in range(10):
@ -320,6 +322,7 @@ def scrub(): # scrubs to startframe
Blender.Set(CURFRAME,curFrame) # computes the constrained location of the 'real' objects Blender.Set(CURFRAME,curFrame) # computes the constrained location of the 'real' objects
Blender.Redraw() Blender.Redraw()
Blender.Set(CURFRAME, staFrame) Blender.Set(CURFRAME, staFrame)
return
######################################## ########################################
def bakeBones(ref_ob,arm_ob): #copy pose from ref_ob to arm_ob def bakeBones(ref_ob,arm_ob): #copy pose from ref_ob to arm_ob
@ -335,7 +338,6 @@ def bakeBones(ref_ob,arm_ob): #copy pose from ref_ob to arm_ob
arm_channels = act.getAllChannelIpos() arm_channels = act.getAllChannelIpos()
pose= arm_ob.getPose() pose= arm_ob.getPose()
pbones= pose.bones.values() #we want the bones themselves, not the dictionary lookup pbones= pose.bones.values() #we want the bones themselves, not the dictionary lookup
print arm_channels.keys()
for pbone in pbones: for pbone in pbones:
debug (100,'Channel listing for %s: %s' % (pbone.name,arm_channels[pbone.name] )) debug (100,'Channel listing for %s: %s' % (pbone.name,arm_channels[pbone.name] ))
ipo=arm_channels[pbone.name] ipo=arm_channels[pbone.name]
@ -344,8 +346,7 @@ def bakeBones(ref_ob,arm_ob): #copy pose from ref_ob to arm_ob
return return
######################################## ########################################
def getOrCreateCurve(ipo, curvename): def getOrCreateCurve(ipo, curvename):
""" """
Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo
Either an ipo curve named C{curvename} exists before the call then this curve is returned, Either an ipo curve named C{curvename} exists before the call then this curve is returned,
@ -362,18 +363,17 @@ def getOrCreateCurve(ipo, curvename):
return mycurve return mycurve
######################################## ########################################
def eraseCurve(ipo,numCurves): def eraseCurve(ipo,numCurves):
debug(80,'Erasing %i curves for %' % (numCurves,ipo.GetName())) debug(90,'Erasing %i curves for %' % (numCurves,ipo.GetName()))
for i in range(numCurves): for i in range(numCurves):
nbBezPoints = ipo.getNBezPoints(i) nbBezPoints= ipo.getNBezPoints(i)
for j in range(nbBezPoints): for j in range(nbBezPoints):
ipo.delBezPoint(i) ipo.delBezPoint(i)
return return
######################################## ########################################
def resetIPO(ipo): def resetIPO(ipo):
ipoName=ipoObjectNamePrefix + obName debug(60,'Resetting ipo curve named %s' %ipo.name)
debug(40,'Resetting ipo curve named %s' %ipoName)
numCurves = ipo.getNcurves() #like LocX, LocY, etc numCurves = ipo.getNcurves() #like LocX, LocY, etc
if numCurves > 0: if numCurves > 0:
eraseCurve(ipo, numCurves) #erase data if one exists eraseCurve(ipo, numCurves) #erase data if one exists
@ -399,11 +399,11 @@ def resetIPOs(ob): #resets all IPO curvess assocated with an object and its bone
return return
######################################## ########################################
def parse(string,delim): def parse(string,delim):
index = string.find(delim) # -1 if not found, else pointer to delim index = string.find(delim) # -1 if not found, else pointer to delim
if index+1: return string[:index] if index+1: return string[:index]
return string return string
######################################## ########################################
def newIpo(ipoName): #add a new Ipo object to the Blender scene def newIpo(ipoName): #add a new Ipo object to the Blender scene
ipo=Blender.Ipo.New('Object',ipoName) ipo=Blender.Ipo.New('Object',ipoName)
@ -438,19 +438,16 @@ def makeUpaName(type,name): #i know this exists in Blender somewhere...
name=ipoName name=ipoName
else: else:
debug (0,'FATAL ERROR: I dont know how to make up a new %s name based on %s' % (type,ob)) debug (0,'FATAL ERROR: I dont know how to make up a new %s name based on %s' % (type,ob))
return return None
return name return name
######################################## ########################################
def createIpo(ob): #create an Ipo and curves and link them to this object def createIpo(ob): #create an Ipo and curves and link them to this object
#first, we have to create a unique name #first, we have to create a unique name
#try first with just the name of the object to keep things simple. #try first with just the name of the object to keep things simple.
ipoName = makeUpaName('Ipo',ob.getName()) # make up a name for a new Ipo based on the object name ipoName = makeUpaName('Ipo',ob.getName()) # make up a name for a new Ipo based on the object name
debug(20,'Ipo and LocRot curves called %s' % ipoName) debug(20,'Ipo and LocRot curves called %s' % ipoName)
ipo=newIpo(ipoName) ipo=newIpo(ipoName)
ob.setIpo(ipo) #link them ob.setIpo(ipo) #link them
return ipo return ipo
@ -465,7 +462,7 @@ def getLocLocal(ob):
ob.RotZ*R2D ob.RotZ*R2D
] ]
return key return key
######################################## ########################################
def getLocReal(ob): def getLocReal(ob):
obMatrix = ob.matrixWorld #Thank you IdeasMan42 obMatrix = ob.matrixWorld #Thank you IdeasMan42
@ -505,7 +502,7 @@ def getCurves(ipo):
ipo[Ipo.OB_ROTZ] ipo[Ipo.OB_ROTZ]
] ]
return ipos return ipos
######################################## ########################################
def addPoint(time,keyLocRot,ipos): def addPoint(time,keyLocRot,ipos):
if BLENDER_VERSION < 245: if BLENDER_VERSION < 245:
@ -579,7 +576,7 @@ def removeConstraints(ob):
debug(90,'removed %s => %s' % (ob.name, const)) debug(90,'removed %s => %s' % (ob.name, const))
ob.constraints.remove(const) ob.constraints.remove(const)
return return
######################################## ########################################
def removeConstraintsOb(ob): # from object or armature def removeConstraintsOb(ob): # from object or armature
debug(40,'Removing constraints from '+ob.getName()) debug(40,'Removing constraints from '+ob.getName())
@ -605,37 +602,27 @@ def bakeObject(ob): #bakes the core object locrot and assigns the Ipo to a Clone
if ob != None: if ob != None:
# Clone the object - duplicate it, clean the clone, and create an ipo curve for the clone # Clone the object - duplicate it, clean the clone, and create an ipo curve for the clone
myob = duplicateLinked(ob) #clone it myob = duplicateLinked(ob) #clone it
myob.name= usrObjectNamePrefix + ob.getName()
removeConstraintsOb(myob) #my object is a free man removeConstraintsOb(myob) #my object is a free man
deLinkOb('Ipo',myob) #kids, it's not nice to share. you've been lied to deLinkOb('Ipo',myob) #kids, it's not nice to share. you've been lied to
if usrBAKEobjIPO: if ob.getType() != ARMATURE: # baking armatures is based on bones, not object
myipo = createIpo(myob) #create own IPO and curves for the clone object myipo = createIpo(myob) #create own IPO and curves for the clone object
ipos = bakeFrames(ob,myipo) #bake the locrot for this obj for the scene frames ipos = bakeFrames(ob,myipo) #bake the locrot for this obj for the scene frames
# staframe,endframe,curframe = getRenderInfo()
# frame = staframe
# Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
# frame +=1
# Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
# frame -=1
# Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
# if not BATCH: Blender.Redraw()
#
return myob return myob
######################################## ########################################
def bake(ob): #bakes an object of any type def bake(ob,par): #bakes an object of any type, linking it to parent
debug(0,'Baking %s object %s' % (ob.getType(), ob))
debug(30,'Baking %s object %s' % (ob.getType(), ob)) clone = bakeObject(ob) #creates and bakes the object motion
if par!= None:
myob = bakeObject(ob) #creates and bakes the object motion par.makeParent([clone])
debug(20,"assigned object to parent %s" % par)
if ob.getType() == ARMATURE: if ob.getType() == ARMATURE:
# error('Object baked. Continue with bones?') ## error('Object baked. Continue with bones?')
bakeBones(ob,myob) #go into the bones and copy from -> to in frame range bakeBones(ob,clone) #go into the bones and copy from -> to in frame range
#future idea: bakeMesh (net result of Shapekeys, Softbody, Cloth, Fluidsim,...) #future idea: bakeMesh (net result of Shapekeys, Softbody, Cloth, Fluidsim,...)
return clone
return
######################################## ########################################
def tstCreateArm(): #create a test armature in scene def tstCreateArm(): #create a test armature in scene
# rip-off from http://www.blender.org/documentation/245PythonDoc/Pose-module.html - thank you! # rip-off from http://www.blender.org/documentation/245PythonDoc/Pose-module.html - thank you!
@ -690,8 +677,8 @@ def tstCreateArm(): #create a test armature in scene
frame = 1 frame = 1
for pbone in pbones: # set bones to no rotation for pbone in pbones: # set bones to no rotation
pbone.quat[:] = 1.000,0.000,0.000,0.0000 pbone.quat[:] = 1.000,0.000,0.000,0.0000
pbone.insertKey(arm_ob, frame, Object.Pose.ROT) pbone.insertKey(arm_ob, frame, Object.Pose.ROT)
# Set a different rotation at frame 25 # Set a different rotation at frame 25
pbones[0].quat[:] = 1.000,0.1000,0.2000,0.20000 pbones[0].quat[:] = 1.000,0.1000,0.2000,0.20000
@ -747,7 +734,7 @@ def tstMoveOb(ob): # makes a simple LocRot animation of object in the scene
debug(100,'%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f' % (ipo.name, frame, time, key[0], key[1], key[2], key[3], key[4], key[5])) debug(100,'%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f' % (ipo.name, frame, time, key[0], key[1], key[2], key[3], key[4], key[5]))
frame += frameDelta frame += frameDelta
Blender.Set('curframe',curframe) # reset back to where we started Blender.Set(CURFRAME,curframe) # reset back to where we started
return return
#================= #=================
# Program Template # Program Template
@ -755,25 +742,31 @@ def tstMoveOb(ob): # makes a simple LocRot animation of object in the scene
######################################## ########################################
def main(): def main():
# return code set via rt button in Blender Buttons Scene Context Anim panel # return code set via rt button in Blender Buttons Scene Context Anim panel
if MODE == 1: #create test armature #1 if MODE == 1: #create test armature #1
ob = tstCreateArm() # make test arm and select it ob = tstCreateArm() # make test arm and select it
tstMoveOb(ob) tstMoveOb(ob)
scn.objects.selected = [ob] scn.objects.selected = [ob]
obs = Blender.Object.GetSelected() #scn.objects.selected obs= Blender.Object.GetSelected() #scn.objects.selected
debug(20,'Baking %i objects' % len(obs)) obs= sortObjects(obs)
debug(0,'Baking %i objects' % len(obs))
if len(obs) >= 1: # user might have multiple objects selected if len(obs) >= 1: # user might have multiple objects selected
i= 0
clones=[] # my clone army
for ob in obs: for ob in obs:
bake(ob) par= ob.getParent()
if not usrParent:
if par in obs:
par= clones[obs.index(par)]
clones.append(bake(ob,par))
scn.objects.selected = clones
else: else:
error('Please select at least one object') error('Please select at least one object')
return return
######################################## ########################################
def benchmark(): # This lets you benchmark (time) the script's running duration def benchmark(): # This lets you benchmark (time) the script's running duration
Window.WaitCursor(1) Window.WaitCursor(1)
t = sys.time() t = sys.time()
debug(60,'%s began at %.0f' %(__script__,sys.time())) debug(60,'%s began at %.0f' %(__script__,sys.time()))
@ -787,7 +780,7 @@ def benchmark(): # This lets you benchmark (time) the script's running duration
if in_editmode: Window.EditMode(1) if in_editmode: Window.EditMode(1)
# Timing the script is a good way to be aware on any speed hits when scripting # Timing the script is a good way to be aware on any speed hits when scripting
debug(60,'%s Script finished in %.2f seconds' % (__script__,sys.time()-t) ) debug(0,'%s Script finished in %.2f seconds' % (__script__,sys.time()-t) )
Window.WaitCursor(0) Window.WaitCursor(0)
return return
@ -795,6 +788,5 @@ def benchmark(): # This lets you benchmark (time) the script's running duration
# This lets you can import the script without running it # This lets you can import the script without running it
if __name__ == '__main__': if __name__ == '__main__':
debug(0, "------------------------------------") debug(0, "------------------------------------")
debug(0, '%s %s Script begins with mode=%i debug=%i batch=%s version=%i' % (__script__,__version__,MODE,DEBUG,BATCH,BLENDER_VERSION)) debug(0, "%s %s Script begins with mode=%i debug=%i batch=%s" % (__script__,__version__,MODE,DEBUG,BATCH))
benchmark() benchmark()

@ -8,7 +8,7 @@ Tooltip: 'Import a C3D Motion Capture file'
""" """
__script__ = "C3D Motion Capture file import" __script__ = "C3D Motion Capture file import"
__author__ = " Jean-Baptiste PERIN, Roger D. Wickes (rogerwickes@yahoo.com)" __author__ = " Jean-Baptiste PERIN, Roger D. Wickes (rogerwickes@yahoo.com)"
__version__ = "0.8" __version__ = "0.9"
__url__ = ["Communicate problems and errors, BlenderArtists.org, Python forum"] __url__ = ["Communicate problems and errors, BlenderArtists.org, Python forum"]
__email__= ["rogerwickes@yahoo.com", "c3d script"] __email__= ["rogerwickes@yahoo.com", "c3d script"]
__bpydoc__ = """\ __bpydoc__ = """\
@ -16,9 +16,9 @@ c3d_import.py v0.8
Script loading Graphics Lab Motion Capture file, Script loading Graphics Lab Motion Capture file,
Usage:<br> Usage:<br>
- Run the script <br> - Run the script <br>
- Choose the file to open<br> - Choose the file to open<br>
- Press Import C3D button<br> - Press Import C3D button<br>
Version History: Version History:
0.4: PERIN Released under Blender Artistic Licence 0.4: PERIN Released under Blender Artistic Licence
@ -26,6 +26,7 @@ Version History:
0.6: WICKES creates armature for each subject 0.6: WICKES creates armature for each subject
0.7: WICKES constrains armature to follow the empties (markers). Verified for shake hands s 0.7: WICKES constrains armature to follow the empties (markers). Verified for shake hands s
0.8: WICKES resolved DEC support issue 0.8: WICKES resolved DEC support issue
0.9: BARTON removed scene name change, whitespace edits. WICKES added IK layers
""" """
#---------------------------------------------- #----------------------------------------------
@ -69,12 +70,12 @@ XYZ_LIMIT= 10000 #max value for coordinates if in integer format
# selecting only layer 2 shows only the armature moving, 12 shows only the empties # selecting only layer 2 shows only the armature moving, 12 shows only the empties
LAYERS_ARMOB= [1,2] LAYERS_ARMOB= [1,2]
LAYERS_MARKER=[1,12] LAYERS_MARKER=[1,12]
LAYERS_IK=[1,11]
IK_PREFIX="ik_" # prefix in empty name: ik_prefix+subject prefix+bone name
CLEAN=True # Should program ignore markers at (0,0,0) and beyond the outer limits? CLEAN=True # Should program ignore markers at (0,0,0) and beyond the outer limits?
scn = Blender.Scene.GetCurrent() scn = Blender.Scene.GetCurrent()
# Why on earth would you rename a scene when importing data??? - Campbell
# scn.name="MoCap" #may want this enterable or derived based on motion being analyzed
#TODO: ultimately, a library of motions to append from means you need good naming of things
BCS=Blender.Constraint.Settings # shorthand dictionary - define with brace, reference with bracket BCS=Blender.Constraint.Settings # shorthand dictionary - define with brace, reference with bracket
trackto={"+x":BCS.TRACKX, "+y":BCS.TRACKY, "+z":BCS.TRACKZ, "-x":BCS.TRACKNEGX, "-y":BCS.TRACKNEGY, "-z":BCS.TRACKNEGZ} trackto={"+x":BCS.TRACKX, "+y":BCS.TRACKY, "+z":BCS.TRACKZ, "-x":BCS.TRACKNEGX, "-y":BCS.TRACKNEGY, "-z":BCS.TRACKNEGZ}
@ -169,22 +170,21 @@ def getEmpty(name):
# in : objname : le nom de l'empty recherche # in : objname : le nom de l'empty recherche
# out : myobj : l'empty cree ou retrouve # out : myobj : l'empty cree ou retrouve
######### #########
def GetOrCreateEmpty(objname): def getOrCreateEmpty(objname):
myobj= getEmpty(objname) myobj= getEmpty(objname)
if myobj==None: if myobj==None:
myobj = scn.objects.new("Empty",objname) myobj = scn.objects.new("Empty",objname)
myobj.layers= LAYERS_MARKER
debug(50,'Marker/Empty created %s' % myobj) debug(50,'Marker/Empty created %s' % myobj)
return myobj return myobj
def GetOrCreateCurve(ipo, curvename): def getOrCreateCurve(ipo, curvename):
""" """
Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo
>>> import mylib >>> import mylib
>>> lIpo = GetOrCreateIPO("Une IPO") >>> lIpo = GetOrCreateIPO("Une IPO")
>>> laCurve = GetOrCreateCurve(lIpo, "RotX") >>> laCurve = getOrCreateCurve(lIpo, "RotX")
Either an ipo curve named C{curvename} exists before the call then this curve is returned, Either an ipo curve named C{curvename} exists before the call then this curve is returned,
Or such a curve doesn't exist before the call .. then it is created into the c{ipo} Ipo and returned Or such a curve doesn't exist before the call .. then it is created into the c{ipo} Ipo and returned
@ -338,7 +338,8 @@ def makeNodes(prefix, markerList, empties, marker_set): #make sure the file has
elif usrOption==1: #add these markers as static empties, and user will automate them later elif usrOption==1: #add these markers as static empties, and user will automate them later
#and the bones will be keyed to them, so it will all be good. #and the bones will be keyed to them, so it will all be good.
#file may have just mis-named the empty, or the location can be derived based on other markers #file may have just mis-named the empty, or the location can be derived based on other markers
em= GetOrCreateEmpty(err[2]) em= getOrCreateEmpty(err[2])
em.layers= LAYERS_MARKER
else: abort() #abend else: abort() #abend
if DEBUG==100: status("Nodes Updated") if DEBUG==100: status("Nodes Updated")
return nodes #nodes may be updated return nodes #nodes may be updated
@ -411,8 +412,9 @@ def makeConstIK(prefix,pbone,const):
#Blender 246 only supports one IK Solver per bone, but we might want many, #Blender 246 only supports one IK Solver per bone, but we might want many,
# so we need to create a reference empty named after the bone # so we need to create a reference empty named after the bone
# that floats between the markers, so the bone can point to it as a singularity # that floats between the markers, so the bone can point to it as a singularity
myob= GetOrCreateEmpty(prefix+pbone.name) myob= getOrCreateEmpty(IK_PREFIX+prefix+pbone.name)
# note that this empty gets all the IK constraints added on myob.layers= LAYERS_IK
# note that this empty gets all the IK constraints added on as location constraints
myconst= myob.constraints.append(Constraint.Type.COPYLOC) myconst= myob.constraints.append(Constraint.Type.COPYLOC)
myconst.name=const[0]+"-"+const[1] myconst.name=const[0]+"-"+const[1]
myconst[Constraint.Settings.TARGET]= Blender.Object.Get(const[1]) myconst[Constraint.Settings.TARGET]= Blender.Object.Get(const[1])
@ -438,15 +440,18 @@ def makeConstTT(pbone,const):
myconst= pbone.constraints.append(Constraint.Type.TRACKTO) myconst= pbone.constraints.append(Constraint.Type.TRACKTO)
myconst.name=const[0]+"-"+const[1] myconst.name=const[0]+"-"+const[1]
debug(70,"%s %s" % (myconst,const[3])) debug(70,"%s %s" % (myconst,const[3]))
myob= GetOrCreateEmpty(const[1]) myob= getEmpty(const[1])
myconst[BCS.TARGET]= myob if myob!= None:
myconst.influence = const[2] myconst[BCS.TARGET]= myob
#const[3] is the Track and the thrird char is the Up indicator myconst.influence = const[2]
myconst[BCS.TRACK]= trackto[const[3][0:2].lower()] #const[3] is the Track and the thrird char is the Up indicator
myconst[BCS.UP]=trackup[const[3][2].lower()]#up direction myconst[BCS.TRACK]= trackto[const[3][0:2].lower()]
myconst[BCS.OWNERSPACE]= BCS.SPACE_LOCAL myconst[BCS.UP]=trackup[const[3][2].lower()]#up direction
myconst[BCS.TARGETSPACE]= [BCS.SPACE_LOCAL] myconst[BCS.OWNERSPACE]= BCS.SPACE_LOCAL
if const[3][1]==const[3][2]: debug(0,"WARNING: Track To axis and up axis should not be the same. Constraint is INACTIVE") myconst[BCS.TARGETSPACE]= [BCS.SPACE_LOCAL]
if const[3][1]==const[3][2]: debug(0,"WARNING: Track To axis and up axis should not be the same. Constraint is INACTIVE")
else: #marker not found. could be missing from this file, or an error in node spec
error("TrackTo Constraint for %s |specifies unknown marker %s" % (pbone.name,const[1]))
return return
def makePoses(prefix,arm_ob,nodes): # pose this armature object based on node requirements def makePoses(prefix,arm_ob,nodes): # pose this armature object based on node requirements
@ -543,15 +548,16 @@ def makeCloud(Nmarkers,markerList,StartFrame,EndFrame,Markers):
for i in range(Nmarkers): for i in range(Nmarkers):
debug(100,"%i marker %s"%(i, markerList[i])) debug(100,"%i marker %s"%(i, markerList[i]))
emptyname = markerList[i] # rdw: to use meaningful names from Points parameter emptyname = markerList[i] # rdw: to use meaningful names from Points parameter
em= GetOrCreateEmpty(emptyname) #in this scene em= getOrCreateEmpty(emptyname) #in this scene
em.layers= LAYERS_MARKER
#make a list of the actual empty #make a list of the actual empty
empties.append(em) empties.append(em)
#assign it an ipo with the loc xyz curves #assign it an ipo with the loc xyz curves
lipo = Ipo.New("Object",em.name) lipo = Ipo.New("Object",em.name)
ipos.append(lipo) ipos.append(lipo)
curvesX.append(GetOrCreateCurve(ipos[i],'LocX')) curvesX.append(getOrCreateCurve(ipos[i],'LocX'))
curvesY.append(GetOrCreateCurve(ipos[i],'LocY')) curvesY.append(getOrCreateCurve(ipos[i],'LocY'))
curvesZ.append(GetOrCreateCurve(ipos[i],'LocZ')) curvesZ.append(getOrCreateCurve(ipos[i],'LocZ'))
empties[i].setIpo(ipos[i]) empties[i].setIpo(ipos[i])
debug(30,"Cloud of %i empties created." % len(empties)) debug(30,"Cloud of %i empties created." % len(empties))
NvideoFrames= EndFrame-StartFrame+1 NvideoFrames= EndFrame-StartFrame+1

@ -353,6 +353,7 @@ Section "Blender-VERSION (required)" SecCopyUI
SetOutPath $INSTDIR SetOutPath $INSTDIR
; Write the installation path into the registry ; Write the installation path into the registry
WriteRegStr HKLM SOFTWARE\BlenderFoundation "Install_Dir" "$INSTDIR" WriteRegStr HKLM SOFTWARE\BlenderFoundation "Install_Dir" "$INSTDIR"
WriteRegStr HKLM SOFTWARE\BlenderFoundation "Home_Dir" "$BLENDERHOME"
; Write the uninstall keys for Windows ; Write the uninstall keys for Windows
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Blender" "DisplayName" "Blender (remove only)" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Blender" "DisplayName" "Blender (remove only)"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Blender" "UninstallString" '"$INSTDIR\uninstall.exe"' WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Blender" "UninstallString" '"$INSTDIR\uninstall.exe"'
@ -406,28 +407,32 @@ SectionEnd
UninstallText "This will uninstall Blender VERSION. Hit next to continue." UninstallText "This will uninstall Blender VERSION. Hit next to continue."
Section "Uninstall" Section "Uninstall"
Delete $INSTDIR\uninstall.exe
ReadRegStr $BLENDERHOME HKLM "SOFTWARE\BlenderFoundation" "Home_Dir"
; remove registry keys ; remove registry keys
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Blender" DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Blender"
DeleteRegKey HKLM SOFTWARE\BlenderFoundation DeleteRegKey HKLM SOFTWARE\BlenderFoundation
; remove files ; remove files
[DELROOTDIRCONTS] [DELROOTDIRCONTS]
Delete $INSTDIR\.blender\.bfont.ttf Delete $BLENDERHOME\.blender\.bfont.ttf
Delete $INSTDIR\.blender\.Blanguages Delete $BLENDERHOME\.blender\.Blanguages
; remove shortcuts, if any. ; remove shortcuts, if any.
Delete "$SMPROGRAMS\Blender Foundation\Blender\*.*" Delete "$SMPROGRAMS\Blender Foundation\Blender\*.*"
Delete "$DESKTOP\Blender.lnk" Delete "$DESKTOP\Blender.lnk"
; remove directories used. ; remove directories used.
RMDir /r $INSTDIR\.blender\locale RMDir /r $BLENDERHOME\.blender\locale
MessageBox MB_YESNO "Erase .blender\scripts folder? (ALL contents will be erased!)" IDNO Next MessageBox MB_YESNO "Erase .blender\scripts folder? (ALL contents will be erased!)" IDNO Next
RMDir /r $INSTDIR\.blender\scripts RMDir /r $BLENDERHOME\.blender\scripts
RMDir /r $INSTDIR\.blender\scripts\bpymodules RMDir /r $BLENDERHOME\.blender\scripts\bpymodules
RMDir /r $INSTDIR\.blender\scripts\bpydata RMDir /r $BLENDERHOME\.blender\scripts\bpydata
RMDir /r $INSTDIR\.blender\scripts\bpydata\config RMDir /r $BLENDERHOME\.blender\scripts\bpydata\config
Next: Next:
RMDir /r $INSTDIR\plugins\include RMDir /r $BLENDERHOME\plugins\include
RMDir /r $INSTDIR\plugins RMDir /r $BLENDERHOME\plugins
RMDir $INSTDIR\.blender RMDir $BLENDERHOME\.blender
RMDir "$SMPROGRAMS\Blender Foundation\Blender" RMDir "$SMPROGRAMS\Blender Foundation\Blender"
RMDir "$SMPROGRAMS\Blender Foundation" RMDir "$SMPROGRAMS\Blender Foundation"
RMDir "$INSTDIR" RMDir "$INSTDIR"

@ -39,12 +39,12 @@
#include "DNA_listBase.h" #include "DNA_listBase.h"
#include "BLI_ghash.h" #include "BLI_ghash.h"
#include "BLI_mempool.h"
#include "BLI_memarena.h" #include "BLI_memarena.h"
#include "DNA_image_types.h" #include "DNA_image_types.h"
#include "BLI_editVert.h" #include "BLI_editVert.h"
#include "BKE_DerivedMesh.h" #include "BKE_DerivedMesh.h"
#include "transform.h" #include "transform.h"
#include "BKE_bmeshCustomData.h"
/*forward declerations*/ /*forward declerations*/
struct BME_Vert; struct BME_Vert;
@ -53,13 +53,6 @@ struct BME_Poly;
struct BME_Loop; struct BME_Loop;
/*structure for fast memory allocation/frees*/
typedef struct BME_mempool{
struct ListBase chunks;
int esize, csize, pchunk; /*size of elements and chunks in bytes and number of elements per chunk*/
struct BME_freenode *free; /*free element list. Interleaved into chunk datas.*/
}BME_mempool;
/*Notes on further structure Cleanup: /*Notes on further structure Cleanup:
-Remove the tflags, they belong in custom data layers -Remove the tflags, they belong in custom data layers
-Remove the eflags completely, they are mostly not used -Remove the eflags completely, they are mostly not used
@ -78,10 +71,10 @@ typedef struct BME_Mesh
{ {
ListBase verts, edges, polys; ListBase verts, edges, polys;
/*memory pools used for storing mesh elements*/ /*memory pools used for storing mesh elements*/
struct BME_mempool *vpool; struct BLI_mempool *vpool;
struct BME_mempool *epool; struct BLI_mempool *epool;
struct BME_mempool *ppool; struct BLI_mempool *ppool;
struct BME_mempool *lpool; struct BLI_mempool *lpool;
/*some scratch arrays used by eulers*/ /*some scratch arrays used by eulers*/
struct BME_Vert **vtar; struct BME_Vert **vtar;
struct BME_Edge **edar; struct BME_Edge **edar;
@ -90,7 +83,7 @@ typedef struct BME_Mesh
int vtarlen, edarlen, lparlen, plarlen; int vtarlen, edarlen, lparlen, plarlen;
int totvert, totedge, totpoly, totloop; /*record keeping*/ int totvert, totedge, totpoly, totloop; /*record keeping*/
int nextv, nexte, nextp, nextl; /*Next element ID for verts/edges/faces/loops. Never reused*/ int nextv, nexte, nextp, nextl; /*Next element ID for verts/edges/faces/loops. Never reused*/
struct BME_CustomData vdata, edata, pdata, ldata; /*Custom Data Layer information*/ struct CustomData vdata, edata, pdata, ldata; /*Custom Data Layer information*/
} BME_Mesh; } BME_Mesh;
typedef struct BME_Vert typedef struct BME_Vert
@ -169,7 +162,7 @@ int BME_radial_find_face(struct BME_Edge *e,struct BME_Poly *f);
struct BME_Loop *BME_loop_find_loop(struct BME_Poly *f, struct BME_Vert *v); struct BME_Loop *BME_loop_find_loop(struct BME_Poly *f, struct BME_Vert *v);
/*MESH CREATION/DESTRUCTION*/ /*MESH CREATION/DESTRUCTION*/
struct BME_Mesh *BME_make_mesh(int allocsize[4], struct BME_CustomDataInit init[4]); struct BME_Mesh *BME_make_mesh(int allocsize[4]);
void BME_free_mesh(struct BME_Mesh *bm); void BME_free_mesh(struct BME_Mesh *bm);
/*FULL MESH VALIDATION*/ /*FULL MESH VALIDATION*/
int BME_validate_mesh(struct BME_Mesh *bm, int halt); int BME_validate_mesh(struct BME_Mesh *bm, int halt);

@ -38,7 +38,7 @@
#ifndef BKE_BMESHCUSTOMDATA_H #ifndef BKE_BMESHCUSTOMDATA_H
#define BKE_BMESHCUSTOMDATA_H #define BKE_BMESHCUSTOMDATA_H
struct BME_mempool; struct BLI_mempool;
/*Custom Data Types and defines /*Custom Data Types and defines
Eventual plan is to move almost everything to custom data and let caller Eventual plan is to move almost everything to custom data and let caller
@ -62,7 +62,7 @@ typedef struct BME_CustomDataLayer {
typedef struct BME_CustomData { typedef struct BME_CustomData {
struct BME_CustomDataLayer *layers; /*Custom Data Layers*/ struct BME_CustomDataLayer *layers; /*Custom Data Layers*/
struct BME_mempool *pool; /*pool for alloc of blocks*/ struct BLI_mempool *pool; /*pool for alloc of blocks*/
int totlayer, totsize; /*total layers and total size in bytes of each block*/ int totlayer, totsize; /*total layers and total size in bytes of each block*/
} BME_CustomData; } BME_CustomData;

@ -208,7 +208,7 @@ typedef enum
//////////////////////////////////////////////// ////////////////////////////////////////////////
// needed for implicit.c // needed for implicit.c
int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ); int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, float dt );
//////////////////////////////////////////////// ////////////////////////////////////////////////

@ -40,6 +40,8 @@ extern const CustomDataMask CD_MASK_BAREMESH;
extern const CustomDataMask CD_MASK_MESH; extern const CustomDataMask CD_MASK_MESH;
extern const CustomDataMask CD_MASK_EDITMESH; extern const CustomDataMask CD_MASK_EDITMESH;
extern const CustomDataMask CD_MASK_DERIVEDMESH; extern const CustomDataMask CD_MASK_DERIVEDMESH;
extern const CustomDataMask CD_MASK_BMESH;
extern const CustomDataMask CD_MASK_FACECORNERS;
/* for ORIGINDEX layer type, indicates no original index for this element */ /* for ORIGINDEX layer type, indicates no original index for this element */
#define ORIGINDEX_NONE -1 #define ORIGINDEX_NONE -1
@ -134,6 +136,9 @@ void CustomData_copy_data(const struct CustomData *source,
void CustomData_em_copy_data(const struct CustomData *source, void CustomData_em_copy_data(const struct CustomData *source,
struct CustomData *dest, void *src_block, struct CustomData *dest, void *src_block,
void **dest_block); void **dest_block);
void CustomData_bmesh_copy_data(const struct CustomData *source,
struct CustomData *dest,void *src_block,
void **dest_block);
/* frees data in a CustomData object /* frees data in a CustomData object
* return 1 on success, 0 on failure * return 1 on success, 0 on failure
@ -160,6 +165,10 @@ void CustomData_interp(const struct CustomData *source, struct CustomData *dest,
void CustomData_em_interp(struct CustomData *data, void **src_blocks, void CustomData_em_interp(struct CustomData *data, void **src_blocks,
float *weights, float *sub_weights, int count, float *weights, float *sub_weights, int count,
void *dest_block); void *dest_block);
void CustomData_bmesh_interp(struct CustomData *data, void **src_blocks,
float *weights, float *sub_weights, int count,
void *dest_block);
/* swaps the data in the element corners, to new corners with indices as /* swaps the data in the element corners, to new corners with indices as
specified in corner_indices. for edges this is an array of length 2, for specified in corner_indices. for edges this is an array of length 2, for
@ -172,6 +181,8 @@ void CustomData_swap(struct CustomData *data, int index, int *corner_indices);
void *CustomData_get(const struct CustomData *data, int index, int type); void *CustomData_get(const struct CustomData *data, int index, int type);
void *CustomData_em_get(const struct CustomData *data, void *block, int type); void *CustomData_em_get(const struct CustomData *data, void *block, int type);
void *CustomData_em_get_n(const struct CustomData *data, void *block, int type, int n); void *CustomData_em_get_n(const struct CustomData *data, void *block, int type, int n);
void *CustomData_bmesh_get(const struct CustomData *data, void *block, int type);
void *CustomData_bmesh_get_n(const struct CustomData *data, void *block, int type, int n);
/* gets a pointer to the active or first layer of type /* gets a pointer to the active or first layer of type
* returns NULL if there is no layer of type * returns NULL if there is no layer of type
@ -199,6 +210,12 @@ void CustomData_em_set(struct CustomData *data, void *block, int type,
void CustomData_em_set_n(struct CustomData *data, void *block, int type, int n, void CustomData_em_set_n(struct CustomData *data, void *block, int type, int n,
void *source); void *source);
void CustomData_bmesh_set(const struct CustomData *data, void *block, int type,
void *source);
void CustomData_bmesh_set_n(struct CustomData *data, void *block, int type, int n,
void *source);
/* set the pointer of to the first layer of type. the old data is not freed. /* set the pointer of to the first layer of type. the old data is not freed.
* returns the value of ptr if the layer is found, NULL otherwise * returns the value of ptr if the layer is found, NULL otherwise
*/ */
@ -220,12 +237,20 @@ void CustomData_set_layer_flag(struct CustomData *data, int type, int flag);
void CustomData_em_set_default(struct CustomData *data, void **block); void CustomData_em_set_default(struct CustomData *data, void **block);
void CustomData_em_free_block(struct CustomData *data, void **block); void CustomData_em_free_block(struct CustomData *data, void **block);
void CustomData_bmesh_set_default(struct CustomData *data, void **block);
void CustomData_bmesh_free_block(struct CustomData *data, void **block);
/* copy custom data to/from layers as in mesh/derivedmesh, to editmesh /* copy custom data to/from layers as in mesh/derivedmesh, to editmesh
blocks of data. the CustomData's must not be compatible */ blocks of data. the CustomData's must not be compatible */
void CustomData_to_em_block(const struct CustomData *source, void CustomData_to_em_block(const struct CustomData *source,
struct CustomData *dest, int index, void **block); struct CustomData *dest, int index, void **block);
void CustomData_from_em_block(const struct CustomData *source, void CustomData_from_em_block(const struct CustomData *source,
struct CustomData *dest, void *block, int index); struct CustomData *dest, void *block, int index);
void CustomData_to_bmesh_block(const struct CustomData *source,
struct CustomData *dest, int src_index, void **dest_block);
void CustomData_from_bmesh_block(const struct CustomData *source,
struct CustomData *dest, void *src_block, int dest_index);
/* query info over types */ /* query info over types */
void CustomData_file_write_info(int type, char **structname, int *structnum); void CustomData_file_write_info(int type, char **structname, int *structnum);
@ -241,4 +266,8 @@ void CustomData_set_layer_unique_name(struct CustomData *data, int index);
only after this test passes, layer->data should be assigned */ only after this test passes, layer->data should be assigned */
int CustomData_verify_versions(struct CustomData *data, int index); int CustomData_verify_versions(struct CustomData *data, int index);
/*BMesh specific customdata stuff*/
void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata);
void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata, int total);
void CustomData_bmesh_init_pool(struct CustomData *data, int allocsize);
#endif #endif

@ -31,6 +31,10 @@
#ifndef BKE_IPO_H #ifndef BKE_IPO_H
#define BKE_IPO_H #define BKE_IPO_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct CfraElem { typedef struct CfraElem {
struct CfraElem *next, *prev; struct CfraElem *next, *prev;
float cfra; float cfra;
@ -111,5 +115,9 @@ float IPO_GetFloatValue(struct Ipo *ipo,
short c, short c,
float ctime); float ctime);
#ifdef __cplusplus
};
#endif
#endif #endif

@ -40,6 +40,7 @@
#include "bmesh_private.h" #include "bmesh_private.h"
#include <string.h> #include <string.h>
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "BLI_mempool.h"
/********************* Layer type information **********************/ /********************* Layer type information **********************/
typedef struct BME_LayerTypeInfo { typedef struct BME_LayerTypeInfo {
@ -83,7 +84,7 @@ void BME_CD_Create(BME_CustomData *data, BME_CustomDataInit *init, int initalloc
if(data->totlayer){ if(data->totlayer){
/*alloc memory*/ /*alloc memory*/
data->layers = MEM_callocN(sizeof(BME_CustomDataLayer)*data->totlayer, "BMesh Custom Data Layers"); data->layers = MEM_callocN(sizeof(BME_CustomDataLayer)*data->totlayer, "BMesh Custom Data Layers");
data->pool = BME_mempool_create(data->totsize, initalloc, initalloc); data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc);
/*initialize layer data*/ /*initialize layer data*/
for(i=0; i < BME_CD_NUMTYPES; i++){ for(i=0; i < BME_CD_NUMTYPES; i++){
if(init->layout[i]){ if(init->layout[i]){
@ -102,7 +103,7 @@ void BME_CD_Create(BME_CustomData *data, BME_CustomDataInit *init, int initalloc
void BME_CD_Free(BME_CustomData *data) void BME_CD_Free(BME_CustomData *data)
{ {
if(data->pool) BME_mempool_destroy(data->pool); if(data->pool) BLI_mempool_destroy(data->pool);
} }
/*Block level ops*/ /*Block level ops*/
@ -119,7 +120,7 @@ void BME_CD_free_block(BME_CustomData *data, void **block)
typeInfo->free((char*)*block + offset, 1, typeInfo->size); typeInfo->free((char*)*block + offset, 1, typeInfo->size);
} }
} }
BME_mempool_free(data->pool, *block); BLI_mempool_free(data->pool, *block);
*block = NULL; *block = NULL;
} }
@ -130,7 +131,7 @@ static void BME_CD_alloc_block(BME_CustomData *data, void **block)
if (*block) BME_CD_free_block(data, block); //if we copy layers that have their own free functions like deformverts if (*block) BME_CD_free_block(data, block); //if we copy layers that have their own free functions like deformverts
if (data->totsize > 0) if (data->totsize > 0)
*block = BME_mempool_alloc(data->pool); *block = BLI_mempool_alloc(data->pool);
else else
*block = NULL; *block = NULL;
} }

@ -33,6 +33,7 @@
*/ */
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "BKE_customdata.h"
#include "DNA_listBase.h" #include "DNA_listBase.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
@ -55,10 +56,199 @@
#include "BSE_edit.h" #include "BSE_edit.h"
/*merge these functions*/
static void BME_DMcorners_to_loops(BME_Mesh *bm, CustomData *facedata, int index, BME_Poly *f, int numCol, int numTex){
int i, j;
BME_Loop *l;
MTFace *texface;
MTexPoly *texpoly;
MCol *mcol;
MLoopCol *mloopcol;
MLoopUV *mloopuv;
for(i=0; i< numTex; i++){
texface = CustomData_get_layer_n(facedata, CD_MTFACE, i);
texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
texpoly->tpage = texface[index].tpage;
texpoly->flag = texface[index].flag;
texpoly->transp = texface[index].transp;
texpoly->mode = texface[index].mode;
texpoly->tile = texface[index].tile;
texpoly->unwrap = texface[index].unwrap;
j = 0;
l = f->loopbase;
do{
mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
mloopuv->uv[0] = texface[index].uv[j][0];
mloopuv->uv[1] = texface[index].uv[j][1];
j++;
l = l->next;
}while(l!=f->loopbase);
}
for(i=0; i < numCol; i++){
mcol = CustomData_get_layer_n(facedata, CD_MCOL, i);
j = 0;
l = f->loopbase;
do{
mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
mloopcol->r = mcol[(index*4)+j].r;
mloopcol->g = mcol[(index*4)+j].g;
mloopcol->b = mcol[(index*4)+j].b;
mloopcol->a = mcol[(index*4)+j].a;
j++;
l = l->next;
}while(l!=f->loopbase);
}
}
static void BME_DMloops_to_corners(BME_Mesh *bm, CustomData *facedata, int index, BME_Poly *f,int numCol, int numTex){
int i, j;
BME_Loop *l;
MTFace *texface;
MTexPoly *texpoly;
MCol *mcol;
MLoopCol *mloopcol;
MLoopUV *mloopuv;
for(i=0; i < numTex; i++){
texface = CustomData_get_layer_n(facedata, CD_MTFACE, i);
texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
texface[index].tpage = texpoly->tpage;
texface[index].flag = texpoly->flag;
texface[index].transp = texpoly->transp;
texface[index].mode = texpoly->mode;
texface[index].tile = texpoly->tile;
texface[index].unwrap = texpoly->unwrap;
j = 0;
l = f->loopbase;
do{
mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
texface[index].uv[j][0] = mloopuv->uv[0];
texface[index].uv[j][1] = mloopuv->uv[1];
j++;
l = l->next;
}while(l!=f->loopbase);
}
for(i=0; i < numCol; i++){
mcol = CustomData_get_layer_n(facedata,CD_MCOL, i);
j = 0;
l = f->loopbase;
do{
mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
mcol[(index*4) + j].r = mloopcol->r;
mcol[(index*4) + j].g = mloopcol->g;
mcol[(index*4) + j].b = mloopcol->b;
mcol[(index*4) + j].a = mloopcol->a;
j++;
l = l->next;
}while(l!=f->loopbase);
}
}
static void BME_corners_to_loops(BME_Mesh *bm, CustomData *facedata, void *face_block, BME_Poly *f,int numCol, int numTex){
int i, j;
BME_Loop *l;
MTFace *texface;
MTexPoly *texpoly;
MCol *mcol;
MLoopCol *mloopcol;
MLoopUV *mloopuv;
for(i=0; i < numTex; i++){
texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i);
texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
texpoly->tpage = texface->tpage;
texpoly->flag = texface->flag;
texpoly->transp = texface->transp;
texpoly->mode = texface->mode;
texpoly->tile = texface->tile;
texpoly->unwrap = texface->unwrap;
j = 0;
l = f->loopbase;
do{
mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
mloopuv->uv[0] = texface->uv[j][0];
mloopuv->uv[1] = texface->uv[j][1];
j++;
l = l->next;
}while(l!=f->loopbase);
}
for(i=0; i < numCol; i++){
mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i);
j = 0;
l = f->loopbase;
do{
mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
mloopcol->r = mcol[j].r;
mloopcol->g = mcol[j].g;
mloopcol->b = mcol[j].b;
mloopcol->a = mcol[j].a;
j++;
l = l->next;
}while(l!=f->loopbase);
}
}
static void BME_loops_to_corners(BME_Mesh *bm, CustomData *facedata, void *face_block, BME_Poly *f,int numCol, int numTex){
int i, j;
BME_Loop *l;
MTFace *texface;
MTexPoly *texpoly;
MCol *mcol;
MLoopCol *mloopcol;
MLoopUV *mloopuv;
for(i=0; i < numTex; i++){
texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i);
texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
texface->tpage = texpoly->tpage;
texface->flag = texpoly->flag;
texface->transp = texpoly->transp;
texface->mode = texpoly->mode;
texface->tile = texpoly->tile;
texface->unwrap = texpoly->unwrap;
j = 0;
l = f->loopbase;
do{
mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
texface->uv[j][0] = mloopuv->uv[0];
texface->uv[j][1] = mloopuv->uv[1];
j++;
l = l->next;
}while(l!=f->loopbase);
}
for(i=0; i < numCol; i++){
mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i);
j = 0;
l = f->loopbase;
do{
mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
mcol[j].r = mloopcol->r;
mcol[j].g = mloopcol->g;
mcol[j].b = mloopcol->b;
mcol[j].a = mloopcol->a;
j++;
l = l->next;
}while(l!=f->loopbase);
}
}
/*move the EditMesh conversion functions to editmesh_tools.c*/
BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) { BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
BME_Mesh *bm; BME_Mesh *bm;
int allocsize[4] = {512,512,2048,512}; int allocsize[4] = {512,512,2048,512}, numTex, numCol;
BME_CustomDataInit *init = MEM_callocN(sizeof(BME_CustomDataInit) * 4, "Bmesh custom data init");
BME_Vert *v1, *v2; BME_Vert *v1, *v2;
BME_Edge *e, *edar[4]; BME_Edge *e, *edar[4];
BME_Poly *f; BME_Poly *f;
@ -68,9 +258,25 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
EditFace *efa; EditFace *efa;
int len; int len;
bm = BME_make_mesh(allocsize,init); bm = BME_make_mesh(allocsize);
/*copy custom data layout*/
CustomData_copy(&em->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&em->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&em->fdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
/*copy face corner data*/
CustomData_to_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata);
/*initialize memory pools*/
CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]);
CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]);
/*needed later*/
numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
BME_model_begin(bm); BME_model_begin(bm);
/*add verts*/ /*add verts*/
eve= em->verts.first; eve= em->verts.first;
while(eve) { while(eve) {
@ -79,9 +285,8 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
v1->flag = eve->f; v1->flag = eve->f;
v1->h = eve->h; v1->h = eve->h;
v1->bweight = eve->bweight; v1->bweight = eve->bweight;
/*Copy Custom Data*/
/* link the verts for edge and face construction; CustomData_bmesh_copy_data(&em->vdata, &bm->vdata, eve->data, &v1->data);
* kind of a dangerous thing - remember to cast back to BME_Vert before using! */
eve->tmp.v = (EditVert*)v1; eve->tmp.v = (EditVert*)v1;
eve = eve->next; eve = eve->next;
} }
@ -99,13 +304,10 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
if(eed->seam) e->flag |= ME_SEAM; if(eed->seam) e->flag |= ME_SEAM;
if(eed->h & EM_FGON) e->flag |= ME_FGON; if(eed->h & EM_FGON) e->flag |= ME_FGON;
if(eed->h & 1) e->flag |= ME_HIDE; if(eed->h & 1) e->flag |= ME_HIDE;
/* link the edges for face construction;
* kind of a dangerous thing - remember to cast back to BME_Edge before using! */
eed->tmp.e = (EditEdge*)e; eed->tmp.e = (EditEdge*)e;
CustomData_bmesh_copy_data(&em->edata, &bm->edata, eed->data, &e->data);
eed = eed->next; eed = eed->next;
} }
/*add faces.*/ /*add faces.*/
efa= em->faces.first; efa= em->faces.first;
while(efa) { while(efa) {
@ -134,13 +336,13 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
if(efa->f & 1) f->flag |= ME_FACE_SEL; if(efa->f & 1) f->flag |= ME_FACE_SEL;
else f->flag &= ~ME_FACE_SEL; else f->flag &= ~ME_FACE_SEL;
} }
CustomData_bmesh_copy_data(&em->fdata, &bm->pdata, efa->data, &f->data);
BME_corners_to_loops(bm, &em->fdata, efa->data, f,numCol,numTex);
efa = efa->next; efa = efa->next;
} }
BME_model_end(bm); BME_model_end(bm);
MEM_freeN(init);
return bm; return bm;
} }
/* adds the geometry in the bmesh to G.editMesh (does not free G.editMesh) /* adds the geometry in the bmesh to G.editMesh (does not free G.editMesh)
* if td != NULL, the transdata will be mapped to the EditVert's co */ * if td != NULL, the transdata will be mapped to the EditVert's co */
EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) { EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
@ -155,12 +357,21 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
EditEdge *eed; EditEdge *eed;
EditFace *efa; EditFace *efa;
int totvert, len, i; int totvert, len, i, numTex, numCol;
em = G.editMesh; em = G.editMesh;
if (em == NULL) return NULL; if (em == NULL) return NULL;
CustomData_copy(&bm->vdata, &em->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&bm->edata, &em->edata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&bm->pdata, &em->fdata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_from_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata,0);
numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
/* convert to EditMesh */ /* convert to EditMesh */
/* make editverts */ /* make editverts */
totvert = BLI_countlist(&(bm->verts)); totvert = BLI_countlist(&(bm->verts));
@ -176,6 +387,7 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
eve1->f = (unsigned char)v1->flag; eve1->f = (unsigned char)v1->flag;
eve1->h = (unsigned char)v1->h; eve1->h = (unsigned char)v1->h;
eve1->bweight = v1->bweight; eve1->bweight = v1->bweight;
CustomData_em_copy_data(&bm->vdata, &em->vdata, v1->data, &eve1->data);
} }
/* make edges */ /* make edges */
@ -191,6 +403,8 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
if(e->flag & ME_HIDE) eed->h |= 1; if(e->flag & ME_HIDE) eed->h |= 1;
if(G.scene->selectmode==SCE_SELECT_EDGE) if(G.scene->selectmode==SCE_SELECT_EDGE)
EM_select_edge(eed, eed->f & SELECT); EM_select_edge(eed, eed->f & SELECT);
CustomData_em_copy_data(&bm->edata, &em->edata, e->data, &eed->data);
} }
} }
@ -217,6 +431,8 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
if(f->flag & ME_HIDE) efa->h= 1; if(f->flag & ME_HIDE) efa->h= 1;
if((G.f & G_FACESELECT) && (efa->f & SELECT)) if((G.f & G_FACESELECT) && (efa->f & SELECT))
EM_select_face(efa, 1); /* flush down */ EM_select_face(efa, 1); /* flush down */
CustomData_em_copy_data(&bm->pdata, &em->fdata, f->data, &efa->data);
BME_loops_to_corners(bm, &em->fdata, efa->data, f,numCol,numTex);
} }
} }
@ -234,18 +450,33 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm)
BME_Mesh *bm; BME_Mesh *bm;
int allocsize[4] = {512,512,2048,512}; int allocsize[4] = {512,512,2048,512};
BME_CustomDataInit *init = MEM_callocN(sizeof(BME_CustomDataInit) * 4, "Bmesh custom data init");
MVert *mvert, *mv; MVert *mvert, *mv;
MEdge *medge, *me; MEdge *medge, *me;
MFace *mface, *mf; MFace *mface, *mf;
int totface,totedge,totvert,i,len; int totface,totedge,totvert,i,len, numTex, numCol;
BME_Vert *v1=NULL,*v2=NULL, **vert_array; BME_Vert *v1=NULL,*v2=NULL, **vert_array;
BME_Edge *e=NULL; BME_Edge *e=NULL;
BME_Poly *f=NULL; BME_Poly *f=NULL;
EdgeHash *edge_hash = BLI_edgehash_new(); EdgeHash *edge_hash = BLI_edgehash_new();
bm = BME_make_mesh(allocsize,init); bm = BME_make_mesh(allocsize);
/*copy custom data layout*/
CustomData_copy(&dm->vertData, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&dm->edgeData, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
CustomData_copy(&dm->faceData, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
/*copy face corner data*/
CustomData_to_bmeshpoly(&dm->faceData, &bm->pdata, &bm->ldata);
/*initialize memory pools*/
CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]);
CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]);
/*needed later*/
numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
totvert = dm->getNumVerts(dm); totvert = dm->getNumVerts(dm);
totedge = dm->getNumEdges(dm); totedge = dm->getNumEdges(dm);
totface = dm->getNumFaces(dm); totface = dm->getNumFaces(dm);
@ -262,6 +493,7 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm)
vert_array[i] = v1; vert_array[i] = v1;
v1->flag = mv->flag; v1->flag = mv->flag;
v1->bweight = mv->bweight/255.0f; v1->bweight = mv->bweight/255.0f;
CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v1->data);
} }
/*add edges*/ /*add edges*/
for(i=0,me = medge; i < totedge;i++,me++){ for(i=0,me = medge; i < totedge;i++,me++){
@ -272,6 +504,7 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm)
e->bweight = me->bweight/255.0f; e->bweight = me->bweight/255.0f;
e->flag = (unsigned char)me->flag; e->flag = (unsigned char)me->flag;
BLI_edgehash_insert(edge_hash,me->v1,me->v2,e); BLI_edgehash_insert(edge_hash,me->v1,me->v2,e);
CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->data);
} }
/*add faces.*/ /*add faces.*/
for(i=0,mf = mface; i < totface;i++,mf++){ for(i=0,mf = mface; i < totface;i++,mf++){
@ -295,12 +528,13 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm)
f = BME_MF(bm,v1,v2,edar,len); f = BME_MF(bm,v1,v2,edar,len);
f->mat_nr = mf->mat_nr; f->mat_nr = mf->mat_nr;
f->flag = mf->flag; f->flag = mf->flag;
CustomData_to_bmesh_block(&dm->faceData,&bm->pdata,i,&f->data);
BME_DMcorners_to_loops(bm, &dm->faceData,i,f, numCol,numTex);
} }
BME_model_end(bm); BME_model_end(bm);
BLI_edgehash_free(edge_hash, NULL); BLI_edgehash_free(edge_hash, NULL);
MEM_freeN(vert_array); MEM_freeN(vert_array);
MEM_freeN(init);
return bm; return bm;
} }
@ -309,7 +543,7 @@ DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm)
MFace *mface, *mf; MFace *mface, *mf;
MEdge *medge, *me; MEdge *medge, *me;
MVert *mvert, *mv; MVert *mvert, *mv;
int totface,totedge,totvert,i,bmeshok,len; int totface,totedge,totvert,i,bmeshok,len, numTex, numCol;
BME_Vert *v1=NULL; BME_Vert *v1=NULL;
BME_Edge *e=NULL, *oe=NULL; BME_Edge *e=NULL, *oe=NULL;
@ -345,12 +579,21 @@ DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm)
/*convert back to mesh*/ /*convert back to mesh*/
result = CDDM_from_template(dm,totvert,totedge,totface); result = CDDM_from_template(dm,totvert,totedge,totface);
CustomData_merge(&bm->vdata, &result->vertData, CD_MASK_BMESH, CD_CALLOC, totvert);
CustomData_merge(&bm->edata, &result->edgeData, CD_MASK_BMESH, CD_CALLOC, totedge);
CustomData_merge(&bm->pdata, &result->faceData, CD_MASK_BMESH, CD_CALLOC, totface);
CustomData_from_bmeshpoly(&result->faceData, &bm->pdata, &bm->ldata,totface);
numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
/*Make Verts*/ /*Make Verts*/
mvert = CDDM_get_verts(result); mvert = CDDM_get_verts(result);
for(i=0,v1=bm->verts.first,mv=mvert;v1;v1=v1->next,i++,mv++){ for(i=0,v1=bm->verts.first,mv=mvert;v1;v1=v1->next,i++,mv++){
VECCOPY(mv->co,v1->co); VECCOPY(mv->co,v1->co);
mv->flag = (unsigned char)v1->flag; mv->flag = (unsigned char)v1->flag;
mv->bweight = (char)(255.0*v1->bweight); mv->bweight = (char)(255.0*v1->bweight);
CustomData_from_bmesh_block(&bm->vdata, &result->vertData, &v1->data, i);
} }
medge = CDDM_get_edges(result); medge = CDDM_get_edges(result);
i=0; i=0;
@ -368,6 +611,7 @@ DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm)
me->crease = (char)(255.0*e->crease); me->crease = (char)(255.0*e->crease);
me->bweight = (char)(255.0*e->bweight); me->bweight = (char)(255.0*e->bweight);
me->flag = e->flag; me->flag = e->flag;
CustomData_from_bmesh_block(&bm->edata, &result->edgeData, &e->data, i);
me++; me++;
i++; i++;
} }
@ -389,9 +633,11 @@ DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm)
if(mf->v3 == 0 || (len == 4 && mf->v4 == 0)){ if(mf->v3 == 0 || (len == 4 && mf->v4 == 0)){
test_index_face(mf, NULL, i, len); test_index_face(mf, NULL, i, len);
} }
i++;
mf->mat_nr = (unsigned char)f->mat_nr; mf->mat_nr = (unsigned char)f->mat_nr;
mf->flag = (unsigned char)f->flag; mf->flag = (unsigned char)f->flag;
CustomData_from_bmesh_block(&bm->pdata, &result->faceData, &f->data, i);
BME_DMloops_to_corners(bm, &result->faceData, i, f,numCol,numTex);
i++;
} }
} }
} }

@ -39,6 +39,7 @@
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "BKE_utildefines.h" #include "BKE_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_bmesh.h" #include "BKE_bmesh.h"
#include "BLI_blenlib.h" #include "BLI_blenlib.h"
@ -618,8 +619,8 @@ BME_Poly *BME_SFME(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Lo
BME_disk_append_edge(e, v2); BME_disk_append_edge(e, v2);
f2 = BME_addpolylist(bm,f); f2 = BME_addpolylist(bm,f);
f1loop = BME_create_loop(bm,v2,e,f,NULL); f1loop = BME_create_loop(bm,v2,e,f,v2loop);
f2loop = BME_create_loop(bm,v1,e,f2,NULL); f2loop = BME_create_loop(bm,v1,e,f2,v1loop);
f1loop->prev = v2loop->prev; f1loop->prev = v2loop->prev;
f2loop->prev = v1loop->prev; f2loop->prev = v1loop->prev;
@ -663,16 +664,16 @@ BME_Poly *BME_SFME(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Lo
* Takes a an edge and pointer to one of its vertices and collapses * Takes a an edge and pointer to one of its vertices and collapses
* the edge on that vertex. * the edge on that vertex.
* *
* Before: OE KE * Before: OE KE
* ------- ------- * ------- -------
* | || | * | || |
* OV KV TV * OV KV TV
* *
* *
* After: OE * After: OE
* --------------- * ---------------
* | | * | |
* OV TV * OV TV
* *
* *
* Restrictions: * Restrictions:
@ -723,6 +724,8 @@ int BME_JEKV(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv)
/*remove ke from tv's disk cycle*/ /*remove ke from tv's disk cycle*/
BME_disk_remove_edge(ke, tv); BME_disk_remove_edge(ke, tv);
/*deal with radial cycle of ke*/ /*deal with radial cycle of ke*/
if(ke->loop){ if(ke->loop){
/*first step, fix the neighboring loops of all loops in ke's radial cycle*/ /*first step, fix the neighboring loops of all loops in ke's radial cycle*/
@ -763,6 +766,7 @@ int BME_JEKV(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv)
} }
/*Validate disk cycles*/ /*Validate disk cycles*/
diskbase = BME_disk_getpointer(ov->edge,ov); diskbase = BME_disk_getpointer(ov->edge,ov);
edok = BME_cycle_validate(valance1, diskbase); edok = BME_cycle_validate(valance1, diskbase);

@ -32,64 +32,33 @@
* ***** END GPL LICENSE BLOCK ***** * ***** END GPL LICENSE BLOCK *****
*/ */
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "DNA_listBase.h" #include "DNA_listBase.h"
#include "DNA_meshdata_types.h" #include "BLI_blenlib.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BKE_utildefines.h" #include "BKE_utildefines.h"
#include "BKE_bmesh.h" #include "BKE_bmesh.h"
#include "BKE_global.h"
#include "BKE_depsgraph.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
#include "BIF_editmesh.h"
#include "BIF_space.h"
#include "editmesh.h"
#include "bmesh_private.h" #include "bmesh_private.h"
#include "mydevice.h"
#include "BSE_edit.h"
/* /*
* BME MAKE MESH * BME MAKE MESH
* *
* Allocates a new BME_Mesh structure. * Allocates a new BME_Mesh structure.
* The arguments are two arrays, one of type int
* and another of type BME_CustomDataInit. The first array
* contains the allocation size for each element pool in
* the mesh. For instance allocsize[0] contains the number
* of vertices to allocate at a time for the vertex pool.
*
* The second array contains structures describing the layout
* of custom data for each element type in the mesh. So init[0]
* contains the custom data layout information for vertices, init[1]
* the layout information for edges and so on.
*
* Returns - * Returns -
* Pointer to a Bmesh * Pointer to a Bmesh
* *
*/ */
BME_Mesh *BME_make_mesh(int allocsize[4], BME_CustomDataInit init[4]) BME_Mesh *BME_make_mesh(int allocsize[4])
{ {
/*allocate the structure*/ /*allocate the structure*/
BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh"); BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh");
/*allocate the memory pools for the mesh elements*/ /*allocate the memory pools for the mesh elements*/
bm->vpool = BME_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0]); bm->vpool = BLI_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0]);
bm->epool = BME_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1]); bm->epool = BLI_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1]);
bm->lpool = BME_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2]); bm->lpool = BLI_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2]);
bm->ppool = BME_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3]); bm->ppool = BLI_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3]);
/*Setup custom data layers*/
BME_CD_Create(&bm->vdata, &init[0], allocsize[0]);
BME_CD_Create(&bm->edata, &init[1], allocsize[1]);
BME_CD_Create(&bm->ldata, &init[2], allocsize[2]);
BME_CD_Create(&bm->pdata, &init[3], allocsize[3]);
return bm; return bm;
} }
/* /*
@ -105,26 +74,35 @@ void BME_free_mesh(BME_Mesh *bm)
BME_Loop *l; BME_Loop *l;
BME_Poly *f; BME_Poly *f;
for(v=bm->verts.first; v; v=v->next) BME_CD_free_block(&bm->vdata, &v->data); for(v=bm->verts.first; v; v=v->next) CustomData_bmesh_free_block(&bm->vdata, &v->data);
for(e=bm->edges.first; e; e=e->next) BME_CD_free_block(&bm->edata, &e->data); for(e=bm->edges.first; e; e=e->next) CustomData_bmesh_free_block(&bm->edata, &e->data);
for(f=bm->polys.first; f; f=f->next){ for(f=bm->polys.first; f; f=f->next){
BME_CD_free_block(&bm->pdata, &f->data); CustomData_bmesh_free_block(&bm->pdata, &f->data);
l = f->loopbase; l = f->loopbase;
do{ do{
BME_CD_free_block(&bm->ldata, &l->data); CustomData_bmesh_free_block(&bm->ldata, &l->data);
l = l->next; l = l->next;
}while(l!=f->loopbase); }while(l!=f->loopbase);
} }
/*Free custom data pools, This should probably go in CustomData_free?*/
if(bm->vdata.totlayer) BLI_mempool_destroy(bm->vdata.pool);
if(bm->edata.totlayer) BLI_mempool_destroy(bm->edata.pool);
if(bm->ldata.totlayer) BLI_mempool_destroy(bm->ldata.pool);
if(bm->pdata.totlayer) BLI_mempool_destroy(bm->pdata.pool);
/*free custom data*/
CustomData_free(&bm->vdata,0);
CustomData_free(&bm->edata,0);
CustomData_free(&bm->ldata,0);
CustomData_free(&bm->pdata,0);
/*destroy element pools*/ /*destroy element pools*/
BME_mempool_destroy(bm->vpool); BLI_mempool_destroy(bm->vpool);
BME_mempool_destroy(bm->epool); BLI_mempool_destroy(bm->epool);
BME_mempool_destroy(bm->ppool); BLI_mempool_destroy(bm->ppool);
BME_mempool_destroy(bm->lpool); BLI_mempool_destroy(bm->lpool);
/*free custom data pools*/
BME_CD_Free(&bm->vdata);
BME_CD_Free(&bm->edata);
BME_CD_Free(&bm->ldata);
BME_CD_Free(&bm->pdata);
MEM_freeN(bm); MEM_freeN(bm);
} }

@ -41,101 +41,6 @@
#include "BLI_blenlib.h" #include "BLI_blenlib.h"
#include "BLI_linklist.h" #include "BLI_linklist.h"
#include "BLI_ghash.h" #include "BLI_ghash.h"
#include "BKE_customdata.h"
/*
Simple, fast memory allocator for allocating many elements of the same size.
*/
typedef struct BME_mempool_chunk{
struct BME_mempool_chunk *next, *prev;
void *data;
}BME_mempool_chunk;
/*this is just to make things prettier*/
typedef struct BME_freenode{
struct BME_freenode *next;
}BME_freenode;
BME_mempool *BME_mempool_create(int esize, int tote, int pchunk)
{ BME_mempool *pool = NULL;
BME_freenode *lasttail = NULL, *curnode = NULL;
int i,j, maxchunks;
char *addr;
/*allocate the pool structure*/
pool = MEM_mallocN(sizeof(BME_mempool),"memory pool");
pool->esize = esize;
pool->pchunk = pchunk;
pool->csize = esize * pchunk;
pool->chunks.first = pool->chunks.last = NULL;
maxchunks = tote / pchunk;
/*allocate the actual chunks*/
for(i=0; i < maxchunks; i++){
BME_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BME_mempool_chunk), "BME_Mempool Chunk");
mpchunk->next = mpchunk->prev = NULL;
mpchunk->data = MEM_mallocN(pool->csize, "BME Mempool Chunk Data");
BLI_addtail(&(pool->chunks), mpchunk);
if(i==0) pool->free = mpchunk->data; /*start of the list*/
/*loop through the allocated data, building the pointer structures*/
for(addr = mpchunk->data, j=0; j < pool->pchunk; j++){
curnode = ((BME_freenode*)addr);
addr += pool->esize;
curnode->next = (BME_freenode*)addr;
}
/*final pointer in the previously allocated chunk is wrong.*/
if(lasttail) lasttail->next = mpchunk->data;
/*set the end of this chunks memory to the new tail for next iteration*/
lasttail = curnode;
}
/*terminate the list*/
curnode->next = NULL;
return pool;
}
void *BME_mempool_alloc(BME_mempool *pool){
void *retval=NULL;
BME_freenode *curnode=NULL;
char *addr=NULL;
int j;
if(!(pool->free)){
/*need to allocate a new chunk*/
BME_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BME_mempool_chunk), "BME_Mempool Chunk");
mpchunk->next = mpchunk->prev = NULL;
mpchunk->data = MEM_mallocN(pool->csize, "BME_Mempool Chunk Data");
BLI_addtail(&(pool->chunks), mpchunk);
pool->free = mpchunk->data; /*start of the list*/
for(addr = mpchunk->data, j=0; j < pool->pchunk; j++){
curnode = ((BME_freenode*)addr);
addr += pool->esize;
curnode->next = (BME_freenode*)addr;
}
curnode->next = NULL; /*terminate the list*/
}
retval = pool->free;
pool->free = pool->free->next;
//memset(retval, 0, pool->esize);
return retval;
}
void BME_mempool_free(BME_mempool *pool, void *addr){ //doesnt protect against double frees, dont be stupid!
BME_freenode *newhead = addr;
newhead->next = pool->free;
pool->free = newhead;
}
void BME_mempool_destroy(BME_mempool *pool)
{
BME_mempool_chunk *mpchunk=NULL;
for(mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk->next) MEM_freeN(mpchunk->data);
BLI_freelistN(&(pool->chunks));
MEM_freeN(pool);
}
/** /**
* MISC utility functions. * MISC utility functions.
* *
@ -179,7 +84,7 @@ int BME_edge_swapverts(BME_Edge *e, BME_Vert *orig, BME_Vert *new){
BME_Vert *BME_addvertlist(BME_Mesh *bm, BME_Vert *example){ BME_Vert *BME_addvertlist(BME_Mesh *bm, BME_Vert *example){
BME_Vert *v=NULL; BME_Vert *v=NULL;
v = BME_mempool_alloc(bm->vpool); v = BLI_mempool_alloc(bm->vpool);
v->next = v->prev = NULL; v->next = v->prev = NULL;
v->EID = bm->nextv; v->EID = bm->nextv;
v->co[0] = v->co[1] = v->co[2] = 0.0f; v->co[0] = v->co[1] = v->co[2] = 0.0f;
@ -195,16 +100,16 @@ BME_Vert *BME_addvertlist(BME_Mesh *bm, BME_Vert *example){
if(example){ if(example){
VECCOPY(v->co,example->co); VECCOPY(v->co,example->co);
BME_CD_copy_data(&bm->vdata, &bm->vdata, example->data, &v->data); CustomData_bmesh_copy_data(&bm->vdata, &bm->vdata, example->data, &v->data);
} }
else else
BME_CD_set_default(&bm->vdata, &v->data); CustomData_bmesh_set_default(&bm->vdata, &v->data);
return v; return v;
} }
BME_Edge *BME_addedgelist(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge *example){ BME_Edge *BME_addedgelist(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge *example){
BME_Edge *e=NULL; BME_Edge *e=NULL;
e = BME_mempool_alloc(bm->epool); e = BLI_mempool_alloc(bm->epool);
e->next = e->prev = NULL; e->next = e->prev = NULL;
e->EID = bm->nexte; e->EID = bm->nexte;
e->v1 = v1; e->v1 = v1;
@ -222,16 +127,16 @@ BME_Edge *BME_addedgelist(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge *ex
BLI_addtail(&(bm->edges), e); BLI_addtail(&(bm->edges), e);
if(example) if(example)
BME_CD_copy_data(&bm->edata, &bm->edata, example->data, &e->data); CustomData_bmesh_copy_data(&bm->edata, &bm->edata, example->data, &e->data);
else else
BME_CD_set_default(&bm->edata, &e->data); CustomData_bmesh_set_default(&bm->edata, &e->data);
return e; return e;
} }
BME_Loop *BME_create_loop(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Poly *f, BME_Loop *example){ BME_Loop *BME_create_loop(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Poly *f, BME_Loop *example){
BME_Loop *l=NULL; BME_Loop *l=NULL;
l = BME_mempool_alloc(bm->lpool); l = BLI_mempool_alloc(bm->lpool);
l->next = l->prev = NULL; l->next = l->prev = NULL;
l->EID = bm->nextl; l->EID = bm->nextl;
l->radial.next = l->radial.prev = NULL; l->radial.next = l->radial.prev = NULL;
@ -246,16 +151,16 @@ BME_Loop *BME_create_loop(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Poly *f, B
bm->totloop++; bm->totloop++;
if(example) if(example)
BME_CD_copy_data(&bm->ldata, &bm->ldata, example->data, &l->data); CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->data, &l->data);
else else
BME_CD_set_default(&bm->ldata, &l->data); CustomData_bmesh_set_default(&bm->ldata, &l->data);
return l; return l;
} }
BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){ BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){
BME_Poly *f = NULL; BME_Poly *f = NULL;
f = BME_mempool_alloc(bm->ppool); f = BLI_mempool_alloc(bm->ppool);
f->next = f->prev = NULL; f->next = f->prev = NULL;
f->EID = bm->nextp; f->EID = bm->nextp;
f->loopbase = NULL; f->loopbase = NULL;
@ -268,9 +173,9 @@ BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){
bm->totpoly++; bm->totpoly++;
if(example) if(example)
BME_CD_copy_data(&bm->pdata, &bm->pdata, example->data, &f->data); CustomData_bmesh_copy_data(&bm->pdata, &bm->pdata, example->data, &f->data);
else else
BME_CD_set_default(&bm->pdata, &f->data); CustomData_bmesh_set_default(&bm->pdata, &f->data);
return f; return f;
@ -281,23 +186,23 @@ BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){
*/ */
void BME_free_vert(BME_Mesh *bm, BME_Vert *v){ void BME_free_vert(BME_Mesh *bm, BME_Vert *v){
bm->totvert--; bm->totvert--;
BME_CD_free_block(&bm->vdata, &v->data); CustomData_bmesh_free_block(&bm->vdata, &v->data);
BME_mempool_free(bm->vpool, v); BLI_mempool_free(bm->vpool, v);
} }
void BME_free_edge(BME_Mesh *bm, BME_Edge *e){ void BME_free_edge(BME_Mesh *bm, BME_Edge *e){
bm->totedge--; bm->totedge--;
BME_CD_free_block(&bm->edata, &e->data); CustomData_bmesh_free_block(&bm->edata, &e->data);
BME_mempool_free(bm->epool, e); BLI_mempool_free(bm->epool, e);
} }
void BME_free_poly(BME_Mesh *bm, BME_Poly *f){ void BME_free_poly(BME_Mesh *bm, BME_Poly *f){
bm->totpoly--; bm->totpoly--;
BME_CD_free_block(&bm->pdata, &f->data); CustomData_bmesh_free_block(&bm->pdata, &f->data);
BME_mempool_free(bm->ppool, f); BLI_mempool_free(bm->ppool, f);
} }
void BME_free_loop(BME_Mesh *bm, BME_Loop *l){ void BME_free_loop(BME_Mesh *bm, BME_Loop *l){
bm->totloop--; bm->totloop--;
BME_CD_free_block(&bm->ldata, &l->data); CustomData_bmesh_free_block(&bm->ldata, &l->data);
BME_mempool_free(bm->lpool, l); BLI_mempool_free(bm->lpool, l);
} }
/** /**
* BMESH CYCLES * BMESH CYCLES

@ -205,7 +205,53 @@ static BME_Poly *BME_split_face(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Ver
return nf; return nf;
} }
/* a wrapper for BME_SEMV that transfers element flags */
static void BME_data_interp_from_verts(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Vert *v, float fac)
{
void *src[2];
float w[2];
if (v1->data && v2->data) {
src[0]= v1->data;
src[1]= v2->data;
w[0] = 1.0f-fac;
w[1] = fac;
CustomData_bmesh_interp(&bm->vdata, src, w, NULL, 2, v->data);
}
}
static void BME_data_facevert_edgesplit(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Vert *v, BME_Edge *e1, float fac){
void *src[2];
float w[2];
BME_Loop *l=NULL, *v1loop = NULL, *vloop = NULL, *v2loop = NULL;
w[0] = 1.0f - fac;
w[1] = fac;
if(!e1->loop) return;
l = e1->loop;
do{
if(l->v == v1){
v1loop = l;
vloop = v1loop->next;
v2loop = vloop->next;
}else if(l->v == v){
v1loop = l->next;
vloop = l;
v2loop = l->prev;
}
src[0] = v1loop->data;
src[1] = v2loop->data;
CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, vloop->data);
l = l->radial.next->data;
}while(l!=e1->loop);
}
/* a wrapper for BME_SEMV that transfers element flags */ /*add custom data interpolation in here!*/
static BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge **ne, float percent) { static BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge **ne, float percent) {
BME_Vert *nv, *v2; BME_Vert *nv, *v2;
float len; float len;
@ -224,10 +270,39 @@ static BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge
(*ne)->crease = e->crease; (*ne)->crease = e->crease;
(*ne)->bweight = e->bweight; (*ne)->bweight = e->bweight;
} }
/*v->nv->v2*/
BME_data_facevert_edgesplit(bm,v2, v, nv, e, 0.75);
return nv; return nv;
} }
static void BME_collapse_vert(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv, float fac){
void *src[2];
float w[2];
BME_Loop *l=NULL, *kvloop=NULL, *tvloop=NULL;
BME_Vert *tv = BME_edge_getothervert(ke,kv);
w[0] = 1.0f - fac;
w[1] = fac;
if(ke->loop){
l = ke->loop;
do{
if(l->v == tv && l->next->v == kv){
tvloop = l;
kvloop = l->next;
src[0] = kvloop->data;
src[1] = tvloop->data;
CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, kvloop->data);
}
l=l->radial.next->data;
}while(l!=ke->loop);
}
BME_JEKV(bm,ke,kv);
}
static int BME_bevel_is_split_vert(BME_Loop *l) { static int BME_bevel_is_split_vert(BME_Loop *l) {
/* look for verts that have already been added to the edge when /* look for verts that have already been added to the edge when
* beveling other polys; this can be determined by testing the * beveling other polys; this can be determined by testing the
@ -315,7 +390,7 @@ static float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec, int
* Finally, return the split vert. */ * Finally, return the split vert. */
static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop *l, float *up_vec, float value, BME_TransData_Head *td) { static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop *l, float *up_vec, float value, BME_TransData_Head *td) {
BME_TransData *vtd, *vtd1, *vtd2; BME_TransData *vtd, *vtd1, *vtd2;
BME_Vert *sv, *v2, *v3; BME_Vert *sv, *v2, *v3, *ov;
BME_Loop *lv1, *lv2; BME_Loop *lv1, *lv2;
BME_Edge *ne, *e1, *e2; BME_Edge *ne, *e1, *e2;
float maxfactor, scale, len, dis, vec1[3], vec2[3], t_up_vec[3]; float maxfactor, scale, len, dis, vec1[3], vec2[3], t_up_vec[3];
@ -349,7 +424,11 @@ static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, B
else { else {
e1 = e2; e1 = e2;
} }
ov = BME_edge_getothervert(e1,v);
sv = BME_split_edge(bm,v,e1,&ne,0); sv = BME_split_edge(bm,v,e1,&ne,0);
//BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /*this is technically wrong...*/
//BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25);
//BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25);
BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */ BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */
sv->tflag1 |= BME_BEVEL_BEVEL; sv->tflag1 |= BME_BEVEL_BEVEL;
ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */ ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */
@ -388,7 +467,11 @@ static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, B
} }
else { else {
is_split_vert = 0; is_split_vert = 0;
ov = BME_edge_getothervert(l->e,v);
sv = BME_split_edge(bm,v,l->e,&ne,0); sv = BME_split_edge(bm,v,l->e,&ne,0);
//BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /*this is technically wrong...*/
//BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25);
//BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25);
BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */ BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */
sv->tflag1 |= BME_BEVEL_BEVEL; sv->tflag1 |= BME_BEVEL_BEVEL;
ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */ ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */
@ -567,12 +650,15 @@ static BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int opti
if (kl->v == kv) { if (kl->v == kv) {
BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e); BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e);
BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e); BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e);
BME_JEKV(bm,kl->e,kv); BME_collapse_vert(bm, kl->e, kv, 1.0);
//BME_JEKV(bm,kl->e,kv);
} }
else { else {
BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e); BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e);
BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e); BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e);
BME_JEKV(bm,kl->e,kv); BME_collapse_vert(bm, kl->e, kv, 1.0);
//BME_JEKV(bm,kl->e,kv);
} }
l = l->prev; l = l->prev;
} }
@ -601,12 +687,14 @@ static BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int opti
if (kl->v == kv) { if (kl->v == kv) {
BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e); BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e);
BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e); BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e);
BME_JEKV(bm,kl->e,kv); BME_collapse_vert(bm, kl->e, kv, 1.0);
//BME_JEKV(bm,kl->e,kv);
} }
else { else {
BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e); BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e);
BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e); BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e);
BME_JEKV(bm,kl->e,kv); BME_collapse_vert(bm, kl->e, kv, 1.0);
//BME_JEKV(bm,kl->e,kv);
} }
} }
@ -1073,7 +1161,8 @@ static void bmesh_dissolve_disk(BME_Mesh *bm, BME_Vert *v){
e = BME_disk_nextedge(e,v); e = BME_disk_nextedge(e,v);
}while(e != v->edge); }while(e != v->edge);
} }
BME_JEKV(bm,v->edge,v); BME_collapse_vert(bm, v->edge, v, 1.0);
//BME_JEKV(bm,v->edge,v);
} }
} }
static BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int defgrp_index, BME_TransData_Head *td) { static BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int defgrp_index, BME_TransData_Head *td) {

@ -1052,7 +1052,7 @@ void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
/* store vertex indices in tmp union */ /* store vertex indices in tmp union */
for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i) for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
ev->tmp.l = (long) i++; ev->tmp.l = (long) i;
for( ; ee; ee = ee->next, ++edge_r) { for( ; ee; ee = ee->next, ++edge_r) {
edge_r->crease = (unsigned char) (ee->crease*255.0f); edge_r->crease = (unsigned char) (ee->crease*255.0f);

@ -350,7 +350,7 @@ static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan
pchan->flag= chan->flag; pchan->flag= chan->flag;
con= chan->constraints.first; con= chan->constraints.first;
for(pcon= pchan->constraints.first; pcon; pcon= pcon->next) { for(pcon= pchan->constraints.first; pcon; pcon= pcon->next, con= con->next) {
pcon->enforce= con->enforce; pcon->enforce= con->enforce;
pcon->headtail= con->headtail; pcon->headtail= con->headtail;
} }

@ -39,11 +39,6 @@
#include "BKE_bmesh.h" #include "BKE_bmesh.h"
struct BME_mempool *BME_mempool_create(int esize, int tote, int pchunk);
void BME_mempool_destroy(struct BME_mempool *pool);
void *BME_mempool_alloc(struct BME_mempool *pool);
void BME_mempool_free(struct BME_mempool *pool, void *address);
/*ALLOCATION/DEALLOCATION*/ /*ALLOCATION/DEALLOCATION*/
struct BME_Vert *BME_addvertlist(struct BME_Mesh *bm, struct BME_Vert *example); struct BME_Vert *BME_addvertlist(struct BME_Mesh *bm, struct BME_Vert *example);
struct BME_Edge *BME_addedgelist(struct BME_Mesh *bm, struct BME_Vert *v1, struct BME_Vert *v2, struct BME_Edge *example); struct BME_Edge *BME_addedgelist(struct BME_Mesh *bm, struct BME_Vert *v1, struct BME_Vert *v2, struct BME_Edge *example);
@ -54,7 +49,6 @@ void BME_free_vert(struct BME_Mesh *bm, struct BME_Vert *v);
void BME_free_edge(struct BME_Mesh *bm, struct BME_Edge *e); void BME_free_edge(struct BME_Mesh *bm, struct BME_Edge *e);
void BME_free_poly(struct BME_Mesh *bm, struct BME_Poly *f); void BME_free_poly(struct BME_Mesh *bm, struct BME_Poly *f);
void BME_free_loop(struct BME_Mesh *bm, struct BME_Loop *l); void BME_free_loop(struct BME_Mesh *bm, struct BME_Loop *l);
//void BME_delete_loop(struct BME_Mesh *bm, struct BME_Loop *l);
/*DOUBLE CIRCULAR LINKED LIST FUNCTIONS*/ /*DOUBLE CIRCULAR LINKED LIST FUNCTIONS*/
void BME_cycle_append(void *h, void *nt); void BME_cycle_append(void *h, void *nt);

@ -132,7 +132,7 @@ void cloth_init ( ClothModifierData *clmd )
clmd->coll_parms->self_friction = 5.0; clmd->coll_parms->self_friction = 5.0;
clmd->coll_parms->friction = 5.0; clmd->coll_parms->friction = 5.0;
clmd->coll_parms->loop_count = 3; clmd->coll_parms->loop_count = 2;
clmd->coll_parms->epsilon = 0.015f; clmd->coll_parms->epsilon = 0.015f;
clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED; clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED;
clmd->coll_parms->collision_list = NULL; clmd->coll_parms->collision_list = NULL;
@ -471,7 +471,7 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
tend(); tend();
/* printf ( "Cloth simulation time: %f\n", ( float ) tval() ); */ // printf ( "%f\n", ( float ) tval() );
return ret; return ret;
} }

@ -541,7 +541,7 @@ int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifier
{ {
Normalize ( vrel_t_pre ); Normalize ( vrel_t_pre );
impulse = 2.0 * magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); impulse = magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); // 2.0 *
VECADDMUL ( cloth1->verts[collpair->ap1].impulse, vrel_t_pre, w1 * impulse ); VECADDMUL ( cloth1->verts[collpair->ap1].impulse, vrel_t_pre, w1 * impulse );
VECADDMUL ( cloth1->verts[collpair->ap2].impulse, vrel_t_pre, w2 * impulse ); VECADDMUL ( cloth1->verts[collpair->ap2].impulse, vrel_t_pre, w2 * impulse );
VECADDMUL ( cloth1->verts[collpair->ap3].impulse, vrel_t_pre, w3 * impulse ); VECADDMUL ( cloth1->verts[collpair->ap3].impulse, vrel_t_pre, w3 * impulse );
@ -1291,52 +1291,223 @@ int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *col
return 1; return 1;
} }
int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData *collmd, float step, float dt ) int cloth_do_selfcollisions(ClothModifierData * clmd)
{
int ret2 = 0, l;
Cloth *cloth = clmd->clothObject;
if ( clmd->clothObject->bvhselftree )
{
for(l = 0; l < clmd->coll_parms->self_loop_count; l++)
{
BVHTreeOverlap *overlap = NULL;
ClothVertex *verts = clmd->clothObject->verts; // needed for openMP
int k;
int ret = 0, result = 0;
// search for overlapping collision pairs
overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result );
// #pragma omp parallel for private(k, i, j) schedule(static)
for ( k = 0; k < result; k++ )
{
float temp[3];
float length = 0;
float mindistance;
int i, j;
i = overlap[k].indexA;
j = overlap[k].indexB;
mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len );
if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
{
if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
&& ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) )
{
continue;
}
}
VECSUB ( temp, verts[i].tx, verts[j].tx );
if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue;
// check for adjacent points (i must be smaller j)
if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) )
{
continue;
}
length = Normalize ( temp );
if ( length < mindistance )
{
float correction = mindistance - length;
if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
{
VecMulf ( temp, -correction );
VECADD ( verts[j].tx, verts[j].tx, temp );
}
else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED )
{
VecMulf ( temp, correction );
VECADD ( verts[i].tx, verts[i].tx, temp );
}
else
{
VecMulf ( temp, -correction*0.5 );
VECADD ( verts[j].tx, verts[j].tx, temp );
VECSUB ( verts[i].tx, verts[i].tx, temp );
}
ret = 1;
ret2 += ret;
}
else
{
// check for approximated time collisions
}
}
if ( overlap )
MEM_freeN ( overlap );
if(!ret)
break;
}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// SELFCOLLISIONS: update velocities
////////////////////////////////////////////////////////////
if ( ret2 )
{
int i;
ClothVertex *verts = clmd->clothObject->verts; // needed for openMP
for ( i = 0; i < cloth->numverts; i++ )
{
if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) )
{
VECSUB ( verts[i].tv, verts[i].tx, verts[i].txold );
}
}
}
////////////////////////////////////////////////////////////
}
return ret2;
}
// return all collision objects in scene
// collision object will exclude self
CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj)
{
Base *base=NULL;
CollisionModifierData **objs = NULL;
Object *coll_ob = NULL;
CollisionModifierData *collmd = NULL;
int numobj = 0, maxobj = 100;
objs = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
// check all collision objects
for ( base = G.scene->base.first; base; base = base->next )
{
coll_ob = base->object;
collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
if ( !collmd )
{
if ( coll_ob->dup_group )
{
GroupObject *go;
Group *group = coll_ob->dup_group;
for ( go= group->gobject.first; go; go= go->next )
{
coll_ob = go->ob;
collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
if ( !collmd )
continue;
if(coll_ob == self)
continue;
if(numobj >= maxobj)
{
// realloc
int oldmax = maxobj;
CollisionModifierData **tmp;
maxobj *= 2;
tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
MEM_freeN(objs);
objs = tmp;
}
objs[numobj] = collmd;
numobj++;
}
}
}
else
{
if(coll_ob == self)
continue;
if(numobj >= maxobj)
{
// realloc
int oldmax = maxobj;
CollisionModifierData **tmp;
maxobj *= 2;
tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
MEM_freeN(objs);
objs = tmp;
}
objs[numobj] = collmd;
numobj++;
}
}
*numcollobj = numobj;
return objs;
}
void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap)
{
int i;
*collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * numresult * 4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
*collisions_index = *collisions;
for ( i = 0; i < numresult; i++ )
{
*collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, *collisions_index );
}
}
int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index)
{ {
Cloth *cloth = clmd->clothObject; Cloth *cloth = clmd->clothObject;
BVHTree *cloth_bvh= ( BVHTree * ) cloth->bvhtree; int i=0, j = 0, numfaces = 0, numverts = 0;
long i=0, j = 0, numfaces = 0, numverts = 0;
ClothVertex *verts = NULL; ClothVertex *verts = NULL;
CollPair *collisions = NULL, *collisions_index = NULL;
int ret = 0; int ret = 0;
int result = 0; int result = 0;
float tnull[3] = {0,0,0}; float tnull[3] = {0,0,0};
BVHTreeOverlap *overlap = NULL;
numfaces = clmd->clothObject->numfaces; numfaces = clmd->clothObject->numfaces;
numverts = clmd->clothObject->numverts; numverts = clmd->clothObject->numverts;
verts = cloth->verts; verts = cloth->verts;
if ( collmd->bvhtree )
{
/* get pointer to bounding volume hierarchy */
BVHTree *coll_bvh = collmd->bvhtree;
/* move object to position (step) in time */
collision_move_object ( collmd, step + dt, step );
/* search for overlapping collision pairs */
overlap = BLI_bvhtree_overlap ( cloth_bvh, coll_bvh, &result );
collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * result*4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
collisions_index = collisions;
for ( i = 0; i < result; i++ )
{
collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, collisions_index );
}
if ( overlap )
MEM_freeN ( overlap );
}
else
{
if ( G.rt > 0 )
printf ( "cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n" );
}
// process all collisions (calculate impulses, TODO: also repulses if distance too short) // process all collisions (calculate impulses, TODO: also repulses if distance too short)
result = 1; result = 1;
for ( j = 0; j < 5; j++ ) // 5 is just a value that ensures convergence for ( j = 0; j < 5; j++ ) // 5 is just a value that ensures convergence
@ -1363,48 +1534,22 @@ int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData
} }
} }
} }
/*
result += cloth_collision_moving ( clmd, collmd, collisions, collisions_index );
// apply impulses in parallel
if ( result )
{
for ( i = 0; i < numverts; i++ )
{
// calculate "velocities" (just xnew = xold + v; no dt in v)
if ( verts[i].impulse_count )
{
VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count );
VECCOPY ( verts[i].impulse, tnull );
verts[i].impulse_count = 0;
ret++;
}
}
}
*/
} }
} }
if ( collisions ) MEM_freeN ( collisions );
return ret; return ret;
} }
// cloth - object collisions // cloth - object collisions
int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt ) int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, float dt )
{ {
Base *base=NULL;
CollisionModifierData *collmd=NULL;
Cloth *cloth=NULL; Cloth *cloth=NULL;
Object *coll_ob=NULL;
BVHTree *cloth_bvh=NULL; BVHTree *cloth_bvh=NULL;
long i=0, j = 0, k = 0, l = 0, numfaces = 0, numverts = 0; long i=0, numfaces = 0, numverts = 0;
int result = 0, rounds = 0; // result counts applied collisions; ic is for debug output; int rounds = 0; // result counts applied collisions; ic is for debug output;
ClothVertex *verts = NULL; ClothVertex *verts = NULL;
int ret = 0, ret2 = 0; int ret = 0, ret2 = 0;
ClothModifierData *tclmd; CollisionModifierData **collobjs = NULL;
int collisions = 0; int numcollobj = 0;
if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) || ! ( ( ( Cloth * ) clmd->clothObject )->bvhtree ) ) if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) || ! ( ( ( Cloth * ) clmd->clothObject )->bvhtree ) )
{ {
@ -1424,54 +1569,61 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt )
// update cloth bvh // update cloth bvh
bvhtree_update_from_cloth ( clmd, 1 ); // 0 means STATIC, 1 means MOVING (see later in this function) bvhtree_update_from_cloth ( clmd, 1 ); // 0 means STATIC, 1 means MOVING (see later in this function)
bvhselftree_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function) bvhselftree_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function)
collobjs = get_collisionobjects(ob, &numcollobj);
if(!collobjs)
return 0;
do do
{ {
result = 0; CollPair **collisions, **collisions_index;
ret2 = 0; ret2 = 0;
collisions = MEM_callocN(sizeof(CollPair *) *numcollobj , "CollPair");
collisions_index = MEM_callocN(sizeof(CollPair *) *numcollobj , "CollPair");
// check all collision objects // check all collision objects
for ( base = G.scene->base.first; base; base = base->next ) for(i = 0; i < numcollobj; i++)
{ {
coll_ob = base->object; CollisionModifierData *collmd = collobjs[i];
collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision ); BVHTreeOverlap *overlap = NULL;
int result = 0;
if ( !collmd )
/* move object to position (step) in time */
collision_move_object ( collmd, step + dt, step );
/* search for overlapping collision pairs */
overlap = BLI_bvhtree_overlap ( cloth_bvh, collmd->bvhtree, &result );
// go to next object if no overlap is there
if(!result || !overlap)
{ {
if ( coll_ob->dup_group ) if ( overlap )
{ MEM_freeN ( overlap );
GroupObject *go; continue;
Group *group = coll_ob->dup_group;
for ( go= group->gobject.first; go; go= go->next )
{
coll_ob = go->ob;
collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
if ( !collmd )
continue;
tclmd = ( ClothModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Cloth );
if ( tclmd == clmd )
continue;
ret += cloth_bvh_objcollisions_do ( clmd, collmd, step, dt );
ret2 += ret;
}
}
}
else
{
tclmd = ( ClothModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Cloth );
if ( tclmd == clmd )
continue;
ret += cloth_bvh_objcollisions_do ( clmd, collmd, step, dt );
ret2 += ret;
} }
/* check if collisions really happen (costly near check) */
cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], &collisions_index[i], result, overlap);
// resolve nearby collisions
ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i], collisions_index[i]);
ret2 += ret;
if ( overlap )
MEM_freeN ( overlap );
} }
rounds++; rounds++;
for(i = 0; i < numcollobj; i++)
{
if ( collisions[i] ) MEM_freeN ( collisions[i] );
}
MEM_freeN(collisions);
MEM_freeN(collisions_index);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// update positions // update positions
@ -1493,117 +1645,20 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt )
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Test on *simple* selfcollisions // Test on *simple* selfcollisions
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
if ( clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) if ( clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF )
{ {
for(l = 0; l < clmd->coll_parms->self_loop_count; l++) ret2 += cloth_do_selfcollisions(clmd);
{
// TODO: add coll quality rounds again
BVHTreeOverlap *overlap = NULL;
collisions = 1;
verts = cloth->verts; // needed for openMP
numfaces = clmd->clothObject->numfaces;
numverts = clmd->clothObject->numverts;
verts = cloth->verts;
if ( cloth->bvhselftree )
{
// search for overlapping collision pairs
overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result );
// #pragma omp parallel for private(k, i, j) schedule(static)
for ( k = 0; k < result; k++ )
{
float temp[3];
float length = 0;
float mindistance;
i = overlap[k].indexA;
j = overlap[k].indexB;
mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len );
if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
{
if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
&& ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) )
{
continue;
}
}
VECSUB ( temp, verts[i].tx, verts[j].tx );
if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue;
// check for adjacent points (i must be smaller j)
if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) )
{
continue;
}
length = Normalize ( temp );
if ( length < mindistance )
{
float correction = mindistance - length;
if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
{
VecMulf ( temp, -correction );
VECADD ( verts[j].tx, verts[j].tx, temp );
}
else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED )
{
VecMulf ( temp, correction );
VECADD ( verts[i].tx, verts[i].tx, temp );
}
else
{
VecMulf ( temp, -correction*0.5 );
VECADD ( verts[j].tx, verts[j].tx, temp );
VECSUB ( verts[i].tx, verts[i].tx, temp );
}
ret = 1;
ret2 += ret;
}
else
{
// check for approximated time collisions
}
}
if ( overlap )
MEM_freeN ( overlap );
}
}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// SELFCOLLISIONS: update velocities
////////////////////////////////////////////////////////////
if ( ret2 )
{
for ( i = 0; i < cloth->numverts; i++ )
{
if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) )
{
VECSUB ( verts[i].tv, verts[i].tx, verts[i].txold );
}
}
}
////////////////////////////////////////////////////////////
} }
////////////////////////////////////////////////////////////
} }
while ( ret2 && ( clmd->coll_parms->loop_count>rounds ) ); while ( ret2 && ( clmd->coll_parms->loop_count>rounds ) );
if(collobjs)
+ MEM_freeN(collobjs);
return MIN2 ( ret, 1 ); return MIN2 ( ret, 1 );
} }

@ -36,6 +36,7 @@
#include "BLI_blenlib.h" #include "BLI_blenlib.h"
#include "BLI_linklist.h" #include "BLI_linklist.h"
#include "BLI_mempool.h"
#include "DNA_customdata_types.h" #include "DNA_customdata_types.h"
#include "DNA_listBase.h" #include "DNA_listBase.h"
@ -359,8 +360,80 @@ static void layerDefault_origspace_face(void *data, int count)
} }
/* --------- */ /* --------- */
static void layerDefault_mloopcol(void *data, int count)
{
static MLoopCol default_mloopcol = {255,255,255,255};
MLoopCol *mlcol = (MLoopCol*)data;
int i;
for(i = 0; i < count; i++)
mlcol[i] = default_mloopcol;
}
static void layerInterp_mloopcol(void **sources, float *weights,
float *sub_weights, int count, void *dest)
{
MLoopCol *mc = dest;
int i;
float *sub_weight;
struct {
float a;
float r;
float g;
float b;
} col;
col.a = col.r = col.g = col.b = 0;
sub_weight = sub_weights;
for(i = 0; i < count; ++i){
float weight = weights ? weights[i] : 1;
MLoopCol *src = sources[i];
if(sub_weights){
col.a += src->a * (*sub_weight) * weight;
col.r += src->r * (*sub_weight) * weight;
col.g += src->g * (*sub_weight) * weight;
col.b += src->b * (*sub_weight) * weight;
sub_weight++;
} else {
col.a += src->a * weight;
col.r += src->r * weight;
col.g += src->g * weight;
col.b += src->b * weight;
}
}
mc->a = (int)col.a;
mc->r = (int)col.r;
mc->g = (int)col.g;
mc->b = (int)col.b;
}
static void layerInterp_mloopuv(void **sources, float *weights,
float *sub_weights, int count, void *dest)
{
MLoopUV *mluv = dest;
int i;
float *sub_weight;
struct {
float u;
float v;
}uv;
uv.u = uv.v = 0.0;
sub_weight = sub_weights;
for(i = 0; i < count; ++i){
float weight = weights ? weights[i] : 1;
MLoopUV *src = sources[i];
if(sub_weights){
uv.u += src->uv[0] * (*sub_weight) * weight;
uv.v += src->uv[1] * (*sub_weight) * weight;
sub_weight++;
} else {
uv.u += src->uv[0] * weight;
uv.v += src->uv[1] * weight;
}
}
mluv->uv[0] = uv.u;
mluv->uv[1] = uv.v;
}
static void layerInterp_mcol(void **sources, float *weights, static void layerInterp_mcol(void **sources, float *weights,
float *sub_weights, int count, void *dest) float *sub_weights, int count, void *dest)
@ -432,6 +505,8 @@ static void layerDefault_mcol(void *data, int count)
mcol[i] = default_mcol; mcol[i] = default_mcol;
} }
const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL}, {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
{sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL, {sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL,
@ -454,13 +529,16 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL}, {sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
{sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL, {sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL,
layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face}, layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
{sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL} {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
{sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
{sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL},
{sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol}
}; };
const char *LAYERTYPENAMES[CD_NUMTYPES] = { const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace", "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
"CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
"CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco"}; "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol"};
const CustomDataMask CD_MASK_BAREMESH = const CustomDataMask CD_MASK_BAREMESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE; CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
@ -475,6 +553,12 @@ const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO; CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO;
const CustomDataMask CD_MASK_BMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
const CustomDataMask CD_MASK_FACECORNERS =
CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
CD_MASK_MLOOPCOL;
static const LayerTypeInfo *layerType_getInfo(int type) static const LayerTypeInfo *layerType_getInfo(int type)
{ {
@ -1449,6 +1533,302 @@ void CustomData_from_em_block(const CustomData *source, CustomData *dest,
} }
/*Bmesh functions*/
/*needed to convert to/from different face reps*/
void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata)
{
int i;
for(i=0; i < fdata->totlayer; i++){
if(fdata->layers[i].type == CD_MTFACE){
CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), 0);
CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), 0);
}
else if(fdata->layers[i].type == CD_MCOL)
CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), 0);
}
}
void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total){
int i;
for(i=0; i < pdata->totlayer; i++){
if(pdata->layers[i].type == CD_MTEXPOLY)
CustomData_add_layer(fdata, CD_MTFACE, CD_CALLOC, &(pdata->layers[i].name), total);
}
for(i=0; i < ldata->totlayer; i++){
if(ldata->layers[i].type == CD_MLOOPCOL)
CustomData_add_layer(fdata, CD_MCOL, CD_CALLOC, &(ldata->layers[i].name), total);
}
}
void CustomData_bmesh_init_pool(CustomData *data, int allocsize){
if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize);
}
void CustomData_bmesh_free_block(CustomData *data, void **block)
{
const LayerTypeInfo *typeInfo;
int i;
if(!*block) return;
for(i = 0; i < data->totlayer; ++i) {
if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
typeInfo = layerType_getInfo(data->layers[i].type);
if(typeInfo->free) {
int offset = data->layers[i].offset;
typeInfo->free((char*)*block + offset, 1, typeInfo->size);
}
}
}
BLI_mempool_free(data->pool, *block);
*block = NULL;
}
static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
{
if (*block)
CustomData_bmesh_free_block(data, block);
if (data->totsize > 0)
*block = BLI_mempool_calloc(data->pool);
else
*block = NULL;
}
void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest,
void *src_block, void **dest_block)
{
const LayerTypeInfo *typeInfo;
int dest_i, src_i;
if (!*dest_block)
CustomData_bmesh_alloc_block(dest, dest_block);
/* copies a layer at a time */
dest_i = 0;
for(src_i = 0; src_i < source->totlayer; ++src_i) {
/* find the first dest layer with type >= the source type
* (this should work because layers are ordered by type)
*/
while(dest_i < dest->totlayer
&& dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
if(dest_i >= dest->totlayer) return;
/* if we found a matching layer, copy the data */
if(dest->layers[dest_i].type == source->layers[src_i].type &&
strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) {
char *src_data = (char*)src_block + source->layers[src_i].offset;
char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset;
typeInfo = layerType_getInfo(source->layers[src_i].type);
if(typeInfo->copy)
typeInfo->copy(src_data, dest_data, 1);
else
memcpy(dest_data, src_data, typeInfo->size);
/* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so
* increment dest_i
*/
++dest_i;
}
}
}
/*Bmesh Custom Data Functions. Should replace editmesh ones with these as well, due to more effecient memory alloc*/
void *CustomData_bmesh_get(const CustomData *data, void *block, int type)
{
int layer_index;
/* get the layer index of the first layer of type */
layer_index = CustomData_get_active_layer_index(data, type);
if(layer_index < 0) return NULL;
return (char *)block + data->layers[layer_index].offset;
}
void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int n)
{
int layer_index;
/* get the layer index of the first layer of type */
layer_index = CustomData_get_layer_index(data, type);
if(layer_index < 0) return NULL;
return (char *)block + data->layers[layer_index+n].offset;
}
void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source)
{
void *dest = CustomData_bmesh_get(data, block, type);
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
if(!dest) return;
if(typeInfo->copy)
typeInfo->copy(source, dest, 1);
else
memcpy(dest, source, typeInfo->size);
}
void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void *source)
{
void *dest = CustomData_bmesh_get_n(data, block, type, n);
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
if(!dest) return;
if(typeInfo->copy)
typeInfo->copy(source, dest, 1);
else
memcpy(dest, source, typeInfo->size);
}
void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights,
float *sub_weights, int count, void *dest_block)
{
int i, j;
void *source_buf[SOURCE_BUF_SIZE];
void **sources = source_buf;
/* slow fallback in case we're interpolating a ridiculous number of
* elements
*/
if(count > SOURCE_BUF_SIZE)
sources = MEM_callocN(sizeof(*sources) * count,
"CustomData_interp sources");
/* interpolates a layer at a time */
for(i = 0; i < data->totlayer; ++i) {
CustomDataLayer *layer = &data->layers[i];
const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
if(typeInfo->interp) {
for(j = 0; j < count; ++j)
sources[j] = (char *)src_blocks[j] + layer->offset;
typeInfo->interp(sources, weights, sub_weights, count,
(char *)dest_block + layer->offset);
}
}
if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
}
void CustomData_bmesh_set_default(CustomData *data, void **block)
{
const LayerTypeInfo *typeInfo;
int i;
if (!*block)
CustomData_bmesh_alloc_block(data, block);
for(i = 0; i < data->totlayer; ++i) {
int offset = data->layers[i].offset;
typeInfo = layerType_getInfo(data->layers[i].type);
if(typeInfo->set_default)
typeInfo->set_default((char*)*block + offset, 1);
}
}
void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
int src_index, void **dest_block)
{
const LayerTypeInfo *typeInfo;
int dest_i, src_i, src_offset;
if (!*dest_block)
CustomData_bmesh_alloc_block(dest, dest_block);
/* copies a layer at a time */
dest_i = 0;
for(src_i = 0; src_i < source->totlayer; ++src_i) {
/* find the first dest layer with type >= the source type
* (this should work because layers are ordered by type)
*/
while(dest_i < dest->totlayer
&& dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
if(dest_i >= dest->totlayer) return;
/* if we found a matching layer, copy the data */
if(dest->layers[dest_i].type == source->layers[src_i].type) {
int offset = dest->layers[dest_i].offset;
char *src_data = source->layers[src_i].data;
char *dest_data = (char*)*dest_block + offset;
typeInfo = layerType_getInfo(dest->layers[dest_i].type);
src_offset = src_index * typeInfo->size;
if(typeInfo->copy)
typeInfo->copy(src_data + src_offset, dest_data, 1);
else
memcpy(dest_data, src_data + src_offset, typeInfo->size);
/* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so
* increment dest_i
*/
++dest_i;
}
}
}
void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,
void *src_block, int dest_index)
{
const LayerTypeInfo *typeInfo;
int dest_i, src_i, dest_offset;
/* copies a layer at a time */
dest_i = 0;
for(src_i = 0; src_i < source->totlayer; ++src_i) {
/* find the first dest layer with type >= the source type
* (this should work because layers are ordered by type)
*/
while(dest_i < dest->totlayer
&& dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
if(dest_i >= dest->totlayer) return;
/* if we found a matching layer, copy the data */
if(dest->layers[dest_i].type == source->layers[src_i].type) {
int offset = source->layers[src_i].offset;
char *src_data = (char*)src_block + offset;
char *dest_data = dest->layers[dest_i].data;
typeInfo = layerType_getInfo(dest->layers[dest_i].type);
dest_offset = dest_index * typeInfo->size;
if(typeInfo->copy)
typeInfo->copy(src_data, dest_data + dest_offset, 1);
else
memcpy(dest_data + dest_offset, src_data, typeInfo->size);
/* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so
* increment dest_i
*/
++dest_i;
}
}
}
void CustomData_file_write_info(int type, char **structname, int *structnum) void CustomData_file_write_info(int type, char **structname, int *structnum)
{ {
const LayerTypeInfo *typeInfo = layerType_getInfo(type); const LayerTypeInfo *typeInfo = layerType_getInfo(type);

@ -848,17 +848,13 @@ void BKE_add_image_extension(char *string, int imtype)
if(!BLI_testextensie(string, ".tga")) if(!BLI_testextensie(string, ".tga"))
extension= ".tga"; extension= ".tga";
} }
else if(ELEM5(imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) {
if(!( BLI_testextensie(string, ".jpg") || BLI_testextensie(string, ".jpeg")))
extension= ".jpg";
}
else if(imtype==R_BMP) { else if(imtype==R_BMP) {
if(!BLI_testextensie(string, ".bmp")) if(!BLI_testextensie(string, ".bmp"))
extension= ".bmp"; extension= ".bmp";
} }
else if(G.have_libtiff && (imtype==R_TIFF)) { else if(G.have_libtiff && (imtype==R_TIFF)) {
if(!BLI_testextensie(string, ".tif")) if(!BLI_testextensie(string, ".tif") &&
extension= ".tif"; !BLI_testextensie(string, ".tiff")) extension= ".tif";
} }
#ifdef WITH_OPENEXR #ifdef WITH_OPENEXR
else if( ELEM(imtype, R_OPENEXR, R_MULTILAYER)) { else if( ELEM(imtype, R_OPENEXR, R_MULTILAYER)) {
@ -874,10 +870,14 @@ void BKE_add_image_extension(char *string, int imtype)
if (!BLI_testextensie(string, ".dpx")) if (!BLI_testextensie(string, ".dpx"))
extension= ".dpx"; extension= ".dpx";
} }
else { /* targa default */ else if(imtype==R_TARGA) {
if(!BLI_testextensie(string, ".tga")) if(!BLI_testextensie(string, ".tga"))
extension= ".tga"; extension= ".tga";
} }
else { // R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90, R_QUICKTIME etc
if(!( BLI_testextensie(string, ".jpg") || BLI_testextensie(string, ".jpeg")))
extension= ".jpg";
}
strcat(string, extension); strcat(string, extension);
} }
@ -1512,6 +1512,10 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
image_initialize_after_load(ima, ibuf); image_initialize_after_load(ima, ibuf);
image_assign_ibuf(ima, ibuf, 0, frame); image_assign_ibuf(ima, ibuf, 0, frame);
#endif #endif
if(ima->flag & IMA_DO_PREMUL)
converttopremul(ibuf);
} }
else else
ima->ok= 0; ima->ok= 0;

@ -1588,10 +1588,17 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
VECSUB(verts[i].tv, verts[i].tx, verts[i].txold); VECSUB(verts[i].tv, verts[i].tx, verts[i].txold);
VECCOPY(verts[i].v, verts[i].tv); VECCOPY(verts[i].v, verts[i].tv);
} }
// call collision function // call collision function
result = cloth_bvh_objcollision(clmd, step + dt, dt); // TODO: check if "step" or "step+dt" is correct - dg
result = cloth_bvh_objcollision(ob, clmd, step, dt);
// correct velocity again, just to be sure we had to change it due to adaptive collisions
for(i = 0; i < numverts; i++)
{
VECSUB(verts[i].tv, verts[i].tx, id->X[i]);
}
// copy corrected positions back to simulation // copy corrected positions back to simulation
for(i = 0; i < numverts; i++) for(i = 0; i < numverts; i++)
{ {

@ -1859,7 +1859,7 @@ void set_icu_vars(IpoCurve *icu)
/* yafray: aperture & focal distance params */ /* yafray: aperture & focal distance params */
switch(icu->adrcode) { switch(icu->adrcode) {
case CAM_LENS: case CAM_LENS:
icu->ymin= 5.0; icu->ymin= 1.0;
icu->ymax= 1000.0; icu->ymax= 1000.0;
break; break;
case CAM_STA: case CAM_STA:

@ -224,48 +224,50 @@ void flag_all_listbases_ids(short flag, short value)
/* note: MAX_LIBARRAY define should match this code */ /* note: MAX_LIBARRAY define should match this code */
int set_listbasepointers(Main *main, ListBase **lb) int set_listbasepointers(Main *main, ListBase **lb)
{ {
int a = 0;
/* BACKWARDS! also watch order of free-ing! (mesh<->mat) */ /* BACKWARDS! also watch order of free-ing! (mesh<->mat) */
lb[0]= &(main->ipo); lb[a++]= &(main->ipo);
lb[1]= &(main->key); lb[a++]= &(main->key);
lb[2]= &(main->image); lb[a++]= &(main->nodetree);
lb[3]= &(main->tex); lb[a++]= &(main->image);
lb[4]= &(main->mat); lb[a++]= &(main->tex);
lb[5]= &(main->vfont); lb[a++]= &(main->mat);
lb[a++]= &(main->vfont);
/* Important!: When adding a new object type, /* Important!: When adding a new object type,
* the specific data should be inserted here * the specific data should be inserted here
*/ */
lb[6]= &(main->armature); lb[a++]= &(main->armature);
lb[7]= &(main->action); lb[a++]= &(main->action);
lb[8]= &(main->mesh); lb[a++]= &(main->mesh);
lb[9]= &(main->curve); lb[a++]= &(main->curve);
lb[10]= &(main->mball); lb[a++]= &(main->mball);
lb[11]= &(main->wave); lb[a++]= &(main->wave);
lb[12]= &(main->latt); lb[a++]= &(main->latt);
lb[13]= &(main->lamp); lb[a++]= &(main->lamp);
lb[14]= &(main->camera); lb[a++]= &(main->camera);
lb[15]= &(main->text); lb[a++]= &(main->text);
lb[16]= &(main->sound); lb[a++]= &(main->sound);
lb[17]= &(main->group); lb[a++]= &(main->group);
lb[18]= &(main->nodetree); lb[a++]= &(main->brush);
lb[19]= &(main->brush); lb[a++]= &(main->script);
lb[20]= &(main->script); lb[a++]= &(main->particle);
lb[21]= &(main->particle);
lb[22]= &(main->world); lb[a++]= &(main->world);
lb[23]= &(main->screen); lb[a++]= &(main->screen);
lb[24]= &(main->object); lb[a++]= &(main->object);
lb[25]= &(main->scene); lb[a++]= &(main->scene);
lb[26]= &(main->library); lb[a++]= &(main->library);
lb[27]= NULL; lb[a]= NULL;
return 27; return a;
} }
/* *********** ALLOC AND FREE ***************** /* *********** ALLOC AND FREE *****************

@ -4920,7 +4920,7 @@ static void waveModifier_deformVertsEM(
if(!wmd->texture && !wmd->defgrp_name[0] && !(wmd->flag & MOD_WAVE_NORM)) if(!wmd->texture && !wmd->defgrp_name[0] && !(wmd->flag & MOD_WAVE_NORM))
dm = derivedData; dm = derivedData;
else if(derivedData) dm = derivedData; else if(derivedData) dm = CDDM_copy(derivedData);
else dm = CDDM_from_editmesh(editData, ob->data); else dm = CDDM_from_editmesh(editData, ob->data);
if(wmd->flag & MOD_WAVE_NORM) { if(wmd->flag & MOD_WAVE_NORM) {

@ -732,6 +732,17 @@ void *add_lamp(char *name)
la->preview=NULL; la->preview=NULL;
la->falloff_type = LA_FALLOFF_INVLINEAR; la->falloff_type = LA_FALLOFF_INVLINEAR;
la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f); la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f);
la->sun_effect_type = 0;
la->horizon_brightness = 1.0;
la->spread = 1.0;
la->sun_brightness = 1.0;
la->sun_size = 1.0;
la->backscattered_light = 1.0;
la->atm_turbidity = 2.0;
la->atm_inscattering_factor = 1.0;
la->atm_extinction_factor = 1.0;
la->atm_distance_factor = 1.0;
la->sun_intensity = 1.0;
curvemapping_initialize(la->curfalloff); curvemapping_initialize(la->curfalloff);
return la; return la;
} }

@ -1371,7 +1371,7 @@ void psys_particle_on_shape(int distr, int index, float *fuv, float *vec, float
/************************************************/ /************************************************/
void psys_particle_on_emitter(Object *ob, ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor){ void psys_particle_on_emitter(Object *ob, ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor){
if(psmd){ if(psmd){
if(psmd->psys->part->distr==PART_DISTR_GRID){ if(psmd->psys->part->distr==PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT){
if(vec){ if(vec){
VECCOPY(vec,fuv); VECCOPY(vec,fuv);
} }

@ -168,7 +168,7 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
int i, totpart, totsaved = 0; int i, totpart, totsaved = 0;
if(new_totpart<0) { if(new_totpart<0) {
if(psys->part->distr==PART_DISTR_GRID) { if(psys->part->distr==PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) {
totpart= psys->part->grid_res; totpart= psys->part->grid_res;
totpart*=totpart*totpart; totpart*=totpart*totpart;
} }
@ -1056,7 +1056,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
dm= CDDM_from_mesh((Mesh*)ob->data, ob); dm= CDDM_from_mesh((Mesh*)ob->data, ob);
/* special handling of grid distribution */ /* special handling of grid distribution */
if(part->distr==PART_DISTR_GRID){ if(part->distr==PART_DISTR_GRID && from != PART_FROM_VERT){
distribute_particles_in_grid(dm,psys); distribute_particles_in_grid(dm,psys);
dm->release(dm); dm->release(dm);
return 0; return 0;
@ -1600,7 +1600,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
NormalQuat(pa->r_rot); NormalQuat(pa->r_rot);
if(part->distr!=PART_DISTR_GRID){ if(part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){
/* any unique random number will do (r_ave[0]) */ /* any unique random number will do (r_ave[0]) */
if(ptex.exist < 0.5*(1.0+pa->r_ave[0])) if(ptex.exist < 0.5*(1.0+pa->r_ave[0]))
pa->flag |= PARS_UNEXIST; pa->flag |= PARS_UNEXIST;
@ -4515,7 +4515,7 @@ void psys_changed_type(ParticleSystem *psys)
if(part->from == PART_FROM_PARTICLE) { if(part->from == PART_FROM_PARTICLE) {
if(part->type != PART_REACTOR) if(part->type != PART_REACTOR)
part->from = PART_FROM_FACE; part->from = PART_FROM_FACE;
if(part->distr == PART_DISTR_GRID) if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
part->distr = PART_DISTR_JIT; part->distr = PART_DISTR_JIT;
} }
@ -4710,7 +4710,7 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
oldtotpart = psys->totpart; oldtotpart = psys->totpart;
oldtotchild = psys->totchild; oldtotchild = psys->totchild;
if(part->distr == PART_DISTR_GRID) if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
totpart = part->grid_res*part->grid_res*part->grid_res; totpart = part->grid_res*part->grid_res*part->grid_res;
else else
totpart = psys->part->totpart; totpart = psys->part->totpart;

@ -459,9 +459,10 @@ int BKE_ptcache_object_reset(Object *ob, int mode)
PTCacheID pid; PTCacheID pid;
ParticleSystem *psys; ParticleSystem *psys;
ModifierData *md; ModifierData *md;
int reset; int reset, skip;
reset= 0; reset= 0;
skip= 0;
if(ob->soft) { if(ob->soft) {
BKE_ptcache_id_from_softbody(&pid, ob, ob->soft); BKE_ptcache_id_from_softbody(&pid, ob, ob->soft);
@ -469,11 +470,18 @@ int BKE_ptcache_object_reset(Object *ob, int mode)
} }
for(psys=ob->particlesystem.first; psys; psys=psys->next) { for(psys=ob->particlesystem.first; psys; psys=psys->next) {
BKE_ptcache_id_from_particles(&pid, ob, psys); /* Baked softbody hair has to be checked first, because we don't want to reset */
reset |= BKE_ptcache_id_reset(&pid, mode); /* particles or softbody in that case -jahka */
if(psys->soft) { if(psys->soft) {
BKE_ptcache_id_from_softbody(&pid, ob, psys->soft); BKE_ptcache_id_from_softbody(&pid, ob, psys->soft);
if(mode == PSYS_RESET_ALL || !(psys->part->type == PART_HAIR && (pid.cache->flag & PTCACHE_BAKED)))
reset |= BKE_ptcache_id_reset(&pid, mode);
else
skip = 1;
}
if(skip == 0) {
BKE_ptcache_id_from_particles(&pid, ob, psys);
reset |= BKE_ptcache_id_reset(&pid, mode); reset |= BKE_ptcache_id_reset(&pid, mode);
} }
} }

@ -150,6 +150,9 @@ void init_sensor(bSensor *sens)
case SENS_PROPERTY: case SENS_PROPERTY:
sens->data= MEM_callocN(sizeof(bPropertySensor), "propsens"); sens->data= MEM_callocN(sizeof(bPropertySensor), "propsens");
break; break;
case SENS_ACTUATOR:
sens->data= MEM_callocN(sizeof(bActuatorSensor), "actsens");
break;
case SENS_MOUSE: case SENS_MOUSE:
ms=sens->data= MEM_callocN(sizeof(bMouseSensor), "mousesens"); ms=sens->data= MEM_callocN(sizeof(bMouseSensor), "mousesens");
ms->type= LEFTMOUSE; ms->type= LEFTMOUSE;

@ -942,7 +942,8 @@ char *txt_to_buf (Text *text)
if (!text) return NULL; if (!text) return NULL;
if (!text->curl) return NULL; if (!text->curl) return NULL;
if (!text->sell) return NULL; if (!text->sell) return NULL;
if (!text->lines.first) return NULL;
linef= text->lines.first; linef= text->lines.first;
charf= 0; charf= 0;

@ -50,6 +50,9 @@ extern "C" {
#ifndef M_SQRT1_2 #ifndef M_SQRT1_2
#define M_SQRT1_2 0.70710678118654752440 #define M_SQRT1_2 0.70710678118654752440
#endif #endif
#ifndef M_1_PI
#define M_1_PI 0.318309886183790671538
#endif
#ifdef WIN32 #ifdef WIN32
#ifndef FREE_WINDOWS #ifndef FREE_WINDOWS
@ -323,6 +326,9 @@ void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb);
void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb); void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb);
void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr); void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr);
void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv); void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv);
void xyz_to_rgb(float x, float y, float z, float *r, float *g, float *b);
int constrain_rgb(float *r, float *g, float *b);
void gamma_correct_rgb(float *r, float *g, float *b);
unsigned int hsv_to_cpack(float h, float s, float v); unsigned int hsv_to_cpack(float h, float s, float v);
unsigned int rgb_to_cpack(float r, float g, float b); unsigned int rgb_to_cpack(float r, float g, float b);
void cpack_to_rgb(unsigned int col, float *r, float *g, float *b); void cpack_to_rgb(unsigned int col, float *r, float *g, float *b);

@ -0,0 +1,44 @@
/**
* Simple fast memory allocator
*
*
* ***** 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.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Geoffrey Bantle.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef BLI_MEMPOOL_H
#define BLI_MEMPOOL_H
struct BLI_mempool;
typedef struct BLI_mempool BLI_mempool;
BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk);
void *BLI_mempool_alloc(BLI_mempool *pool);
void *BLI_mempool_calloc(BLI_mempool *pool);
void BLI_mempool_free(BLI_mempool *pool, void *addr);
void BLI_mempool_destroy(BLI_mempool *pool);
#endif

@ -73,6 +73,9 @@
#ifndef M_SQRT1_2 #ifndef M_SQRT1_2
#define M_SQRT1_2 0.70710678118654752440 #define M_SQRT1_2 0.70710678118654752440
#endif #endif
#ifndef M_1_PI
#define M_1_PI 0.318309886183790671538
#endif
#define MAXPATHLEN MAX_PATH #define MAXPATHLEN MAX_PATH

@ -523,6 +523,7 @@ static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end, char
return; return;
} }
#if 0
static void verify_tree(BVHTree *tree) static void verify_tree(BVHTree *tree)
{ {
int i, j, check = 0; int i, j, check = 0;
@ -569,6 +570,7 @@ static void verify_tree(BVHTree *tree)
printf("branches: %d, leafs: %d, total: %d\n", tree->totbranch, tree->totleaf, tree->totbranch + tree->totleaf); printf("branches: %d, leafs: %d, total: %d\n", tree->totbranch, tree->totleaf, tree->totbranch + tree->totleaf);
} }
#endif
void BLI_bvhtree_balance(BVHTree *tree) void BLI_bvhtree_balance(BVHTree *tree)
{ {

@ -0,0 +1,140 @@
/**
*
* ***** 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 by Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/*
Simple, fast memory allocator for allocating many elements of the same size.
*/
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "DNA_listBase.h"
#include "BLI_linklist.h"
#include <string.h>
typedef struct BLI_freenode{
struct BLI_freenode *next;
}BLI_freenode;
typedef struct BLI_mempool_chunk{
struct BLI_mempool_chunk *next, *prev;
void *data;
}BLI_mempool_chunk;
typedef struct BLI_mempool{
struct ListBase chunks;
int esize, csize, pchunk; /*size of elements and chunks in bytes and number of elements per chunk*/
struct BLI_freenode *free; /*free element list. Interleaved into chunk datas.*/
}BLI_mempool;
BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk)
{ BLI_mempool *pool = NULL;
BLI_freenode *lasttail = NULL, *curnode = NULL;
int i,j, maxchunks;
char *addr;
/*allocate the pool structure*/
pool = MEM_mallocN(sizeof(BLI_mempool),"memory pool");
pool->esize = esize;
pool->pchunk = pchunk;
pool->csize = esize * pchunk;
pool->chunks.first = pool->chunks.last = NULL;
maxchunks = tote / pchunk;
/*allocate the actual chunks*/
for(i=0; i < maxchunks; i++){
BLI_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BLI_mempool_chunk), "BLI_Mempool Chunk");
mpchunk->next = mpchunk->prev = NULL;
mpchunk->data = MEM_mallocN(pool->csize, "BLI Mempool Chunk Data");
BLI_addtail(&(pool->chunks), mpchunk);
if(i==0) pool->free = mpchunk->data; /*start of the list*/
/*loop through the allocated data, building the pointer structures*/
for(addr = mpchunk->data, j=0; j < pool->pchunk; j++){
curnode = ((BLI_freenode*)addr);
addr += pool->esize;
curnode->next = (BLI_freenode*)addr;
}
/*final pointer in the previously allocated chunk is wrong.*/
if(lasttail) lasttail->next = mpchunk->data;
/*set the end of this chunks memoryy to the new tail for next iteration*/
lasttail = curnode;
}
/*terminate the list*/
curnode->next = NULL;
return pool;
}
void *BLI_mempool_alloc(BLI_mempool *pool){
void *retval=NULL;
BLI_freenode *curnode=NULL;
char *addr=NULL;
int j;
if(!(pool->free)){
/*need to allocate a new chunk*/
BLI_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BLI_mempool_chunk), "BLI_Mempool Chunk");
mpchunk->next = mpchunk->prev = NULL;
mpchunk->data = MEM_mallocN(pool->csize, "BLI_Mempool Chunk Data");
BLI_addtail(&(pool->chunks), mpchunk);
pool->free = mpchunk->data; /*start of the list*/
for(addr = mpchunk->data, j=0; j < pool->pchunk; j++){
curnode = ((BLI_freenode*)addr);
addr += pool->esize;
curnode->next = (BLI_freenode*)addr;
}
curnode->next = NULL; /*terminate the list*/
}
retval = pool->free;
pool->free = pool->free->next;
//memset(retval, 0, pool->esize);
return retval;
}
void *BLI_mempool_calloc(BLI_mempool *pool){
void *retval=NULL;
retval = BLI_mempool_alloc(pool);
memset(retval, 0, pool->esize);
return retval;
}
void BLI_mempool_free(BLI_mempool *pool, void *addr){ //doesnt protect against double frees, dont be stupid!
BLI_freenode *newhead = addr;
newhead->next = pool->free;
pool->free = newhead;
}
void BLI_mempool_destroy(BLI_mempool *pool)
{
BLI_mempool_chunk *mpchunk=NULL;
for(mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk->next) MEM_freeN(mpchunk->data);
BLI_freelistN(&(pool->chunks));
MEM_freeN(pool);
}

@ -3414,6 +3414,66 @@ void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv)
*lv = v; *lv = v;
} }
/*http://brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
* SMPTE-C XYZ to RGB matrix*/
void xyz_to_rgb(float xc, float yc, float zc, float *r, float *g, float *b)
{
*r = (3.50570 * xc) + (-1.73964 * yc) + (-0.544011 * zc);
*g = (-1.06906 * xc) + (1.97781 * yc) + (0.0351720 * zc);
*b = (0.0563117 * xc) + (-0.196994 * yc) + (1.05005 * zc);
}
/*If the requested RGB shade contains a negative weight for
one of the primaries, it lies outside the colour gamut
accessible from the given triple of primaries. Desaturate
it by adding white, equal quantities of R, G, and B, enough
to make RGB all positive. The function returns 1 if the
components were modified, zero otherwise.*/
int constrain_rgb(float *r, float *g, float *b)
{
float w;
/* Amount of white needed is w = - min(0, *r, *g, *b) */
w = (0 < *r) ? 0 : *r;
w = (w < *g) ? w : *g;
w = (w < *b) ? w : *b;
w = -w;
/* Add just enough white to make r, g, b all positive. */
if (w > 0) {
*r += w; *g += w; *b += w;
return 1; /* Colour modified to fit RGB gamut */
}
return 0; /* Colour within RGB gamut */
}
/*Transform linear RGB values to nonlinear RGB values. Rec.
709 is ITU-R Recommendation BT. 709 (1990) ``Basic
Parameter Values for the HDTV Standard for the Studio and
for International Programme Exchange'', formerly CCIR Rec.
709.*/
void gamma_correct(float *c)
{
/* Rec. 709 gamma correction. */
float cc = 0.018;
if (*c < cc) {
*c *= ((1.099 * pow(cc, 0.45)) - 0.099) / cc;
} else {
*c = (1.099 * pow(*c, 0.45)) - 0.099;
}
}
void gamma_correct_rgb(float *r, float *g, float *b)
{
gamma_correct(r);
gamma_correct(g);
gamma_correct(b);
}
/* we define a 'cpack' here as a (3 byte color code) number that can be expressed like 0xFFAA66 or so. /* we define a 'cpack' here as a (3 byte color code) number that can be expressed like 0xFFAA66 or so.
for that reason it is sensitive for endianness... with this function it works correctly for that reason it is sensitive for endianness... with this function it works correctly

@ -1722,6 +1722,7 @@ void BLI_where_am_i(char *fullname, const char *name)
path = br_find_exe( NULL ); path = br_find_exe( NULL );
if (path) { if (path) {
strcpy(fullname, path); strcpy(fullname, path);
free(path);
return; return;
} }
#endif #endif

@ -7646,6 +7646,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
} }
} }
/* sun/sky */
if ((main->versionfile < 246) ){
Lamp *la;
for(la=main->lamp.first; la; la= la->id.next) {
la->sun_effect_type = 0;
la->horizon_brightness = 1.0;
la->spread = 1.0;
la->sun_brightness = 1.0;
la->sun_size = 1.0;
la->backscattered_light = 1.0;
la->atm_turbidity = 2.0;
la->atm_inscattering_factor = 1.0;
la->atm_extinction_factor = 1.0;
la->atm_distance_factor = 1.0;
la->sun_intensity = 1.0;
}
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */

@ -603,6 +603,9 @@ static void write_sensors(WriteData *wd, ListBase *lb)
case SENS_PROPERTY: case SENS_PROPERTY:
writestruct(wd, DATA, "bPropertySensor", 1, sens->data); writestruct(wd, DATA, "bPropertySensor", 1, sens->data);
break; break;
case SENS_ACTUATOR:
writestruct(wd, DATA, "bActuatorSensor", 1, sens->data);
break;
case SENS_COLLISION: case SENS_COLLISION:
writestruct(wd, DATA, "bCollisionSensor", 1, sens->data); writestruct(wd, DATA, "bCollisionSensor", 1, sens->data);
break; break;

@ -183,8 +183,9 @@ struct anim {
AVFormatContext *pFormatCtx; AVFormatContext *pFormatCtx;
AVCodecContext *pCodecCtx; AVCodecContext *pCodecCtx;
AVCodec *pCodec; AVCodec *pCodec;
AVFrame *pFrameRGB;
AVFrame *pFrame; AVFrame *pFrame;
AVFrame *pFrameRGB;
AVFrame *pFrameDeinterlaced;
struct SwsContext *img_convert_ctx; struct SwsContext *img_convert_ctx;
int videoStream; int videoStream;
#endif #endif

@ -600,6 +600,7 @@ static int startffmpeg(struct anim * anim) {
anim->videoStream = videoStream; anim->videoStream = videoStream;
anim->pFrame = avcodec_alloc_frame(); anim->pFrame = avcodec_alloc_frame();
anim->pFrameDeinterlaced = avcodec_alloc_frame();
anim->pFrameRGB = avcodec_alloc_frame(); anim->pFrameRGB = avcodec_alloc_frame();
if (avpicture_get_size(PIX_FMT_BGR32, anim->x, anim->y) if (avpicture_get_size(PIX_FMT_BGR32, anim->x, anim->y)
@ -609,10 +610,20 @@ static int startffmpeg(struct anim * anim) {
avcodec_close(anim->pCodecCtx); avcodec_close(anim->pCodecCtx);
av_close_input_file(anim->pFormatCtx); av_close_input_file(anim->pFormatCtx);
av_free(anim->pFrameRGB); av_free(anim->pFrameRGB);
av_free(anim->pFrameDeinterlaced);
av_free(anim->pFrame); av_free(anim->pFrame);
return -1; return -1;
} }
if (anim->ib_flags & IB_animdeinterlace) {
avpicture_fill((AVPicture*) anim->pFrameDeinterlaced,
MEM_callocN(avpicture_get_size(
anim->pCodecCtx->pix_fmt,
anim->x, anim->y),
"ffmpeg deinterlace"),
anim->pCodecCtx->pix_fmt, anim->x, anim->y);
}
if (pCodecCtx->has_b_frames) { if (pCodecCtx->has_b_frames) {
anim->preseek = 25; /* FIXME: detect gopsize ... */ anim->preseek = 25; /* FIXME: detect gopsize ... */
} else { } else {
@ -644,7 +655,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect, 0); ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect, 0);
avpicture_fill((AVPicture *)anim->pFrameRGB, avpicture_fill((AVPicture*) anim->pFrameRGB,
(unsigned char*) ibuf->rect, (unsigned char*) ibuf->rect,
PIX_FMT_BGR32, anim->x, anim->y); PIX_FMT_BGR32, anim->x, anim->y);
@ -723,15 +734,29 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
} }
if(frameFinished && pos_found == 1) { if(frameFinished && pos_found == 1) {
AVFrame * input = anim->pFrame;
/* This means the data wasnt read properly,
this check stops crashing */
if (input->data[0]==0 && input->data[1]==0
&& input->data[2]==0 && input->data[3]==0){
av_free_packet(&packet);
break;
}
if (anim->ib_flags & IB_animdeinterlace) { if (anim->ib_flags & IB_animdeinterlace) {
if (avpicture_deinterlace( if (avpicture_deinterlace(
anim->pFrame, (AVPicture*)
anim->pFrameDeinterlaced,
(const AVPicture*)
anim->pFrame, anim->pFrame,
anim->pCodecCtx->pix_fmt, anim->pCodecCtx->pix_fmt,
anim->pCodecCtx->width, anim->pCodecCtx->width,
anim->pCodecCtx->height) anim->pCodecCtx->height)
< 0) { < 0) {
filter_y = 1; filter_y = 1;
} else {
input = anim->pFrameDeinterlaced;
} }
} }
@ -748,8 +773,8 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
unsigned char* top; unsigned char* top;
sws_scale(anim->img_convert_ctx, sws_scale(anim->img_convert_ctx,
anim->pFrame->data, input->data,
anim->pFrame->linesize, input->linesize,
0, 0,
anim->pCodecCtx->height, anim->pCodecCtx->height,
dst2, dst2,
@ -806,27 +831,25 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
int i; int i;
unsigned char* r; unsigned char* r;
/* This means the data wasnt read properly, this check stops crashing */
if (anim->pFrame->data[0]!=0 || anim->pFrame->data[1]!=0 || anim->pFrame->data[2]!=0 || anim->pFrame->data[3]!=0) {
sws_scale(anim->img_convert_ctx, sws_scale(anim->img_convert_ctx,
anim->pFrame->data, input->data,
anim->pFrame->linesize, input->linesize,
0, 0,
anim->pCodecCtx->height, anim->pCodecCtx->height,
dst2, dst2,
dstStride2); dstStride2);
/* workaround: sws_scale /* workaround: sws_scale
sets alpha = 0... */ sets alpha = 0... */
r = (unsigned char*) ibuf->rect; r = (unsigned char*) ibuf->rect;
for (i = 0; i < ibuf->x * ibuf->y;i++){ for (i = 0; i < ibuf->x * ibuf->y;i++){
r[3] = 0xff; r[3] = 0xff;
r+=4; r+=4;
}
} }
av_free_packet(&packet); av_free_packet(&packet);
break; break;
} }
@ -851,6 +874,11 @@ static void free_anim_ffmpeg(struct anim * anim) {
av_close_input_file(anim->pFormatCtx); av_close_input_file(anim->pFormatCtx);
av_free(anim->pFrameRGB); av_free(anim->pFrameRGB);
av_free(anim->pFrame); av_free(anim->pFrame);
if (anim->ib_flags & IB_animdeinterlace) {
MEM_freeN(anim->pFrameDeinterlaced->data[0]);
}
av_free(anim->pFrameDeinterlaced);
sws_freeContext(anim->img_convert_ctx); sws_freeContext(anim->img_convert_ctx);
} }
anim->duration = 0; anim->duration = 0;

@ -451,7 +451,7 @@ void IMB_exr_begin_write(void *handle, char *filename, int width, int height, in
openexr_header_compression(&header, compress); openexr_header_compression(&header, compress);
/* header.lineOrder() = DECREASING_Y; this crashes in windows for file read! */ /* 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); data->ofile = new OutputFile(filename, header);
} }
@ -842,7 +842,7 @@ typedef struct RGBA
} RGBA; } RGBA;
#if 0 /* debug only */
static void exr_print_filecontents(InputFile *file) static void exr_print_filecontents(InputFile *file)
{ {
const ChannelList &channels = file->header().channels(); const ChannelList &channels = file->header().channels();
@ -853,7 +853,27 @@ static void exr_print_filecontents(InputFile *file)
printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type); printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type);
} }
} }
#endif
/* for non-multilayer, map R G B A channel names to something that's in this file */
static const char *exr_rgba_channelname(InputFile *file, const char *chan)
{
const ChannelList &channels = file->header().channels();
for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
{
const Channel &channel = i.channel();
const char *str= i.name();
int len= strlen(str);
if(len) {
if(BLI_strcasecmp(chan, str+len-1)==0) {
return str;
}
}
}
return chan;
}
static int exr_has_zbuffer(InputFile *file) static int exr_has_zbuffer(InputFile *file)
{ {
@ -896,7 +916,8 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
//printf("OpenEXR-load: image data window %d %d %d %d\n", //printf("OpenEXR-load: image data window %d %d %d %d\n",
// dw.min.x, dw.min.y, dw.max.x, dw.max.y); // dw.min.x, dw.min.y, dw.max.x, dw.max.y);
// exr_print_filecontents(file); if(0) // debug
exr_print_filecontents(file);
is_multi= exr_is_renderresult(file); is_multi= exr_is_renderresult(file);
@ -935,11 +956,15 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
/* but, since we read y-flipped (negative y stride) we move to last scanline */ /* but, since we read y-flipped (negative y stride) we move to last scanline */
first+= 4*(height-1)*width; first+= 4*(height-1)*width;
frameBuffer.insert ("R", Slice (FLOAT, (char *) first, xstride, ystride)); frameBuffer.insert ( exr_rgba_channelname(file, "R"),
frameBuffer.insert ("G", Slice (FLOAT, (char *) (first+1), xstride, ystride)); Slice (FLOAT, (char *) first, xstride, ystride));
frameBuffer.insert ("B", Slice (FLOAT, (char *) (first+2), xstride, ystride)); frameBuffer.insert ( exr_rgba_channelname(file, "G"),
/* 1.0 is fill value */ Slice (FLOAT, (char *) (first+1), xstride, ystride));
frameBuffer.insert ("A", Slice (FLOAT, (char *) (first+3), xstride, ystride, 1, 1, 1.0f)); frameBuffer.insert ( exr_rgba_channelname(file, "B"),
Slice (FLOAT, (char *) (first+2), xstride, ystride));
frameBuffer.insert ( exr_rgba_channelname(file, "A"),
Slice (FLOAT, (char *) (first+3), xstride, ystride, 1, 1, 1.0f)); /* 1.0 is fill value */
if(exr_has_zbuffer(file)) if(exr_has_zbuffer(file))
{ {

@ -63,6 +63,7 @@ void get_local_bounds(struct Object *ob, float *center, float *size);
/* drawing flags: */ /* drawing flags: */
#define DRAW_PICKING 1 #define DRAW_PICKING 1
#define DRAW_CONSTCOLOR 2 #define DRAW_CONSTCOLOR 2
#define DRAW_SCENESET 4
void draw_object(struct Base *base, int flag); void draw_object(struct Base *base, int flag);
void drawaxes(float size, int flag, char drawtype); void drawaxes(float size, int flag, char drawtype);

@ -141,6 +141,7 @@ void paste_actdata(void);
/* Group/Channel Operations */ /* Group/Channel Operations */
struct bActionGroup *get_active_actiongroup(struct bAction *act); struct bActionGroup *get_active_actiongroup(struct bAction *act);
void set_active_actiongroup(struct bAction *act, struct bActionGroup *agrp, short select); 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 verify_pchan2achan_grouping(struct bAction *act, struct bPose *pose, char name[]);
void sync_pchan2achan_grouping(void); void sync_pchan2achan_grouping(void);
void action_groups_group(short add_group); void action_groups_group(short add_group);
@ -166,6 +167,7 @@ void deselect_action_channels(short mode);
void deselect_actionchannels(struct bAction *act, short mode); void deselect_actionchannels(struct bAction *act, short mode);
int select_channel(struct bAction *act, struct bActionChannel *achan, int selectmode); 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_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); void selectkeys_leftright (short leftright, short select_mode);
/* Action Markers */ /* Action Markers */

@ -82,7 +82,7 @@ void clear_armature(struct Object *ob, char mode);
void delete_armature(void); void delete_armature(void);
void deselectall_armature(int toggle, int doundo); void deselectall_armature(int toggle, int doundo);
void deselectall_posearmature (struct Object *ob, int test, int doundo); void deselectall_posearmature (struct Object *ob, int test, int doundo);
int draw_armature(struct Base *base, int dt); int draw_armature(struct Base *base, int dt, int flag);
void extrude_armature(int forked); void extrude_armature(int forked);
void subdivide_armature(int numcuts); void subdivide_armature(int numcuts);

@ -591,6 +591,9 @@ void BIF_load_ui_colors (void);
char *BIF_ThemeGetColorPtr(struct bTheme *btheme, int spacetype, int colorid); char *BIF_ThemeGetColorPtr(struct bTheme *btheme, int spacetype, int colorid);
char *BIF_ThemeColorsPup(int spacetype); 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); void BIF_def_color (BIFColorID colorid, unsigned char r, unsigned char g, unsigned char b);

@ -92,6 +92,8 @@ void update_changed_seq_and_deps(struct Sequence *seq, int len_change, int ibuf_
struct RenderResult; struct RenderResult;
void do_render_seq(struct RenderResult *rr, int cfra); void do_render_seq(struct RenderResult *rr, int cfra);
int seq_can_blend(struct Sequence *seq);
#define SEQ_HAS_PATH(seq) (seq->type==SEQ_MOVIE || seq->type==SEQ_HD_SOUND || seq->type==SEQ_RAM_SOUND || seq->type==SEQ_IMAGE) #define SEQ_HAS_PATH(seq) (seq->type==SEQ_MOVIE || seq->type==SEQ_HD_SOUND || seq->type==SEQ_RAM_SOUND || seq->type==SEQ_IMAGE)
#endif #endif

@ -409,6 +409,12 @@
#define B_ACTCOPYKEYS 710 #define B_ACTCOPYKEYS 710
#define B_ACTPASTEKEYS 711 #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 */ /* TIME: 751 - 800 */
#define B_TL_REW 751 #define B_TL_REW 751
#define B_TL_PLAY 752 #define B_TL_PLAY 752

@ -51,8 +51,9 @@ typedef struct bActionActuator {
int sta, end; /* Start & End frames */ int sta, end; /* Start & End frames */
char name[32]; /* For property-driven playback */ char name[32]; /* For property-driven playback */
char frameProp[32]; /* Set this property to the actions current frame */ char frameProp[32]; /* Set this property to the actions current frame */
int blendin; /* Number of frames of blending */ short blendin; /* Number of frames of blending */
short priority; /* Execution priority */ short priority; /* Execution priority */
short end_reset; /* Ending the actuator (negative pulse) wont reset the the action to its starting frame */
short strideaxis; /* Displacement axis */ short strideaxis; /* Displacement axis */
float stridelength; /* Displacement incurred by cycle */ float stridelength; /* Displacement incurred by cycle */
} bActionActuator; } bActionActuator;
@ -81,7 +82,7 @@ typedef struct bEditObjectActuator {
char name[32]; char name[32];
float linVelocity[3]; /* initial lin. velocity on creation */ float linVelocity[3]; /* initial lin. velocity on creation */
short localflag; /* flag for the lin. vel: apply locally */ short localflag; /* flag for the lin. vel: apply locally */
short pad; short dyn_operation;
} bEditObjectActuator; } bEditObjectActuator;
typedef struct bSceneActuator { typedef struct bSceneActuator {
@ -98,7 +99,8 @@ typedef struct bPropertyActuator {
} bPropertyActuator; } bPropertyActuator;
typedef struct bObjectActuator { typedef struct bObjectActuator {
int flag, type; short flag, type, otype;
short damping;
float forceloc[3], forcerot[3]; float forceloc[3], forcerot[3];
float loc[3], rot[3]; float loc[3], rot[3];
float dloc[3], drot[3]; float dloc[3], drot[3];
@ -123,10 +125,13 @@ typedef struct bCameraActuator {
} bCameraActuator ; } bCameraActuator ;
typedef struct bConstraintActuator { typedef struct bConstraintActuator {
short type, mode;
short flag, damp; short flag, damp;
float slow; short time, rotdamp;
int pad;
float minloc[3], maxloc[3]; float minloc[3], maxloc[3];
float minrot[3], maxrot[3]; float minrot[3], maxrot[3];
char matprop[32];
} bConstraintActuator; } bConstraintActuator;
typedef struct bGroupActuator { typedef struct bGroupActuator {
@ -192,10 +197,10 @@ typedef struct bVisibilityActuator {
typedef struct bTwoDFilterActuator{ typedef struct bTwoDFilterActuator{
char pad[4]; char pad[4];
/* Tells what type of 2D Filter*/ /* Tells what type of 2D Filter */
short type; short type;
/* (flag == 0) means 2D filter is activate and /* (flag == 0) means 2D filter is activate and
(flag != 0) means 2D filter is inactive*/ (flag != 0) means 2D filter is inactive */
short flag; short flag;
int int_arg; int int_arg;
/* a float argument */ /* a float argument */
@ -246,19 +251,19 @@ typedef struct FreeCamera {
/* objectactuator->flag */ /* objectactuator->flag */
#define ACT_FORCE_LOCAL 1 #define ACT_FORCE_LOCAL 1
#define ACT_TORQUE_LOCAL 2 #define ACT_TORQUE_LOCAL 2
#define ACT_SERVO_LIMIT_X 2
#define ACT_DLOC_LOCAL 4 #define ACT_DLOC_LOCAL 4
#define ACT_SERVO_LIMIT_Y 4
#define ACT_DROT_LOCAL 8 #define ACT_DROT_LOCAL 8
#define ACT_SERVO_LIMIT_Z 8
#define ACT_LIN_VEL_LOCAL 16 #define ACT_LIN_VEL_LOCAL 16
#define ACT_ANG_VEL_LOCAL 32 #define ACT_ANG_VEL_LOCAL 32
//#define ACT_ADD_LIN_VEL_LOCAL 64 //#define ACT_ADD_LIN_VEL_LOCAL 64
#define ACT_ADD_LIN_VEL 64 #define ACT_ADD_LIN_VEL 64
#define ACT_OBJECT_FORCE 0 /* objectactuator->type */
#define ACT_OBJECT_TORQUE 1 #define ACT_OBJECT_NORMAL 0
#define ACT_OBJECT_DLOC 2 #define ACT_OBJECT_SERVO 1
#define ACT_OBJECT_DROT 3
#define ACT_OBJECT_LINV 4
#define ACT_OBJECT_ANGV 5
/* actuator->type */ /* actuator->type */
#define ACT_OBJECT 0 #define ACT_OBJECT 0
@ -333,8 +338,9 @@ typedef struct FreeCamera {
/* ipoactuator->flag */ /* ipoactuator->flag */
#define ACT_IPOFORCE (1 << 0) #define ACT_IPOFORCE (1 << 0)
#define ACT_IPOEND (1 << 1) #define ACT_IPOEND (1 << 1)
#define ACT_IPOFORCE_LOCAL (1 << 2) #define ACT_IPOLOCAL (1 << 2)
#define ACT_IPOCHILD (1 << 4) #define ACT_IPOCHILD (1 << 4)
#define ACT_IPOADD (1 << 5)
/* ipoactuator->flag for k2k */ /* ipoactuator->flag for k2k */
#define ACT_K2K_PREV 1 #define ACT_K2K_PREV 1
@ -354,14 +360,31 @@ typedef struct FreeCamera {
#define ACT_CONST_ROTX 8 #define ACT_CONST_ROTX 8
#define ACT_CONST_ROTY 16 #define ACT_CONST_ROTY 16
#define ACT_CONST_ROTZ 32 #define ACT_CONST_ROTZ 32
#define ACT_CONST_NORMAL 64
#define ACT_CONST_MATERIAL 128
#define ACT_CONST_PERMANENT 256
#define ACT_CONST_DISTANCE 512
/* constraint mode */
#define ACT_CONST_DIRPX 1
#define ACT_CONST_DIRPY 2
#define ACT_CONST_DIRPZ 4
#define ACT_CONST_DIRMX 8
#define ACT_CONST_DIRMY 16
#define ACT_CONST_DIRMZ 32
/* constraint type */
#define ACT_CONST_TYPE_LOC 0
#define ACT_CONST_TYPE_DIST 1
#define ACT_CONST_TYPE_ORI 2
/* editObjectActuator->type */ /* editObjectActuator->type */
#define ACT_EDOB_ADD_OBJECT 0 #define ACT_EDOB_ADD_OBJECT 0
#define ACT_EDOB_END_OBJECT 1 #define ACT_EDOB_END_OBJECT 1
#define ACT_EDOB_REPLACE_MESH 2 #define ACT_EDOB_REPLACE_MESH 2
#define ACT_EDOB_TRACK_TO 3 #define ACT_EDOB_TRACK_TO 3
#define ACT_EDOB_MAKE_CHILD 4 #define ACT_EDOB_DYNAMICS 4
#define ACT_EDOB_END_CHILD 5
/* editObjectActuator->flag */ /* editObjectActuator->flag */
#define ACT_TRACK_3D 1 #define ACT_TRACK_3D 1

@ -66,6 +66,10 @@ typedef struct bController {
#define CONT_LOGIC_OR 1 #define CONT_LOGIC_OR 1
#define CONT_EXPRESSION 2 #define CONT_EXPRESSION 2
#define CONT_PYTHON 3 #define CONT_PYTHON 3
#define CONT_LOGIC_NAND 4
#define CONT_LOGIC_NOR 5
#define CONT_LOGIC_XOR 6
#define CONT_LOGIC_XNOR 7
/* controller->flag */ /* controller->flag */
#define CONT_SHOW 1 #define CONT_SHOW 1

@ -26,6 +26,7 @@
* *
* ***** END GPL LICENSE BLOCK ***** * ***** END GPL LICENSE BLOCK *****
*/ */
#ifndef DNA_CUSTOMDATA_TYPES_H #ifndef DNA_CUSTOMDATA_TYPES_H
#define DNA_CUSTOMDATA_TYPES_H #define DNA_CUSTOMDATA_TYPES_H
@ -48,6 +49,7 @@ typedef struct CustomData {
CustomDataLayer *layers; /* CustomDataLayers, ordered by type */ CustomDataLayer *layers; /* CustomDataLayers, ordered by type */
int totlayer, maxlayer; /* number of layers, size of layers array */ int totlayer, maxlayer; /* number of layers, size of layers array */
int totsize, pad; /* in editmode, total size of all data layers */ int totsize, pad; /* in editmode, total size of all data layers */
void *pool; /* for Bmesh: Memory pool for allocation of blocks*/
} CustomData; } CustomData;
/* CustomData.type */ /* CustomData.type */
@ -66,7 +68,10 @@ typedef struct CustomData {
#define CD_PROP_STR 12 #define CD_PROP_STR 12
#define CD_ORIGSPACE 13 /* for modifier stack face location mapping */ #define CD_ORIGSPACE 13 /* for modifier stack face location mapping */
#define CD_ORCO 14 #define CD_ORCO 14
#define CD_NUMTYPES 15 #define CD_MTEXPOLY 15
#define CD_MLOOPUV 16
#define CD_MLOOPCOL 17
#define CD_NUMTYPES 18
/* Bits for CustomDataMask */ /* Bits for CustomDataMask */
#define CD_MASK_MVERT (1 << CD_MVERT) #define CD_MASK_MVERT (1 << CD_MVERT)
@ -84,6 +89,9 @@ typedef struct CustomData {
#define CD_MASK_PROP_STR (1 << CD_PROP_STR) #define CD_MASK_PROP_STR (1 << CD_PROP_STR)
#define CD_MASK_ORIGSPACE (1 << CD_ORIGSPACE) #define CD_MASK_ORIGSPACE (1 << CD_ORIGSPACE)
#define CD_MASK_ORCO (1 << CD_ORCO) #define CD_MASK_ORCO (1 << CD_ORCO)
#define CD_MASK_MTEXPOLY (1 << CD_MTEXPOLY)
#define CD_MASK_MLOOPUV (1 << CD_MLOOPUV)
#define CD_MASK_MLOOPCOL (1 << CD_MLOOPCOL)
/* CustomData.flag */ /* CustomData.flag */

@ -76,6 +76,21 @@ typedef struct Lamp {
/* texact is for buttons */ /* texact is for buttons */
short texact, shadhalostep; short texact, shadhalostep;
/* sun/sky */
short sun_effect_type;
short atm_pad[3];
float horizon_brightness;
float spread;
float sun_brightness;
float sun_size;
float backscattered_light;
float sun_intensity;
float atm_turbidity;
float atm_inscattering_factor;
float atm_extinction_factor;
float atm_distance_factor;
/* yafray: photonlight params */ /* yafray: photonlight params */
int YF_numphotons, YF_numsearch; int YF_numphotons, YF_numsearch;
short YF_phdepth, YF_useqmc, YF_bufsize, YF_pad; short YF_phdepth, YF_useqmc, YF_bufsize, YF_pad;
@ -123,6 +138,10 @@ typedef struct Lamp {
/* Since it is used with LOCAL lamp, can't use LA_SHAD */ /* Since it is used with LOCAL lamp, can't use LA_SHAD */
#define LA_YF_SOFT 16384 #define LA_YF_SOFT 16384
/* sun effect type*/
#define LA_SUN_EFFECT_SKY 1
#define LA_SUN_EFFECT_AP 2
/* falloff_type */ /* falloff_type */
#define LA_FALLOFF_CONSTANT 0 #define LA_FALLOFF_CONSTANT 0
#define LA_FALLOFF_INVLINEAR 1 #define LA_FALLOFF_INVLINEAR 1

@ -69,6 +69,21 @@ typedef struct MCol {
char a, r, g, b; char a, r, g, b;
} MCol; } MCol;
/*bmesh custom data stuff*/
typedef struct MTexPoly{
struct Image *tpage;
char flag, transp;
short mode,tile,unwrap;
}MTexPoly;
typedef struct MLoopUV{
float uv[2];
}MLoopUV;
typedef struct MLoopCol{
char a, r, g, b;
}MLoopCol;
typedef struct MSticky { typedef struct MSticky {
float co[2]; float co[2];
} MSticky; } MSticky;

@ -82,6 +82,12 @@ typedef struct bPropertySensor {
char maxvalue[32]; char maxvalue[32];
} bPropertySensor; } bPropertySensor;
typedef struct bActuatorSensor {
int type;
int pad;
char name[32];
} bActuatorSensor;
typedef struct bCollisionSensor { typedef struct bCollisionSensor {
char name[32]; /* property name */ char name[32]; /* property name */
char materialName[32]; /* material */ char materialName[32]; /* material */
@ -144,7 +150,7 @@ typedef struct bSensor {
/* just add here, to avoid align errors... */ /* just add here, to avoid align errors... */
short invert; /* Whether or not to invert the output. */ short invert; /* Whether or not to invert the output. */
short freq2; /* The negative pulsing frequency? Not used anymore... */ short level; /* Whether the sensor is level base (edge by default) */
int pad; int pad;
} bSensor; } bSensor;
@ -197,6 +203,7 @@ typedef struct bJoystickSensor {
#define SENS_RAY 9 #define SENS_RAY 9
#define SENS_MESSAGE 10 #define SENS_MESSAGE 10
#define SENS_JOYSTICK 11 #define SENS_JOYSTICK 11
#define SENS_ACTUATOR 12
/* sensor->flag */ /* sensor->flag */
#define SENS_SHOW 1 #define SENS_SHOW 1
#define SENS_DEL 2 #define SENS_DEL 2

@ -232,8 +232,9 @@ typedef struct SpaceImage {
short imanr; short imanr;
short curtile; /* the currently active tile of the image when tile is enabled, is kept in sync with the active faces tile */ short curtile; /* the currently active tile of the image when tile is enabled, is kept in sync with the active faces tile */
int flag; int flag;
short selectmode;
short imtypenr, lock; short imtypenr, lock;
short pin, pad2; short pin;
float zoom; float zoom;
char dt_uv; /* UV draw type */ char dt_uv; /* UV draw type */
char sticky; /* sticky selection type */ char sticky; /* sticky selection type */
@ -496,6 +497,12 @@ typedef struct SpaceImaSel {
#define SI_STICKY_DISABLE 1 #define SI_STICKY_DISABLE 1
#define SI_STICKY_VERTEX 2 #define SI_STICKY_VERTEX 2
/* SpaceImage->selectmode */
#define SI_SELECT_VERTEX 0
#define SI_SELECT_EDGE 1 /* not implemented */
#define SI_SELECT_FACE 2
#define SI_SELECT_ISLAND 3
/* SpaceImage->flag */ /* SpaceImage->flag */
#define SI_BE_SQUARE 1<<0 #define SI_BE_SQUARE 1<<0
#define SI_EDITTILE 1<<1 #define SI_EDITTILE 1<<1
@ -503,7 +510,7 @@ typedef struct SpaceImaSel {
#define SI_DRAWTOOL 1<<3 #define SI_DRAWTOOL 1<<3
#define SI_DEPRECATED1 1<<4 /* stick UVs to others in the same location */ #define SI_DEPRECATED1 1<<4 /* stick UVs to others in the same location */
#define SI_DRAWSHADOW 1<<5 #define SI_DRAWSHADOW 1<<5
#define SI_SELACTFACE 1<<6 #define SI_SELACTFACE 1<<6 /* deprecated */
#define SI_DEPRECATED2 1<<7 #define SI_DEPRECATED2 1<<7
#define SI_DEPRECATED3 1<<8 /* stick UV selection to mesh vertex (UVs wont always be touching) */ #define SI_DEPRECATED3 1<<8 /* stick UV selection to mesh vertex (UVs wont always be touching) */
#define SI_COORDFLOATS 1<<9 #define SI_COORDFLOATS 1<<9

@ -116,6 +116,7 @@ typedef struct ThemeWireColor {
/* flags for ThemeWireColor */ /* flags for ThemeWireColor */
#define TH_WIRECOLOR_CONSTCOLS (1<<0) #define TH_WIRECOLOR_CONSTCOLS (1<<0)
#define TH_WIRECOLOR_TEXTCOLS (1<<1)
/* A theme */ /* A theme */
typedef struct bTheme { typedef struct bTheme {
@ -310,7 +311,7 @@ extern UserDef U; /* from usiblender.c !!!! */
#define USER_DUP_ACT (1 << 10) #define USER_DUP_ACT (1 << 10)
/* gameflags */ /* gameflags */
#define USER_VERTEX_ARRAYS 1 #define USER_DEPRECATED_FLAG 1
#define USER_DISABLE_SOUND 2 #define USER_DISABLE_SOUND 2
#define USER_DISABLE_MIPMAP 4 #define USER_DISABLE_MIPMAP 4

@ -47,7 +47,7 @@ static void do_gamma(bNode *node, float *out, float *in, float *fac)
int i=0; int i=0;
for(i=0; i<3; i++) { for(i=0; i<3; i++) {
/* check for negative to avoid nan's */ /* check for negative to avoid nan's */
out[i] = (in[0] > 0.0f)? pow(in[i],fac[0]): in[0]; out[i] = (in[i] > 0.0f)? pow(in[i],fac[0]): in[i];
} }
out[3] = in[3]; out[3] = in[3];
} }

@ -57,7 +57,7 @@ static void do_math(bNode *node, float *out, float *in, float *in2)
break; break;
case 3: /* Divide */ case 3: /* Divide */
{ {
if(in[1]==0) /* We don't want to divide by zero. */ if(in2[0]==0) /* We don't want to divide by zero. */
out[0]= 0.0; out[0]= 0.0;
else else
out[0]= in[0] / in2[0]; out[0]= in[0] / in2[0];

@ -229,13 +229,6 @@ void BPY_start_python( int argc, char **argv )
/* Initialize thread support (also acquires lock) */ /* Initialize thread support (also acquires lock) */
PyEval_InitThreads(); PyEval_InitThreads();
/* Don't allow the Python Interpreter to release the GIL on
* its own, to guarantee PyNodes work properly. For Blender this
* is currently the best default behavior.
* The following code in C is equivalent in Python to:
* "import sys; sys.setcheckinterval(sys.maxint)" */
_Py_CheckInterval = PyInt_GetMax();
//Overrides __import__ //Overrides __import__
init_ourImport( ); init_ourImport( );
init_ourReload( ); init_ourReload( );
@ -2188,6 +2181,18 @@ void BPY_do_all_scripts( short event )
BPY_do_pyscript( &( G.scene->id ), event ); BPY_do_pyscript( &( G.scene->id ), event );
/* Don't allow the Python Interpreter to release the GIL on
* its own, to guarantee PyNodes work properly. For Blender this
* is currently the best default behavior.
* The following code in C is equivalent in Python to:
* "import sys; sys.setcheckinterval(sys.maxint)" */
if (event == SCRIPT_RENDER) {
_Py_CheckInterval = PyInt_GetMax();
}
else if (event == SCRIPT_POSTRENDER) {
_Py_CheckInterval = 100; /* Python default */
}
return; return;
} }
@ -2270,9 +2275,9 @@ void BPY_do_pyscript( ID * id, short event )
return; return;
} }
/* tell we're running a scriptlink. The sum also tells if this script /* tell we're running a scriptlink. The sum also tells if this
* is running nested inside another. Blender.Load needs this info to * script is running nested inside another. Blender.Load needs
* avoid trouble with invalid slink pointers. */ * this info to avoid trouble with invalid slink pointers. */
during_slink++; during_slink++;
disable_where_scriptlink( (short)during_slink ); disable_where_scriptlink( (short)during_slink );

@ -53,6 +53,8 @@ static int CurNurb_setFlagU( BPy_CurNurb * self, PyObject * args );
static PyObject *CurNurb_getFlagV( BPy_CurNurb * self ); static PyObject *CurNurb_getFlagV( BPy_CurNurb * self );
static PyObject *CurNurb_oldsetFlagV( BPy_CurNurb * self, PyObject * args ); static PyObject *CurNurb_oldsetFlagV( BPy_CurNurb * self, PyObject * args );
static int CurNurb_setFlagV( BPy_CurNurb * self, PyObject * args ); static int CurNurb_setFlagV( BPy_CurNurb * self, PyObject * args );
static PyObject *CurNurb_getOrderU( BPy_CurNurb * self );
static int CurNurb_setOrderU( BPy_CurNurb * self, PyObject * args );
static PyObject *CurNurb_getType( BPy_CurNurb * self ); static PyObject *CurNurb_getType( BPy_CurNurb * self );
static PyObject *CurNurb_oldsetType( BPy_CurNurb * self, PyObject * args ); static PyObject *CurNurb_oldsetType( BPy_CurNurb * self, PyObject * args );
static int CurNurb_setType( BPy_CurNurb * self, PyObject * args ); static int CurNurb_setType( BPy_CurNurb * self, PyObject * args );
@ -176,6 +178,9 @@ static PyGetSetDef BPy_CurNurb_getseters[] = {
(getter)CurNurb_getFlagV, (setter)CurNurb_setFlagV, (getter)CurNurb_getFlagV, (setter)CurNurb_setFlagV,
"The knot type in the V direction", "The knot type in the V direction",
NULL}, NULL},
{"orderU",
(getter)CurNurb_getOrderU, (setter)CurNurb_setOrderU,
"order setting for U direction", NULL},
{"type", {"type",
(getter)CurNurb_getType, (setter)CurNurb_setType, (getter)CurNurb_getType, (setter)CurNurb_setType,
"The curve type (poly: bezier, or NURBS)", "The curve type (poly: bezier, or NURBS)",
@ -710,6 +715,35 @@ static int CurNurb_setFlagV( BPy_CurNurb * self, PyObject * args )
return 0; return 0;
} }
static PyObject *CurNurb_getOrderU( BPy_CurNurb * self )
{
return PyInt_FromLong( ( long ) self->nurb->orderu );
}
static int CurNurb_setOrderU( BPy_CurNurb * self, PyObject * args )
{
int order;
args = PyNumber_Int( args );
if( !args )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected integer argument" );
order = ( int )PyInt_AS_LONG( args );
Py_DECREF( args );
if( order < 2 ) order = 2;
else if( order > 6 ) order = 6;
if( self->nurb->pntsu < order )
order = self->nurb->pntsu;
self->nurb->orderu = (short)order;
makeknots( self->nurb, 1, self->nurb->flagu >> 1 );
return 0;
}
/* /*
* CurNurb_getIter * CurNurb_getIter
* *

@ -1520,12 +1520,11 @@ static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * value )
char *type = PyString_AsString(value); char *type = PyString_AsString(value);
PyObject *arg, *error; PyObject *arg, *error;
/* parse string argument */ /* parse string argument */
if( !type )
if( !value ) return EXPP_ReturnPyObjError ( PyExc_TypeError,
return ( EXPP_ReturnPyObjError( PyExc_TypeError, "expected string argument" );
"expected string argument" ) );
/* check for valid arguments, set type accordingly */ /* check for valid arguments, set type accordingly */
if( !strcmp( type, "Lamp" ) ) if( !strcmp( type, "Lamp" ) )
@ -1546,7 +1545,7 @@ static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * value )
/* build tuple, call wrapper */ /* build tuple, call wrapper */
arg = Py_BuildValue( "(i)", type ); arg = Py_BuildValue( "(i)", self->lamp->type );
error = EXPP_setterWrapper ( (void *)self, arg, (setter)Lamp_setType ); error = EXPP_setterWrapper ( (void *)self, arg, (setter)Lamp_setType );
Py_DECREF ( arg ); Py_DECREF ( arg );
return error; return error;

@ -535,6 +535,8 @@ class CurNurb:
@type flagU: int @type flagU: int
@ivar flagV: The CurNurb knot flag V. See L{setFlagU} for description. @ivar flagV: The CurNurb knot flag V. See L{setFlagU} for description.
@type flagV: int @type flagV: int
@ivar orderU: The CurNurb knot order U, for nurbs curves only, this is clamped by the number of points, so the orderU will never be greater.
@type orderU: int
@ivar type: The type of the curve (Poly: 0, Bezier: 1, NURBS: 4) @ivar type: The type of the curve (Poly: 0, Bezier: 1, NURBS: 4)
@type type: int @type type: int
@ivar knotsU: The knot vector in the U direction. The tuple will be empty @ivar knotsU: The knot vector in the U direction. The tuple will be empty

@ -483,7 +483,7 @@ static char MatrixObject_doc[] = "This is a wrapper for matrix objects.";
sequence length*/ sequence length*/
static int Matrix_len(MatrixObject * self) static int Matrix_len(MatrixObject * self)
{ {
return (self->colSize * self->rowSize); return (self->rowSize);
} }
/*----------------------------object[]--------------------------- /*----------------------------object[]---------------------------
sequence accessor (get) sequence accessor (get)

@ -81,6 +81,7 @@ returns None if notfound.\nIf 'name' is not specified, it returns a list of all
static PyObject *Sequence_copy( BPy_Sequence * self ); static PyObject *Sequence_copy( BPy_Sequence * self );
static PyObject *Sequence_new( BPy_Sequence * self, PyObject * args ); static PyObject *Sequence_new( BPy_Sequence * self, PyObject * args );
static PyObject *Sequence_remove( BPy_Sequence * self, PyObject * args ); static PyObject *Sequence_remove( BPy_Sequence * self, PyObject * args );
static PyObject *Sequence_rebuildProxy( BPy_Sequence * self );
static PyObject *SceneSeq_new( BPy_SceneSeq * self, PyObject * args ); static PyObject *SceneSeq_new( BPy_SceneSeq * self, PyObject * args );
static PyObject *SceneSeq_remove( BPy_SceneSeq * self, PyObject * args ); static PyObject *SceneSeq_remove( BPy_SceneSeq * self, PyObject * args );
@ -96,6 +97,8 @@ static PyMethodDef BPy_Sequence_methods[] = {
"() - Return a copy of the sequence containing the same objects."}, "() - Return a copy of the sequence containing the same objects."},
{"copy", ( PyCFunction ) Sequence_copy, METH_NOARGS, {"copy", ( PyCFunction ) Sequence_copy, METH_NOARGS,
"() - Return a copy of the sequence containing the same objects."}, "() - Return a copy of the sequence containing the same objects."},
{"rebuildProxy", ( PyCFunction ) Sequence_rebuildProxy, METH_VARARGS,
"() - Rebuild the active strip's Proxy."},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
@ -309,6 +312,7 @@ static PyObject *Sequence_copy( BPy_Sequence * self )
Py_RETURN_NONE; Py_RETURN_NONE;
} }
/*****************************************************************************/ /*****************************************************************************/
/* PythonTypeObject callback function prototypes */ /* PythonTypeObject callback function prototypes */
/*****************************************************************************/ /*****************************************************************************/
@ -383,8 +387,6 @@ static PyObject *SceneSeq_nextIter( BPy_Sequence * self )
} }
static PyObject *Sequence_getName( BPy_Sequence * self ) static PyObject *Sequence_getName( BPy_Sequence * self )
{ {
return PyString_FromString( self->seq->name+2 ); return PyString_FromString( self->seq->name+2 );
@ -403,11 +405,13 @@ static int Sequence_setName( BPy_Sequence * self, PyObject * value )
return 0; return 0;
} }
static PyObject *Sequence_getProxyDir( BPy_Sequence * self ) static PyObject *Sequence_getProxyDir( BPy_Sequence * self )
{ {
return PyString_FromString( self->seq->strip->proxy ? self->seq->strip->proxy->dir : "" ); return PyString_FromString( self->seq->strip->proxy ? self->seq->strip->proxy->dir : "" );
} }
static int Sequence_setProxyDir( BPy_Sequence * self, PyObject * value ) static int Sequence_setProxyDir( BPy_Sequence * self, PyObject * value )
{ {
char *name = NULL; char *name = NULL;
@ -430,6 +434,14 @@ static int Sequence_setProxyDir( BPy_Sequence * self, PyObject * value )
} }
static PyObject *Sequence_rebuildProxy( BPy_Sequence * self )
{
if (self->seq->strip->proxy)
seq_proxy_rebuild(self->seq);
Py_RETURN_NONE;
}
static PyObject *Sequence_getSound( BPy_Sequence * self ) static PyObject *Sequence_getSound( BPy_Sequence * self )
{ {
if (self->seq->type == SEQ_RAM_SOUND && self->seq->sound) if (self->seq->type == SEQ_RAM_SOUND && self->seq->sound)
@ -622,6 +634,54 @@ static int Sequence_setImages( BPy_Sequence * self, PyObject *value )
return 0; return 0;
} }
static PyObject *M_Sequence_BlendModesDict( void )
{
PyObject *M = PyConstant_New( );
if( M ) {
BPy_constant *d = ( BPy_constant * ) M;
PyConstant_Insert( d, "CROSS", PyInt_FromLong( SEQ_CROSS ) );
PyConstant_Insert( d, "ADD", PyInt_FromLong( SEQ_ADD ) );
PyConstant_Insert( d, "SUBTRACT", PyInt_FromLong( SEQ_SUB ) );
PyConstant_Insert( d, "ALPHAOVER", PyInt_FromLong( SEQ_ALPHAOVER ) );
PyConstant_Insert( d, "ALPHAUNDER", PyInt_FromLong( SEQ_ALPHAUNDER ) );
PyConstant_Insert( d, "GAMMACROSS", PyInt_FromLong( SEQ_GAMCROSS ) );
PyConstant_Insert( d, "MULTIPLY", PyInt_FromLong( SEQ_MUL ) );
PyConstant_Insert( d, "OVERDROP", PyInt_FromLong( SEQ_OVERDROP ) );
PyConstant_Insert( d, "PLUGIN", PyInt_FromLong( SEQ_PLUGIN ) );
PyConstant_Insert( d, "WIPE", PyInt_FromLong( SEQ_WIPE ) );
PyConstant_Insert( d, "GLOW", PyInt_FromLong( SEQ_GLOW ) );
PyConstant_Insert( d, "TRANSFORM", PyInt_FromLong( SEQ_TRANSFORM ) );
PyConstant_Insert( d, "COLOR", PyInt_FromLong( SEQ_COLOR ) );
PyConstant_Insert( d, "SPEED", PyInt_FromLong( SEQ_SPEED ) );
}
return M;
}
static PyObject *Sequence_getBlendMode( BPy_Sequence * self )
{
return PyInt_FromLong( self->seq->blend_mode );
}
static int Sequence_setBlendMode( BPy_Sequence * self, PyObject * value )
{
struct Sequence *seq= self->seq;
int number = PyInt_AsLong( value );
if( number==-1 && PyErr_Occurred() )
return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
if ( !seq_can_blend(seq) )
return EXPP_ReturnIntError( PyExc_AttributeError, "this sequence type dosnt support blending" );
if (number<SEQ_EFFECT || number>SEQ_EFFECT_MAX)
return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
seq->blend_mode=number;
return 0;
}
/* /*
* get floating point attributes * get floating point attributes
*/ */
@ -836,7 +896,11 @@ static PyGetSetDef BPy_Sequence_getseters[] = {
(getter)Sequence_getImages, (setter)Sequence_setImages, (getter)Sequence_getImages, (setter)Sequence_setImages,
"Sequence scene", "Sequence scene",
NULL}, NULL},
{"blendMode",
(getter)Sequence_getBlendMode, (setter)Sequence_setBlendMode,
"Sequence Blend Mode",
NULL},
{"type", {"type",
(getter)getIntAttr, (setter)NULL, (getter)getIntAttr, (setter)NULL,
"", "",
@ -1131,6 +1195,7 @@ PyObject *M_Sequence_Get( PyObject * self, PyObject * args )
/*****************************************************************************/ /*****************************************************************************/
PyObject *Sequence_Init( void ) PyObject *Sequence_Init( void )
{ {
PyObject *BlendModesDict = M_Sequence_BlendModesDict( );
PyObject *submodule; PyObject *submodule;
if( PyType_Ready( &Sequence_Type ) < 0 ) if( PyType_Ready( &Sequence_Type ) < 0 )
return NULL; return NULL;
@ -1142,6 +1207,9 @@ PyObject *Sequence_Init( void )
"The Blender Sequence module\n\n\ "The Blender Sequence module\n\n\
This module provides access to **Sequence Data** in Blender.\n" ); This module provides access to **Sequence Data** in Blender.\n" );
if( BlendModesDict )
PyModule_AddObject( submodule, "BlendModes", BlendModesDict );
/*Add SUBMODULES to the module*/ /*Add SUBMODULES to the module*/
/*PyDict_SetItemString(dict, "Constraint", Constraint_Init()); //creates a *new* module*/ /*PyDict_SetItemString(dict, "Constraint", Constraint_Init()); //creates a *new* module*/
return submodule; return submodule;

@ -369,9 +369,18 @@ printf(" Rad elems: %d emittors %d\n", RG.totelem, RG.totpatch);
if(vlr->mat->mode & MA_RADIO) { if(vlr->mat->mode & MA_RADIO) {
/* during render, vlr->n gets flipped/corrected, we cannot have that */ /* during render, vlr->n gets flipped/corrected, we cannot have that */
if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm); if (obr->ob->transflag & OB_NEG_SCALE){
else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm); /* The object has negative scale that will cause the normals to flip.
To counter this unwanted normal flip, swap vertex 2 and 4 for a quad
or vertex 2 and 3 (see flip_face) for a triangle in the call to CalcNormFloat4
in order to flip the normals back to the way they were in the original mesh. */
if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v4->co, vlr->v3->co, vlr->v2->co, rf->norm);
else CalcNormFloat(vlr->v1->co, vlr->v3->co, vlr->v2->co, rf->norm);
}else{
if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm);
else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm);
}
rf->totrad[0]= vlr->mat->emit*vlr->mat->r; rf->totrad[0]= vlr->mat->emit*vlr->mat->r;
rf->totrad[1]= vlr->mat->emit*vlr->mat->g; rf->totrad[1]= vlr->mat->emit*vlr->mat->g;
rf->totrad[2]= vlr->mat->emit*vlr->mat->b; rf->totrad[2]= vlr->mat->emit*vlr->mat->b;

@ -55,6 +55,7 @@ int shadeHaloFloat(HaloRen *har,
*/ */
void shadeSkyPixel(float *collector, float fx, float fy); void shadeSkyPixel(float *collector, float fx, float fy);
void shadeSkyView(float *colf, float *rco, float *view, float *dxyview); void shadeSkyView(float *colf, float *rco, float *view, float *dxyview);
void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance);
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */

@ -42,6 +42,7 @@
#include "RE_pipeline.h" #include "RE_pipeline.h"
#include "RE_shader_ext.h" /* TexResult, ShadeResult, ShadeInput */ #include "RE_shader_ext.h" /* TexResult, ShadeResult, ShadeInput */
#include "sunsky.h"
struct Object; struct Object;
struct MemArena; struct MemArena;
@ -455,6 +456,9 @@ typedef struct LampRen {
float area_size, area_sizey, area_sizez; float area_size, area_sizey, area_sizez;
float adapt_thresh; float adapt_thresh;
/* sun/sky */
struct SunSky *sunsky;
struct ShadBuf *shb; struct ShadBuf *shb;
float *jitter; float *jitter;

@ -0,0 +1,141 @@
/**
* ***** 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.
*
* Contributor(s): zaghaghi
*
* ***** END GPL LICENSE BLOCK *****
*/
/**
* This feature comes from Preetham paper on "A Practical Analytic Model for Daylight"
* and example code from Brian Smits, another author of that paper in
* http://www.cs.utah.edu/vissim/papers/sunsky/code/
* */
#ifndef SUNSKY_H_
#define SUNSKY_H_
#define SPECTRUM_MAX_COMPONENTS 100
#define SPECTRUM_START 350.0
#define SPECTRUM_END 800.0
typedef struct SunSky
{
short effect_type;
float turbidity;
float theta, phi;
float toSun[3];
/*float sunSpectralRaddata[SPECTRUM_MAX_COMPONENTS];*/
float sunSolidAngle;
float zenith_Y, zenith_x, zenith_y;
float perez_Y[5], perez_x[5], perez_y[5];
/* suggested by glome in
* http://projects.blender.org/tracker/?func=detail&atid=127&aid=8063&group_id=9*/
float horizon_brightness;
float spread;
float sun_brightness;
float sun_size;
float backscattered_light;
float atm_HGg;
float atm_SunIntensity;
float atm_InscatteringMultiplier;
float atm_ExtinctionMultiplier;
float atm_BetaRayMultiplier;
float atm_BetaMieMultiplier;
float atm_DistanceMultiplier;
float atm_BetaRay[3];
float atm_BetaDashRay[3];
float atm_BetaMie[3];
float atm_BetaDashMie[3];
float atm_BetaRM[3];
}SunSky;
/**
* InitSunSky:
* this function compute some sun,sky parameters according to input parameters and also initiate some other sun, sky parameters
* parameters:
* sunSky, is a structure that contains informtion about sun, sky and atmosphere, in this function, most of its values initiated
* turb, is atmosphere turbidity
* toSun, contains sun direction
* horizon_brighness, controls the brightness of the horizon colors
* spread, controls colors spreed at horizon
* sun_brightness, controls sun's brightness
* sun_size, controls sun's size
* back_scatter, controls back scatter light
* */
void InitSunSky(struct SunSky *sunsky, float turb, float *toSun, float horizon_brightness,
float spread,float sun_brightness, float sun_size, float back_scatter);
/**
* GetSkyXYZRadiance:
* this function compute sky radiance according to a view parameters `theta' and `phi'and sunSky values
* parameters:
* sunSky, sontains sun and sky parameters
* theta, is sun's theta
* phi, is sun's phi
* color_out, is computed color that shows sky radiance in XYZ color format
* */
void GetSkyXYZRadiance(struct SunSky* sunsky, float theta, float phi, float color_out[3]);
/**
* GetSkyXYZRadiancef:
* this function compute sky radiance according to a view direction `varg' and sunSky values
* parameters:
* sunSky, sontains sun and sky parameters
* varg, shows direction
* color_out, is computed color that shows sky radiance in XYZ color format
* */
void GetSkyXYZRadiancef(struct SunSky* sunsky, const float varg[3], float color_out[3]);
/**
* InitAtmosphere:
* this function intiate sunSky structure with user input parameters.
* parameters:
* sunSky, contains information about sun, and in this function some atmosphere parameters will initiated
* sun_intens, shows sun intensity value
* mief, Mie scattering factor this factor currently call with 1.0
* rayf, Rayleigh scattering factor, this factor currently call with 1.0
* inscattf, inscatter light factor that range from 0.0 to 1.0, 0.0 means no inscatter light and 1.0 means full inscatter light
* extincf, extinction light factor that range from 0.0 to 1.0, 0.0 means no extinction and 1.0 means full extinction
* disf, is distance factor, multiplyed to pixle's z value to compute each pixle's distance to camera,
* */
void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float rayf, float inscattf, float extincf, float disf);
/**
* AtmospherePixleShader:
* this function apply atmosphere effect on a pixle color `rgb' at distance `s'
* parameters:
* sunSky, contains information about sun parameters and user values
* view, is camera view vector
* s, is distance
* rgb, contains rendered color value for a pixle
* */
void AtmospherePixleShader( struct SunSky* sunSky, float view[3], float s, float rgb[3]);
/**
* ClipColor:
* clip a color to range [0,1];
* */
void ClipColor(float c[3]);
#endif /*SUNSKY_H_*/

@ -114,6 +114,7 @@
#include "sss.h" #include "sss.h"
#include "strand.h" #include "strand.h"
#include "zbuf.h" #include "zbuf.h"
#include "sunsky.h"
#ifndef DISABLE_YAFRAY /* disable yafray */ #ifndef DISABLE_YAFRAY /* disable yafray */
@ -203,6 +204,7 @@ void RE_make_stars(Render *re, void (*initfunc)(void),
else stargrid *= 1.0; /* then it draws fewer */ else stargrid *= 1.0; /* then it draws fewer */
if(re) MTC_Mat4Invert(mat, re->viewmat); if(re) MTC_Mat4Invert(mat, re->viewmat);
else MTC_Mat4One(mat);
/* BOUNDING BOX CALCULATION /* BOUNDING BOX CALCULATION
* bbox goes from z = loc_near_var | loc_far_var, * bbox goes from z = loc_near_var | loc_far_var,
@ -3494,6 +3496,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
LampRen *lar; LampRen *lar;
GroupObject *go; GroupObject *go;
float mat[4][4], angle, xn, yn; float mat[4][4], angle, xn, yn;
float vec[3];
int c; int c;
/* previewrender sets this to zero... prevent accidents */ /* previewrender sets this to zero... prevent accidents */
@ -3576,8 +3579,9 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
lar->ray_samp_type= la->ray_samp_type; lar->ray_samp_type= la->ray_samp_type;
lar->adapt_thresh= la->adapt_thresh; lar->adapt_thresh= la->adapt_thresh;
lar->sunsky = NULL;
if( ELEM3(lar->type, LA_SPOT, LA_SUN, LA_LOCAL)) { if( ELEM(lar->type, LA_SPOT, LA_LOCAL)) {
lar->ray_totsamp= lar->ray_samp*lar->ray_samp; lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
lar->area_shape = LA_AREA_SQUARE; lar->area_shape = LA_AREA_SQUARE;
lar->area_sizey= lar->area_size; lar->area_sizey= lar->area_size;
@ -3607,6 +3611,26 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
area_lamp_vectors(lar); area_lamp_vectors(lar);
init_jitter_plane(lar); // subsamples init_jitter_plane(lar); // subsamples
} }
else if(lar->type==LA_SUN){
lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
lar->area_shape = LA_AREA_SQUARE;
lar->area_sizey= lar->area_size;
if((la->sun_effect_type & LA_SUN_EFFECT_SKY) ||
(la->sun_effect_type & LA_SUN_EFFECT_AP)){
lar->sunsky = (struct SunSky*)MEM_callocN(sizeof(struct SunSky), "sunskyren");
lar->sunsky->effect_type = la->sun_effect_type;
VECCOPY(vec,ob->obmat[2]);
Normalize(vec);
InitSunSky(lar->sunsky, la->atm_turbidity, vec, la->horizon_brightness,
la->spread, la->sun_brightness, la->sun_size, la->backscattered_light);
InitAtmosphere(lar->sunsky, la->sun_intensity, 1.0, 1.0, la->atm_inscattering_factor, la->atm_extinction_factor,
la->atm_distance_factor);
}
}
else lar->ray_totsamp= 0; else lar->ray_totsamp= 0;
#ifndef DISABLE_YAFRAY #ifndef DISABLE_YAFRAY
@ -4447,6 +4471,7 @@ void RE_Database_Free(Render *re)
freeshadowbuf(lar); freeshadowbuf(lar);
if(lar->jitter) MEM_freeN(lar->jitter); if(lar->jitter) MEM_freeN(lar->jitter);
if(lar->shadsamp) MEM_freeN(lar->shadsamp); if(lar->shadsamp) MEM_freeN(lar->shadsamp);
if(lar->sunsky) MEM_freeN(lar->sunsky);
curvemapping_free(lar->curfalloff); curvemapping_free(lar->curfalloff);
} }

@ -2675,9 +2675,9 @@ void RE_set_max_threads(int threads)
void RE_init_threadcount(Render *re) void RE_init_threadcount(Render *re)
{ {
if ((re->r.mode & R_FIXED_THREADS)==0 || commandline_threads == 0) { /* Automatic threads */ if(commandline_threads >= 1) { /* only set as an arg in background mode */
re->r.threads= MIN2(commandline_threads, BLENDER_MAX_THREADS);
} else if ((re->r.mode & R_FIXED_THREADS)==0 || commandline_threads == 0) { /* Automatic threads */
re->r.threads = BLI_system_thread_count(); re->r.threads = BLI_system_thread_count();
} else if(commandline_threads >= 1 && commandline_threads<=BLENDER_MAX_THREADS) {
re->r.threads= commandline_threads;
} }
} }

@ -57,6 +57,7 @@
#include "rendercore.h" #include "rendercore.h"
#include "shadbuf.h" #include "shadbuf.h"
#include "pixelshading.h" #include "pixelshading.h"
#include "sunsky.h"
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
@ -567,13 +568,49 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview)
} }
} }
/* shade sky according to sun lamps, all parameters are like shadeSkyView except sunsky*/
void shadeSunView(struct SunSky *sunsky, float *colf, float *rco, float *view, float *dxyview)
{
float colorxyz[3];
float scale;
/**
sunAngle = sqrt(sunsky->sunSolidAngle / M_PI);
sunDir[0] = sunsky->toSun[0];
sunDir[1] = sunsky->toSun[1];
sunDir[2] = sunsky->toSun[2];
*/
Normalize(view);
MTC_Mat3MulVecfl(R.imat, view);
if (view[2] < 0.0)
view[2] = 0.0;
Normalize(view);
GetSkyXYZRadiancef(sunsky, view, colorxyz);
scale = MAX3(colorxyz[0], colorxyz[1], colorxyz[2]);
colorxyz[0] /= scale;
colorxyz[1] /= scale;
colorxyz[2] /= scale;
xyz_to_rgb(colorxyz[0], colorxyz[1], colorxyz[2], &colf[0], &colf[1], &colf[2]);
ClipColor(colf);
}
/* /*
Stuff the sky color into the collector. Stuff the sky color into the collector.
*/ */
void shadeSkyPixel(float *collector, float fx, float fy) void shadeSkyPixel(float *collector, float fx, float fy)
{ {
float view[3], dxyview[2]; float view[3], dxyview[2];
float sun_collector[3];
float suns_color[3];
short num_sun_lamp;
GroupObject *go;
LampRen *lar;
/* /*
The rules for sky: The rules for sky:
1. Draw an image, if a background image was provided. Stop 1. Draw an image, if a background image was provided. Stop
@ -585,7 +622,6 @@ void shadeSkyPixel(float *collector, float fx, float fy)
/* 1. Do a backbuffer image: */ /* 1. Do a backbuffer image: */
if(R.r.bufflag & 1) { if(R.r.bufflag & 1) {
fillBackgroundImage(collector, fx, fy); fillBackgroundImage(collector, fx, fy);
return;
} }
else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) { else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) {
/* 2. solid color */ /* 2. solid color */
@ -620,7 +656,45 @@ void shadeSkyPixel(float *collector, float fx, float fy)
shadeSkyView(collector, NULL, view, dxyview); shadeSkyView(collector, NULL, view, dxyview);
collector[3] = 0.0f; collector[3] = 0.0f;
} }
suns_color[0] = suns_color[1] = suns_color[2] = 0;
num_sun_lamp = 0;
for(go=R.lights.first; go; go= go->next) {
lar= go->lampren;
if(lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_SKY)){
num_sun_lamp ++;
calc_view_vector(view, fx, fy);
Normalize(view);
shadeSunView(lar->sunsky, sun_collector, NULL, view, NULL);
suns_color[0] += sun_collector[0];
suns_color[1] += sun_collector[1];
suns_color[2] += sun_collector[2];
}
}
if( num_sun_lamp > 0 ){
suns_color[0] /= num_sun_lamp;
suns_color[1] /= num_sun_lamp;
suns_color[2] /= num_sun_lamp;
collector[0] += suns_color[0];
collector[1] += suns_color[1];
collector[2] += suns_color[2];
ClipColor(collector);
}
} }
/* aerial perspective */
void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance)
{
float view[3];
calc_view_vector(view, fx, fy);
Normalize(view);
/*MTC_Mat3MulVecfl(R.imat, view);*/
AtmospherePixleShader(sunsky, view, distance, collector);
}
/* eof */ /* eof */

@ -47,6 +47,7 @@
#include "DNA_lamp_types.h" #include "DNA_lamp_types.h"
#include "DNA_material_types.h" #include "DNA_material_types.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
#include "DNA_group_types.h"
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_image.h" #include "BKE_image.h"
@ -665,6 +666,88 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl)
} }
} }
static void atm_tile(RenderPart *pa, RenderLayer *rl)
{
RenderPass *zpass;
GroupObject *go;
LampRen *lar;
int x, y;
short first_lamp;
float *zrect;
float *rgbrect;
float rgb[3]={0};
float tmp_rgb[3];
float fac;
float facm;
fac = 0.5;
facm = 1.0 - fac;
/* check that z pass is enabled */
if(pa->rectz==NULL) return;
for(zpass= rl->passes.first; zpass; zpass= zpass->next)
if(zpass->passtype==SCE_PASS_Z)
break;
if(zpass==NULL) return;
/* check for at least one sun lamp that its atmosphere flag is is enabled */
first_lamp = 1;
for(go=R.lights.first; go; go= go->next) {
lar= go->lampren;
if(lar->type==LA_SUN && lar->sunsky &&
(lar->sunsky->effect_type & LA_SUN_EFFECT_AP)){
first_lamp = 0;
break;
}
}
/* do nothign and return if there is no sun lamp */
if(first_lamp)
return;
zrect = zpass->rect;
rgbrect = rl->rectf;
/* 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) {
first_lamp = 1;
for(go=R.lights.first; go; go= go->next) {
lar= go->lampren;
if(lar->type==LA_SUN && lar->sunsky)
{
/* if it's sky continue and don't apply atmosphere effect on it */
if(*zrect >= 9.9e10){
continue;
}
if(lar->sunsky->effect_type & LA_SUN_EFFECT_AP){
VECCOPY(tmp_rgb, rgbrect);
shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect);
if(first_lamp){
VECCOPY(rgb, tmp_rgb);
first_lamp = 0;
}
else{
rgb[0] = facm*rgb[0] + fac*tmp_rgb[0];
rgb[1] = facm*rgb[1] + fac*tmp_rgb[1];
rgb[2] = facm*rgb[2] + fac*tmp_rgb[2];
}
}
}
}
/* if at least for one sun lamp aerial perspective was applied*/
if(first_lamp==0)
VECCOPY(rgbrect, rgb);
}
}
}
static void shadeDA_tile(RenderPart *pa, RenderLayer *rl) static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
{ {
RenderResult *rr= pa->result; RenderResult *rr= pa->result;
@ -1122,6 +1205,10 @@ void zbufshadeDA_tile(RenderPart *pa)
if(R.r.mode & R_EDGE) if(R.r.mode & R_EDGE)
edge_enhance_add(pa, rl->rectf, edgerect); edge_enhance_add(pa, rl->rectf, edgerect);
/* sun/sky */
if(rl->layflag & SCE_LAY_SKY)
atm_tile(pa, rl);
if(rl->passflag & SCE_PASS_VECTOR) if(rl->passflag & SCE_PASS_VECTOR)
reset_sky_speed(pa, rl); reset_sky_speed(pa, rl);
@ -1282,6 +1369,10 @@ void zbufshade_tile(RenderPart *pa)
edge_enhance_add(pa, rl->rectf, edgerect); edge_enhance_add(pa, rl->rectf, edgerect);
} }
/* sun/sky */
if(rl->layflag & SCE_LAY_SKY)
atm_tile(pa, rl);
if(rl->passflag & SCE_PASS_VECTOR) if(rl->passflag & SCE_PASS_VECTOR)
reset_sky_speed(pa, rl); reset_sky_speed(pa, rl);

@ -0,0 +1,492 @@
/**
* ***** 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.
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "sunsky.h"
#include "math.h"
#include "BLI_arithb.h"
/**
* These macros are defined for vector operations
* */
/**
* compute v1 = v2 op v3
* v1, v2 and v3 are vectors contains 3 float
* */
#define vec3opv(v1, v2, op, v3) \
v1[0] = (v2[0] op v3[0]); \
v1[1] = (v2[1] op v3[1]);\
v1[2] = (v2[2] op v3[2]);
/**
* compute v1 = v2 op f1
* v1, v2 are vectors contains 3 float
* and f1 is a float
* */
#define vec3opf(v1, v2, op, f1)\
v1[0] = (v2[0] op (f1));\
v1[1] = (v2[1] op (f1));\
v1[2] = (v2[2] op (f1));
/**
* compute v1 = f1 op v2
* v1, v2 are vectors contains 3 float
* and f1 is a float
* */
#define fopvec3(v1, f1, op, v2)\
v1[0] = ((f1) op v2[0]);\
v1[1] = ((f1) op v2[1]);\
v1[2] = ((f1) op v2[2]);
/**
* ClipColor:
* clip a color to range [0,1];
* */
void ClipColor(float c[3])
{
if (c[0] > 1.0) c[0] = 1.0;
if (c[0] < 0.0) c[0] = 0.0;
if (c[1] > 1.0) c[1] = 1.0;
if (c[1] < 0.0) c[1] = 0.0;
if (c[2] > 1.0) c[2] = 1.0;
if (c[2] < 0.0) c[2] = 0.0;
}
/**
* AngleBetween:
* compute angle between to direction
* all angles are in radians
* */
static float AngleBetween(float thetav, float phiv, float theta, float phi)
{
float cospsi = sin(thetav) * sin(theta) * cos(phi - phiv) + cos(thetav) * cos(theta);
if (cospsi > 1.0)
return 0;
if (cospsi < -1.0)
return M_PI;
return acos(cospsi);
}
/**
* DirectionToThetaPhi:
* this function convert a direction to it's theta and phi value
* parameters:
* toSun: contains direction information
* theta, phi, are return values from this conversion
* */
static void DirectionToThetaPhi(float *toSun, float *theta, float *phi)
{
*theta = acos(toSun[2]);
if (fabs(*theta) < 1e-5)
*phi = 0;
else
*phi = atan2(toSun[1], toSun[0]);
}
/**
* PerezFunction:
* compute perez function value based on input paramters
* */
float PerezFunction(struct SunSky *sunsky, const float *lam, float theta, float gamma, float lvz)
{
float den, num;
den = ((1 + lam[0] * exp(lam[1])) *
(1 + lam[2] * exp(lam[3] * sunsky->theta) + lam[4] * cos(sunsky->theta) * cos(sunsky->theta)));
num = ((1 + lam[0] * exp(lam[1] / cos(theta))) *
(1 + lam[2] * exp(lam[3] * gamma) + lam[4] * cos(gamma) * cos(gamma)));
return(lvz * num / den);
}
/**
* InitSunSky:
* this function compute some sun,sky parameters according to input parameters and also initiate some other sun, sky parameters
* parameters:
* sunSky, is a structure that contains informtion about sun, sky and atmosphere, in this function, most of its values initiated
* turb, is atmosphere turbidity
* toSun, contains sun direction
* horizon_brighness, controls the brightness of the horizon colors
* spread, controls colors spreed at horizon
* sun_brightness, controls sun's brightness
* sun_size, controls sun's size
* back_scatter, controls back scatter light
* */
void InitSunSky(struct SunSky *sunsky, float turb, float *toSun, float horizon_brightness,
float spread,float sun_brightness, float sun_size, float back_scatter)
{
float theta2;
float theta3;
float T;
float T2;
float chi;
sunsky->turbidity = turb;
sunsky->horizon_brightness = horizon_brightness;
sunsky->spread = spread;
sunsky->sun_brightness = sun_brightness;
sunsky->sun_size = sun_size;
sunsky->backscattered_light = back_scatter;
sunsky->toSun[0] = toSun[0];
sunsky->toSun[1] = toSun[1];
sunsky->toSun[2] = toSun[2];
DirectionToThetaPhi(sunsky->toSun, &sunsky->theta, &sunsky->phi);
sunsky->sunSolidAngle = 0.25 * M_PI * 1.39 * 1.39 / (150 * 150); // = 6.7443e-05
theta2 = sunsky->theta*sunsky->theta;
theta3 = theta2 * sunsky->theta;
T = turb;
T2 = turb*turb;
chi = (4.0 / 9.0 - T / 120.0) * (M_PI - 2 * sunsky->theta);
sunsky->zenith_Y = (4.0453 * T - 4.9710) * tan(chi) - .2155 * T + 2.4192;
sunsky->zenith_Y *= 1000; // conversion from kcd/m^2 to cd/m^2
if (sunsky->zenith_Y<=0)
sunsky->zenith_Y = 1e-6;
sunsky->zenith_x =
( + 0.00165 * theta3 - 0.00374 * theta2 + 0.00208 * sunsky->theta + 0) * T2 +
( -0.02902 * theta3 + 0.06377 * theta2 - 0.03202 * sunsky->theta + 0.00394) * T +
( + 0.11693 * theta3 - 0.21196 * theta2 + 0.06052 * sunsky->theta + 0.25885);
sunsky->zenith_y =
( + 0.00275 * theta3 - 0.00610 * theta2 + 0.00316 * sunsky->theta + 0) * T2 +
( -0.04214 * theta3 + 0.08970 * theta2 - 0.04153 * sunsky->theta + 0.00515) * T +
( + 0.15346 * theta3 - 0.26756 * theta2 + 0.06669 * sunsky->theta + 0.26688);
sunsky->perez_Y[0] = 0.17872 * T - 1.46303;
sunsky->perez_Y[1] = -0.35540 * T + 0.42749;
sunsky->perez_Y[2] = -0.02266 * T + 5.32505;
sunsky->perez_Y[3] = 0.12064 * T - 2.57705;
sunsky->perez_Y[4] = -0.06696 * T + 0.37027;
sunsky->perez_x[0] = -0.01925 * T - 0.25922;
sunsky->perez_x[1] = -0.06651 * T + 0.00081;
sunsky->perez_x[2] = -0.00041 * T + 0.21247;
sunsky->perez_x[3] = -0.06409 * T - 0.89887;
sunsky->perez_x[4] = -0.00325 * T + 0.04517;
sunsky->perez_y[0] = -0.01669 * T - 0.26078;
sunsky->perez_y[1] = -0.09495 * T + 0.00921;
sunsky->perez_y[2] = -0.00792 * T + 0.21023;
sunsky->perez_y[3] = -0.04405 * T - 1.65369;
sunsky->perez_y[4] = -0.01092 * T + 0.05291;
/* suggested by glome in
* http://projects.blender.org/tracker/?func=detail&atid=127&aid=8063&group_id=9*/
sunsky->perez_Y[0] *= sunsky->horizon_brightness;
sunsky->perez_x[0] *= sunsky->horizon_brightness;
sunsky->perez_y[0] *= sunsky->horizon_brightness;
sunsky->perez_Y[1] *= sunsky->spread;
sunsky->perez_x[1] *= sunsky->spread;
sunsky->perez_y[1] *= sunsky->spread;
sunsky->perez_Y[2] *= sunsky->sun_brightness;
sunsky->perez_x[2] *= sunsky->sun_brightness;
sunsky->perez_y[2] *= sunsky->sun_brightness;
sunsky->perez_Y[3] *= sunsky->sun_size;
sunsky->perez_x[3] *= sunsky->sun_size;
sunsky->perez_y[3] *= sunsky->sun_size;
sunsky->perez_Y[4] *= sunsky->backscattered_light;
sunsky->perez_x[4] *= sunsky->backscattered_light;
sunsky->perez_y[4] *= sunsky->backscattered_light;
}
/**
* GetSkyXYZRadiance:
* this function compute sky radiance according to a view parameters `theta' and `phi'and sunSky values
* parameters:
* sunSky, sontains sun and sky parameters
* theta, is sun's theta
* phi, is sun's phi
* color_out, is computed color that shows sky radiance in XYZ color format
* */
void GetSkyXYZRadiance(struct SunSky* sunsky, float theta, float phi, float color_out[3])
{
float gamma;
float x,y,Y,X,Z;
float hfade=1, nfade=1;
if (theta>(0.5*M_PI)) {
hfade = 1.0-(theta*M_1_PI-0.5)*2.0;
hfade = hfade*hfade*(3.0-2.0*hfade);
theta = 0.5*M_PI;
}
if (sunsky->theta>(0.5*M_PI)) {
if (theta<=0.5*M_PI) {
nfade = 1.0-(0.5-theta*M_1_PI)*2.0;
nfade *= 1.0-(sunsky->theta*M_1_PI-0.5)*2.0;
nfade = nfade*nfade*(3.0-2.0*nfade);
}
}
gamma = AngleBetween(theta, phi, sunsky->theta, sunsky->phi);
// Compute xyY values
x = PerezFunction(sunsky, sunsky->perez_x, theta, gamma, sunsky->zenith_x);
y = PerezFunction(sunsky, sunsky->perez_y, theta, gamma, sunsky->zenith_y);
Y = nfade * hfade * PerezFunction(sunsky, sunsky->perez_Y, theta, gamma, sunsky->zenith_Y);
X = (x / y) * Y;
Z = ((1 - x - y) / y) * Y;
color_out[0] = X;
color_out[1] = Y;
color_out[2] = Z;
}
/**
* GetSkyXYZRadiancef:
* this function compute sky radiance according to a view direction `varg' and sunSky values
* parameters:
* sunSky, sontains sun and sky parameters
* varg, shows direction
* color_out, is computed color that shows sky radiance in XYZ color format
* */
void GetSkyXYZRadiancef(struct SunSky* sunsky, const float varg[3], float color_out[3])
{
float theta, phi;
float v[3];
VecCopyf(v, (float*)varg);
Normalize(v);
if (v[2] < 0.001){
v[2] = 0.001;
Normalize(v);
}
DirectionToThetaPhi(v, &theta, &phi);
GetSkyXYZRadiance(sunsky, theta, phi, color_out);
}
/**
* ComputeAttenuatedSunlight:
* this function compute attenuated sun light based on sun's theta and atmosphere turbidity
* parameters:
* theta, is sun's theta
* turbidity: is atmosphere turbidity
* fTau: contains computed attenuated sun light
* */
void ComputeAttenuatedSunlight(float theta, int turbidity, float fTau[3])
{
float fBeta ;
float fTauR, fTauA;
float m ;
float fAlpha;
int i;
float fLambda[3];
fLambda[0] = 0.65f;
fLambda[1] = 0.57f;
fLambda[2] = 0.475f;
fAlpha = 1.3f;
fBeta = 0.04608365822050f * turbidity - 0.04586025928522f;
m = 1.0/(cos(theta) + 0.15f*pow(93.885f-theta/M_PI*180.0f,-1.253f));
for(i = 0; i < 3; i++)
{
// Rayleigh Scattering
fTauR = exp( -m * 0.008735f * pow(fLambda[i], (float)(-4.08f)));
// Aerosal (water + dust) attenuation
fTauA = exp(-m * fBeta * pow(fLambda[i], -fAlpha));
fTau[i] = fTauR * fTauA;
}
}
/**
* InitAtmosphere:
* this function intiate sunSky structure with user input parameters.
* parameters:
* sunSky, contains information about sun, and in this function some atmosphere parameters will initiated
* sun_intens, shows sun intensity value
* mief, Mie scattering factor this factor currently call with 1.0
* rayf, Rayleigh scattering factor, this factor currently call with 1.0
* inscattf, inscatter light factor that range from 0.0 to 1.0, 0.0 means no inscatter light and 1.0 means full inscatter light
* extincf, extinction light factor that range from 0.0 to 1.0, 0.0 means no extinction and 1.0 means full extinction
* disf, is distance factor, multiplyed to pixle's z value to compute each pixle's distance to camera,
* */
void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float rayf,
float inscattf, float extincf, float disf)
{
const float pi = 3.14159265358f;
const float n = 1.003f; // refractive index
const float N = 2.545e25;
const float pn = 0.035f;
const float T = 2.0f;
float fTemp, fTemp2, fTemp3, fBeta, fBetaDash;
float c = (6.544*T - 6.51)*1e-17;
float K[3] = {0.685f, 0.679f, 0.670f};
float vBetaMieTemp[3];
float fLambda[3],fLambda2[3], fLambda4[3];
float vLambda2[3];
float vLambda4[3];
int i;
sunSky->atm_SunIntensity = sun_intens;
sunSky->atm_BetaMieMultiplier = mief;
sunSky->atm_BetaRayMultiplier = rayf;
sunSky->atm_InscatteringMultiplier = inscattf;
sunSky->atm_ExtinctionMultiplier = extincf;
sunSky->atm_DistanceMultiplier = disf;
sunSky->atm_HGg=0.8;
fLambda[0] = 1/650e-9f;
fLambda[1] = 1/570e-9f;
fLambda[2] = 1/475e-9f;
for (i=0; i < 3; i++)
{
fLambda2[i] = fLambda[i]*fLambda[i];
fLambda4[i] = fLambda2[i]*fLambda2[i];
}
vLambda2[0] = fLambda2[0];
vLambda2[1] = fLambda2[1];
vLambda2[2] = fLambda2[2];
vLambda4[0] = fLambda4[0];
vLambda4[1] = fLambda4[1];
vLambda4[2] = fLambda4[2];
// Rayleigh scattering constants.
fTemp = pi*pi*(n*n-1)*(n*n-1)*(6+3*pn)/(6-7*pn)/N;
fBeta = 8*fTemp*pi/3;
vec3opf(sunSky->atm_BetaRay, vLambda4, *, fBeta);
fBetaDash = fTemp/2;
vec3opf(sunSky->atm_BetaDashRay, vLambda4,*, fBetaDash);
// Mie scattering constants.
fTemp2 = 0.434*c*(2*pi)*(2*pi)*0.5f;
vec3opf(sunSky->atm_BetaDashMie, vLambda2, *, fTemp2);
fTemp3 = 0.434f*c*pi*(2*pi)*(2*pi);
vec3opv(vBetaMieTemp, K, *, fLambda);
vec3opf(sunSky->atm_BetaMie, vBetaMieTemp,*, fTemp3);
}
/**
* AtmospherePixleShader:
* this function apply atmosphere effect on a pixle color `rgb' at distance `s'
* parameters:
* sunSky, contains information about sun parameters and user values
* view, is camera view vector
* s, is distance
* rgb, contains rendered color value for a pixle
* */
void AtmospherePixleShader( struct SunSky* sunSky, float view[3], float s, float rgb[3])
{
float costheta;
float Phase_1;
float Phase_2;
float sunColor[3];
float E[3];
float E1[3];
float I[3];
float fTemp;
float vTemp1[3], vTemp2[3];
float sunDirection[3];
s *= sunSky->atm_DistanceMultiplier;
sunDirection[0] = sunSky->toSun[0];
sunDirection[1] = sunSky->toSun[1];
sunDirection[2] = sunSky->toSun[2];
costheta = Inpf(view, sunDirection); // cos(theta)
Phase_1 = 1 + (costheta * costheta); // Phase_1
vec3opf(sunSky->atm_BetaRay, sunSky->atm_BetaRay, *, sunSky->atm_BetaRayMultiplier);
vec3opf(sunSky->atm_BetaMie, sunSky->atm_BetaMie, *, sunSky->atm_BetaMieMultiplier);
vec3opv(sunSky->atm_BetaRM, sunSky->atm_BetaRay, +, sunSky->atm_BetaMie);
//e^(-(beta_1 + beta_2) * s) = E1
vec3opf(E1, sunSky->atm_BetaRM, *, -s/log(2));
E1[0] = exp(E1[0]);
E1[1] = exp(E1[1]);
E1[2] = exp(E1[2]);
VecCopyf(E, E1);
//Phase2(theta) = (1-g^2)/(1+g-2g*cos(theta))^(3/2)
fTemp = 1 + sunSky->atm_HGg - 2 * sunSky->atm_HGg * costheta;
fTemp = fTemp * sqrt(fTemp);
Phase_2 = (1 - sunSky->atm_HGg * sunSky->atm_HGg)/fTemp;
vec3opf(vTemp1, sunSky->atm_BetaDashRay, *, Phase_1);
vec3opf(vTemp2, sunSky->atm_BetaDashMie, *, Phase_2);
vec3opv(vTemp1, vTemp1, +, vTemp2);
fopvec3(vTemp2, 1.0, -, E1);
vec3opv(vTemp1, vTemp1, *, vTemp2);
fopvec3(vTemp2, 1.0, / , sunSky->atm_BetaRM);
vec3opv(I, vTemp1, *, vTemp2);
vec3opf(I, I, *, sunSky->atm_InscatteringMultiplier);
vec3opf(E, E, *, sunSky->atm_ExtinctionMultiplier);
//scale to color sun
ComputeAttenuatedSunlight(sunSky->theta, sunSky->turbidity, sunColor);
vec3opv(E, E, *, sunColor);
vec3opf(I, I, *, sunSky->atm_SunIntensity);
vec3opv(rgb, rgb, *, E);
vec3opv(rgb, rgb, +, I);
}
#undef vec3opv
#undef vec3opf
#undef fopvec3
/* EOF */

@ -3545,7 +3545,7 @@ void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
for(rpass= rl->passes.first; rpass; rpass= rpass->next) { for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
float *col= NULL; float *col= NULL;
int pixsize= 0; int pixsize= 3;
switch(rpass->passtype) { switch(rpass->passtype) {
case SCE_PASS_RGBA: case SCE_PASS_RGBA:
@ -3580,6 +3580,10 @@ void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
col= &shr->mist; col= &shr->mist;
pixsize= 1; pixsize= 1;
break; break;
case SCE_PASS_Z:
col= &shr->z;
pixsize= 1;
break;
case SCE_PASS_VECTOR: case SCE_PASS_VECTOR:
{ {
@ -3612,14 +3616,18 @@ void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
for(samp= 1; samp<R.osa; samp++, fp+=delta) { for(samp= 1; samp<R.osa; samp++, fp+=delta) {
col[0]+= fp[0]; col[0]+= fp[0];
col[1]+= fp[1]; if(pixsize>1) {
col[2]+= fp[2]; col[1]+= fp[1];
if(pixsize) col[3]+= fp[3]; col[2]+= fp[2];
if(pixsize==4) col[3]+= fp[3];
}
} }
col[0]*= weight; col[0]*= weight;
col[1]*= weight; if(pixsize>1) {
col[2]*= weight; col[1]*= weight;
if(pixsize) col[3]*= weight; col[2]*= weight;
if(pixsize==4) col[3]*= weight;
}
} }
} }
@ -3973,7 +3981,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
/* general shader info, passes */ /* general shader info, passes */
shade_sample_initialize(&ssamp, pa, rl); 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; addzbuf= rl->passflag & SCE_PASS_Z;
if(R.osa) if(R.osa)

@ -515,7 +515,6 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
} else { } else {
editmesh_deselect_by_material(G.obedit->actcol-1); editmesh_deselect_by_material(G.obedit->actcol-1);
} }
allqueue(REDRAWVIEW3D, 0);
} }
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
nu= editNurb.first; nu= editNurb.first;
@ -555,8 +554,9 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
nu= nu->next; nu= nu->next;
} }
BIF_undo_push("Select material index"); BIF_undo_push("Select material index");
allqueue(REDRAWVIEW3D, 0);
} }
allqueue(REDRAWIMAGE, 0);
allqueue(REDRAWVIEW3D, 0);
} }
countall(); countall();
break; break;
@ -5231,32 +5231,6 @@ static void verify_posegroup_groupname(void *arg1, void *arg2)
BLI_uniquename(&pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32); 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) static void editing_panel_links(Object *ob)
{ {
uiBlock *block; uiBlock *block;
@ -5416,32 +5390,14 @@ static void editing_panel_links(Object *ob)
/* color set for 'active' group */ /* color set for 'active' group */
if (pose->active_group && grp) { if (pose->active_group && grp) {
uiBlockBeginAlign(block); 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"); 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); MEM_freeN(menustr);
/* show color-selection/preview */ /* show color-selection/preview */
if (grp->customCol) { if (grp->customCol) {
if (grp->customCol > 0) { /* do color copying/init (to stay up to date) */
/* copy theme colors on-to group's custom color in case user tries to edit color */ actionbone_group_copycolors(grp, 1);
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
}
}
/* color changing */ /* 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"); uiDefButC(block, COL, B_POSEGRP_MCUSTOM, "", xco, 65, 30, 19, grp->cs.solid, 0, 0, 0, 0, "Color to use for surface of bones");
@ -6297,7 +6253,7 @@ static void editing_panel_mesh_texface(void)
uiDefButBitS(block, TOG, TF_TILES, B_REDR_3D_IMA, "Tiles", 660,160,60,19, &tf->mode, 0, 0, 0, 0, "Use tilemode for face"); uiDefButBitS(block, TOG, TF_TILES, B_REDR_3D_IMA, "Tiles", 660,160,60,19, &tf->mode, 0, 0, 0, 0, "Use tilemode for face");
uiDefButBitS(block, TOG, TF_LIGHT, REDRAWVIEW3D, "Light", 720,160,60,19, &tf->mode, 0, 0, 0, 0, "Use light for face"); uiDefButBitS(block, TOG, TF_LIGHT, REDRAWVIEW3D, "Light", 720,160,60,19, &tf->mode, 0, 0, 0, 0, "Use light for face");
uiDefButBitS(block, TOG, TF_INVISIBLE, REDRAWVIEW3D, "Invisible",780,160,60,19, &tf->mode, 0, 0, 0, 0, "Make face invisible"); uiDefButBitS(block, TOG, TF_INVISIBLE, REDRAWVIEW3D, "Invisible",780,160,60,19, &tf->mode, 0, 0, 0, 0, "Make face invisible");
uiDefButBitS(block, TOG, TF_DYNAMIC, REDRAWVIEW3D, "Collision", 840,160,60,19, &tf->mode, 0, 0, 0, 0, "Use face for collision detection"); uiDefButBitS(block, TOG, TF_DYNAMIC, REDRAWVIEW3D, "Collision", 840,160,60,19, &tf->mode, 0, 0, 0, 0, "Use face for collision and ray-sensor detection");
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
uiDefButBitS(block, TOG, TF_SHAREDCOL, REDRAWVIEW3D, "Shared", 600,135,60,19, &tf->mode, 0, 0, 0, 0, "Blend vertex colors across face when vertices are shared"); uiDefButBitS(block, TOG, TF_SHAREDCOL, REDRAWVIEW3D, "Shared", 600,135,60,19, &tf->mode, 0, 0, 0, 0, "Blend vertex colors across face when vertices are shared");

@ -387,7 +387,6 @@ void do_logic_buts(unsigned short event)
bSensor *sens; bSensor *sens;
bController *cont; bController *cont;
bActuator *act; bActuator *act;
Base *base;
Object *ob; Object *ob;
int didit, bit; int didit, bit;
@ -443,16 +442,14 @@ void do_logic_buts(unsigned short event)
break; break;
case B_ADD_SENS: case B_ADD_SENS:
base= FIRSTBASE; for(ob=G.main->object.first; ob; ob=ob->id.next) {
while(base) { if(ob->scaflag & OB_ADDSENS) {
if(base->object->scaflag & OB_ADDSENS) { ob->scaflag &= ~OB_ADDSENS;
base->object->scaflag &= ~OB_ADDSENS;
sens= new_sensor(SENS_ALWAYS); sens= new_sensor(SENS_ALWAYS);
BLI_addtail(&(base->object->sensors), sens); BLI_addtail(&(ob->sensors), sens);
make_unique_prop_names(sens->name); make_unique_prop_names(sens->name);
base->object->scaflag |= OB_SHOWSENS; ob->scaflag |= OB_SHOWSENS;
} }
base= base->next;
} }
BIF_undo_push("Add sensor"); BIF_undo_push("Add sensor");
@ -460,9 +457,8 @@ void do_logic_buts(unsigned short event)
break; break;
case B_CHANGE_SENS: case B_CHANGE_SENS:
base= FIRSTBASE; for(ob=G.main->object.first; ob; ob=ob->id.next) {
while(base) { sens= ob->sensors.first;
sens= base->object->sensors.first;
while(sens) { while(sens) {
if(sens->type != sens->otype) { if(sens->type != sens->otype) {
init_sensor(sens); init_sensor(sens);
@ -471,43 +467,39 @@ void do_logic_buts(unsigned short event)
} }
sens= sens->next; sens= sens->next;
} }
base= base->next;
} }
allqueue(REDRAWBUTSLOGIC, 0); allqueue(REDRAWBUTSLOGIC, 0);
break; break;
case B_DEL_SENS: case B_DEL_SENS:
base= FIRSTBASE; for(ob=G.main->object.first; ob; ob=ob->id.next) {
while(base) { sens= ob->sensors.first;
sens= base->object->sensors.first;
while(sens) { while(sens) {
if(sens->flag & SENS_DEL) { if(sens->flag & SENS_DEL) {
BLI_remlink(&(base->object->sensors), sens); BLI_remlink(&(ob->sensors), sens);
free_sensor(sens); free_sensor(sens);
break; break;
} }
sens= sens->next; sens= sens->next;
} }
base= base->next;
} }
BIF_undo_push("Delete sensor"); BIF_undo_push("Delete sensor");
allqueue(REDRAWBUTSLOGIC, 0); allqueue(REDRAWBUTSLOGIC, 0);
break; break;
case B_ADD_CONT: case B_ADD_CONT:
base= FIRSTBASE; for(ob=G.main->object.first; ob; ob=ob->id.next) {
while(base) { if(ob->scaflag & OB_ADDCONT) {
if(base->object->scaflag & OB_ADDCONT) { ob->scaflag &= ~OB_ADDCONT;
base->object->scaflag &= ~OB_ADDCONT;
cont= new_controller(CONT_LOGIC_AND); cont= new_controller(CONT_LOGIC_AND);
make_unique_prop_names(cont->name); make_unique_prop_names(cont->name);
base->object->scaflag |= OB_SHOWCONT; ob->scaflag |= OB_SHOWCONT;
BLI_addtail(&(base->object->controllers), cont); BLI_addtail(&(ob->controllers), cont);
/* set the controller state mask from the current object state. /* set the controller state mask from the current object state.
A controller is always in a single state, so select the lowest bit set A controller is always in a single state, so select the lowest bit set
from the object state */ from the object state */
for (bit=0; bit<32; bit++) { for (bit=0; bit<32; bit++) {
if (base->object->state & (1<<bit)) if (ob->state & (1<<bit))
break; break;
} }
cont->state_mask = (1<<bit); cont->state_mask = (1<<bit);
@ -516,42 +508,36 @@ void do_logic_buts(unsigned short event)
cont->state_mask = 1; cont->state_mask = 1;
} }
} }
base= base->next;
} }
BIF_undo_push("Add controller"); BIF_undo_push("Add controller");
allqueue(REDRAWBUTSLOGIC, 0); allqueue(REDRAWBUTSLOGIC, 0);
break; break;
case B_SET_STATE_BIT: case B_SET_STATE_BIT:
base= FIRSTBASE; for(ob=G.main->object.first; ob; ob=ob->id.next) {
while(base) { if(ob->scaflag & OB_SETSTBIT) {
if(base->object->scaflag & OB_SETSTBIT) { ob->scaflag &= ~OB_SETSTBIT;
base->object->scaflag &= ~OB_SETSTBIT; ob->state = 0x3FFFFFFF;
base->object->state = 0x3FFFFFFF;
} }
base= base->next;
} }
allqueue(REDRAWBUTSLOGIC, 0); allqueue(REDRAWBUTSLOGIC, 0);
break; break;
case B_INIT_STATE_BIT: case B_INIT_STATE_BIT:
base= FIRSTBASE; for(ob=G.main->object.first; ob; ob=ob->id.next) {
while(base) { if(ob->scaflag & OB_INITSTBIT) {
if(base->object->scaflag & OB_INITSTBIT) { ob->scaflag &= ~OB_INITSTBIT;
base->object->scaflag &= ~OB_INITSTBIT; ob->state = ob->init_state;
base->object->state = base->object->init_state; if (!ob->state)
if (!base->object->state) ob->state = 1;
base->object->state = 1;
} }
base= base->next;
} }
allqueue(REDRAWBUTSLOGIC, 0); allqueue(REDRAWBUTSLOGIC, 0);
break; break;
case B_CHANGE_CONT: case B_CHANGE_CONT:
base= FIRSTBASE; for(ob=G.main->object.first; ob; ob=ob->id.next) {
while(base) { cont= ob->controllers.first;
cont= base->object->controllers.first;
while(cont) { while(cont) {
if(cont->type != cont->otype) { if(cont->type != cont->otype) {
init_controller(cont); init_controller(cont);
@ -560,51 +546,45 @@ void do_logic_buts(unsigned short event)
} }
cont= cont->next; cont= cont->next;
} }
base= base->next;
} }
allqueue(REDRAWBUTSLOGIC, 0); allqueue(REDRAWBUTSLOGIC, 0);
break; break;
case B_DEL_CONT: case B_DEL_CONT:
base= FIRSTBASE; for(ob=G.main->object.first; ob; ob=ob->id.next) {
while(base) { cont= ob->controllers.first;
cont= base->object->controllers.first;
while(cont) { while(cont) {
if(cont->flag & CONT_DEL) { if(cont->flag & CONT_DEL) {
BLI_remlink(&(base->object->controllers), cont); BLI_remlink(&(ob->controllers), cont);
unlink_controller(cont); unlink_controller(cont);
free_controller(cont); free_controller(cont);
break; break;
} }
cont= cont->next; cont= cont->next;
} }
base= base->next;
} }
BIF_undo_push("Delete controller"); BIF_undo_push("Delete controller");
allqueue(REDRAWBUTSLOGIC, 0); allqueue(REDRAWBUTSLOGIC, 0);
break; break;
case B_ADD_ACT: case B_ADD_ACT:
base= FIRSTBASE; for(ob=G.main->object.first; ob; ob=ob->id.next) {
while(base) { if(ob->scaflag & OB_ADDACT) {
if(base->object->scaflag & OB_ADDACT) { ob->scaflag &= ~OB_ADDACT;
base->object->scaflag &= ~OB_ADDACT;
act= new_actuator(ACT_OBJECT); act= new_actuator(ACT_OBJECT);
make_unique_prop_names(act->name); make_unique_prop_names(act->name);
BLI_addtail(&(base->object->actuators), act); BLI_addtail(&(ob->actuators), act);
base->object->scaflag |= OB_SHOWACT; ob->scaflag |= OB_SHOWACT;
} }
base= base->next;
} }
BIF_undo_push("Add actuator"); BIF_undo_push("Add actuator");
allqueue(REDRAWBUTSLOGIC, 0); allqueue(REDRAWBUTSLOGIC, 0);
break; break;
case B_CHANGE_ACT: case B_CHANGE_ACT:
base= FIRSTBASE; for(ob=G.main->object.first; ob; ob=ob->id.next) {
while(base) { act= ob->actuators.first;
act= base->object->actuators.first;
while(act) { while(act) {
if(act->type != act->otype) { if(act->type != act->otype) {
init_actuator(act); init_actuator(act);
@ -613,25 +593,22 @@ void do_logic_buts(unsigned short event)
} }
act= act->next; act= act->next;
} }
base= base->next;
} }
allqueue(REDRAWBUTSLOGIC, 0); allqueue(REDRAWBUTSLOGIC, 0);
break; break;
case B_DEL_ACT: case B_DEL_ACT:
base= FIRSTBASE; for(ob=G.main->object.first; ob; ob=ob->id.next) {
while(base) { act= ob->actuators.first;
act= base->object->actuators.first;
while(act) { while(act) {
if(act->flag & ACT_DEL) { if(act->flag & ACT_DEL) {
BLI_remlink(&(base->object->actuators), act); BLI_remlink(&(ob->actuators), act);
unlink_actuator(act); unlink_actuator(act);
free_actuator(act); free_actuator(act);
break; break;
} }
act= act->next; act= act->next;
} }
base= base->next;
} }
BIF_undo_push("Delete actuator"); BIF_undo_push("Delete actuator");
allqueue(REDRAWBUTSLOGIC, 0); allqueue(REDRAWBUTSLOGIC, 0);
@ -640,10 +617,8 @@ void do_logic_buts(unsigned short event)
case B_SOUNDACT_BROWSE: case B_SOUNDACT_BROWSE:
/* since we don't know which... */ /* since we don't know which... */
didit= 0; didit= 0;
base= FIRSTBASE; for(ob=G.main->object.first; ob; ob=ob->id.next) {
while(base) act= ob->actuators.first;
{
act= base->object->actuators.first;
while(act) while(act)
{ {
if(act->type==ACT_SOUND) if(act->type==ACT_SOUND)
@ -684,7 +659,6 @@ void do_logic_buts(unsigned short event)
} }
if(didit) if(didit)
break; break;
base= base->next;
} }
allqueue(REDRAWBUTSLOGIC, 0); allqueue(REDRAWBUTSLOGIC, 0);
allqueue(REDRAWSOUND, 0); allqueue(REDRAWSOUND, 0);
@ -707,6 +681,8 @@ static char *sensor_name(int type)
return "Keyboard"; return "Keyboard";
case SENS_PROPERTY: case SENS_PROPERTY:
return "Property"; return "Property";
case SENS_ACTUATOR:
return "Actuator";
case SENS_MOUSE: case SENS_MOUSE:
return "Mouse"; return "Mouse";
case SENS_COLLISION: case SENS_COLLISION:
@ -730,7 +706,7 @@ static char *sensor_pup(void)
/* the number needs to match defines in game.h */ /* the number needs to match defines in game.h */
return "Sensors %t|Always %x0|Keyboard %x3|Mouse %x5|" return "Sensors %t|Always %x0|Keyboard %x3|Mouse %x5|"
"Touch %x1|Collision %x6|Near %x2|Radar %x7|" "Touch %x1|Collision %x6|Near %x2|Radar %x7|"
"Property %x4|Random %x8|Ray %x9|Message %x10|Joystick %x11"; "Property %x4|Random %x8|Ray %x9|Message %x10|Joystick %x11|Actuator %x12";
} }
static char *controller_name(int type) static char *controller_name(int type)
@ -740,6 +716,14 @@ static char *controller_name(int type)
return "AND"; return "AND";
case CONT_LOGIC_OR: case CONT_LOGIC_OR:
return "OR"; return "OR";
case CONT_LOGIC_NAND:
return "NAND";
case CONT_LOGIC_NOR:
return "NOR";
case CONT_LOGIC_XOR:
return "XOR";
case CONT_LOGIC_XNOR:
return "XNOR";
case CONT_EXPRESSION: case CONT_EXPRESSION:
return "Expression"; return "Expression";
case CONT_PYTHON: case CONT_PYTHON:
@ -750,7 +734,7 @@ static char *controller_name(int type)
static char *controller_pup(void) static char *controller_pup(void)
{ {
return "Controllers %t|AND %x0|OR %x1|Expression %x2|Python %x3"; return "Controllers %t|AND %x0|OR %x1|XOR %x6|NAND %x4|NOR %x5|XNOR %x7|Expression %x2|Python %x3";
} }
static char *actuator_name(int type) static char *actuator_name(int type)
@ -1021,6 +1005,7 @@ static int get_col_sensor(int type)
case SENS_NEAR: return TH_BUT_SETTING1; case SENS_NEAR: return TH_BUT_SETTING1;
case SENS_KEYBOARD: return TH_BUT_SETTING2; case SENS_KEYBOARD: return TH_BUT_SETTING2;
case SENS_PROPERTY: return TH_BUT_NUM; case SENS_PROPERTY: return TH_BUT_NUM;
case SENS_ACTUATOR: return TH_BUT_NUM;
case SENS_MOUSE: return TH_BUT_TEXTFIELD; case SENS_MOUSE: return TH_BUT_TEXTFIELD;
case SENS_RADAR: return TH_BUT_POPUP; case SENS_RADAR: return TH_BUT_POPUP;
case SENS_RANDOM: return TH_BUT_NEUTRAL; case SENS_RANDOM: return TH_BUT_NEUTRAL;
@ -1066,6 +1051,10 @@ static void draw_default_sensor_header(bSensor *sens,
(short)(x + 10 + 0.85 * (w-20)), (short)(y - 19), (short)(0.15 * (w-20)), 19, (short)(x + 10 + 0.85 * (w-20)), (short)(y - 19), (short)(0.15 * (w-20)), 19,
&sens->invert, 0.0, 0.0, 0, 0, &sens->invert, 0.0, 0.0, 0, 0,
"Invert the level (output) of this sensor"); "Invert the level (output) of this sensor");
uiDefButS(block, TOG, 1, "Lvl",
(short)(x + 10 + 0.70 * (w-20)), (short)(y - 19), (short)(0.15 * (w-20)), 19,
&sens->level, 0.0, 0.0, 0, 0,
"Level detector versus edge detector (only applicable in case of logic state transition)");
} }
static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short yco, short width,char* objectname) static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short yco, short width,char* objectname)
@ -1081,6 +1070,7 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
bRaySensor *raySens = NULL; bRaySensor *raySens = NULL;
bMessageSensor *mes = NULL; bMessageSensor *mes = NULL;
bJoystickSensor *joy = NULL; bJoystickSensor *joy = NULL;
bActuatorSensor *as = NULL;
short ysize; short ysize;
char *str; char *str;
@ -1291,6 +1281,22 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
yco-= ysize; yco-= ysize;
break; break;
} }
case SENS_ACTUATOR:
{
ysize= 48;
glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize,
(float)xco+width, (float)yco, 1);
draw_default_sensor_header(sens, block, xco, yco, width);
as= sens->data;
uiDefBut(block, TEX, 1, "Act: ", xco+30,yco-44,width-60, 19,
as->name, 0, 31, 0, 0, "Actuator name, actuator active state modifications will be detected");
yco-= ysize;
break;
}
case SENS_MOUSE: case SENS_MOUSE:
{ {
ms= sens->data; ms= sens->data;
@ -1551,6 +1557,48 @@ static void set_col_actuator(int item, int medium)
} }
static void change_object_actuator(void *act, void *arg)
{
bObjectActuator *oa = act;
if (oa->type != oa->otype) {
switch (oa->type) {
case ACT_OBJECT_NORMAL:
memset(oa, 0, sizeof(bObjectActuator));
oa->flag = ACT_FORCE_LOCAL|ACT_TORQUE_LOCAL|ACT_DLOC_LOCAL|ACT_DROT_LOCAL;
oa->type = ACT_OBJECT_NORMAL;
break;
case ACT_OBJECT_SERVO:
memset(oa, 0, sizeof(bObjectActuator));
oa->flag = ACT_LIN_VEL_LOCAL;
oa->type = ACT_OBJECT_SERVO;
oa->forcerot[0] = 30.0f;
oa->forcerot[1] = 0.5f;
oa->forcerot[2] = 0.0f;
break;
}
}
}
static void change_ipo_actuator(void *arg1_but, void *arg2_ia)
{
bIpoActuator *ia = arg2_ia;
uiBut *but = arg1_but;
if (but->retval & ACT_IPOFORCE)
ia->flag &= ~ACT_IPOADD;
else if (but->retval & ACT_IPOADD)
ia->flag &= ~ACT_IPOFORCE;
but->retval = B_REDR;
}
void update_object_actuator_PID(void *act, void *arg)
{
bObjectActuator *oa = act;
oa->forcerot[0] = 60.0f*oa->forcerot[1];
}
char *get_state_name(Object *ob, short bit) char *get_state_name(Object *ob, short bit)
{ {
bController *cont; bController *cont;
@ -1590,8 +1638,9 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
float *fp; float *fp;
short ysize = 0, wval; short ysize = 0, wval;
char *str, name[32]; char *str;
int myline, stbit; int myline, stbit;
uiBut *but;
/* yco is at the top of the rect, draw downwards */ /* yco is at the top of the rect, draw downwards */
uiBlockSetEmboss(block, UI_EMBOSSM); uiBlockSetEmboss(block, UI_EMBOSSM);
@ -1601,53 +1650,100 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
{ {
case ACT_OBJECT: case ACT_OBJECT:
{ {
ysize= 129;
glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
oa = act->data; oa = act->data;
wval = (width-100)/3; wval = (width-100)/3;
if (oa->type == ACT_OBJECT_NORMAL)
uiDefBut(block, LABEL, 0, "Force", xco, yco-22, 55, 19, NULL, 0, 0, 0, 0, "Sets the force"); {
uiDefButF(block, NUM, 0, "", xco+45, yco-22, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, ""); ysize= 175;
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-22, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-22, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, ""); glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
uiDefBut(block, LABEL, 0, "Torque", xco, yco-41, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
uiDefButF(block, NUM, 0, "", xco+45, yco-41, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, ""); uiDefBut(block, LABEL, 0, "Force", xco, yco-45, 55, 19, NULL, 0, 0, 0, 0, "Sets the force");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-41, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45, yco-45, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-41, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+wval, yco-45, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-45, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "dLoc", xco, yco-64, 45, 19, NULL, 0, 0, 0, 0, "Sets the dLoc");
uiDefButF(block, NUM, 0, "", xco+45, yco-64, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, ""); uiDefBut(block, LABEL, 0, "Torque", xco, yco-64, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-64, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45, yco-64, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-64, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+wval, yco-64, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-64, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "dRot", xco, yco-83, 45, 19, NULL, 0, 0, 0, 0, "Sets the dRot");
uiDefButF(block, NUM, 0, "", xco+45, yco-83, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, ""); uiDefBut(block, LABEL, 0, "dLoc", xco, yco-87, 45, 19, NULL, 0, 0, 0, 0, "Sets the dLoc");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-83, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45, yco-87, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-83, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+wval, yco-87, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-87, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "linV", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity");
uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, ""); uiDefBut(block, LABEL, 0, "dRot", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Sets the dRot");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "angV", xco, yco-125, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity");
uiDefButF(block, NUM, 0, "", xco+45, yco-125, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, ""); uiDefBut(block, LABEL, 0, "linV", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-125, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45, yco-129, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-125, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
uiDefButBitI(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-22, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitI(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-41, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); uiDefBut(block, LABEL, 0, "angV", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity");
uiDefButBitI(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); uiDefButF(block, NUM, 0, "", xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, "");
uiDefButBitI(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-83, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); uiDefButF(block, NUM, 0, "", xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, "");
uiDefButBitI(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, "");
uiDefButBitI(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-125, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefBut(block, LABEL, 0, "damp", xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity");
uiDefButBitI(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-106, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV"); uiDefButS(block, NUM, 0, "", xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, "");
uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-87, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV");
} else if (oa->type == ACT_OBJECT_SERVO)
{
ysize= 172;
glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
uiDefBut(block, LABEL, 0, "linV", xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, "Sets the target linear velocity, it will be achieve by automatic application of force. Null velocity is a valid target");
uiDefButF(block, NUM, 0, "", xco+45, yco-45, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-45, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-45, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Velocity is defined in local coordinates");
uiDefBut(block, LABEL, 0, "Limit", xco, yco-68, 45, 19, NULL, 0, 0, 0, 0, "Select if the force need to be limited along certain axis (local or global depending on LinV Local flag)");
uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_X, B_REDR, "X", xco+45, yco-68, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the X axis");
uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Y, B_REDR, "Y", xco+45+wval, yco-68, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Y axis");
uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Z, B_REDR, "Z", xco+45+2*wval, yco-68, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Z axis");
uiDefBut(block, LABEL, 0, "Max", xco, yco-87, 45, 19, NULL, 0, 0, 0, 0, "Set the upper limit for force");
uiDefBut(block, LABEL, 0, "Min", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Set the lower limit for force");
if (oa->flag & ACT_SERVO_LIMIT_X) {
uiDefButF(block, NUM, 0, "", xco+45, yco-87, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
}
if (oa->flag & ACT_SERVO_LIMIT_Y) {
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-87, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
}
if (oa->flag & ACT_SERVO_LIMIT_Z) {
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-87, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
}
uiDefBut(block, LABEL, 0, "Servo", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Coefficients of the PID servo controller");
uiDefButF(block, NUMSLI, B_REDR, "P: ", xco+45, yco-129, wval*3, 19, oa->forcerot, 0.00, 200.0, 100, 0, "Proportional coefficient, typical value is 60x Integral coefficient");
uiDefBut(block, LABEL, 0, "Slow", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Low value of I coefficient correspond to slow response");
but = uiDefButF(block, NUMSLI, B_REDR, " I : ", xco+45, yco-148, wval*3, 19, oa->forcerot+1, 0.0, 3.0, 1, 0, "Integral coefficient, low value (0.01) for slow response, high value (0.5) for fast response");
uiButSetFunc(but, update_object_actuator_PID, oa, NULL);
uiDefBut(block, LABEL, 0, "Fast", xco+45+3*wval, yco-148, 45, 19, NULL, 0, 0, 0, 0, "High value of I coefficient correspond to fast response");
uiDefButF(block, NUMSLI, B_REDR, "D: ", xco+45, yco-167, wval*3, 19, oa->forcerot+2, -100.0, 100.0, 100, 0, "Derivate coefficient, not required, high values can cause instability");
}
str= "Motion Type %t|Simple motion %x0|Servo Control %x1";
but = uiDefButS(block, MENU, B_REDR, str, xco+40, yco-23, (width-80), 19, &oa->type, 0.0, 0.0, 0, 0, "");
oa->otype = oa->type;
uiButSetFunc(but, change_object_actuator, oa, NULL);
yco-= ysize; yco-= ysize;
break; break;
} }
@ -1673,23 +1769,27 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
#else #else
str= "Action types %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6"; str= "Action types %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
#endif #endif
uiDefButS(block, MENU, B_REDR, str, xco+30, yco-24, (width-60)/2, 19, &aa->type, 0.0, 0.0, 0.0, 0.0, "Action playback type"); uiDefButS(block, MENU, B_REDR, str, xco+10, yco-24, width/3, 19, &aa->type, 0.0, 0.0, 0.0, 0.0, "Action playback type");
uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+30 + ((width-60)/2), yco-24, (width-60)/2, 19, &aa->act, "Action name"); uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+10+ (width/3), yco-24, ((width/3)*2) - (20 + 60), 19, &aa->act, "Action name");
uiDefButBitS(block, TOGN, 1, 0, "Continue", xco+((width/3)*2)+20, yco-24, 60, 19,
&aa->end_reset, 0.0, 0.0, 0, 0, "Restore last frame when switching on/off, otherwise play from the start each time");
if(aa->type == ACT_ACTION_FROM_PROP) if(aa->type == ACT_ACTION_FROM_PROP)
{ {
uiDefBut(block, TEX, 0, "Prop: ",xco+30, yco-44, width-60, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position"); uiDefBut(block, TEX, 0, "Prop: ",xco+10, yco-44, width-20, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position");
} }
else else
{ {
uiDefButI(block, NUM, 0, "Sta: ",xco+30, yco-44, (width-60)/2, 19, &aa->sta, 0.0, MAXFRAMEF, 0, 0, "Start frame"); uiDefButI(block, NUM, 0, "Sta: ",xco+10, yco-44, (width-20)/2, 19, &aa->sta, 0.0, MAXFRAMEF, 0, 0, "Start frame");
uiDefButI(block, NUM, 0, "End: ",xco+30+(width-60)/2, yco-44, (width-60)/2, 19, &aa->end, 0.0, MAXFRAMEF, 0, 0, "End frame"); uiDefButI(block, NUM, 0, "End: ",xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &aa->end, 0.0, MAXFRAMEF, 0, 0, "End frame");
} }
uiDefButI(block, NUM, 0, "Blendin: ", xco+30, yco-64, (width-60)/2, 19, &aa->blendin, 0.0, MAXFRAMEF, 0.0, 0.0, "Number of frames of motion blending"); uiDefButS(block, NUM, 0, "Blendin: ", xco+10, yco-64, (width-20)/2, 19, &aa->blendin, 0.0, 32767, 0.0, 0.0, "Number of frames of motion blending");
uiDefButS(block, NUM, 0, "Priority: ", xco+30+(width-60)/2, yco-64, (width-60)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers"); uiDefButS(block, NUM, 0, "Priority: ", xco+10+(width-20)/2, yco-64, (width-20)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers, With 2 or more actions at once, the overriding channels must be lower in the stack");
uiDefBut(block, TEX, 0, "FrameProp: ",xco+30, yco-84, width-60, 19, aa->frameProp, 0.0, 31.0, 0, 0, "Assign this property this actions current frame number"); uiDefBut(block, TEX, 0, "FrameProp: ",xco+10, yco-84, width-20, 19, aa->frameProp, 0.0, 31.0, 0, 0, "Assign this property this actions current frame number");
#ifdef __NLA_ACTION_BY_MOTION_ACTUATOR #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
@ -1715,42 +1815,49 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
str = "Ipo types %t|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6"; str = "Ipo types %t|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
uiDefButS(block, MENU, B_REDR, str, xco+20, yco-24, width-40 - (width-40)/3, 19, &ia->type, 0, 0, 0, 0, ""); uiDefButS(block, MENU, B_REDR, str, xco+10, yco-24, (width-20)/2, 19, &ia->type, 0, 0, 0, 0, "");
uiDefButBitS(block, TOG, ACT_IPOCHILD, B_REDR,
"Child", xco+20+0.666*(width-40), yco-24, (width-40)/3, 19, but = uiDefButBitS(block, TOG, ACT_IPOFORCE, ACT_IPOFORCE,
"Force", xco+10+(width-20)/2, yco-24, (width-20)/4-10, 19,
&ia->flag, 0, 0, 0, 0, &ia->flag, 0, 0, 0, 0,
"Add all children Objects as well"); "Convert Ipo to force. Force is applied in global or local coordinate according to Local flag");
uiButSetFunc(but, change_ipo_actuator, but, ia);
but = uiDefButBitS(block, TOG, ACT_IPOADD, ACT_IPOADD,
"Add", xco+3*(width-20)/4, yco-24, (width-20)/4-10, 19,
&ia->flag, 0, 0, 0, 0,
"Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag");
uiButSetFunc(but, change_ipo_actuator, but, ia);
/* Only show the do-force-local toggle if force is requested */
if (ia->flag & (ACT_IPOFORCE|ACT_IPOADD)) {
uiDefButBitS(block, TOG, ACT_IPOLOCAL, 0,
"L", xco+width-30, yco-24, 20, 19,
&ia->flag, 0, 0, 0, 0,
"Let the ipo acts in local coordinates, used in Force and Add mode.");
}
if(ia->type==ACT_IPO_FROM_PROP) { if(ia->type==ACT_IPO_FROM_PROP) {
uiDefBut(block, TEX, 0, uiDefBut(block, TEX, 0,
"Prop: ", xco+20, yco-44, width-40, 19, "Prop: ", xco+10, yco-44, width-80, 19,
ia->name, 0.0, 31.0, 0, 0, ia->name, 0.0, 31.0, 0, 0,
"Use this property to define the Ipo position"); "Use this property to define the Ipo position");
} }
else { else {
uiDefButI(block, NUM, 0, uiDefButI(block, NUM, 0,
"Sta", xco+20, yco-44, (width-100)/2, 19, "Sta", xco+10, yco-44, (width-80)/2, 19,
&ia->sta, 0.0, MAXFRAMEF, 0, 0, &ia->sta, 0.0, MAXFRAMEF, 0, 0,
"Start frame"); "Start frame, (subtract 1 to match blenders frame numbers)");
uiDefButI(block, NUM, 0, uiDefButI(block, NUM, 0,
"End", xco+18+(width-90)/2, yco-44, (width-100)/2, 19, "End", xco+10+(width-80)/2, yco-44, (width-80)/2, 19,
&ia->end, 0.0, MAXFRAMEF, 0, 0, &ia->end, 0.0, MAXFRAMEF, 0, 0,
"End frame"); "End frame, (subtract 1 to match blenders frame numbers)");
uiDefButBitS(block, TOG, ACT_IPOFORCE, B_REDR,
"Force", xco+width-78, yco-44, 43, 19,
&ia->flag, 0, 0, 0, 0,
"Convert Ipo to force");
/* Only show the do-force-local toggle if force is requested */
if (ia->flag & ACT_IPOFORCE) {
uiDefButBitS(block, TOG, ACT_IPOFORCE_LOCAL, 0,
"L", xco+width-35, yco-44, 15, 19,
&ia->flag, 0, 0, 0, 0,
"Let the force-ipo act in local coordinates.");
}
} }
uiDefButBitS(block, TOG, ACT_IPOCHILD, B_REDR,
"Child", xco+10+(width-80), yco-44, 60, 19,
&ia->flag, 0, 0, 0, 0,
"Update IPO on all children Objects as well");
yco-= ysize; yco-= ysize;
break; break;
} }
@ -1882,7 +1989,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
glRects(xco, yco-ysize, xco+width, yco); glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Add this Object (cant be on an visible layer)"); uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Add this Object and all its children (cant be on an visible layer)");
uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the new Object lives"); uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the new Object lives");
wval= (width-60)/3; wval= (width-60)/3;
@ -1924,8 +2031,15 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2-40, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the tracking takes"); uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2-40, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the tracking takes");
uiDefButS(block, TOG, 0, "3D", xco+width-50, yco-44, 40, 19, &eoa->flag, 0.0, 0.0, 0, 0, "Enable 3D tracking"); uiDefButS(block, TOG, 0, "3D", xco+width-50, yco-44, 40, 19, &eoa->flag, 0.0, 0.0, 0, 0, "Enable 3D tracking");
} }
else if(eoa->type==ACT_EDOB_DYNAMICS) {
str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3"; ysize= 48;
glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
str= "Dynamic Operation %t|Restore Dynamics %x0|Suspend Dynamics %x1|Enable Rigid Body %x2|Disable Rigid Body %x3";
uiDefButS(block, MENU, B_REDR, str, xco+40, yco-44, (width-80), 19, &(eoa->dyn_operation), 0.0, 0.0, 0, 0, "");
}
str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3|Dynamics %x4";
uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &eoa->type, 0.0, 0.0, 0, 0, ""); uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &eoa->type, 0.0, 0.0, 0, 0, "");
yco-= ysize; yco-= ysize;
@ -1933,34 +2047,97 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
break; break;
case ACT_CONSTRAINT: case ACT_CONSTRAINT:
ysize= 44;
glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
coa= act->data; coa= act->data;
/* str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */
str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4";
uiDefButS(block, MENU, 1, str, xco+10, yco-40, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, "");
uiDefButS(block, NUM, 0, "Damp:", xco+10, yco-20, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, ""); if (coa->type == ACT_CONST_TYPE_LOC) {
uiDefBut(block, LABEL, 0, "Min", xco+80, yco-20, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); ysize= 69;
uiDefBut(block, LABEL, 0, "Max", xco+80+(width-90)/2, yco-20, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
if(coa->flag & ACT_CONST_LOCX) fp= coa->minloc;
else if(coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1;
else if(coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2;
else if(coa->flag & ACT_CONST_ROTX) fp= coa->minrot;
else if(coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1;
else fp= coa->minrot+2;
uiDefButF(block, NUM, 0, "", xco+80, yco-40, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+80+(width-90)/2, yco-40, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, "");
yco-= ysize;
glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
/* str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */
/* coa->flag &= ~(63); */
str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4";
coa->flag &= ~(7);
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, "");
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, "");
if(coa->flag & ACT_CONST_LOCX) fp= coa->minloc;
else if(coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1;
else if(coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2;
else if(coa->flag & ACT_CONST_ROTX) fp= coa->minrot;
else if(coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1;
else fp= coa->minrot+2;
uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, "");
uiDefButF(block, NUM, 0, "", xco+80+(width-90)/2, yco-65, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, "");
} else if (coa->type == ACT_CONST_TYPE_DIST) {
ysize= 106;
glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
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, "");
uiDefBut(block, LABEL, 0, "Range", xco+80, yco-45, (width-115)/2, 19, NULL, 0.0, 0.0, 0, 0, "Set the maximum length of ray");
uiDefButBitS(block, TOG, ACT_CONST_DISTANCE, B_REDR, "Dist", xco+80+(width-115)/2, yco-45, (width-115)/2, 19, &coa->flag, 0.0, 0.0, 0, 0, "Force distance of object to point of impact of ray");
if(coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRMX)) fp= coa->minloc;
else if(coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRMY)) fp= coa->minloc+1;
else fp= coa->minloc+2;
uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/2, 19, fp+3, 0.0, 2000.0, 10, 0, "Maximum length of ray");
if (coa->flag & ACT_CONST_DISTANCE)
uiDefButF(block, NUM, 0, "", xco+80+(width-115)/2, yco-65, (width-115)/2, 19, fp, -2000.0, 2000.0, 10, 0, "Keep this distance to target");
uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19,
&coa->flag, 0.0, 0.0, 0, 0, "Set object axis along the normal at hit position");
uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19,
&coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property");
if (coa->flag & ACT_CONST_MATERIAL)
{
uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19,
coa->matprop, 0, 31, 0, 0,
"Ray detects only Objects with this material");
}
else
{
uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19,
coa->matprop, 0, 31, 0, 0,
"Ray detect only Objects with this property");
}
uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19,
&coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target");
uiDefButS(block, NUM, 0, "time", xco+50, yco-103, (width-60)/2, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited");
uiDefButS(block, NUM, 0, "rotDamp", xco+50+(width-60)/2, yco-103, (width-60)/2, 19, &(coa->rotdamp), 0.0, 100.0, 0, 0, "Use a different damping for orientation");
} else if (coa->type == ACT_CONST_TYPE_ORI) {
ysize= 87;
glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
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, "");
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, yco-65, (width-115)/3, 19, &coa->maxrot[0], -2000.0, 2000.0, 10, 0, "X component of reference direction");
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");
}
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, "");
yco-= ysize;
break; break;
case ACT_SCENE: case ACT_SCENE:
@ -2093,7 +2270,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
uiDefBut(block, TEX, 0, "Prop: ", xco+20, yco-44, width-40, 19, ga->name, 0.0, 31.0, 0, 0, "Use this property to define the Group position"); uiDefBut(block, TEX, 0, "Prop: ", xco+20, yco-44, width-40, 19, ga->name, 0.0, 31.0, 0, 0, "Use this property to define the Group position");
} }
else { else {
uiDefButI(block, NUM, 0, "Sta", xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame"); uiDefButI(block, NUM, 0, "State", xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame");
uiDefButI(block, NUM, 0, "End", xco+20+(width-40)/2, yco-44, (width-40)/2, 19, &ga->end, 0.0, 2500.0, 0, 0, "End frame"); uiDefButI(block, NUM, 0, "End", xco+20+(width-40)/2, yco-44, (width-40)/2, 19, &ga->end, 0.0, 2500.0, 0, 0, "End frame");
} }
yco-= ysize; yco-= ysize;
@ -2766,7 +2943,6 @@ static uiBlock *controller_state_mask_menu(void *arg_cont)
uiBlock *block; uiBlock *block;
uiBut *but; uiBut *but;
bController *cont = arg_cont; bController *cont = arg_cont;
int mask;
short yco = 12, xco = 0, stbit, offset; short yco = 12, xco = 0, stbit, offset;
@ -2816,7 +2992,6 @@ static void do_object_state_menu(void *arg, int event)
static uiBlock *object_state_mask_menu(void *arg_obj) static uiBlock *object_state_mask_menu(void *arg_obj)
{ {
uiBlock *block; uiBlock *block;
uiBut *but;
short xco = 0; short xco = 0;
block= uiNewBlock(&curarea->uiblocks, "obstatemenu", UI_EMBOSSP, UI_HELV, curarea->win); block= uiNewBlock(&curarea->uiblocks, "obstatemenu", UI_EMBOSSP, UI_HELV, curarea->win);
@ -2969,6 +3144,8 @@ void logic_buts(void)
ob= OBACT; ob= OBACT;
for(a=0; a<count; a++) { for(a=0; a<count; a++) {
unsigned int controller_state_mask = 0; /* store a bitmask for states that are used */
ob= (Object *)idar[a]; ob= (Object *)idar[a];
uiClearButLock(); uiClearButLock();
uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE); uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
@ -2993,6 +3170,7 @@ void logic_buts(void)
act = cont->links[iact]; act = cont->links[iact];
act->flag |= ACT_LINKED; act->flag |= ACT_LINKED;
} }
controller_state_mask |= cont->state_mask;
cont = cont->next; cont = cont->next;
} }
@ -3007,11 +3185,11 @@ void logic_buts(void)
for (offset=0; offset<15; offset+=5) { for (offset=0; offset<15; offset+=5) {
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
for (stbit=0; stbit<5; stbit++) { for (stbit=0; stbit<5; stbit++) {
but = uiDefButBitI(block, TOG, 1<<(stbit+offset), stbit+offset, "", (short)(xco+35+12*stbit+13*offset), yco, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset))); but = uiDefButBitI(block, controller_state_mask&(1<<(stbit+offset)) ? BUT_TOGDUAL:TOG, 1<<(stbit+offset), stbit+offset, "", (short)(xco+35+12*stbit+13*offset), yco, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset)));
uiButSetFunc(but, check_object_state, but, &(ob->state)); uiButSetFunc(but, check_object_state, but, &(ob->state));
} }
for (stbit=0; stbit<5; stbit++) { for (stbit=0; stbit<5; stbit++) {
but = uiDefButBitI(block, TOG, 1<<(stbit+offset+15), stbit+offset+15, "", (short)(xco+35+12*stbit+13*offset), yco-12, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset+15))); but = uiDefButBitI(block, controller_state_mask&(1<<(stbit+offset+15)) ? BUT_TOGDUAL:TOG, 1<<(stbit+offset+15), stbit+offset+15, "", (short)(xco+35+12*stbit+13*offset), yco-12, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset+15)));
uiButSetFunc(but, check_object_state, but, &(ob->state)); uiButSetFunc(but, check_object_state, but, &(ob->state));
} }
} }
@ -3095,7 +3273,7 @@ void logic_buts(void)
uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+80, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects"); uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+80, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+80+(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object"); uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+80+(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+80+2*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller"); uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+80+2*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "Sta", xco+80+3*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states"); uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "State", xco+80+3*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states");
uiBlockEndAlign(block); uiBlockEndAlign(block);
for(a=0; a<count; a++) { for(a=0; a<count; a++) {
@ -3168,7 +3346,7 @@ void logic_buts(void)
uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects"); uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object"); uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller"); uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "Sta", xco+110+3*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states"); uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "State", xco+110+3*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states");
uiBlockEndAlign(block); uiBlockEndAlign(block);
for(a=0; a<count; a++) { for(a=0; a<count; a++) {
ob= (Object *)idar[a]; ob= (Object *)idar[a];

@ -4812,7 +4812,7 @@ static void object_panel_particle_system(Object *ob)
uiDefBut(block, LABEL, 0, "Basic:", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, ""); uiDefBut(block, LABEL, 0, "Basic:", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
if(part->distr==PART_DISTR_GRID) if(part->distr==PART_DISTR_GRID && part->from != PART_FROM_VERT)
uiDefButI(block, NUM, B_PART_ALLOC, "Resol:", butx,(buty-=buth),butw,buth, &part->grid_res, 1.0, 100.0, 0, 0, "The resolution of the particle grid"); uiDefButI(block, NUM, B_PART_ALLOC, "Resol:", butx,(buty-=buth),butw,buth, &part->grid_res, 1.0, 100.0, 0, 0, "The resolution of the particle grid");
else else
uiDefButI(block, NUM, B_PART_ALLOC, "Amount:", butx,(buty-=buth),butw,buth, &part->totpart, 0.0, 100000.0, 0, 0, "The total number of particles"); uiDefButI(block, NUM, B_PART_ALLOC, "Amount:", butx,(buty-=buth),butw,buth, &part->totpart, 0.0, 100000.0, 0, 0, "The total number of particles");

@ -499,7 +499,7 @@ static char* seq_panel_blend_modes()
so that would collide also. so that would collide also.
*/ */
if (!(last_seq->type & SEQ_EFFECT)) { if ( seq_can_blend(last_seq) ) {
int i; int i;
for (i = SEQ_EFFECT; i <= SEQ_EFFECT_MAX; i++) { for (i = SEQ_EFFECT; i <= SEQ_EFFECT_MAX; i++) {

@ -2803,6 +2803,42 @@ static void lamp_panel_yafray(Object *ob, Lamp *la)
} }
static void lamp_panel_atmosphere(Object *ob, Lamp *la)
{
uiBlock *block;
int y;
block= uiNewBlock(&curarea->uiblocks, "lamp_panel_atm", UI_EMBOSS, UI_HELV, curarea->win);
uiNewPanelTabbed("Shadow and Spot", "Lamp");
if(uiNewPanel(curarea, block, "Sky/Atmosphere", "Lamp", 3*PANELX, PANELY, PANELW, PANELH)==0) return;
uiSetButLock(la->id.lib!=0, ERROR_LIBDATA_MESSAGE);
uiDefButBitS(block, TOG, LA_SUN_EFFECT_SKY, REDRAWVIEW3D, "Sky", 10,205,BUTW2,20,&(la->sun_effect_type), 0, 0, 0, 0, "Apply sun light effect on sky.");
uiDefButBitS(block, TOG, LA_SUN_EFFECT_AP, REDRAWVIEW3D, "Atmosphere", 20+BUTW2,205,BUTW2,20,&(la->sun_effect_type), 0, 0, 0, 0, "Apply sun light effect on atmosphere.");
if(la->sun_effect_type & (LA_SUN_EFFECT_SKY|LA_SUN_EFFECT_AP)){
uiDefButF(block, NUM, B_LAMPREDRAW, "Turbidity:",10,180,BUTW1,19, &(la->atm_turbidity), 1.000f, 30.0f, 1, 0, "Sky Turbidity");
}
y = 180;
if(la->sun_effect_type & LA_SUN_EFFECT_SKY)
{
uiDefButF(block, NUM, B_LAMPREDRAW, "Hor.Bright:",10,y-25,BUTW2,19, &(la->horizon_brightness), 0.00f, 20.00f, 10, 0, "Sets horizon brightness.");
uiDefButF(block, NUM, B_LAMPREDRAW, "Hor.Spread:",10,y-50,BUTW2,19, &(la->spread), 0.00f, 10.00f, 10, 0, "Sets horizon spread.");
uiDefButF(block, NUM, B_LAMPREDRAW, "Sun Bright:",10,y-75,BUTW2,19, &(la->sun_brightness), 0.00f, 10.0f, 10, 0, "Sets sun brightness.");
uiDefButF(block, NUM, B_LAMPREDRAW, "Sun Size:",10,y-100,BUTW2,19, &(la->sun_size), 0.00f, 10.00f, 10, 0, "Sets sun size.");
uiDefButF(block, NUM, B_LAMPREDRAW, "Back Light:",10,y-125,BUTW2,19, &(la->backscattered_light), -1.00f, 1.00f, 10, 0, "Sets backscatter light.");
}
if(la->sun_effect_type & LA_SUN_EFFECT_AP)
{
uiDefButF(block, NUM, B_LAMPREDRAW, "Sun Intens.:",20+BUTW2,y-25,BUTW2,19, &(la->sun_intensity), 0.00f, 10.00f, 10, 0, "Sets sun intensity.");
uiDefButF(block, NUM, B_LAMPREDRAW, "Inscattering:",20+BUTW2,y-50,BUTW2,19, &(la->atm_inscattering_factor), 0.00f, 1.00f, 10, 0, "In Scattering Contribution Factor.");
uiDefButF(block, NUM, B_LAMPREDRAW, "Extinction:",20+BUTW2,y-75,BUTW2,19, &(la->atm_extinction_factor), 0.00f, 1.00f, 10, 0, "Extinction Scattering Contribution Factor.");
uiDefButF(block, NUM, B_LAMPREDRAW, "Distance:",20+BUTW2,y-100,BUTW2,19, &(la->atm_distance_factor), 0.000f, 500.0f, 10, 0, "Scale blender distance to real distance.");
}
}
static void lamp_panel_falloff(Object *ob, Lamp *la) static void lamp_panel_falloff(Object *ob, Lamp *la)
{ {
uiBlock *block; uiBlock *block;
@ -2864,15 +2900,15 @@ static void lamp_panel_lamp(Object *ob, Lamp *la)
uiBlockSetCol(block, TH_BUT_SETTING1); uiBlockSetCol(block, TH_BUT_SETTING1);
uiDefButS(block, MENU, B_LAMPREDRAW, "Falloff %t|Constant %x0|Inverse Linear %x1|Inverse Square %x2|Custom Curve %x3|Lin/Quad Weighted %x4|", uiDefButS(block, MENU, B_LAMPREDRAW, "Falloff %t|Constant %x0|Inverse Linear %x1|Inverse Square %x2|Custom Curve %x3|Lin/Quad Weighted %x4|",
10,150,100,19, &la->falloff_type, 0,0,0,0, "Lamp falloff - intensity decay with distance"); 10,150,100,19, &la->falloff_type, 0,0,0,0, "Lamp falloff - intensity decay with distance");
uiDefButBitS(block, TOG, LA_SPHERE, REDRAWVIEW3D,"Sphere", 10,130,100,19,&la->mode, 0, 0, 0, 0, "Sets light intensity to zero for objects beyond the distance value"); uiDefButBitS(block, TOG, LA_SPHERE, B_LAMPPRV,"Sphere", 10,130,100,19,&la->mode, 0, 0, 0, 0, "Sets light intensity to zero for objects beyond the distance value");
} }
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1); uiBlockSetCol(block, TH_BUT_SETTING1);
uiDefButBitS(block, TOG, LA_LAYER, 0,"Layer", 10,70,100,19,&la->mode, 0, 0, 0, 0, "Illuminates objects in the same layer as the lamp only"); uiDefButBitS(block, TOG, LA_LAYER, 0,"Layer", 10,70,100,19,&la->mode, 0, 0, 0, 0, "Illuminates objects in the same layer as the lamp only");
uiDefButBitS(block, TOG, LA_NEG, B_LAMPPRV,"Negative", 10,50,100,19,&la->mode, 0, 0, 0, 0, "Sets lamp to cast negative light"); uiDefButBitS(block, TOG, LA_NEG, B_LAMPPRV,"Negative", 10,50,100,19,&la->mode, 0, 0, 0, 0, "Sets lamp to cast negative light");
uiDefButBitS(block, TOG, LA_NO_DIFF, 0,"No Diffuse", 10,30,100,19,&la->mode, 0, 0, 0, 0, "Disables diffuse shading of material illuminated by this lamp"); uiDefButBitS(block, TOG, LA_NO_DIFF, B_LAMPPRV,"No Diffuse", 10,30,100,19,&la->mode, 0, 0, 0, 0, "Disables diffuse shading of material illuminated by this lamp");
uiDefButBitS(block, TOG, LA_NO_SPEC, 0,"No Specular", 10,10,100,19,&la->mode, 0, 0, 0, 0, "Disables specular shading of material illuminated by this lamp"); uiDefButBitS(block, TOG, LA_NO_SPEC, B_LAMPPRV,"No Specular", 10,10,100,19,&la->mode, 0, 0, 0, 0, "Disables specular shading of material illuminated by this lamp");
uiBlockEndAlign(block); uiBlockEndAlign(block);
uiBlockSetCol(block, TH_AUTO); uiBlockSetCol(block, TH_AUTO);
@ -4354,6 +4390,11 @@ void lamp_panels()
/* spherelight radius default is zero, so nothing to do */ /* spherelight radius default is zero, so nothing to do */
lamp_panel_yafray(ob, la); lamp_panel_yafray(ob, la);
} }
if(la->type == LA_SUN){
lamp_panel_atmosphere(ob, ob->data);
}
lamp_panel_texture(ob, ob->data); lamp_panel_texture(ob, ob->data);
lamp_panel_mapto(ob, ob->data); lamp_panel_mapto(ob, ob->data);

@ -32,6 +32,7 @@
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
@ -56,6 +57,7 @@
#include "DNA_space_types.h" #include "DNA_space_types.h"
#include "DNA_constraint_types.h" #include "DNA_constraint_types.h"
#include "DNA_key_types.h" #include "DNA_key_types.h"
#include "DNA_userdef_types.h"
#include "BKE_action.h" #include "BKE_action.h"
#include "BKE_depsgraph.h" #include "BKE_depsgraph.h"
@ -474,10 +476,13 @@ static void draw_channel_names(void)
indent= 0; indent= 0;
special= -1; special= -1;
if (EXPANDED_AGRP(agrp)) /* only show expand if there are any channels */
expand = ICON_TRIA_DOWN; if (agrp->channels.first) {
else if (EXPANDED_AGRP(agrp))
expand = ICON_TRIA_RIGHT; expand = ICON_TRIA_DOWN;
else
expand = ICON_TRIA_RIGHT;
}
if (EDITABLE_AGRP(agrp)) if (EDITABLE_AGRP(agrp))
protect = ICON_UNLOCKED; protect = ICON_UNLOCKED;
@ -925,12 +930,55 @@ static void draw_channel_strips(void)
void do_actionbuts(unsigned short event) void do_actionbuts(unsigned short event)
{ {
switch(event) { switch(event) {
/* general */
case REDRAWVIEW3D: case REDRAWVIEW3D:
allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWVIEW3D, 0);
break; break;
case B_REDR: case B_REDR:
allqueue(REDRAWACTION, 0); allqueue(REDRAWACTION, 0);
break; 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;
} }
} }
@ -938,14 +986,68 @@ void do_actionbuts(unsigned short event)
static void action_panel_properties(short cntrl) // ACTION_HANDLER_PROPERTIES static void action_panel_properties(short cntrl) // ACTION_HANDLER_PROPERTIES
{ {
uiBlock *block; uiBlock *block;
void *data;
short datatype;
block= uiNewBlock(&curarea->uiblocks, "action_panel_properties", UI_EMBOSS, UI_HELV, curarea->win); block= uiNewBlock(&curarea->uiblocks, "action_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(ACTION_HANDLER_PROPERTIES); // for close and esc 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; 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) static void action_blockhandlers(ScrArea *sa)

@ -2500,7 +2500,7 @@ static void draw_ghost_poses(Base *base)
/* ********************************** Armature Drawing - Main ************************* */ /* ********************************** Armature Drawing - Main ************************* */
/* called from drawobject.c, return 1 if nothing was drawn */ /* called from drawobject.c, return 1 if nothing was drawn */
int draw_armature(Base *base, int dt) int draw_armature(Base *base, int dt, int flag)
{ {
Object *ob= base->object; Object *ob= base->object;
bArmature *arm= ob->data; bArmature *arm= ob->data;
@ -2544,15 +2544,16 @@ int draw_armature(Base *base, int dt)
if (arm->ghostep) if (arm->ghostep)
draw_ghost_poses(base); draw_ghost_poses(base);
} }
if ((flag & DRAW_SCENESET)==0) {
if(ob==OBACT)
arm->flag |= ARM_POSEMODE;
else if(G.f & G_WEIGHTPAINT)
arm->flag |= ARM_POSEMODE;
if(ob==OBACT) draw_pose_paths(ob);
arm->flag |= ARM_POSEMODE; }
else if(G.f & G_WEIGHTPAINT)
arm->flag |= ARM_POSEMODE;
draw_pose_paths(ob);
} }
} }
draw_pose_channels(base, dt); draw_pose_channels(base, dt);
arm->flag &= ~ARM_POSEMODE; arm->flag &= ~ARM_POSEMODE;

Some files were not shown because too many files have changed in this diff Show More