forked from bartvdbraak/blender
Merge from 2.5 -r 21285:21515. Thanks Joshua!
This commit is contained in:
commit
3ad64726ee
@ -87,7 +87,7 @@ INCLUDE(CMake/macros.cmake)
|
||||
#-----------------------------------------------------------------------------
|
||||
#Platform specifics
|
||||
|
||||
IF(UNIX)
|
||||
IF(UNIX AND NOT APPLE)
|
||||
IF(WITH_OPENAL)
|
||||
FIND_PACKAGE(OpenAL)
|
||||
IF(OPENAL_FOUND)
|
||||
@ -177,7 +177,7 @@ IF(UNIX)
|
||||
SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wnested-externs -Wdeclaration-after-statement")
|
||||
|
||||
INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} )
|
||||
ENDIF(UNIX)
|
||||
ENDIF(UNIX AND NOT APPLE)
|
||||
|
||||
IF(WIN32)
|
||||
|
||||
|
@ -3,12 +3,16 @@ LIBDIR = "${LCGDIR}"
|
||||
|
||||
BF_PYTHON = LIBDIR + '/python'
|
||||
BF_PYTHON_VERSION = '2.5'
|
||||
#BF_PYTHON_VERSION = '2.6'
|
||||
WITH_BF_STATICPYTHON = False
|
||||
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
|
||||
BF_PYTHON_BINARY = 'python'
|
||||
BF_PYTHON_LIB = 'python25'
|
||||
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib/lib25_vs2005'
|
||||
BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/lib25_vs2005/libpython25.a'
|
||||
#BF_PYTHON_LIB = 'python25'
|
||||
#BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib/lib25_vs2005'
|
||||
#BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/lib25_vs2005/libpython25.a'
|
||||
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}'
|
||||
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
|
||||
BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/libpython${BF_PYTHON_VERSION[0]}${BF_PYTHON_VERSION[2]}.a'
|
||||
|
||||
WITH_BF_OPENAL = True
|
||||
WITH_BF_STATICOPENAL = False
|
||||
|
@ -367,6 +367,17 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
|
||||
GHOST_TInt32 x,
|
||||
GHOST_TInt32 y);
|
||||
|
||||
/**
|
||||
* Grabs the cursor for a modal operation, to keep receiving
|
||||
* events when the mouse is outside the window. X11 only, others
|
||||
* do this automatically.
|
||||
* @param windowhandle The handle to the window
|
||||
* @param grab The new grab state of the cursor.
|
||||
* @return Indication of success.
|
||||
*/
|
||||
extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
|
||||
int grab);
|
||||
|
||||
/***************************************************************************************
|
||||
** Access to mouse button and keyboard states.
|
||||
***************************************************************************************/
|
||||
|
@ -252,6 +252,14 @@ public:
|
||||
* @return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess setCursorVisibility(bool visible) = 0;
|
||||
|
||||
/**
|
||||
* Grabs the cursor for a modal operation.
|
||||
* @param grab The new grab state of the cursor.
|
||||
* @return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess setCursorGrab(bool grab) { return GHOST_kSuccess; };
|
||||
|
||||
};
|
||||
|
||||
#endif // _GHOST_IWINDOW_H_
|
||||
|
@ -354,6 +354,14 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
|
||||
int grab)
|
||||
{
|
||||
GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
|
||||
|
||||
return window->setCursorGrab(grab?true:false);
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,
|
||||
GHOST_TModifierKeyMask mask,
|
||||
|
@ -550,11 +550,26 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
// We're not interested in the following things.(yet...)
|
||||
case NoExpose :
|
||||
case GraphicsExpose :
|
||||
break;
|
||||
|
||||
case EnterNotify:
|
||||
case LeaveNotify:
|
||||
{
|
||||
// XCrossingEvents pointer leave enter window.
|
||||
// also do cursor move here, MotionNotify only
|
||||
// happens when motion starts & ends inside window
|
||||
XCrossingEvent &xce = xe->xcrossing;
|
||||
|
||||
g_event = new
|
||||
GHOST_EventCursor(
|
||||
getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
xce.x_root,
|
||||
xce.y_root
|
||||
);
|
||||
break;
|
||||
}
|
||||
case MapNotify:
|
||||
/*
|
||||
* From ICCCM:
|
||||
|
@ -50,6 +50,7 @@ GHOST_Window::GHOST_Window(
|
||||
:
|
||||
m_drawingContextType(type),
|
||||
m_cursorVisible(true),
|
||||
m_cursorGrabbed(true),
|
||||
m_cursorShape(GHOST_kStandardCursorDefault),
|
||||
m_stereoVisual(stereoVisual)
|
||||
{
|
||||
@ -93,6 +94,20 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible)
|
||||
}
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab)
|
||||
{
|
||||
if(m_cursorGrabbed == grab)
|
||||
return GHOST_kSuccess;
|
||||
|
||||
if (setWindowCursorGrab(grab)) {
|
||||
m_cursorGrabbed = grab;
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
else {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape)
|
||||
{
|
||||
if (setWindowCursorShape(cursorShape)) {
|
||||
|
@ -166,6 +166,13 @@ public:
|
||||
*/
|
||||
virtual GHOST_TSuccess setCursorVisibility(bool visible);
|
||||
|
||||
/**
|
||||
* Sets the cursor grab.
|
||||
* @param grab The new grab state of the cursor.
|
||||
* @return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess setCursorGrab(bool grab);
|
||||
|
||||
/**
|
||||
* Returns the type of drawing context used in this window.
|
||||
* @return The current type of drawing context.
|
||||
@ -219,6 +226,12 @@ protected:
|
||||
*/
|
||||
virtual GHOST_TSuccess setWindowCursorVisibility(bool visible) = 0;
|
||||
|
||||
/**
|
||||
* Sets the cursor grab on the window using
|
||||
* native window system calls.
|
||||
*/
|
||||
virtual GHOST_TSuccess setWindowCursorGrab(bool grab) { return GHOST_kSuccess; };
|
||||
|
||||
/**
|
||||
* Sets the cursor shape on the window using
|
||||
* native window system calls.
|
||||
@ -243,6 +256,9 @@ protected:
|
||||
/** The current visibility of the cursor */
|
||||
bool m_cursorVisible;
|
||||
|
||||
/** The current grabbed state of the cursor */
|
||||
bool m_cursorGrabbed;
|
||||
|
||||
/** The current shape of the cursor */
|
||||
GHOST_TStandardCursor m_cursorShape;
|
||||
|
||||
|
@ -1271,6 +1271,21 @@ setWindowCursorVisibility(
|
||||
|
||||
GHOST_TSuccess
|
||||
GHOST_WindowX11::
|
||||
setWindowCursorGrab(
|
||||
bool grab
|
||||
){
|
||||
if(grab)
|
||||
XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
||||
else
|
||||
XUngrabPointer(m_display, CurrentTime);
|
||||
|
||||
XFlush(m_display);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
GHOST_TSuccess
|
||||
GHOST_WindowX11::
|
||||
setWindowCursorShape(
|
||||
GHOST_TStandardCursor shape
|
||||
){
|
||||
|
@ -249,6 +249,15 @@ protected:
|
||||
bool visible
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets the cursor grab on the window using
|
||||
* native window system calls.
|
||||
*/
|
||||
GHOST_TSuccess
|
||||
setWindowCursorGrab(
|
||||
bool grab
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets the cursor shape on the window using
|
||||
* native window system calls.
|
||||
|
@ -294,7 +294,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ED_editors", "editors\ED_ed
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RNA_makesrna", "makesrna\RNA_makesrna.vcproj", "{8C2BCCF8-4D9E-46D3-BABF-C1545A332CE6}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{FB88301F-F725-401B-ACD7-D2ABBF333B71} = {FB88301F-F725-401B-ACD7-D2ABBF333B71}
|
||||
{7495FE37-933A-4AC1-BB2A-B3FDB4DE4284} = {7495FE37-933A-4AC1-BB2A-B3FDB4DE4284}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
@ -181,14 +181,6 @@
|
||||
RelativePath="..\..\..\source\blender\editors\include\BIF_glutil.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\include\BIF_retopo.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\include\BIF_transform.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\include\ED_anim_api.h"
|
||||
>
|
||||
@ -261,6 +253,10 @@
|
||||
RelativePath="..\..\..\source\blender\editors\include\ED_particle.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\include\ED_physics.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\include\ED_pointcache.h"
|
||||
>
|
||||
@ -269,6 +265,10 @@
|
||||
RelativePath="..\..\..\source\blender\editors\include\ED_previewrender.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\include\ED_retopo.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\include\ED_screen.h"
|
||||
>
|
||||
@ -426,10 +426,6 @@
|
||||
RelativePath="..\..\..\source\blender\editors\interface\interface_widgets.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\interface\keyval.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\interface\resources.c"
|
||||
>
|
||||
@ -750,10 +746,6 @@
|
||||
RelativePath="..\..\..\source\blender\editors\space_file\file_draw.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\space_file\file_header.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\space_file\file_intern.h"
|
||||
>
|
||||
@ -1062,6 +1054,10 @@
|
||||
RelativePath="..\..\..\source\blender\editors\object\object_ops.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\object\object_vgroup.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="transform"
|
||||
@ -1118,10 +1114,6 @@
|
||||
<Filter
|
||||
Name="mesh"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\mesh\editdeform.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\mesh\editface.c"
|
||||
>
|
||||
@ -1154,6 +1146,10 @@
|
||||
RelativePath="..\..\..\source\blender\editors\mesh\mesh_intern.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\mesh\mesh_layers.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\mesh\mesh_ops.c"
|
||||
>
|
||||
|
@ -27,6 +27,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="DEL ..\..\..\source\blender\makesrna\intern\*_gen.c"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
@ -121,6 +122,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="DEL ..\..\..\source\blender\makesrna\intern\*_gen.c"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
@ -199,7 +201,7 @@
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
Description="Building RNA"
|
||||
CommandLine="CD ..\..\..\source\blender\makesrna\intern
RNA_makesrna.exe rna.c
"
|
||||
CommandLine="CD ..\..\..\source\blender\makesrna\intern\
RNA_makesrna.exe .\
"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
@ -214,6 +216,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="DEL ..\..\..\source\blender\makesrna\intern\*_gen.c"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
@ -307,6 +310,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="del ..\..\..\source\blender\makesrna\intern\rna_*_gen.c"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
@ -388,7 +392,7 @@
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
Description="Building RNA"
|
||||
CommandLine="CD ..\..\..\source\blender\makesrna\intern
RNA_makesrna.exe rna.c
"
|
||||
CommandLine="CD ..\..\..\source\blender\makesrna\intern\
RNA_makesrna.exe .\
"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
@ -403,6 +407,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="DEL ..\..\..\source\blender\makesrna\intern\*_gen.c"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
@ -484,7 +489,7 @@
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
Description="Building RNA"
|
||||
CommandLine="CD ..\..\..\source\blender\makesrna\intern
RNA_makesrna.exe rna.c
"
|
||||
CommandLine="CD ..\..\..\source\blender\makesrna\intern\
RNA_makesrna.exe .\
"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
@ -499,6 +504,7 @@
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
@ -577,7 +583,7 @@
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
Description="Building RNA"
|
||||
CommandLine="CD ..\..\..\source\blender\makesrna\intern
RNA_makesrna.exe rna.c
"
|
||||
CommandLine="CD ..\..\..\source\blender\makesrna\intern\
RNA_makesrna.exe .\
"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
|
@ -166,210 +166,206 @@
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_action_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_actuator_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_animation_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_armature_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.cRNA_blender_cpp.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_brush_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_camera_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_cloth_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_color_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_constraint_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_context_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_controller_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_curve_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_fcurve_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_fluidsim_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_group_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_ID_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_image_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_key_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_lamp_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_lattice_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_main_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_material_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_mesh_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_meta_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_modifier_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_nodetree_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_object_force_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_object_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_packedfile_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_particle_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_pose_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_property_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_rna_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_scene_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_screen_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_scriptlink_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_sensor_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_sequence_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_sound_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_space_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_text_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_texture_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_timeline_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_ui_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_userdef_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_vfont_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_vpaint_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_wm_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_world_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_access.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_action_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_actuator_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_animation_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_armature_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_brush_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_camera_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_cloth_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_color_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_constraint_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_context_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_controller_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_curve_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_fcurve_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_fluidsim_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_group_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_ID_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_image_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_key_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_lamp_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_lattice_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_main_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_material_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_mesh_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_meta_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_modifier_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_nodetree_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_object_force_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_object_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_packedfile_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_particle_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_pose_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_property_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_rna_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_scene_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_screen_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_scriptlink_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_sensor_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_sequence_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_sound_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_space_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_text_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_texture_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_timeline_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_ui_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_userdef_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_vfont_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_vpaint_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_wm_gen.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\makesrna\intern\rna_world_gen.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
|
@ -45,11 +45,14 @@ will be exported as mesh data.
|
||||
# ***** END GPL LICENCE BLOCK *****
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
# import math and other in functions that use them for the sake of fast Blender startup
|
||||
# import math
|
||||
import os # os.sep
|
||||
|
||||
import bpy
|
||||
import os # os.sep
|
||||
import Mathutils
|
||||
|
||||
|
||||
# Returns a tuple - path,extension.
|
||||
# 'hello.obj' > ('hello', '.obj')
|
||||
def splitExt(path):
|
||||
@ -300,6 +303,9 @@ def write(filename, objects, scene,
|
||||
write( 'c:\\test\\foobar.obj', Blender.Object.GetSelected() ) # Using default options.
|
||||
'''
|
||||
|
||||
# XXX
|
||||
import math
|
||||
|
||||
def veckey3d(v):
|
||||
return round(v.x, 6), round(v.y, 6), round(v.z, 6)
|
||||
|
||||
@ -362,7 +368,7 @@ def write(filename, objects, scene,
|
||||
file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] ))
|
||||
|
||||
if EXPORT_ROTX90:
|
||||
mat_xrot90= Mathutils.RotationMatrix(-90, 4, 'x')
|
||||
mat_xrot90= Mathutils.RotationMatrix(-math.pi/2, 4, 'x')
|
||||
|
||||
# Initialize totals, these are updated each object
|
||||
totverts = totuvco = totno = 1
|
||||
@ -416,8 +422,10 @@ def write(filename, objects, scene,
|
||||
me = ob.data.create_copy()
|
||||
|
||||
if EXPORT_ROTX90:
|
||||
print(ob_mat * mat_xrot90)
|
||||
me.transform(ob_mat * mat_xrot90)
|
||||
else:
|
||||
print(ob_mat)
|
||||
me.transform(ob_mat)
|
||||
|
||||
# # Will work for non meshes now! :)
|
||||
|
@ -9,12 +9,9 @@ class DataButtonsPanel(bpy.types.Panel):
|
||||
def poll(self, context):
|
||||
return (context.armature != None)
|
||||
|
||||
class DATA_PT_skeleton(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_skeleton"
|
||||
__label__ = "Skeleton"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object.type == 'ARMATURE' or context.armature)
|
||||
class DATA_PT_context_arm(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_context_arm"
|
||||
__no_header__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -32,8 +29,19 @@ class DATA_PT_skeleton(DataButtonsPanel):
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
class DATA_PT_skeleton(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_skeleton"
|
||||
__label__ = "Skeleton"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
arm = context.armature
|
||||
space = context.space_data
|
||||
|
||||
|
||||
if arm:
|
||||
layout.itemS()
|
||||
layout.itemR(arm, "rest_position")
|
||||
|
||||
split = layout.split()
|
||||
@ -124,6 +132,7 @@ class DATA_PT_ghost(DataButtonsPanel):
|
||||
sub = split.column()
|
||||
sub.itemR(arm, "ghost_only_selected", text="Selected Only")
|
||||
|
||||
bpy.types.register(DATA_PT_context_arm)
|
||||
bpy.types.register(DATA_PT_skeleton)
|
||||
bpy.types.register(DATA_PT_display)
|
||||
bpy.types.register(DATA_PT_paths)
|
||||
|
@ -9,10 +9,25 @@ class BoneButtonsPanel(bpy.types.Panel):
|
||||
def poll(self, context):
|
||||
return (context.bone or context.edit_bone)
|
||||
|
||||
class BONE_PT_context_bone(BoneButtonsPanel):
|
||||
__idname__ = "BONE_PT_context_bone"
|
||||
__no_header__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
bone = context.bone
|
||||
if not bone:
|
||||
bone = context.edit_bone
|
||||
|
||||
split = layout.split(percentage=0.06)
|
||||
split.itemL(text="", icon="ICON_BONE_DATA")
|
||||
split.itemR(bone, "name", text="")
|
||||
|
||||
class BONE_PT_bone(BoneButtonsPanel):
|
||||
__idname__ = "BONE_PT_bone"
|
||||
__label__ = "Bone"
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
bone = context.bone
|
||||
@ -22,28 +37,53 @@ class BONE_PT_bone(BoneButtonsPanel):
|
||||
split = layout.split()
|
||||
|
||||
sub = split.column()
|
||||
sub.itemR(bone, "name")
|
||||
sub.itemR(bone, "parent")
|
||||
sub.itemR(bone, "connected")
|
||||
sub.itemR(bone, "deform")
|
||||
|
||||
sub.itemL(text="Inherit:")
|
||||
sub.itemR(bone, "hinge")
|
||||
sub.itemR(bone, "inherit_scale")
|
||||
|
||||
sub.itemL(text="Envelope:")
|
||||
sub.itemR(bone, "envelope_distance", text="Distance")
|
||||
sub.itemR(bone, "envelope_weight", text="Weight")
|
||||
sub.itemR(bone, "multiply_vertexgroup_with_envelope", text="Multiply")
|
||||
|
||||
sub = split.column()
|
||||
sub.itemL(text="Layers:")
|
||||
sub.template_layers(bone, "layer")
|
||||
|
||||
sub = split.column()
|
||||
|
||||
sub.itemL(text="Inherit:")
|
||||
sub.itemR(bone, "hinge", text="Rotation")
|
||||
sub.itemR(bone, "inherit_scale", text="Scale")
|
||||
|
||||
sub.itemL(text="Display:")
|
||||
sub.itemR(bone, "draw_wire", text="Wireframe")
|
||||
sub.itemR(bone, "hidden", text="Hide")
|
||||
|
||||
|
||||
|
||||
class BONE_PT_deform(BoneButtonsPanel):
|
||||
__idname__ = "BONE_PT_deform"
|
||||
__label__ = "Deform"
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
bone = context.bone
|
||||
if not bone:
|
||||
bone = context.edit_bone
|
||||
|
||||
layout.itemR(bone, "deform", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
bone = context.bone
|
||||
if not bone:
|
||||
bone = context.edit_bone
|
||||
|
||||
layout.active = bone.deform
|
||||
|
||||
split = layout.split()
|
||||
|
||||
sub = split.column()
|
||||
sub.itemL(text="Envelope:")
|
||||
sub.itemR(bone, "envelope_distance", text="Distance")
|
||||
sub.itemR(bone, "envelope_weight", text="Weight")
|
||||
sub.itemR(bone, "multiply_vertexgroup_with_envelope", text="Multiply")
|
||||
sub = split.column()
|
||||
|
||||
sub.itemL(text="Curved Bones:")
|
||||
sub.itemR(bone, "bbone_segments", text="Segments")
|
||||
sub.itemR(bone, "bbone_in", text="Ease In")
|
||||
@ -51,4 +91,7 @@ class BONE_PT_bone(BoneButtonsPanel):
|
||||
|
||||
sub.itemR(bone, "cyclic_offset")
|
||||
|
||||
|
||||
bpy.types.register(BONE_PT_context_bone)
|
||||
bpy.types.register(BONE_PT_bone)
|
||||
bpy.types.register(BONE_PT_deform)
|
||||
|
@ -9,12 +9,9 @@ class DataButtonsPanel(bpy.types.Panel):
|
||||
def poll(self, context):
|
||||
return (context.camera != None)
|
||||
|
||||
class DATA_PT_camera(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_camera"
|
||||
__label__ = "Lens"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object.type == 'CAMERA')
|
||||
class DATA_PT_context_camera(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_context_camera"
|
||||
__no_header__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -28,11 +25,19 @@ class DATA_PT_camera(DataButtonsPanel):
|
||||
if ob:
|
||||
split.template_ID(ob, "data")
|
||||
split.itemS()
|
||||
elif arm:
|
||||
elif cam:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
if cam:
|
||||
class DATA_PT_camera(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_camera"
|
||||
__label__ = "Lens"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
cam = context.camera
|
||||
|
||||
layout.itemS()
|
||||
layout.itemR(cam, "type", expand=True)
|
||||
|
||||
@ -86,5 +91,7 @@ class DATA_PT_camera_display(DataButtonsPanel):
|
||||
colsub.itemR(cam, "passepartout_alpha", text="Alpha", slider=True)
|
||||
col.itemR(cam, "draw_size", text="Size")
|
||||
|
||||
bpy.types.register(DATA_PT_context_camera)
|
||||
bpy.types.register(DATA_PT_camera)
|
||||
bpy.types.register(DATA_PT_camera_display)
|
||||
|
||||
|
@ -7,14 +7,11 @@ class DataButtonsPanel(bpy.types.Panel):
|
||||
__context__ = "data"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object.type == 'CURVE' and context.curve)
|
||||
return (context.object and context.object.type == 'CURVE' and context.curve)
|
||||
|
||||
class DATA_PT_shape_curve(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_shape_curve"
|
||||
__label__ = "Shape"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object.type == 'CURVE')
|
||||
class DATA_PT_context_curve(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_context_curve"
|
||||
__no_header__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -32,8 +29,19 @@ class DATA_PT_shape_curve(DataButtonsPanel):
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
|
||||
class DATA_PT_shape_curve(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_shape_curve"
|
||||
__label__ = "Shape"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
curve = context.curve
|
||||
space = context.space_data
|
||||
|
||||
if curve:
|
||||
layout.itemS()
|
||||
layout.itemR(curve, "curve_2d")
|
||||
|
||||
split = layout.split()
|
||||
@ -46,7 +54,7 @@ class DATA_PT_shape_curve(DataButtonsPanel):
|
||||
colsub.itemR(curve, "back")
|
||||
|
||||
col.itemL(text="Textures:")
|
||||
col.itemR(curve, "uv_orco")
|
||||
# col.itemR(curve, "uv_orco")
|
||||
col.itemR(curve, "auto_texspace")
|
||||
|
||||
sub = split.column()
|
||||
@ -56,13 +64,13 @@ class DATA_PT_shape_curve(DataButtonsPanel):
|
||||
sub.itemR(curve, "render_resolution_u", text="Render U")
|
||||
sub.itemR(curve, "render_resolution_v", text="Render V")
|
||||
|
||||
sub.itemL(text="Display:")
|
||||
sub.itemL(text="HANDLES")
|
||||
sub.itemL(text="NORMALS")
|
||||
sub.itemR(curve, "vertex_normal_flip")
|
||||
# sub.itemL(text="Display:")
|
||||
# sub.itemL(text="HANDLES")
|
||||
# sub.itemL(text="NORMALS")
|
||||
# sub.itemR(curve, "vertex_normal_flip")
|
||||
|
||||
class DATA_PT_geometry(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_geometry"
|
||||
class DATA_PT_geometry_curve(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_geometry_curve"
|
||||
__label__ = "Geometry "
|
||||
|
||||
def draw(self, context):
|
||||
@ -75,13 +83,13 @@ class DATA_PT_geometry(DataButtonsPanel):
|
||||
sub.itemL(text="Modification:")
|
||||
sub.itemR(curve, "width")
|
||||
sub.itemR(curve, "extrude")
|
||||
sub.itemR(curve, "taper_object")
|
||||
sub.itemR(curve, "taper_object", icon="ICON_OUTLINER_OB_CURVE")
|
||||
|
||||
sub = split.column()
|
||||
sub.itemL(text="Bevel:")
|
||||
sub.itemR(curve, "bevel_depth", text="Depth")
|
||||
sub.itemR(curve, "bevel_resolution", text="Resolution")
|
||||
sub.itemR(curve, "bevel_object")
|
||||
sub.itemR(curve, "bevel_object", icon="ICON_OUTLINER_OB_CURVE")
|
||||
|
||||
class DATA_PT_pathanim(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_pathanim"
|
||||
@ -141,7 +149,9 @@ class DATA_PT_current_curve(DataButtonsPanel):
|
||||
sub.itemR(currentcurve, "radius_interpolation", text="Tilt")
|
||||
sub.itemR(currentcurve, "smooth")
|
||||
|
||||
bpy.types.register(DATA_PT_context_curve)
|
||||
bpy.types.register(DATA_PT_shape_curve)
|
||||
bpy.types.register(DATA_PT_geometry)
|
||||
bpy.types.register(DATA_PT_geometry_curve)
|
||||
bpy.types.register(DATA_PT_pathanim)
|
||||
bpy.types.register(DATA_PT_current_curve)
|
||||
|
||||
|
@ -19,12 +19,9 @@ class DATA_PT_preview(DataButtonsPanel):
|
||||
lamp = context.lamp
|
||||
layout.template_preview(lamp)
|
||||
|
||||
class DATA_PT_lamp(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_lamp"
|
||||
__label__ = "Lamp"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object.type == 'LAMP')
|
||||
class DATA_PT_context_lamp(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_context_lamp"
|
||||
__no_header__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -42,9 +39,16 @@ class DATA_PT_lamp(DataButtonsPanel):
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
layout.itemS()
|
||||
class DATA_PT_lamp(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_lamp"
|
||||
__label__ = "Lamp"
|
||||
|
||||
layout.itemR(lamp, "type", expand=True)
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
lamp = context.lamp
|
||||
|
||||
layout.itemR(lamp, "type")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
@ -244,9 +248,11 @@ class DATA_PT_falloff_curve(DataButtonsPanel):
|
||||
|
||||
layout.template_curve_mapping(lamp.falloff_curve)
|
||||
|
||||
bpy.types.register(DATA_PT_context_lamp)
|
||||
bpy.types.register(DATA_PT_preview)
|
||||
bpy.types.register(DATA_PT_lamp)
|
||||
bpy.types.register(DATA_PT_shadow)
|
||||
bpy.types.register(DATA_PT_sunsky)
|
||||
bpy.types.register(DATA_PT_spot)
|
||||
bpy.types.register(DATA_PT_falloff_curve)
|
||||
|
||||
|
@ -9,12 +9,9 @@ class DataButtonsPanel(bpy.types.Panel):
|
||||
def poll(self, context):
|
||||
return (context.lattice != None)
|
||||
|
||||
class DATA_PT_lattice(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_lattice"
|
||||
__label__ = "Lattice"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object.type == 'LATTICE')
|
||||
class DATA_PT_context_lattice(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_context_lattice"
|
||||
__no_header__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -32,8 +29,15 @@ class DATA_PT_lattice(DataButtonsPanel):
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
if lat:
|
||||
layout.itemS()
|
||||
|
||||
class DATA_PT_lattice(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_lattice"
|
||||
__label__ = "Lattice"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
lat = context.lattice
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(lat, "points_u")
|
||||
@ -48,7 +52,9 @@ class DATA_PT_lattice(DataButtonsPanel):
|
||||
row.itemR(lat, "interpolation_type_w", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
row.itemO("LATTICE_OT_make_regular")
|
||||
row.itemR(lat, "outside")
|
||||
row.itemR(lat, "shape_keys")
|
||||
|
||||
bpy.types.register(DATA_PT_context_lattice)
|
||||
bpy.types.register(DATA_PT_lattice)
|
||||
|
||||
|
@ -9,12 +9,9 @@ class DataButtonsPanel(bpy.types.Panel):
|
||||
def poll(self, context):
|
||||
return (context.mesh != None)
|
||||
|
||||
class DATA_PT_mesh(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_mesh"
|
||||
__label__ = "Mesh"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object and context.object.type == 'MESH')
|
||||
class DATA_PT_context_mesh(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_context_mesh"
|
||||
__no_header__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -32,8 +29,14 @@ class DATA_PT_mesh(DataButtonsPanel):
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
if mesh:
|
||||
layout.itemS()
|
||||
class DATA_PT_mesh(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_mesh"
|
||||
__label__ = "Mesh"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mesh = context.mesh
|
||||
|
||||
split = layout.split()
|
||||
|
||||
@ -46,9 +49,9 @@ class DATA_PT_mesh(DataButtonsPanel):
|
||||
sub.itemR(mesh, "vertex_normal_flip")
|
||||
sub.itemR(mesh, "double_sided")
|
||||
|
||||
layout.itemS()
|
||||
layout.itemR(mesh, "texco_mesh")
|
||||
|
||||
|
||||
class DATA_PT_materials(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_materials"
|
||||
__label__ = "Materials"
|
||||
@ -62,30 +65,154 @@ class DATA_PT_materials(DataButtonsPanel):
|
||||
|
||||
row = layout.row()
|
||||
|
||||
row.template_list(ob, "materials", "active_material_index")
|
||||
row.template_list(ob, "materials", ob, "active_material_index")
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("OBJECT_OT_material_slot_add", icon="ICON_ZOOMIN", text="")
|
||||
col.itemO("OBJECT_OT_material_slot_remove", icon="ICON_ZOOMOUT", text="")
|
||||
|
||||
if context.edit_object:
|
||||
row = layout.row(align=True)
|
||||
|
||||
row.itemO("OBJECT_OT_material_slot_assign", text="Assign");
|
||||
row.itemO("OBJECT_OT_material_slot_select", text="Select");
|
||||
row.itemO("OBJECT_OT_material_slot_deselect", text="Deselect");
|
||||
row.itemO("OBJECT_OT_material_slot_assign", text="Assign")
|
||||
row.itemO("OBJECT_OT_material_slot_select", text="Select")
|
||||
row.itemO("OBJECT_OT_material_slot_deselect", text="Deselect")
|
||||
|
||||
"""
|
||||
layout.itemS()
|
||||
|
||||
box= layout.box()
|
||||
|
||||
row = box.row()
|
||||
row.template_list(ob, "materials", "active_material_index", compact=True)
|
||||
row.template_list(ob, "materials", ob, "active_material_index", compact=True)
|
||||
|
||||
subrow = row.row(align=True)
|
||||
subrow.itemO("OBJECT_OT_material_slot_add", icon="ICON_ZOOMIN", text="")
|
||||
subrow.itemO("OBJECT_OT_material_slot_remove", icon="ICON_ZOOMOUT", text="")
|
||||
"""
|
||||
|
||||
class DATA_PT_vertex_groups(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_vertex_groups"
|
||||
__label__ = "Vertex Groups"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object and context.object.type in ('MESH', 'LATTICE'))
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ob = context.object
|
||||
|
||||
row = layout.row()
|
||||
|
||||
row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index")
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("OBJECT_OT_vertex_group_add", icon="ICON_ZOOMIN", text="")
|
||||
col.itemO("OBJECT_OT_vertex_group_remove", icon="ICON_ZOOMOUT", text="")
|
||||
|
||||
col.itemO("OBJECT_OT_vertex_group_copy", icon="ICON_BLANK1", text="")
|
||||
if ob.data.users > 1:
|
||||
col.itemO("OBJECT_OT_vertex_group_copy_to_linked", icon="ICON_BLANK1", text="")
|
||||
|
||||
if context.edit_object:
|
||||
row = layout.row(align=True)
|
||||
|
||||
row.itemO("OBJECT_OT_vertex_group_assign", text="Assign")
|
||||
row.itemO("OBJECT_OT_vertex_group_remove_from", text="Remove")
|
||||
row.itemO("OBJECT_OT_vertex_group_select", text="Select")
|
||||
row.itemO("OBJECT_OT_vertex_group_deselect", text="Deselect")
|
||||
|
||||
layout.itemR(context.tool_settings, "vertex_group_weight", text="Weight")
|
||||
|
||||
class DATA_PT_shape_keys(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_shape_keys"
|
||||
__label__ = "Shape Keys"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object and context.object.type in ('MESH', 'LATTICE'))
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ob = context.object
|
||||
key = ob.data.shape_keys
|
||||
kb = ob.active_shape_key
|
||||
|
||||
row = layout.row()
|
||||
row.template_list(key, "keys", ob, "active_shape_key_index")
|
||||
|
||||
col = row.column()
|
||||
|
||||
subcol = col.column(align=True)
|
||||
subcol.itemO("OBJECT_OT_shape_key_add", icon="ICON_ZOOMIN", text="")
|
||||
subcol.itemO("OBJECT_OT_shape_key_remove", icon="ICON_ZOOMOUT", text="")
|
||||
|
||||
if kb:
|
||||
col.itemS()
|
||||
|
||||
subcol = col.column(align=True)
|
||||
subcol.itemR(ob, "shape_key_lock", icon="ICON_PINNED", text="")
|
||||
subcol.itemR(kb, "mute", icon="ICON_MUTE_IPO_ON", text="")
|
||||
|
||||
if key.relative:
|
||||
row = layout.row()
|
||||
row.itemR(key, "relative")
|
||||
row.itemL()
|
||||
|
||||
if ob.active_shape_key_index != 0:
|
||||
if not ob.shape_key_lock:
|
||||
row = layout.row(align=True)
|
||||
row.itemR(kb, "value", text="")
|
||||
row.itemR(kb, "slider_min", text="Min")
|
||||
row.itemR(kb, "slider_max", text="Max")
|
||||
|
||||
row = layout.row()
|
||||
row.item_pointerR(kb, "vertex_group", ob, "vertex_groups", text="")
|
||||
row.item_pointerR(kb, "relative_key", key, "keys", text="")
|
||||
else:
|
||||
row = layout.row()
|
||||
row.itemR(key, "relative")
|
||||
row.itemR(key, "slurph")
|
||||
|
||||
if context.edit_object:
|
||||
layout.enabled = False
|
||||
|
||||
class DATA_PT_uv_texture(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_uv_texture"
|
||||
__label__ = "UV Texture"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
me = context.mesh
|
||||
|
||||
row = layout.row()
|
||||
|
||||
row.template_list(me, "uv_textures", me, "active_uv_texture_index")
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("MESH_OT_uv_texture_add", icon="ICON_ZOOMIN", text="")
|
||||
col.itemO("MESH_OT_uv_texture_remove", icon="ICON_ZOOMOUT", text="")
|
||||
|
||||
class DATA_PT_vertex_colors(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_vertex_colors"
|
||||
__label__ = "Vertex Colors"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
me = context.mesh
|
||||
|
||||
row = layout.row()
|
||||
|
||||
row.template_list(me, "vertex_colors", me, "active_vertex_color_index")
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("MESH_OT_vertex_color_add", icon="ICON_ZOOMIN", text="")
|
||||
col.itemO("MESH_OT_vertex_color_remove", icon="ICON_ZOOMOUT", text="")
|
||||
|
||||
bpy.types.register(DATA_PT_context_mesh)
|
||||
bpy.types.register(DATA_PT_mesh)
|
||||
bpy.types.register(DATA_PT_materials)
|
||||
bpy.types.register(DATA_PT_vertex_groups)
|
||||
bpy.types.register(DATA_PT_shape_keys)
|
||||
bpy.types.register(DATA_PT_uv_texture)
|
||||
bpy.types.register(DATA_PT_vertex_colors)
|
||||
|
||||
|
@ -24,61 +24,63 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
||||
if box:
|
||||
if md.type == 'ARMATURE':
|
||||
self.armature(box, ob, md)
|
||||
if md.type == 'ARRAY':
|
||||
elif md.type == 'ARRAY':
|
||||
self.array(box, ob, md)
|
||||
if md.type == 'BEVEL':
|
||||
elif md.type == 'BEVEL':
|
||||
self.bevel(box, ob, md)
|
||||
if md.type == 'BOOLEAN':
|
||||
elif md.type == 'BOOLEAN':
|
||||
self.boolean(box, ob, md)
|
||||
if md.type == 'BUILD':
|
||||
elif md.type == 'BUILD':
|
||||
self.build(box, ob, md)
|
||||
if md.type == 'CAST':
|
||||
elif md.type == 'CAST':
|
||||
self.cast(box, ob, md)
|
||||
if md.type == 'CLOTH':
|
||||
elif md.type == 'CLOTH':
|
||||
self.cloth(box, ob, md)
|
||||
if md.type == 'COLLISION':
|
||||
elif md.type == 'COLLISION':
|
||||
self.collision(box, ob, md)
|
||||
if md.type == 'CURVE':
|
||||
elif md.type == 'CURVE':
|
||||
self.curve(box, ob, md)
|
||||
if md.type == 'DECIMATE':
|
||||
elif md.type == 'DECIMATE':
|
||||
self.decimate(box, ob, md)
|
||||
if md.type == 'DISPLACE':
|
||||
elif md.type == 'DISPLACE':
|
||||
self.displace(box, ob, md)
|
||||
if md.type == 'EDGE_SPLIT':
|
||||
elif md.type == 'EDGE_SPLIT':
|
||||
self.edgesplit(box, ob, md)
|
||||
if md.type == 'EXPLODE':
|
||||
elif md.type == 'EXPLODE':
|
||||
self.explode(box, ob, md)
|
||||
if md.type == 'FLUID_SIMULATION':
|
||||
elif md.type == 'FLUID_SIMULATION':
|
||||
self.fluid(box, ob, md)
|
||||
if md.type == 'HOOK':
|
||||
elif md.type == 'HOOK':
|
||||
self.hook(box, ob, md)
|
||||
if md.type == 'LATTICE':
|
||||
elif md.type == 'LATTICE':
|
||||
self.lattice(box, ob, md)
|
||||
if md.type == 'MASK':
|
||||
elif md.type == 'MASK':
|
||||
self.mask(box, ob, md)
|
||||
if md.type == 'MESH_DEFORM':
|
||||
elif md.type == 'MESH_DEFORM':
|
||||
self.mesh_deform(box, ob, md)
|
||||
if md.type == 'MIRROR':
|
||||
elif md.type == 'MIRROR':
|
||||
self.mirror(box, ob, md)
|
||||
if md.type == 'MULTIRES':
|
||||
elif md.type == 'MULTIRES':
|
||||
self.multires(box, ob, md)
|
||||
if md.type == 'PARTICLE_INSTANCE':
|
||||
elif md.type == 'PARTICLE_INSTANCE':
|
||||
self.particleinstance(box, ob, md)
|
||||
if md.type == 'PARTICLE_SYSTEM':
|
||||
elif md.type == 'PARTICLE_SYSTEM':
|
||||
self.particlesystem(box, ob, md)
|
||||
if md.type == 'SHRINKWRAP':
|
||||
elif md.type == 'SHRINKWRAP':
|
||||
self.shrinkwrap(box, ob, md)
|
||||
if md.type == 'SIMPLE_DEFORM':
|
||||
elif md.type == 'SIMPLE_DEFORM':
|
||||
self.simpledeform(box, ob, md)
|
||||
if md.type == 'SMOOTH':
|
||||
elif md.type == 'SMOOTH':
|
||||
self.smooth(box, ob, md)
|
||||
if md.type == 'SOFTBODY':
|
||||
elif md.type == 'SOFTBODY':
|
||||
self.softbody(box, ob, md)
|
||||
if md.type == 'SUBSURF':
|
||||
elif md.type == 'SUBSURF':
|
||||
self.subsurf(box, ob, md)
|
||||
if md.type == 'UV_PROJECT':
|
||||
elif md.type == 'SURFACE':
|
||||
self.surface(box, ob, md)
|
||||
elif md.type == 'UV_PROJECT':
|
||||
self.uvproject(box, ob, md)
|
||||
if md.type == 'WAVE':
|
||||
elif md.type == 'WAVE':
|
||||
self.wave(box, ob, md)
|
||||
|
||||
def armature(self, layout, ob, md):
|
||||
@ -96,9 +98,9 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
||||
layout.itemR(md, "fit_type")
|
||||
if md.fit_type == 'FIXED_COUNT':
|
||||
layout.itemR(md, "count")
|
||||
if md.fit_type == 'FIT_LENGTH':
|
||||
elif md.fit_type == 'FIT_LENGTH':
|
||||
layout.itemR(md, "length")
|
||||
if md.fit_type == 'FIT_CURVE':
|
||||
elif md.fit_type == 'FIT_CURVE':
|
||||
layout.itemR(md, "curve")
|
||||
|
||||
layout.itemS()
|
||||
@ -152,7 +154,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
||||
if md.limit_method == 'ANGLE':
|
||||
row = layout.row()
|
||||
row.itemR(md, "angle")
|
||||
if md.limit_method == 'WEIGHT':
|
||||
elif md.limit_method == 'WEIGHT':
|
||||
row = layout.row()
|
||||
row.itemR(md, "edge_weight_method", expand=True)
|
||||
|
||||
@ -211,7 +213,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
||||
layout.itemR(md, "texture_coordinates")
|
||||
if md.texture_coordinates == 'OBJECT':
|
||||
layout.itemR(md, "texture_coordinate_object", text="Object")
|
||||
if md.texture_coordinates == 'UV' and ob.type == 'MESH':
|
||||
elif md.texture_coordinates == 'UV' and ob.type == 'MESH':
|
||||
layout.item_pointerR(md, "uv_layer", ob.data, "uv_layers")
|
||||
|
||||
def edgesplit(self, layout, ob, md):
|
||||
@ -235,7 +237,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
||||
# Missing: "Refresh" and "Clear Vertex Group" ?
|
||||
|
||||
def fluid(self, layout, ob, md):
|
||||
layout.itemL(text="See Fluidsim panel.")
|
||||
layout.itemL(text="See Fluid panel.")
|
||||
|
||||
def hook(self, layout, ob, md):
|
||||
layout.itemR(md, "falloff")
|
||||
@ -252,7 +254,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
||||
layout.itemR(md, "mode")
|
||||
if md.mode == 'ARMATURE':
|
||||
layout.itemR(md, "armature")
|
||||
if md.mode == 'VERTEX_GROUP':
|
||||
elif md.mode == 'VERTEX_GROUP':
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
layout.itemR(md, "inverse")
|
||||
|
||||
@ -297,10 +299,21 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
||||
col = layout.column_flow()
|
||||
col.itemR(md, "normal")
|
||||
col.itemR(md, "children")
|
||||
col.itemR(md, "size")
|
||||
col.itemR(md, "path")
|
||||
if md.path:
|
||||
col.itemR(md, "keep_shape")
|
||||
col.itemR(md, "unborn")
|
||||
col.itemR(md, "alive")
|
||||
col.itemR(md, "dead")
|
||||
col.itemL(md, "")
|
||||
if md.path:
|
||||
col.itemR(md, "axis", text="")
|
||||
|
||||
if md.path:
|
||||
row = layout.row()
|
||||
row.itemR(md, "position", slider=True)
|
||||
row.itemR(md, "random_position", text = "Random", slider=True)
|
||||
|
||||
def particlesystem(self, layout, ob, md):
|
||||
layout.itemL(text="See Particle panel.")
|
||||
@ -325,7 +338,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
||||
col.itemR(md, "positive")
|
||||
col.itemR(md, "cull_front_faces")
|
||||
col.itemR(md, "cull_back_faces")
|
||||
if md.mode == 'NEAREST_SURFACEPOINT':
|
||||
elif md.mode == 'NEAREST_SURFACEPOINT':
|
||||
layout.itemR(md, "keep_above_surface")
|
||||
# To-Do: Validate if structs
|
||||
|
||||
@ -350,10 +363,10 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
||||
sub.itemR(md, "factor")
|
||||
sub.itemR(md, "repeat")
|
||||
|
||||
layout.template_pointer(md, "vertex_group", ob, "vertex_groups")
|
||||
layout.item_pointerR(md, "vertex_group", ob, "vertex_groups")
|
||||
|
||||
def softbody(self, layout, ob, md):
|
||||
layout.itemL(text="See Softbody panel.")
|
||||
layout.itemL(text="See Soft Body panel.")
|
||||
|
||||
def subsurf(self, layout, ob, md):
|
||||
layout.itemR(md, "subdivision_type")
|
||||
@ -363,6 +376,9 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
||||
col.itemR(md, "optimal_draw", text="Optimal Display")
|
||||
col.itemR(md, "subsurf_uv")
|
||||
|
||||
def surface(self, layout, ob, md):
|
||||
layout.itemL(text="See Fields panel.")
|
||||
|
||||
def uvproject(self, layout, ob, md):
|
||||
if ob.type == 'MESH':
|
||||
layout.item_pointerR(md, "uv_layer", ob.data, "uv_layers")
|
||||
@ -404,7 +420,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
||||
layout.itemR(md, "texture_coordinates")
|
||||
if md.texture_coordinates == 'MAP_UV' and ob.type == 'MESH':
|
||||
layout.item_pointerR(md, "uv_layer", ob.data, "uv_layers")
|
||||
if md.texture_coordinates == 'OBJECT':
|
||||
elif md.texture_coordinates == 'OBJECT':
|
||||
layout.itemR(md, "texture_coordinates_object")
|
||||
|
||||
col = layout.column_flow()
|
||||
|
@ -7,15 +7,11 @@ class DataButtonsPanel(bpy.types.Panel):
|
||||
__context__ = "data"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object.type == 'TEXT' and context.curve)
|
||||
return (context.object and context.object.type == 'TEXT' and context.curve)
|
||||
|
||||
class DATA_PT_shape_text(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_shape_text"
|
||||
__label__ = "Shape Text"
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
return (context.object.type == 'TEXT')
|
||||
class DATA_PT_context_text(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_context_text"
|
||||
__no_header__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -33,8 +29,18 @@ class DATA_PT_shape_text(DataButtonsPanel):
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
class DATA_PT_shape_text(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_shape_text"
|
||||
__label__ = "Shape Text"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
curve = context.curve
|
||||
space = context.space_data
|
||||
|
||||
if curve:
|
||||
layout.itemS()
|
||||
layout.itemR(curve, "curve_2d")
|
||||
|
||||
split = layout.split()
|
||||
@ -58,6 +64,28 @@ class DATA_PT_shape_text(DataButtonsPanel):
|
||||
sub.itemL(text="Display:")
|
||||
sub.itemR(curve, "fast")
|
||||
|
||||
class DATA_PT_geometry_text(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_geometry_text"
|
||||
__label__ = "Geometry"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
curve = context.curve
|
||||
|
||||
split = layout.split()
|
||||
|
||||
sub = split.column()
|
||||
sub.itemL(text="Modification:")
|
||||
sub.itemR(curve, "width")
|
||||
sub.itemR(curve, "extrude")
|
||||
sub.itemR(curve, "taper_object")
|
||||
|
||||
sub = split.column()
|
||||
sub.itemL(text="Bevel:")
|
||||
sub.itemR(curve, "bevel_depth", text="Depth")
|
||||
sub.itemR(curve, "bevel_resolution", text="Resolution")
|
||||
sub.itemR(curve, "bevel_object")
|
||||
|
||||
class DATA_PT_font(DataButtonsPanel):
|
||||
__idname__ = "DATA_PT_font"
|
||||
__label__ = "Font"
|
||||
@ -112,7 +140,7 @@ class DATA_PT_paragraph(DataButtonsPanel):
|
||||
sub.itemL(text="Offset:")
|
||||
sub.itemR(text, "x_offset", text="X")
|
||||
sub.itemR(text, "y_offset", text="Y")
|
||||
sub.itemR(text, "wrap")
|
||||
#sub.itemR(text, "wrap")
|
||||
|
||||
"""
|
||||
class DATA_PT_textboxes(DataButtonsPanel):
|
||||
@ -124,7 +152,10 @@ class DATA_PT_textboxes(DataButtonsPanel):
|
||||
text = context.curve
|
||||
"""
|
||||
|
||||
bpy.types.register(DATA_PT_context_text)
|
||||
bpy.types.register(DATA_PT_shape_text)
|
||||
bpy.types.register(DATA_PT_geometry_text)
|
||||
bpy.types.register(DATA_PT_font)
|
||||
bpy.types.register(DATA_PT_paragraph)
|
||||
#bpy.types.register(DATA_PT_textboxes)
|
||||
|
||||
|
@ -19,12 +19,12 @@ class MATERIAL_PT_preview(MaterialButtonsPanel):
|
||||
|
||||
layout.template_preview(mat)
|
||||
|
||||
class MATERIAL_PT_material(MaterialButtonsPanel):
|
||||
__idname__= "MATERIAL_PT_material"
|
||||
__label__ = "Material"
|
||||
class MATERIAL_PT_context_material(MaterialButtonsPanel):
|
||||
__idname__= "MATERIAL_PT_context_material"
|
||||
__no_header__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object != None)
|
||||
return (context.object)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -34,18 +34,38 @@ class MATERIAL_PT_material(MaterialButtonsPanel):
|
||||
slot = context.material_slot
|
||||
space = context.space_data
|
||||
|
||||
if ob:
|
||||
row = layout.row()
|
||||
|
||||
row.template_list(ob, "materials", ob, "active_material_index")
|
||||
|
||||
col = row.column(align=True)
|
||||
col.itemO("OBJECT_OT_material_slot_add", icon="ICON_ZOOMIN", text="")
|
||||
col.itemO("OBJECT_OT_material_slot_remove", icon="ICON_ZOOMOUT", text="")
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if ob and slot:
|
||||
split.template_ID(slot, "material", new="MATERIAL_OT_new")
|
||||
split.itemR(ob, "active_material_index", text="Active")
|
||||
#split.itemR(ob, "active_material_index", text="Active")
|
||||
elif mat:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
|
||||
if mat:
|
||||
layout.itemS()
|
||||
|
||||
class MATERIAL_PT_material(MaterialButtonsPanel):
|
||||
__idname__= "MATERIAL_PT_material"
|
||||
__label__ = "Material"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = context.material
|
||||
ob = context.object
|
||||
slot = context.material_slot
|
||||
space = context.space_data
|
||||
|
||||
if mat:
|
||||
layout.itemR(mat, "type", expand=True)
|
||||
|
||||
layout.itemR(mat, "alpha", slider=True)
|
||||
@ -170,10 +190,8 @@ class MATERIAL_PT_diffuse(MaterialButtonsPanel):
|
||||
sub = split.column()
|
||||
if mat.diffuse_shader == 'OREN_NAYAR':
|
||||
sub.itemR(mat, "roughness")
|
||||
sub = split.column()
|
||||
if mat.diffuse_shader == 'MINNAERT':
|
||||
sub.itemR(mat, "darkness")
|
||||
sub = split.column()
|
||||
if mat.diffuse_shader == 'TOON':
|
||||
sub.itemR(mat, "diffuse_toon_size", text="Size")
|
||||
sub = split.column()
|
||||
@ -213,13 +231,13 @@ class MATERIAL_PT_specular(MaterialButtonsPanel):
|
||||
sub = split.column()
|
||||
if mat.spec_shader in ('COOKTORR', 'PHONG'):
|
||||
sub.itemR(mat, "specular_hardness", text="Hardness")
|
||||
sub = split.column()
|
||||
if mat.spec_shader == 'BLINN':
|
||||
sub.itemR(mat, "specular_hardness", text="Hardness")
|
||||
sub = split.column()
|
||||
sub.itemR(mat, "specular_ior", text="IOR")
|
||||
if mat.spec_shader == 'WARDISO':
|
||||
sub.itemR(mat, "specular_slope", text="Slope")
|
||||
sub = split.column()
|
||||
sub.itemR(mat, "specular_hardness", text="Hardness")
|
||||
if mat.spec_shader == 'TOON':
|
||||
sub.itemR(mat, "specular_toon_size", text="Size")
|
||||
@ -410,6 +428,8 @@ class MATERIAL_PT_halo(MaterialButtonsPanel):
|
||||
colsub.itemR(halo, "flare_seed", text="Seed")
|
||||
colsub.itemR(halo, "flares_sub", text="Sub")
|
||||
|
||||
|
||||
bpy.types.register(MATERIAL_PT_context_material)
|
||||
bpy.types.register(MATERIAL_PT_preview)
|
||||
bpy.types.register(MATERIAL_PT_material)
|
||||
bpy.types.register(MATERIAL_PT_diffuse)
|
||||
|
@ -6,6 +6,18 @@ class ObjectButtonsPanel(bpy.types.Panel):
|
||||
__region_type__ = "WINDOW"
|
||||
__context__ = "object"
|
||||
|
||||
class OBJECT_PT_context_object(ObjectButtonsPanel):
|
||||
__idname__ = "OBJECT_PT_context_object"
|
||||
__no_header__ = True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ob = context.object
|
||||
|
||||
split = layout.split(percentage=0.06)
|
||||
split.itemL(text="", icon="ICON_OBJECT_DATA")
|
||||
split.itemR(ob, "name", text="")
|
||||
|
||||
class OBJECT_PT_transform(ObjectButtonsPanel):
|
||||
__idname__ = "OBJECT_PT_transform"
|
||||
__label__ = "Transform"
|
||||
@ -124,6 +136,7 @@ class OBJECT_PT_animation(ObjectButtonsPanel):
|
||||
sub.itemR(ob, "up_axis", text="Up Axis")
|
||||
sub.itemR(ob, "track_rotation", text="Rotation")
|
||||
|
||||
bpy.types.register(OBJECT_PT_context_object)
|
||||
bpy.types.register(OBJECT_PT_transform)
|
||||
bpy.types.register(OBJECT_PT_groups)
|
||||
bpy.types.register(OBJECT_PT_display)
|
||||
|
@ -7,23 +7,46 @@ class PhysicButtonsPanel(bpy.types.Panel):
|
||||
__context__ = "physics"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.cloth != None)
|
||||
ob = context.object
|
||||
return (ob and ob.type == 'MESH')
|
||||
|
||||
class Physic_PT_cloth(PhysicButtonsPanel):
|
||||
__idname__ = "Physic_PT_cloth"
|
||||
class PHYSICS_PT_cloth(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_cloth"
|
||||
__label__ = "Cloth"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
cloth = context.cloth.settings
|
||||
md = context.cloth
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
split.operator_context = "EXEC_DEFAULT"
|
||||
|
||||
if md:
|
||||
# remove modifier + settings
|
||||
split.set_context_pointer("modifier", md)
|
||||
split.itemO("OBJECT_OT_modifier_remove", text="Remove")
|
||||
|
||||
row = split.row(align=True)
|
||||
row.itemR(md, "render", text="")
|
||||
row.itemR(md, "realtime", text="")
|
||||
else:
|
||||
# add modifier
|
||||
split.item_enumO("OBJECT_OT_modifier_add", "type", "CLOTH", text="Add")
|
||||
split.itemL()
|
||||
|
||||
if md:
|
||||
cloth = md.settings
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(cloth, "quality", slider=True)
|
||||
col.itemR(cloth, "gravity")
|
||||
col.itemR(cloth, "mass")
|
||||
col.itemR(cloth, "mass_vertex_group", text="Vertex Group")
|
||||
|
||||
subcol = col.column(align=True)
|
||||
subcol.itemR(cloth, "mass")
|
||||
subcol.item_pointerR(cloth, "mass_vertex_group", ob, "vertex_groups", text="")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Stiffness:")
|
||||
@ -46,9 +69,12 @@ class Physic_PT_cloth(PhysicButtonsPanel):
|
||||
|
||||
class PHYSICS_PT_cloth_cache(PhysicButtonsPanel):
|
||||
__idname__= "PHYSICS_PT_cloth_cache"
|
||||
__label__ = "Cache"
|
||||
__label__ = "Cloth Cache"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return (context.cloth != None)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
@ -91,19 +117,22 @@ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel):
|
||||
row.itemO("PTCACHE_OT_free_bake_all", text="Free All Bakes")
|
||||
layout.itemO("PTCACHE_OT_bake_all", text="Update All Dynamics to current frame")
|
||||
|
||||
class Physic_PT_cloth_collision(PhysicButtonsPanel):
|
||||
__idname__ = "Physic_PT_clothcollision"
|
||||
class PHYSICS_PT_cloth_collision(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_clothcollision"
|
||||
__label__ = "Cloth Collision"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.cloth != None)
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
cloth = context.cloth.settings
|
||||
cloth = context.cloth.collision_settings
|
||||
|
||||
layout.itemR(cloth, "enable_collision", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
cloth = context.cloth.settings
|
||||
cloth = context.cloth.collision_settings
|
||||
|
||||
layout.active = cloth.enable_collision
|
||||
|
||||
@ -120,10 +149,13 @@ class Physic_PT_cloth_collision(PhysicButtonsPanel):
|
||||
col.itemR(cloth, "self_collision_quality", slider=True)
|
||||
col.itemR(cloth, "self_min_distance", text="MinDistance")
|
||||
|
||||
class Physic_PT_cloth_stiffness(PhysicButtonsPanel):
|
||||
__idname__ = "Physic_PT_stiffness"
|
||||
class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_stiffness"
|
||||
__label__ = "Cloth Stiffness Scaling"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.cloth != None)
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
cloth = context.cloth.settings
|
||||
@ -132,23 +164,25 @@ class Physic_PT_cloth_stiffness(PhysicButtonsPanel):
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ob = context.object
|
||||
cloth = context.cloth.settings
|
||||
|
||||
layout.active = cloth.stiffness_scaling
|
||||
|
||||
split = layout.split()
|
||||
|
||||
sub = split.column()
|
||||
sub = split.column(align=True)
|
||||
sub.itemL(text="Structural Stiffness:")
|
||||
sub.column().itemR(cloth, "structural_stiffness_vertex_group", text="VGroup")
|
||||
sub.item_pointerR(cloth, "structural_stiffness_vertex_group", ob, "vertex_groups", text="")
|
||||
sub.itemR(cloth, "structural_stiffness_max", text="Max")
|
||||
|
||||
sub = split.column()
|
||||
sub = split.column(align=True)
|
||||
sub.itemL(text="Bending Stiffness:")
|
||||
sub.column().itemR(cloth, "bending_vertex_group", text="VGroup")
|
||||
sub.item_pointerR(cloth, "bending_vertex_group", ob, "vertex_groups", text="")
|
||||
sub.itemR(cloth, "bending_stiffness_max", text="Max")
|
||||
|
||||
bpy.types.register(Physic_PT_cloth)
|
||||
bpy.types.register(PHYSICS_PT_cloth)
|
||||
bpy.types.register(PHYSICS_PT_cloth_cache)
|
||||
bpy.types.register(Physic_PT_cloth_collision)
|
||||
bpy.types.register(Physic_PT_cloth_stiffness)
|
||||
bpy.types.register(PHYSICS_PT_cloth_collision)
|
||||
bpy.types.register(PHYSICS_PT_cloth_stiffness)
|
||||
|
||||
|
66
release/ui/buttons_physics_field.py
Normal file
66
release/ui/buttons_physics_field.py
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class PhysicButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = "BUTTONS_WINDOW"
|
||||
__region_type__ = "WINDOW"
|
||||
__context__ = "physics"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.object != None)
|
||||
|
||||
class PHYSICS_PT_field(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_field"
|
||||
__label__ = "Field"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ob = context.object
|
||||
field = ob.field
|
||||
|
||||
layout.itemR(field, "type")
|
||||
|
||||
if field.type != "NONE":
|
||||
layout.itemR(field, "strength")
|
||||
|
||||
if field.type in ("HARMONIC", "SPHERICAL", "CHARGE", "LENNARDj"):
|
||||
if ob.type in ("MESH", "SURFACE", "FONT", "CURVE"):
|
||||
layout.itemR(field, "surface")
|
||||
|
||||
class PHYSICS_PT_collision(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_collision"
|
||||
__label__ = "Collision"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
return (ob and ob.type == 'MESH')
|
||||
|
||||
def draw_header(self, context):
|
||||
settings = context.object.collision
|
||||
self.layout.itemR(settings, "enabled", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
md = context.collision
|
||||
settings = context.object.collision
|
||||
|
||||
layout.active = settings.enabled
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Damping:")
|
||||
col.itemR(settings, "damping_factor", text="Factor");
|
||||
col.itemR(settings, "random_damping", text="Random");
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Friction:")
|
||||
col.itemR(settings, "friction_factor", text="Factor");
|
||||
col.itemR(settings, "random_friction", text="Random");
|
||||
|
||||
layout.itemR(settings, "permeability");
|
||||
layout.itemR(settings, "kill_particles");
|
||||
|
||||
bpy.types.register(PHYSICS_PT_field)
|
||||
bpy.types.register(PHYSICS_PT_collision)
|
223
release/ui/buttons_physics_fluid.py
Normal file
223
release/ui/buttons_physics_fluid.py
Normal file
@ -0,0 +1,223 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class PhysicButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = "BUTTONS_WINDOW"
|
||||
__region_type__ = "WINDOW"
|
||||
__context__ = "physics"
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
return (ob and ob.type == 'MESH')
|
||||
|
||||
class PHYSICS_PT_fluid(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_fluid"
|
||||
__label__ = "Fluid"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
md = context.fluid
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
split.operator_context = "EXEC_DEFAULT"
|
||||
|
||||
if md:
|
||||
# remove modifier + settings
|
||||
split.set_context_pointer("modifier", md)
|
||||
split.itemO("OBJECT_OT_modifier_remove", text="Remove")
|
||||
|
||||
row = split.row(align=True)
|
||||
row.itemR(md, "render", text="")
|
||||
row.itemR(md, "realtime", text="")
|
||||
else:
|
||||
# add modifier
|
||||
split.item_enumO("OBJECT_OT_modifier_add", "type", "FLUID_SIMULATION", text="Add")
|
||||
split.itemL()
|
||||
|
||||
if md:
|
||||
fluid = md.settings
|
||||
|
||||
col = layout.column(align=True)
|
||||
row = col.row()
|
||||
row.item_enumR(fluid, "type", "DOMAIN")
|
||||
row.item_enumR(fluid, "type", "FLUID")
|
||||
row.item_enumR(fluid, "type", "OBSTACLE")
|
||||
row = col.row()
|
||||
row.item_enumR(fluid, "type", "INFLOW")
|
||||
row.item_enumR(fluid, "type", "OUTFLOW")
|
||||
row.item_enumR(fluid, "type", "PARTICLE")
|
||||
row.item_enumR(fluid, "type", "CONTROL")
|
||||
|
||||
if fluid.type == 'DOMAIN':
|
||||
layout.itemO("FLUID_OT_bake", text="BAKE")
|
||||
layout.itemL(text="Required Memory: " + fluid.memory_estimate)
|
||||
|
||||
layout.itemL(text="Resolution:")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
colsub = col.column(align=True)
|
||||
colsub.itemR(fluid, "resolution", text="Final")
|
||||
colsub.itemR(fluid, "render_display_mode", text="")
|
||||
colsub = col.column(align=True)
|
||||
colsub.itemL(text="Time:")
|
||||
colsub.itemR(fluid, "start_time", text="Start")
|
||||
colsub.itemR(fluid, "end_time", text="End")
|
||||
|
||||
col = split.column()
|
||||
colsub = col.column(align=True)
|
||||
colsub.itemR(fluid, "preview_resolution", text="Preview", slider=True)
|
||||
colsub.itemR(fluid, "viewport_display_mode", text="")
|
||||
colsub = col.column()
|
||||
colsub.itemR(fluid, "reverse_frames")
|
||||
colsub.itemR(fluid, "generate_speed_vectors")
|
||||
colsub.itemR(fluid, "path", text="")
|
||||
|
||||
if fluid.type in ('FLUID', 'OBSTACLE', 'INFLOW', 'OUTFLOW'):
|
||||
layout.itemR(fluid, "volume_initialization")
|
||||
|
||||
if fluid.type == 'FLUID':
|
||||
row = layout.row()
|
||||
row.column().itemR(fluid, "initial_velocity")
|
||||
row.itemR(fluid, "export_animated_mesh")
|
||||
|
||||
if fluid.type == 'OBSTACLE':
|
||||
row = layout.row()
|
||||
row.itemL()
|
||||
row.itemR(fluid, "export_animated_mesh")
|
||||
layout.itemR(fluid, "slip_type", expand=True)
|
||||
if fluid.slip_type == 'PARTIALSLIP':
|
||||
layout.itemR(fluid, "partial_slip_amount", text="Amount")
|
||||
|
||||
layout.itemR(fluid, "impact_factor")
|
||||
|
||||
if fluid.type == 'INFLOW':
|
||||
row = layout.row()
|
||||
row.column().itemR(fluid, "inflow_velocity")
|
||||
row.itemR(fluid, "export_animated_mesh")
|
||||
layout.itemR(fluid, "local_coordinates")
|
||||
|
||||
if fluid.type == 'OUTFLOW':
|
||||
row = layout.row()
|
||||
row.itemL()
|
||||
row.itemR(fluid, "export_animated_mesh")
|
||||
|
||||
if fluid.type == 'PARTICLE':
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Type:")
|
||||
col.itemR(fluid, "drops")
|
||||
col.itemR(fluid, "floats")
|
||||
col.itemR(fluid, "tracer")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Influence:")
|
||||
col.itemR(fluid, "particle_influence", text="Particle")
|
||||
col.itemR(fluid, "alpha_influence", text="Alpha")
|
||||
|
||||
layout.itemR(fluid, "path")
|
||||
|
||||
if fluid.type == 'CONTROL':
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Time:")
|
||||
col.itemR(fluid, "start_time", text="Start")
|
||||
col.itemR(fluid, "end_time", text="End")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(fluid, "quality", slider=True)
|
||||
col.itemR(fluid, "reverse_frames")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Attraction:")
|
||||
col.itemR(fluid, "attraction_strength", text="Strength")
|
||||
col.itemR(fluid, "attraction_radius", text="Radius")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Velocity:")
|
||||
col.itemR(fluid, "velocity_strength", text="Strength")
|
||||
col.itemR(fluid, "velocity_radius", text="Radius")
|
||||
|
||||
class PHYSICS_PT_domain_gravity(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_domain_gravity"
|
||||
__label__ = "Domain World/Gravity"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
md = context.fluid
|
||||
if md:
|
||||
return (md.settings.type == 'DOMAIN')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
fluid = context.fluid.settings
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemR(fluid, "gravity")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Viscosity:")
|
||||
col.itemR(fluid, "viscosity_preset", text="")
|
||||
if fluid.viscosity_preset == 'MANUAL':
|
||||
col.itemR(fluid, "viscosity_base", text="Base")
|
||||
col.itemR(fluid, "viscosity_exponent", text="Exponent")
|
||||
|
||||
col = layout.column_flow()
|
||||
col.itemR(fluid, "real_world_size")
|
||||
col.itemR(fluid, "grid_levels")
|
||||
col.itemR(fluid, "compressibility")
|
||||
|
||||
class PHYSICS_PT_domain_boundary(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_domain_boundary"
|
||||
__label__ = "Domain Boundary"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
md = context.fluid
|
||||
if md:
|
||||
return (md.settings.type == 'DOMAIN')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
fluid = context.fluid.settings
|
||||
|
||||
layout.itemL(text="Slip:")
|
||||
|
||||
layout.itemR(fluid, "slip_type", expand=True)
|
||||
if fluid.slip_type == 'PARTIALSLIP':
|
||||
layout.itemR(fluid, "partial_slip_amount", text="Amount")
|
||||
|
||||
layout.itemL(text="Surface:")
|
||||
row = layout.row()
|
||||
row.itemR(fluid, "surface_smoothing", text="Smoothing")
|
||||
row.itemR(fluid, "surface_subdivisions", text="Subdivisions")
|
||||
|
||||
class PHYSICS_PT_domain_particles(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_domain_particles"
|
||||
__label__ = "Domain Particles"
|
||||
__default_closed__ = True
|
||||
|
||||
def poll(self, context):
|
||||
md = context.fluid
|
||||
if md:
|
||||
return (md.settings.type == 'DOMAIN')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
fluid = context.fluid.settings
|
||||
|
||||
layout.itemR(fluid, "tracer_particles")
|
||||
layout.itemR(fluid, "generate_particles")
|
||||
|
||||
bpy.types.register(PHYSICS_PT_fluid)
|
||||
bpy.types.register(PHYSICS_PT_domain_gravity)
|
||||
bpy.types.register(PHYSICS_PT_domain_boundary)
|
||||
bpy.types.register(PHYSICS_PT_domain_particles)
|
219
release/ui/buttons_physics_softbody.py
Normal file
219
release/ui/buttons_physics_softbody.py
Normal file
@ -0,0 +1,219 @@
|
||||
|
||||
import bpy
|
||||
|
||||
class PhysicButtonsPanel(bpy.types.Panel):
|
||||
__space_type__ = "BUTTONS_WINDOW"
|
||||
__region_type__ = "WINDOW"
|
||||
__context__ = "physics"
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.object
|
||||
return (ob and ob.type == 'MESH')
|
||||
|
||||
class PHYSICS_PT_softbody(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_softbody"
|
||||
__label__ = "Soft Body"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
md = context.soft_body
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
split.operator_context = "EXEC_DEFAULT"
|
||||
|
||||
if md:
|
||||
# remove modifier + settings
|
||||
split.set_context_pointer("modifier", md)
|
||||
split.itemO("OBJECT_OT_modifier_remove", text="Remove")
|
||||
|
||||
row = split.row(align=True)
|
||||
row.itemR(md, "render", text="")
|
||||
row.itemR(md, "realtime", text="")
|
||||
else:
|
||||
# add modifier
|
||||
split.item_enumO("OBJECT_OT_modifier_add", "type", "SOFTBODY", text="Add")
|
||||
split.itemL("")
|
||||
|
||||
if md:
|
||||
softbody = md.settings
|
||||
|
||||
# General
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Object:")
|
||||
col.itemR(softbody, "mass")
|
||||
col.itemR(softbody, "friction")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Simulation:")
|
||||
col.itemR(softbody, "gravity")
|
||||
col.itemR(softbody, "speed")
|
||||
|
||||
|
||||
class PHYSICS_PT_softbody_goal(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_softbody_goal"
|
||||
__label__ = "Soft Body Goal"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.soft_body != None)
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
softbody = context.soft_body.settings
|
||||
|
||||
layout.itemR(softbody, "use_goal", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
md = context.soft_body
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
|
||||
if md:
|
||||
softbody = md.settings
|
||||
layout.active = softbody.use_goal
|
||||
|
||||
# Goal
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Goal Strengths:")
|
||||
col.itemR(softbody, "goal_default", text="Default")
|
||||
subcol = col.column(align=True)
|
||||
subcol.itemR(softbody, "goal_min", text="Minimum")
|
||||
subcol.itemR(softbody, "goal_max", text="Maximum")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Goal Settings:")
|
||||
col.itemR(softbody, "goal_spring", text="Stiffness")
|
||||
col.itemR(softbody, "goal_friction", text="Damping")
|
||||
layout.item_pointerR(softbody, "goal_vertex_group", ob, "vertex_groups", text="Vertex Group")
|
||||
|
||||
class PHYSICS_PT_softbody_edge(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_softbody_edge"
|
||||
__label__ = "Soft Body Edges"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.soft_body != None)
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
softbody = context.soft_body.settings
|
||||
|
||||
layout.itemR(softbody, "use_edges", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
md = context.soft_body
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
|
||||
if md:
|
||||
softbody = md.settings
|
||||
|
||||
layout.active = softbody.use_edges
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Springs:")
|
||||
col.itemR(softbody, "pull")
|
||||
col.itemR(softbody, "push")
|
||||
col.itemR(softbody, "damp")
|
||||
col.itemR(softbody, "plastic")
|
||||
col.itemR(softbody, "bending")
|
||||
col.itemR(softbody, "spring_length", text="Length")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(softbody, "stiff_quads")
|
||||
subcol = col.column()
|
||||
subcol.active = softbody.stiff_quads
|
||||
subcol.itemR(softbody, "shear")
|
||||
|
||||
col.itemR(softbody, "new_aero", text="Aero")
|
||||
subcol = col.column()
|
||||
subcol.active = softbody.new_aero
|
||||
subcol.itemR(softbody, "aero", text="Factor", enabled=softbody.new_aero)
|
||||
|
||||
col.itemL(text="Collision:")
|
||||
col.itemR(softbody, "edge_collision", text="Edge")
|
||||
col.itemR(softbody, "face_collision", text="Face")
|
||||
|
||||
class PHYSICS_PT_softbody_collision(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_softbody_collision"
|
||||
__label__ = "Soft Body Collision"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.soft_body != None)
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
softbody = context.soft_body.settings
|
||||
|
||||
layout.itemR(softbody, "self_collision", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
md = context.soft_body
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
|
||||
if md:
|
||||
softbody = md.settings
|
||||
|
||||
layout.active = softbody.self_collision
|
||||
layout.itemL(text="Collision Type:")
|
||||
layout.itemR(softbody, "collision_type", expand=True)
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.itemL(text="Ball:")
|
||||
col.itemR(softbody, "ball_size", text="Size")
|
||||
col.itemR(softbody, "ball_stiff", text="Stiffness")
|
||||
col.itemR(softbody, "ball_damp", text="Dampening")
|
||||
|
||||
class PHYSICS_PT_softbody_solver(PhysicButtonsPanel):
|
||||
__idname__ = "PHYSICS_PT_softbody_solver"
|
||||
__label__ = "Soft Body Solver"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.soft_body != None)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
md = context.soft_body
|
||||
ob = context.object
|
||||
|
||||
split = layout.split()
|
||||
|
||||
if md:
|
||||
softbody = md.settings
|
||||
|
||||
# Solver
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.itemL(text="Step Size:")
|
||||
col.itemR(softbody, "minstep")
|
||||
col.itemR(softbody, "maxstep")
|
||||
col.itemR(softbody, "auto_step", text="Auto-Step")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(softbody, "error_limit")
|
||||
|
||||
col.itemL(text="Helpers:")
|
||||
col.itemR(softbody, "choke")
|
||||
col.itemR(softbody, "fuzzy")
|
||||
|
||||
layout.itemL(text="Diagnostics:")
|
||||
layout.itemR(softbody, "diagnose")
|
||||
|
||||
bpy.types.register(PHYSICS_PT_softbody)
|
||||
bpy.types.register(PHYSICS_PT_softbody_goal)
|
||||
bpy.types.register(PHYSICS_PT_softbody_edge)
|
||||
bpy.types.register(PHYSICS_PT_softbody_collision)
|
||||
bpy.types.register(PHYSICS_PT_softbody_solver)
|
@ -35,6 +35,8 @@ class RENDER_PT_output(RenderButtonsPanel):
|
||||
layout = self.layout
|
||||
rd = context.scene.render_data
|
||||
|
||||
layout.itemR(rd, "display_mode", text="Display")
|
||||
|
||||
layout.itemR(rd, "output_path")
|
||||
|
||||
split = layout.split()
|
||||
@ -54,7 +56,6 @@ class RENDER_PT_output(RenderButtonsPanel):
|
||||
col.itemR(rd, "placeholders")
|
||||
col.itemR(rd, "no_overwrite")
|
||||
|
||||
|
||||
layout.itemR(rd, "file_format", text="Format")
|
||||
|
||||
split = layout.split()
|
||||
|
@ -19,9 +19,9 @@ class TEXTURE_PT_preview(TextureButtonsPanel):
|
||||
|
||||
layout.template_preview(tex)
|
||||
|
||||
class TEXTURE_PT_texture(TextureButtonsPanel):
|
||||
__idname__= "TEXTURE_PT_texture"
|
||||
__label__ = "Texture"
|
||||
class TEXTURE_PT_context_texture(TextureButtonsPanel):
|
||||
__idname__= "TEXTURE_PT_context_texture"
|
||||
__no_header__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return (context.material or context.world or context.lamp)
|
||||
@ -36,6 +36,20 @@ class TEXTURE_PT_texture(TextureButtonsPanel):
|
||||
space = context.space_data
|
||||
slot = context.texture_slot
|
||||
|
||||
if ma or la or wo:
|
||||
row = layout.row()
|
||||
if ma:
|
||||
row.template_list(ma, "textures", ma, "active_texture_index")
|
||||
elif la:
|
||||
row.template_list(la, "textures", la, "active_texture_index")
|
||||
elif wo:
|
||||
row.template_list(wo, "textures", wo, "active_texture_index")
|
||||
"""if ma or la or wo:
|
||||
col = row.column(align=True)
|
||||
col.itemO("TEXTURE_OT_new", icon="ICON_ZOOMIN", text="")
|
||||
#col.itemO("OBJECT_OT_material_slot_remove", icon="ICON_ZOOMOUT", text="")
|
||||
"""
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
if ma or la or wo:
|
||||
@ -44,12 +58,6 @@ class TEXTURE_PT_texture(TextureButtonsPanel):
|
||||
else:
|
||||
split.itemS()
|
||||
|
||||
if ma:
|
||||
split.itemR(ma, "active_texture_index", text="Active")
|
||||
elif la:
|
||||
split.itemR(la, "active_texture_index", text="Active")
|
||||
elif wo:
|
||||
split.itemR(wo, "active_texture_index", text="Active")
|
||||
elif tex:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.itemS()
|
||||
@ -508,8 +516,8 @@ class TEXTURE_PT_distortednoise(TextureButtonsPanel):
|
||||
sub = split.column()
|
||||
sub.itemR(tex, "nabla")
|
||||
|
||||
bpy.types.register(TEXTURE_PT_context_texture)
|
||||
bpy.types.register(TEXTURE_PT_preview)
|
||||
bpy.types.register(TEXTURE_PT_texture)
|
||||
bpy.types.register(TEXTURE_PT_clouds)
|
||||
bpy.types.register(TEXTURE_PT_wood)
|
||||
bpy.types.register(TEXTURE_PT_marble)
|
||||
|
@ -18,8 +18,8 @@ class WORLD_PT_preview(WorldButtonsPanel):
|
||||
|
||||
layout.template_preview(world)
|
||||
|
||||
class WORLD_PT_world(WorldButtonsPanel):
|
||||
__label__ = "World"
|
||||
class WORLD_PT_context_world(WorldButtonsPanel):
|
||||
__no_header__ = True
|
||||
|
||||
def poll(self, context):
|
||||
return (context.scene != None)
|
||||
@ -38,10 +38,15 @@ class WORLD_PT_world(WorldButtonsPanel):
|
||||
elif world:
|
||||
split.template_ID(space, "pin_id")
|
||||
|
||||
split.itemS()
|
||||
class WORLD_PT_world(WorldButtonsPanel):
|
||||
__label__ = "World"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
world = context.world
|
||||
|
||||
if world:
|
||||
layout.itemS()
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(world, "blend_sky")
|
||||
@ -171,6 +176,7 @@ class WORLD_PT_ambient_occlusion(WorldButtonsPanel):
|
||||
col.row().itemR(ao, "color", expand=True)
|
||||
col.itemR(ao, "energy")
|
||||
|
||||
bpy.types.register(WORLD_PT_context_world)
|
||||
bpy.types.register(WORLD_PT_preview)
|
||||
bpy.types.register(WORLD_PT_world)
|
||||
bpy.types.register(WORLD_PT_ambient_occlusion)
|
||||
|
@ -21,6 +21,8 @@ class FILEBROWSER_HT_header(bpy.types.Header):
|
||||
row = layout.row(align=True)
|
||||
row.itemO("FILE_OT_parent", text="", icon='ICON_FILE_PARENT')
|
||||
row.itemO("FILE_OT_refresh", text="", icon='ICON_FILE_REFRESH')
|
||||
row.itemO("FILE_OT_previous", text="", icon='ICON_PREV_KEYFRAME')
|
||||
row.itemO("FILE_OT_next", text="", icon='ICON_NEXT_KEYFRAME')
|
||||
|
||||
layout.itemR(params, "display", expand=True, text="")
|
||||
layout.itemR(params, "sort", expand=True, text="")
|
||||
|
@ -13,7 +13,7 @@ class IMAGE_MT_view(bpy.types.Menu):
|
||||
|
||||
show_uvedit = sima.show_uvedit
|
||||
|
||||
layout.itemO("IMAGE_OT_properties") # icon
|
||||
layout.itemO("IMAGE_OT_properties", icon="ICON_MENU_PANEL")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
@ -55,7 +55,7 @@ class IMAGE_MT_select(bpy.types.Menu):
|
||||
layout.itemS()
|
||||
|
||||
layout.itemO("UV_OT_select_all_toggle")
|
||||
layout.itemO("UV_OT_select_invert")
|
||||
layout.itemO("UV_OT_select_inverse")
|
||||
layout.itemO("UV_OT_unlink_selection")
|
||||
|
||||
layout.itemS()
|
||||
@ -257,8 +257,6 @@ class IMAGE_HT_header(bpy.types.Header):
|
||||
if show_uvedit:
|
||||
uvedit = sima.uv_editor
|
||||
|
||||
layout.itemS()
|
||||
|
||||
layout.itemR(uvedit, "pivot", text="")
|
||||
layout.itemR(settings, "uv_sync_selection", text="")
|
||||
|
||||
|
@ -90,6 +90,10 @@ class SEQUENCER_MT_view(bpy.types.Menu):
|
||||
"""
|
||||
|
||||
layout.itemR(st, "draw_frames")
|
||||
if st.display_mode == 'IMAGE':
|
||||
layout.itemR(st, "draw_safe_margin")
|
||||
if st.display_mode == 'WAVEFORM':
|
||||
layout.itemR(st, "seperate_color_preview")
|
||||
|
||||
"""
|
||||
if(!sa->full) uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Maximize Window|Ctrl UpArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,0, "");
|
||||
@ -115,7 +119,7 @@ class SEQUENCER_MT_select(bpy.types.Menu):
|
||||
layout.itemS()
|
||||
layout.itemO("SEQUENCER_OT_select_linked")
|
||||
layout.itemO("SEQUENCER_OT_select_all_toggle")
|
||||
layout.itemO("SEQUENCER_OT_select_invert")
|
||||
layout.itemO("SEQUENCER_OT_select_inverse")
|
||||
|
||||
class SEQUENCER_MT_marker(bpy.types.Menu):
|
||||
__space_type__ = "SEQUENCE_EDITOR"
|
||||
@ -198,7 +202,7 @@ class SEQUENCER_MT_strip(bpy.types.Menu):
|
||||
layout.itemO("SEQUENCER_OT_images_separate")
|
||||
layout.itemS()
|
||||
|
||||
layout.itemO("SEQUENCER_OT_duplicate_add")
|
||||
layout.itemO("SEQUENCER_OT_duplicate")
|
||||
layout.itemO("SEQUENCER_OT_delete")
|
||||
|
||||
strip = act_strip(context)
|
||||
@ -238,7 +242,7 @@ class SEQUENCER_MT_strip(bpy.types.Menu):
|
||||
layout.itemO("SEQUENCER_OT_mute")
|
||||
layout.itemO("SEQUENCER_OT_unmute")
|
||||
|
||||
layout.item_enumO("SEQUENCER_OT_mute", property="type", value='UNSELECTED', text="Mute Deselected Strips")
|
||||
layout.item_booleanO("SEQUENCER_OT_mute", "unselected", 1, text="Mute Deselected Strips")
|
||||
|
||||
layout.itemO("SEQUENCER_OT_snap")
|
||||
|
||||
|
254
release/ui/space_view3d_toolbar.py
Normal file
254
release/ui/space_view3d_toolbar.py
Normal file
@ -0,0 +1,254 @@
|
||||
|
||||
import bpy
|
||||
|
||||
# ********** default tools for objectmode ****************
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
__space_type__ = "VIEW_3D"
|
||||
__region_type__ = "TOOLS"
|
||||
__context__ = "objectmode"
|
||||
|
||||
class VIEW3D_PT_tools_objectmode(View3DPanel):
|
||||
__idname__ = "VIEW3D_PT_tools_objectmode"
|
||||
__label__ = "Object Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.row().itemO("OBJECT_OT_duplicate")
|
||||
layout.row().itemO("OBJECT_OT_delete")
|
||||
layout.row().itemO("OBJECT_OT_mesh_add")
|
||||
layout.row().itemO("OBJECT_OT_curve_add")
|
||||
layout.row().itemO("OBJECT_OT_text_add")
|
||||
layout.row().itemO("OBJECT_OT_surface_add")
|
||||
|
||||
# ********** default tools for editmode_mesh ****************
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
__space_type__ = "VIEW_3D"
|
||||
__region_type__ = "TOOLS"
|
||||
__context__ = "editmode_mesh"
|
||||
|
||||
class VIEW3D_PT_tools_editmode_mesh(View3DPanel):
|
||||
__idname__ = "VIEW3D_PT_tools_editmode_mesh"
|
||||
__label__ = "Mesh Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.row().itemO("MESH_OT_duplicate")
|
||||
layout.row().itemO("MESH_OT_delete")
|
||||
layout.row().itemO("MESH_OT_spin")
|
||||
layout.row().itemO("MESH_OT_screw")
|
||||
layout.row().itemO("MESH_OT_primitive_plane_add")
|
||||
layout.row().itemO("MESH_OT_primitive_cube_add")
|
||||
layout.row().itemO("MESH_OT_primitive_circle_add")
|
||||
layout.row().itemO("MESH_OT_primitive_cylinder_add")
|
||||
|
||||
# ********** default tools for editmode_curve ****************
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
__space_type__ = "VIEW_3D"
|
||||
__region_type__ = "TOOLS"
|
||||
__context__ = "editmode_curve"
|
||||
|
||||
class VIEW3D_PT_tools_editmode_curve(View3DPanel):
|
||||
__idname__ = "VIEW3D_PT_tools_editmode_curve"
|
||||
__label__ = "Curve Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.row().itemO("CURVE_OT_duplicate")
|
||||
layout.row().itemO("CURVE_OT_delete")
|
||||
layout.row().itemO("OBJECT_OT_curve_add")
|
||||
layout.row().itemO("CURVE_OT_subdivide")
|
||||
|
||||
# ********** default tools for editmode_surface ****************
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
__space_type__ = "VIEW_3D"
|
||||
__region_type__ = "TOOLS"
|
||||
__context__ = "editmode_surface"
|
||||
|
||||
class VIEW3D_PT_tools_editmode_surface(View3DPanel):
|
||||
__idname__ = "VIEW3D_PT_tools_editmode_surface"
|
||||
__label__ = "Surface Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.row().itemO("CURVE_OT_duplicate")
|
||||
layout.row().itemO("CURVE_OT_delete")
|
||||
layout.row().itemO("OBJECT_OT_surface_add")
|
||||
layout.row().itemO("CURVE_OT_subdivide")
|
||||
|
||||
# ********** default tools for editmode_text ****************
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
__space_type__ = "VIEW_3D"
|
||||
__region_type__ = "TOOLS"
|
||||
__context__ = "editmode_text"
|
||||
|
||||
class VIEW3D_PT_tools_editmode_text(View3DPanel):
|
||||
__idname__ = "VIEW3D_PT_tools_editmode_text"
|
||||
__label__ = "Text Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.row().itemO("FONT_OT_text_copy")
|
||||
layout.row().itemO("FONT_OT_text_paste")
|
||||
layout.row().itemO("FONT_OT_case_set")
|
||||
layout.row().itemO("FONT_OT_style_toggle")
|
||||
|
||||
# ********** default tools for editmode_armature ****************
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
__space_type__ = "VIEW_3D"
|
||||
__region_type__ = "TOOLS"
|
||||
__context__ = "editmode_armature"
|
||||
|
||||
class VIEW3D_PT_tools_editmode_armature(View3DPanel):
|
||||
__idname__ = "VIEW3D_PT_tools_editmode_armature"
|
||||
__label__ = "Armature Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.row().itemO("ARMATURE_OT_duplicate_selected")
|
||||
layout.row().itemO("ARMATURE_OT_bone_primitive_add")
|
||||
layout.row().itemO("ARMATURE_OT_delete")
|
||||
layout.row().itemO("ARMATURE_OT_parent_clear")
|
||||
|
||||
# ********** default tools for editmode_mball ****************
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
__space_type__ = "VIEW_3D"
|
||||
__region_type__ = "TOOLS"
|
||||
__context__ = "editmode_mball"
|
||||
|
||||
class VIEW3D_PT_tools_editmode_mball(View3DPanel):
|
||||
__idname__ = "VIEW3D_PT_tools_editmode_mball"
|
||||
__label__ = "Meta Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
row = layout.row()
|
||||
|
||||
# ********** default tools for editmode_lattice ****************
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
__space_type__ = "VIEW_3D"
|
||||
__region_type__ = "TOOLS"
|
||||
__context__ = "editmode_lattice"
|
||||
|
||||
class VIEW3D_PT_tools_editmode_lattice(View3DPanel):
|
||||
__idname__ = "VIEW3D_PT_tools_editmode_lattice"
|
||||
__label__ = "Lattice Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
row = layout.row()
|
||||
|
||||
# ********** default tools for posemode ****************
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
__space_type__ = "VIEW_3D"
|
||||
__region_type__ = "TOOLS"
|
||||
__context__ = "posemode"
|
||||
|
||||
class VIEW3D_PT_tools_posemode(View3DPanel):
|
||||
__idname__ = "VIEW3D_PT_tools_posemode"
|
||||
__label__ = "Pose Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.row().itemO("POSE_OT_hide")
|
||||
layout.row().itemO("POSE_OT_reveal")
|
||||
layout.row().itemO("POSE_OT_rot_clear")
|
||||
layout.row().itemO("POSE_OT_loc_clear")
|
||||
|
||||
# ********** default tools for sculptmode ****************
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
__space_type__ = "VIEW_3D"
|
||||
__region_type__ = "TOOLS"
|
||||
__context__ = "sculptmode"
|
||||
|
||||
class VIEW3D_PT_tools_sculptmode(View3DPanel):
|
||||
__idname__ = "VIEW3D_PT_tools_sculptmode"
|
||||
__label__ = "Sculpt Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.row().itemO("SCULPT_OT_radial_control")
|
||||
|
||||
# ********** default tools for weightpaint ****************
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
__space_type__ = "VIEW_3D"
|
||||
__region_type__ = "TOOLS"
|
||||
__context__ = "weightpaint"
|
||||
|
||||
class VIEW3D_PT_tools_weightpaint(View3DPanel):
|
||||
__idname__ = "VIEW3D_PT_tools_weightpaint"
|
||||
__label__ = "Weight Paint Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.row().itemO("PAINT_OT_weight_paint_radial_control")
|
||||
|
||||
# ********** default tools for vertexpaint ****************
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
__space_type__ = "VIEW_3D"
|
||||
__region_type__ = "TOOLS"
|
||||
__context__ = "vertexpaint"
|
||||
|
||||
class VIEW3D_PT_tools_vertexpaint(View3DPanel):
|
||||
__idname__ = "VIEW3D_PT_tools_vertexpaint"
|
||||
__label__ = "Vertex Paint Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.row().itemO("PAINT_OT_vertex_paint_radial_control")
|
||||
|
||||
# ********** default tools for texturepaint ****************
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
__space_type__ = "VIEW_3D"
|
||||
__region_type__ = "TOOLS"
|
||||
__context__ = "texturepaint"
|
||||
|
||||
class VIEW3D_PT_tools_texturepaint(View3DPanel):
|
||||
__idname__ = "VIEW3D_PT_tools_texturepaint"
|
||||
__label__ = "Texture Paint Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.row().itemO("PAINT_OT_texture_paint_radial_control")
|
||||
|
||||
|
||||
bpy.types.register(VIEW3D_PT_tools_objectmode)
|
||||
bpy.types.register(VIEW3D_PT_tools_editmode_mesh)
|
||||
bpy.types.register(VIEW3D_PT_tools_editmode_curve)
|
||||
bpy.types.register(VIEW3D_PT_tools_editmode_surface)
|
||||
bpy.types.register(VIEW3D_PT_tools_editmode_text)
|
||||
bpy.types.register(VIEW3D_PT_tools_editmode_armature)
|
||||
bpy.types.register(VIEW3D_PT_tools_editmode_mball)
|
||||
bpy.types.register(VIEW3D_PT_tools_editmode_lattice)
|
||||
bpy.types.register(VIEW3D_PT_tools_posemode)
|
||||
bpy.types.register(VIEW3D_PT_tools_sculptmode)
|
||||
bpy.types.register(VIEW3D_PT_tools_weightpaint)
|
||||
bpy.types.register(VIEW3D_PT_tools_vertexpaint)
|
||||
bpy.types.register(VIEW3D_PT_tools_texturepaint)
|
||||
|
||||
|
@ -83,7 +83,6 @@ GRPLIB += $(NAN_SOUNDSYSTEM)/lib/$(DEBUG_DIR)libSoundSystem.a
|
||||
GRPLIB += $(NAN_GHOST)/lib/$(DEBUG_DIR)libghost.a
|
||||
GRPLIB += $(NAN_STRING)/lib/$(DEBUG_DIR)libstring.a
|
||||
GRPLIB += $(OCGDIR)/blender/render/$(DEBUG_DIR)librender.a
|
||||
GRPLIB += $(OCGDIR)/blender/radiosity/$(DEBUG_DIR)libradiosity.a
|
||||
|
||||
# nlin: the reason that some libraries appear more than once below is
|
||||
# to handle circular dependencies in linking among libraries... some
|
||||
@ -221,8 +220,8 @@ PULIB += $(OCGDIR)/blender/ed_sequencer/$(DEBUG_DIR)libed_sequencer.a
|
||||
PULIB += $(OCGDIR)/blender/ed_file/$(DEBUG_DIR)libed_file.a
|
||||
PULIB += $(OCGDIR)/blender/ed_info/$(DEBUG_DIR)libed_info.a
|
||||
PULIB += $(OCGDIR)/blender/ed_buttons/$(DEBUG_DIR)libed_buttons.a
|
||||
PULIB += $(OCGDIR)/blender/ed_node/$(DEBUG_DIR)libed_node.a
|
||||
PULIB += $(OCGDIR)/blender/ed_graph/$(DEBUG_DIR)libed_graph.a
|
||||
PULIB += $(OCGDIR)/blender/ed_node/$(DEBUG_DIR)libed_node.a
|
||||
PULIB += $(OCGDIR)/blender/ed_outliner/$(DEBUG_DIR)libed_outliner.a
|
||||
PULIB += $(OCGDIR)/blender/ed_time/$(DEBUG_DIR)libed_time.a
|
||||
PULIB += $(OCGDIR)/blender/ed_preview/$(DEBUG_DIR)libed_preview.a
|
||||
|
@ -78,6 +78,11 @@ float BLF_height(char *str);
|
||||
float BLF_width_default(char *str);
|
||||
float BLF_height_default(char *str);
|
||||
|
||||
/*
|
||||
* set rotation for default font
|
||||
*/
|
||||
void BLF_default_rotation(float angle);
|
||||
|
||||
/*
|
||||
* By default, rotation and clipping are disable and
|
||||
* have to be enable/disable using BLF_enable/disable.
|
||||
@ -85,7 +90,6 @@ float BLF_height_default(char *str);
|
||||
void BLF_rotation(float angle);
|
||||
void BLF_clipping(float xmin, float ymin, float xmax, float ymax);
|
||||
void BLF_blur(int size);
|
||||
void BLF_kerning(float space);
|
||||
|
||||
void BLF_enable(int option);
|
||||
void BLF_disable(int option);
|
||||
@ -132,10 +136,8 @@ void BLF_dir_free(char **dirs, int count);
|
||||
/* font->flags. */
|
||||
#define BLF_ROTATION (1<<0)
|
||||
#define BLF_CLIPPING (1<<1)
|
||||
#define BLF_FONT_KERNING (1<<2)
|
||||
#define BLF_USER_KERNING (1<<3)
|
||||
#define BLF_SHADOW (1<<4)
|
||||
#define BLF_OVERLAP_CHAR (1<<5)
|
||||
#define BLF_SHADOW (1<<2)
|
||||
#define BLF_KERNING_DEFAULT (1<<3)
|
||||
|
||||
/* font->mode. */
|
||||
#define BLF_MODE_TEXTURE 0
|
||||
|
@ -321,6 +321,19 @@ void BLF_draw_default(float x, float y, float z, char *str)
|
||||
}
|
||||
}
|
||||
|
||||
void BLF_default_rotation(float angle)
|
||||
{
|
||||
|
||||
if (global_font_default>=0) {
|
||||
global_font[global_font_default]->angle= angle;
|
||||
if(angle)
|
||||
global_font[global_font_default]->flags |= BLF_ROTATION;
|
||||
else
|
||||
global_font[global_font_default]->flags &= ~BLF_ROTATION;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BLF_draw(char *str)
|
||||
{
|
||||
FontBLF *font;
|
||||
@ -492,15 +505,6 @@ void BLF_mode(int mode)
|
||||
font->mode= mode;
|
||||
}
|
||||
|
||||
void BLF_kerning(float space)
|
||||
{
|
||||
FontBLF *font;
|
||||
|
||||
font= global_font[global_font_cur];
|
||||
if (font)
|
||||
font->kerning= space;
|
||||
}
|
||||
|
||||
void BLF_shadow(int level, float r, float g, float b, float a)
|
||||
{
|
||||
FontBLF *font;
|
||||
|
@ -101,8 +101,8 @@ void blf_font_draw(FontBLF *font, char *str)
|
||||
GlyphBLF *g, *g_prev;
|
||||
FT_Vector delta;
|
||||
FT_UInt glyph_index, g_prev_index;
|
||||
float pen_x, pen_y, old_pen_x;
|
||||
int i, has_kerning;
|
||||
int pen_x, pen_y;
|
||||
int i, has_kerning, st;
|
||||
|
||||
if (!font->glyph_cache)
|
||||
return;
|
||||
@ -139,33 +139,21 @@ void blf_font_draw(FontBLF *font, char *str)
|
||||
else if (font->mode == BLF_MODE_TEXTURE && (!g->tex_data))
|
||||
g= blf_glyph_add(font, glyph_index, c);
|
||||
|
||||
if ((font->flags & BLF_FONT_KERNING) && has_kerning && g_prev) {
|
||||
old_pen_x= pen_x;
|
||||
if (has_kerning && g_prev) {
|
||||
delta.x= 0;
|
||||
delta.y= 0;
|
||||
|
||||
if (FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta) == 0) {
|
||||
if (font->flags & BLF_KERNING_DEFAULT)
|
||||
st= FT_Get_Kerning(font->face, g_prev_index, glyph_index, ft_kerning_default, &delta);
|
||||
else
|
||||
st= FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta);
|
||||
|
||||
if (st == 0)
|
||||
pen_x += delta.x >> 6;
|
||||
|
||||
if (font->flags & BLF_OVERLAP_CHAR) {
|
||||
if (pen_x < old_pen_x)
|
||||
pen_x= old_pen_x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (font->flags & BLF_USER_KERNING) {
|
||||
old_pen_x= pen_x;
|
||||
pen_x += font->kerning;
|
||||
|
||||
if (font->flags & BLF_OVERLAP_CHAR) {
|
||||
if (pen_x < old_pen_x)
|
||||
pen_x= old_pen_x;
|
||||
}
|
||||
}
|
||||
|
||||
/* do not return this loop if clipped, we want every character tested */
|
||||
blf_glyph_render(font, g, pen_x, pen_y);
|
||||
blf_glyph_render(font, g, (float)pen_x, (float)pen_y);
|
||||
|
||||
pen_x += g->advance;
|
||||
g_prev= g;
|
||||
@ -180,8 +168,8 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box)
|
||||
FT_Vector delta;
|
||||
FT_UInt glyph_index, g_prev_index;
|
||||
rctf gbox;
|
||||
float pen_x, pen_y, old_pen_x;
|
||||
int i, has_kerning;
|
||||
int pen_x, pen_y;
|
||||
int i, has_kerning, st;
|
||||
|
||||
if (!font->glyph_cache)
|
||||
return;
|
||||
@ -223,29 +211,17 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box)
|
||||
else if (font->mode == BLF_MODE_TEXTURE && (!g->tex_data))
|
||||
g= blf_glyph_add(font, glyph_index, c);
|
||||
|
||||
if ((font->flags & BLF_FONT_KERNING) && has_kerning && g_prev) {
|
||||
old_pen_x= pen_x;
|
||||
if (has_kerning && g_prev) {
|
||||
delta.x= 0;
|
||||
delta.y= 0;
|
||||
|
||||
if (FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta) == 0) {
|
||||
if (font->flags & BLF_KERNING_DEFAULT)
|
||||
st= FT_Get_Kerning(font->face, g_prev_index, glyph_index, ft_kerning_default, &delta);
|
||||
else
|
||||
st= FT_Get_Kerning(font->face, g_prev_index, glyph_index, FT_KERNING_UNFITTED, &delta);
|
||||
|
||||
if (st == 0)
|
||||
pen_x += delta.x >> 6;
|
||||
|
||||
if (font->flags & BLF_OVERLAP_CHAR) {
|
||||
if (pen_x < old_pen_x)
|
||||
pen_x= old_pen_x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (font->flags & BLF_USER_KERNING) {
|
||||
old_pen_x= pen_x;
|
||||
pen_x += font->kerning;
|
||||
|
||||
if (font->flags & BLF_OVERLAP_CHAR) {
|
||||
if (pen_x < old_pen_x)
|
||||
pen_x= old_pen_x;
|
||||
}
|
||||
}
|
||||
|
||||
gbox.xmin= g->box.xmin + pen_x;
|
||||
@ -329,10 +305,9 @@ void blf_font_fill(FontBLF *font)
|
||||
font->clip_rec.xmax= 0.0f;
|
||||
font->clip_rec.ymin= 0.0f;
|
||||
font->clip_rec.ymax= 0.0f;
|
||||
font->flags= BLF_USER_KERNING | BLF_FONT_KERNING;
|
||||
font->flags= 0;
|
||||
font->dpi= 0;
|
||||
font->size= 0;
|
||||
font->kerning= 0.0f;
|
||||
font->cache.first= NULL;
|
||||
font->cache.last= NULL;
|
||||
font->glyph_cache= NULL;
|
||||
|
@ -213,11 +213,7 @@ GlyphBLF *blf_glyph_texture_add(FontBLF *font, FT_UInt index, unsigned int c)
|
||||
else
|
||||
do_new= 1;
|
||||
|
||||
if (font->flags & BLF_FONT_KERNING)
|
||||
err= FT_Load_Glyph(font->face, index, FT_LOAD_NO_BITMAP);
|
||||
else
|
||||
err= FT_Load_Glyph(font->face, index, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
|
||||
|
||||
if (err)
|
||||
return(NULL);
|
||||
|
||||
@ -332,11 +328,7 @@ GlyphBLF *blf_glyph_bitmap_add(FontBLF *font, FT_UInt index, unsigned int c)
|
||||
else
|
||||
do_new= 1;
|
||||
|
||||
if (font->flags & BLF_FONT_KERNING)
|
||||
err= FT_Load_Glyph(font->face, index, FT_LOAD_NO_BITMAP);
|
||||
else
|
||||
err= FT_Load_Glyph(font->face, index, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
|
||||
|
||||
if (err)
|
||||
return(NULL);
|
||||
|
||||
|
@ -177,9 +177,6 @@ typedef struct FontBLF {
|
||||
/* font size. */
|
||||
int size;
|
||||
|
||||
/* kerning space, user setting. */
|
||||
float kerning;
|
||||
|
||||
/* max texture size. */
|
||||
int max_tex_size;
|
||||
|
||||
|
@ -68,6 +68,9 @@ void make_local_action(struct bAction *act);
|
||||
/* Some kind of bounding box operation on the action */
|
||||
void calc_action_range(const struct bAction *act, float *start, float *end, int incl_hidden);
|
||||
|
||||
/* Does action have any motion data at all? */
|
||||
short action_has_motion(const struct bAction *act);
|
||||
|
||||
/* Action Groups API ----------------- */
|
||||
|
||||
/* Make the given Action Group the active one */
|
||||
@ -145,12 +148,6 @@ void copy_pose_result(struct bPose *to, struct bPose *from);
|
||||
/* clear all transforms */
|
||||
void rest_pose(struct bPose *pose);
|
||||
|
||||
/* map global time (frame nr) to strip converted time, doesn't clip */
|
||||
float get_action_frame(struct Object *ob, float cframe);
|
||||
/* map strip time to global time (frame nr) */
|
||||
float get_action_frame_inv(struct Object *ob, float cframe);
|
||||
|
||||
|
||||
/* functions used by the game engine */
|
||||
void game_copy_pose(struct bPose **dst, struct bPose *src);
|
||||
void game_free_pose(struct bPose *pose);
|
||||
|
@ -41,6 +41,8 @@ struct Particle;
|
||||
struct Group;
|
||||
struct RNG;
|
||||
|
||||
struct PartDeflect *object_add_collision_fields(void);
|
||||
|
||||
typedef struct pEffectorCache {
|
||||
struct pEffectorCache *next, *prev;
|
||||
Object *ob;
|
||||
|
@ -1,12 +1,33 @@
|
||||
/* Testing code for new animation system in 2.5
|
||||
* Copyright 2009, Joshua Leung
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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) 2009 Blender Foundation, Joshua Leung
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Joshua Leung (full recode)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef BKE_FCURVE_H
|
||||
#define BKE_FCURVE_H
|
||||
|
||||
//struct ListBase;
|
||||
|
||||
struct FCurve;
|
||||
struct FModifier;
|
||||
struct ChannelDriver;
|
||||
@ -54,8 +75,8 @@ typedef struct FModifierTypeInfo {
|
||||
short size; /* size in bytes of the struct */
|
||||
short acttype; /* eFMI_Action_Types */
|
||||
short requires; /* eFMI_Requirement_Flags */
|
||||
char name[32]; /* name of modifier in interface */
|
||||
char structName[32]; /* name of struct for SDNA */
|
||||
char name[64]; /* name of modifier in interface */
|
||||
char structName[64]; /* name of struct for SDNA */
|
||||
|
||||
/* data management function pointers - special handling */
|
||||
/* free any data that is allocated separately (optional) */
|
||||
@ -104,14 +125,20 @@ FModifierTypeInfo *get_fmodifier_typeinfo(int type);
|
||||
|
||||
/* ---------------------- */
|
||||
|
||||
struct FModifier *fcurve_add_modifier(struct FCurve *fcu, int type);
|
||||
void fcurve_copy_modifiers(ListBase *dst, ListBase *src);
|
||||
void fcurve_remove_modifier(struct FCurve *fcu, struct FModifier *fcm);
|
||||
void fcurve_free_modifiers(struct FCurve *fcu);
|
||||
void fcurve_bake_modifiers(struct FCurve *fcu, int start, int end);
|
||||
struct FModifier *add_fmodifier(ListBase *modifiers, int type);
|
||||
void copy_fmodifiers(ListBase *dst, ListBase *src);
|
||||
void remove_fmodifier(ListBase *modifiers, struct FModifier *fcm);
|
||||
void free_fmodifiers(ListBase *modifiers);
|
||||
|
||||
struct FModifier *fcurve_find_active_modifier(struct FCurve *fcu);
|
||||
void fcurve_set_active_modifier(struct FCurve *fcu, struct FModifier *fcm);
|
||||
struct FModifier *find_active_fmodifier(ListBase *modifiers);
|
||||
void set_active_fmodifier(ListBase *modifiers, struct FModifier *fcm);
|
||||
|
||||
short list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype);
|
||||
|
||||
float evaluate_time_fmodifiers(ListBase *modifiers, struct FCurve *fcu, float cvalue, float evaltime);
|
||||
void evaluate_value_fmodifiers(ListBase *modifiers, struct FCurve *fcu, float *cvalue, float evaltime);
|
||||
|
||||
void fcurve_bake_modifiers(struct FCurve *fcu, int start, int end);
|
||||
|
||||
/* ************** F-Curves API ******************** */
|
||||
|
||||
@ -126,9 +153,6 @@ void copy_fcurves(ListBase *dst, ListBase *src);
|
||||
/* find matching F-Curve in the given list of F-Curves */
|
||||
struct FCurve *list_find_fcurve(ListBase *list, const char rna_path[], const int array_index);
|
||||
|
||||
/* test if there is a keyframe at cfra */
|
||||
short on_keyframe_fcurve(struct FCurve *fcu, float cfra);
|
||||
|
||||
/* get the time extents for F-Curve */
|
||||
void calc_fcurve_range(struct FCurve *fcu, float *min, float *max);
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
/**
|
||||
* BKE_fluidsim.h
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@ -28,29 +27,40 @@
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_fluidsim.h" // N_T
|
||||
#include "DNA_object_types.h"
|
||||
#ifndef BKE_FLUIDSIM_H
|
||||
#define BKE_FLUIDSIM_H
|
||||
|
||||
#include "BKE_DerivedMesh.h"
|
||||
struct Object;
|
||||
struct Scene;
|
||||
struct FluidsimModifierData;
|
||||
struct DerivedMesh;
|
||||
struct MVert;
|
||||
|
||||
/* old interface */
|
||||
FluidsimSettings *fluidsimSettingsNew(Object *srcob);
|
||||
|
||||
void initElbeemMesh(Scene *scene, Object *ob, int *numVertices, float **vertices, int *numTriangles, int **triangles, int useGlobalCoords, int modifierIndex);
|
||||
struct FluidsimSettings *fluidsimSettingsNew(struct Object *srcob);
|
||||
|
||||
void initElbeemMesh(struct Scene *scene, struct Object *ob,
|
||||
int *numVertices, float **vertices,
|
||||
int *numTriangles, int **triangles,
|
||||
int useGlobalCoords, int modifierIndex);
|
||||
|
||||
/* new fluid-modifier interface */
|
||||
void fluidsim_init(FluidsimModifierData *fluidmd);
|
||||
void fluidsim_free(FluidsimModifierData *fluidmd);
|
||||
void fluidsim_init(struct FluidsimModifierData *fluidmd);
|
||||
void fluidsim_free(struct FluidsimModifierData *fluidmd);
|
||||
|
||||
DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm, FluidsimModifierData *fluidmd, int framenr, int useRenderParams);
|
||||
void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *dm, char *filename);
|
||||
DerivedMesh *fluidsimModifier_do(FluidsimModifierData *fluidmd, Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc);
|
||||
struct DerivedMesh *fluidsim_read_cache(struct Object *ob, struct DerivedMesh *orgdm,
|
||||
struct FluidsimModifierData *fluidmd, int framenr, int useRenderParams);
|
||||
void fluidsim_read_vel_cache(struct FluidsimModifierData *fluidmd, struct DerivedMesh *dm,
|
||||
char *filename);
|
||||
struct DerivedMesh *fluidsimModifier_do(struct FluidsimModifierData *fluidmd,
|
||||
struct Scene *scene, struct Object *ob, struct DerivedMesh *dm,
|
||||
int useRenderParams, int isFinalCalc);
|
||||
|
||||
// get bounding box of mesh
|
||||
void fluid_get_bb(MVert *mvert, int totvert, float obmat[][4],
|
||||
/*RET*/ float start[3], /*RET*/ float size[3] );
|
||||
/* bounding box & memory estimate */
|
||||
void fluid_get_bb(struct MVert *mvert, int totvert, float obmat[][4],
|
||||
float start[3], float size[3]);
|
||||
|
||||
void fluid_estimate_memory(struct Object *ob, struct FluidsimSettings *fss, char *value);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -62,7 +62,7 @@ typedef enum {
|
||||
* used for particles modifier that doesn't actually modify the object
|
||||
* unless it's a mesh and can be exploded -> curve can also emit particles
|
||||
*/
|
||||
eModifierTypeType_DeformOrConstruct
|
||||
eModifierTypeType_DeformOrConstruct,
|
||||
} ModifierTypeType;
|
||||
|
||||
typedef enum {
|
||||
@ -87,6 +87,9 @@ typedef enum {
|
||||
/* For modifiers that support pointcache, so we can check to see if it has files we need to deal with
|
||||
*/
|
||||
eModifierTypeFlag_UsesPointCache = (1<<6),
|
||||
|
||||
/* For physics modifiers, max one per type */
|
||||
eModifierTypeFlag_Single = (1<<7)
|
||||
} ModifierTypeFlag;
|
||||
|
||||
typedef void (*ObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin);
|
||||
|
@ -17,12 +17,12 @@
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
* Contributor(s): Joshua Leung (full recode)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
@ -30,15 +30,90 @@
|
||||
#ifndef BKE_NLA_H
|
||||
#define BKE_NLA_H
|
||||
|
||||
struct bActionStrip;
|
||||
struct ListBase;
|
||||
struct Object;
|
||||
struct AnimData;
|
||||
struct NlaStrip;
|
||||
struct NlaTrack;
|
||||
struct bAction;
|
||||
|
||||
/* ----------------------------- */
|
||||
/* Data Management */
|
||||
|
||||
void free_nlastrip(ListBase *strips, struct NlaStrip *strip);
|
||||
void free_nlatrack(ListBase *tracks, struct NlaTrack *nlt);
|
||||
void free_nladata(ListBase *tracks);
|
||||
|
||||
struct NlaStrip *copy_nlastrip(struct NlaStrip *strip);
|
||||
struct NlaTrack *copy_nlatrack(struct NlaTrack *nlt);
|
||||
void copy_nladata(ListBase *dst, ListBase *src);
|
||||
|
||||
struct NlaTrack *add_nlatrack(struct AnimData *adt, struct NlaTrack *prev);
|
||||
struct NlaStrip *add_nlastrip(struct bAction *act);
|
||||
struct NlaStrip *add_nlastrip_to_stack(struct AnimData *adt, struct bAction *act);
|
||||
|
||||
/* ----------------------------- */
|
||||
/* API */
|
||||
|
||||
short BKE_nlastrips_has_space(ListBase *strips, float start, float end);
|
||||
void BKE_nlastrips_sort_strips(ListBase *strips);
|
||||
|
||||
short BKE_nlastrips_add_strip(ListBase *strips, struct NlaStrip *strip);
|
||||
|
||||
|
||||
void BKE_nlastrips_make_metas(ListBase *strips, short temp);
|
||||
void BKE_nlastrips_clear_metas(ListBase *strips, short onlySel, short onlyTemp);
|
||||
void BKE_nlastrips_clear_metastrip(ListBase *strips, struct NlaStrip *strip);
|
||||
short BKE_nlameta_add_strip(struct NlaStrip *mstrip, struct NlaStrip *strip);
|
||||
void BKE_nlameta_flush_transforms(struct NlaStrip *mstrip);
|
||||
|
||||
/* ............ */
|
||||
|
||||
struct NlaTrack *BKE_nlatrack_find_active(ListBase *tracks);
|
||||
void BKE_nlatrack_set_active(ListBase *tracks, struct NlaTrack *nlt);
|
||||
|
||||
void BKE_nlatrack_solo_toggle(struct AnimData *adt, struct NlaTrack *nlt);
|
||||
|
||||
short BKE_nlatrack_has_space(struct NlaTrack *nlt, float start, float end);
|
||||
void BKE_nlatrack_sort_strips(struct NlaTrack *nlt);
|
||||
|
||||
short BKE_nlatrack_add_strip(struct NlaTrack *nlt, struct NlaStrip *strip);
|
||||
|
||||
/* ............ */
|
||||
|
||||
struct NlaStrip *BKE_nlastrip_find_active(struct NlaTrack *nlt);
|
||||
|
||||
short BKE_nlastrip_within_bounds(struct NlaStrip *strip, float min, float max);
|
||||
|
||||
void BKE_nlastrip_validate_name(struct AnimData *adt, struct NlaStrip *strip);
|
||||
|
||||
/* ............ */
|
||||
|
||||
short BKE_nlatrack_has_animated_strips(struct NlaTrack *nlt);
|
||||
short BKE_nlatracks_have_animated_strips(ListBase *tracks);
|
||||
void BKE_nlastrip_validate_fcurves(struct NlaStrip *strip);
|
||||
|
||||
/* ............ */
|
||||
|
||||
void BKE_nla_action_pushdown(struct AnimData *adt);
|
||||
|
||||
short BKE_nla_tweakmode_enter(struct AnimData *adt);
|
||||
void BKE_nla_tweakmode_exit(struct AnimData *adt);
|
||||
|
||||
/* ----------------------------- */
|
||||
/* Time Mapping */
|
||||
|
||||
/* time mapping conversion modes */
|
||||
enum {
|
||||
/* convert from global time to strip time - for evaluation */
|
||||
NLATIME_CONVERT_EVAL = 0,
|
||||
/* convert from global time to strip time - for editing corrections */
|
||||
// XXX old 0 invert
|
||||
NLATIME_CONVERT_UNMAP,
|
||||
/* convert from strip time to global time */
|
||||
// xxx old 1 invert
|
||||
NLATIME_CONVERT_MAP,
|
||||
} eNlaTime_ConvertModes;
|
||||
|
||||
float BKE_nla_tweakedit_remap(struct AnimData *adt, float cframe, short mode);
|
||||
|
||||
void free_actionstrip (struct bActionStrip* strip);
|
||||
void free_nlastrips (struct ListBase *nlalist);
|
||||
void copy_nlastrips (struct ListBase *dst, struct ListBase *src);
|
||||
void copy_actionstrip (struct bActionStrip **dst, struct bActionStrip **src);
|
||||
void find_stridechannel(struct Object *ob, struct bActionStrip *strip);
|
||||
struct bActionStrip *convert_action_to_strip (struct Object *ob);
|
||||
#endif
|
||||
|
||||
|
@ -91,7 +91,8 @@ typedef struct ParticleTexture{
|
||||
float ivel; /* used in reset */
|
||||
float time, life, exist, size; /* used in init */
|
||||
float pvel[3]; /* used in physics */
|
||||
float length, clump, kink, rough; /* used in path caching */
|
||||
float length, clump, kink, effector;/* used in path caching */
|
||||
float rough1, rough2, roughe; /* used in path caching */
|
||||
} ParticleTexture;
|
||||
|
||||
typedef struct BoidVecFunc{
|
||||
@ -270,7 +271,7 @@ void psys_update_world_cos(struct Object *ob, struct ParticleSystem *psys);
|
||||
int do_guide(struct Scene *scene, struct ParticleKey *state, int pa_num, float time, struct ListBase *lb);
|
||||
float psys_get_size(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct IpoCurve *icu_size, struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleData *pa, float *vg_size);
|
||||
float psys_get_timestep(struct ParticleSettings *part);
|
||||
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra);
|
||||
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime);
|
||||
float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *pa_time);
|
||||
void psys_get_particle_on_path(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, int pa_num, struct ParticleKey *state, int vel);
|
||||
int psys_get_particle_state(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, int p, struct ParticleKey *state, int always);
|
||||
|
@ -114,6 +114,7 @@ typedef struct PTCacheBaker {
|
||||
struct Scene *scene;
|
||||
int bake;
|
||||
int render;
|
||||
int anim_init;
|
||||
int quick_step;
|
||||
struct PTCacheID *pid;
|
||||
int (*break_test)(void *data);
|
||||
|
@ -91,6 +91,9 @@ typedef struct SpaceType {
|
||||
/* region type definitions */
|
||||
ListBase regiontypes;
|
||||
|
||||
/* tool shelf definitions */
|
||||
ListBase toolshelf;
|
||||
|
||||
/* read and write... */
|
||||
|
||||
/* default keymaps to add */
|
||||
|
@ -128,6 +128,7 @@
|
||||
|
||||
#define IS_EQT(a, b, c) ((a > b)? (((a-b) <= c)? 1:0) : ((((b-a) <= c)? 1:0)))
|
||||
#define IN_RANGE(a, b, c) ((b < c)? ((b<a && a<c)? 1:0) : ((c<a && a<b)? 1:0))
|
||||
#define IN_RANGE_INCL(a, b, c) ((b < c)? ((b<=a && a<=c)? 1:0) : ((c<=a && a<=b)? 1:0))
|
||||
|
||||
/* this weirdo pops up in two places ... */
|
||||
#if !defined(WIN32)
|
||||
|
@ -769,70 +769,23 @@ void framechange_poses_clear_unkeyed(void)
|
||||
|
||||
/* ************** time ****************** */
|
||||
|
||||
static bActionStrip *get_active_strip(Object *ob)
|
||||
/* Check if the given action has any keyframes */
|
||||
short action_has_motion(const bAction *act)
|
||||
{
|
||||
#if 0 // XXX old animation system
|
||||
bActionStrip *strip;
|
||||
FCurve *fcu;
|
||||
|
||||
if(ob->action==NULL)
|
||||
return NULL;
|
||||
|
||||
for (strip=ob->nlastrips.first; strip; strip=strip->next)
|
||||
if(strip->flag & ACTSTRIP_ACTIVE)
|
||||
break;
|
||||
|
||||
if(strip && strip->act==ob->action)
|
||||
return strip;
|
||||
#endif // XXX old animation system
|
||||
|
||||
return NULL;
|
||||
/* return on the first F-Curve that has some keyframes/samples defined */
|
||||
if (act) {
|
||||
for (fcu= act->curves.first; fcu; fcu= fcu->next) {
|
||||
if (fcu->totvert)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* non clipped mapping of strip */
|
||||
static float get_actionstrip_frame(bActionStrip *strip, float cframe, int invert)
|
||||
{
|
||||
float length, actlength, repeat, scale;
|
||||
|
||||
if (strip->repeat == 0.0f) strip->repeat = 1.0f;
|
||||
repeat = (strip->flag & ACTSTRIP_USESTRIDE) ? (1.0f) : (strip->repeat);
|
||||
|
||||
if (strip->scale == 0.0f) strip->scale= 1.0f;
|
||||
scale = (float)fabs(strip->scale); /* scale must be positive (for now) */
|
||||
|
||||
actlength = strip->actend-strip->actstart;
|
||||
if (actlength == 0.0f) actlength = 1.0f;
|
||||
length = repeat * scale * actlength;
|
||||
|
||||
/* invert = convert action-strip time to global time */
|
||||
if (invert)
|
||||
return length*(cframe - strip->actstart)/(repeat*actlength) + strip->start;
|
||||
else
|
||||
return repeat*actlength*(cframe - strip->start)/length + strip->actstart;
|
||||
/* nothing found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if the conditions match, it converts current time to strip time */
|
||||
float get_action_frame(Object *ob, float cframe)
|
||||
{
|
||||
bActionStrip *strip= get_active_strip(ob);
|
||||
|
||||
if(strip)
|
||||
return get_actionstrip_frame(strip, cframe, 0);
|
||||
return cframe;
|
||||
}
|
||||
|
||||
/* inverted, strip time to current time */
|
||||
float get_action_frame_inv(Object *ob, float cframe)
|
||||
{
|
||||
bActionStrip *strip= get_active_strip(ob);
|
||||
|
||||
if(strip)
|
||||
return get_actionstrip_frame(strip, cframe, 1);
|
||||
return cframe;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Calculate the extents of given action */
|
||||
void calc_action_range(const bAction *act, float *start, float *end, int incl_hidden)
|
||||
{
|
||||
|
@ -786,8 +786,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
||||
BLI_srandom(31415926 + psys->seed);
|
||||
|
||||
lay= scene->lay;
|
||||
if((part->draw_as == PART_DRAW_OB && part->dup_ob) ||
|
||||
(part->draw_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first)) {
|
||||
if((psys->renderdata || part->draw_as==PART_DRAW_REND) &&
|
||||
((part->ren_as == PART_DRAW_OB && part->dup_ob) ||
|
||||
(part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first))) {
|
||||
|
||||
/* if we have a hair particle system, use the path cache */
|
||||
if(part->type == PART_HAIR) {
|
||||
@ -804,7 +805,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
||||
psys->lattice = psys_get_lattice(scene, par, psys);
|
||||
|
||||
/* gather list of objects or single object */
|
||||
if(part->draw_as==PART_DRAW_GR) {
|
||||
if(part->ren_as==PART_DRAW_GR) {
|
||||
group_handle_recalc_and_update(scene, par, part->dup_group);
|
||||
|
||||
for(go=part->dup_group->gobject.first; go; go=go->next)
|
||||
@ -850,7 +851,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
||||
size = psys_get_child_size(psys, cpa, ctime, 0);
|
||||
}
|
||||
|
||||
if(part->draw_as==PART_DRAW_GR) {
|
||||
if(part->ren_as==PART_DRAW_GR) {
|
||||
/* for groups, pick the object based on settings */
|
||||
if(part->draw&PART_DRAW_RAND_GR)
|
||||
b= BLI_rand() % totgroup;
|
||||
@ -894,7 +895,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
||||
pamat[3][3]= 1.0f;
|
||||
}
|
||||
|
||||
if(part->draw_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
|
||||
if(part->ren_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
|
||||
for(go= part->dup_group->gobject.first, b=0; go; go= go->next, b++) {
|
||||
Mat4MulMat4(tmat, oblist[b]->obmat, pamat);
|
||||
Mat4MulFloat3((float *)tmat, size*scale);
|
||||
@ -930,7 +931,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
||||
}
|
||||
|
||||
/* restore objects since they were changed in where_is_object_time */
|
||||
if(part->draw_as==PART_DRAW_GR) {
|
||||
if(part->ren_as==PART_DRAW_GR) {
|
||||
for(a=0; a<totgroup; a++)
|
||||
*(oblist[a])= obcopylist[a];
|
||||
}
|
||||
|
@ -1,10 +1,37 @@
|
||||
/* Testing code for new animation system in 2.5
|
||||
* Copyright 2009, Joshua Leung
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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) 2009 Blender Foundation, Joshua Leung
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Joshua Leung (full recode)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@ -12,9 +39,12 @@
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_dynstr.h"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_nla.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_utildefines.h"
|
||||
@ -22,7 +52,7 @@
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_types.h"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "nla_private.h"
|
||||
|
||||
/* ***************************************** */
|
||||
/* AnimData API */
|
||||
@ -116,6 +146,12 @@ void BKE_free_animdata (ID *id)
|
||||
/* unlink action (don't free, as it's in its own list) */
|
||||
if (adt->action)
|
||||
adt->action->id.us--;
|
||||
/* same goes for the temporarily displaced action */
|
||||
if (adt->tmpact)
|
||||
adt->tmpact->id.us--;
|
||||
|
||||
/* free nla data */
|
||||
free_nladata(&adt->nla_tracks);
|
||||
|
||||
/* free drivers - stored as a list of F-Curves */
|
||||
free_fcurves(&adt->drivers);
|
||||
@ -146,9 +182,10 @@ AnimData *BKE_copy_animdata (AnimData *adt)
|
||||
// XXX review this... it might not be optimal behaviour yet...
|
||||
//id_us_plus((ID *)dadt->action);
|
||||
dadt->action= copy_action(adt->action);
|
||||
dadt->tmpact= copy_action(adt->tmpact);
|
||||
|
||||
/* duplicate NLA data */
|
||||
// XXX todo...
|
||||
copy_nladata(&dadt->nla_tracks, &adt->nla_tracks);
|
||||
|
||||
/* duplicate drivers (F-Curves) */
|
||||
copy_fcurves(&dadt->drivers, &adt->drivers);
|
||||
@ -355,10 +392,10 @@ void BKE_keyingsets_free (ListBase *list)
|
||||
short animsys_remap_path (AnimMapper *remap, char *path, char **dst)
|
||||
{
|
||||
/* is there a valid remapping table to use? */
|
||||
if (remap) {
|
||||
//if (remap) {
|
||||
/* find a matching entry... to use to remap */
|
||||
// ...TODO...
|
||||
}
|
||||
//}
|
||||
|
||||
/* nothing suitable found, so just set dst to look at path (i.e. no alloc/free needed) */
|
||||
*dst= path;
|
||||
@ -455,6 +492,8 @@ static void animsys_evaluate_fcurves (PointerRNA *ptr, ListBase *list, AnimMappe
|
||||
/* calculate then execute each curve */
|
||||
for (fcu= list->first; fcu; fcu= fcu->next)
|
||||
{
|
||||
/* check if this F-Curve doesn't belong to a muted group */
|
||||
if ((fcu->grp == NULL) || (fcu->grp->flag & AGRP_MUTED)==0) {
|
||||
/* check if this curve should be skipped */
|
||||
if ((fcu->flag & (FCURVE_MUTED|FCURVE_DISABLED)) == 0)
|
||||
{
|
||||
@ -463,6 +502,7 @@ static void animsys_evaluate_fcurves (PointerRNA *ptr, ListBase *list, AnimMappe
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ***************************************** */
|
||||
/* Driver Evaluation */
|
||||
@ -481,7 +521,6 @@ static void animsys_evaluate_drivers (PointerRNA *ptr, AnimData *adt, float ctim
|
||||
short ok= 0;
|
||||
|
||||
/* check if this driver's curve should be skipped */
|
||||
// FIXME: maybe we shouldn't check for muted, though that would make things more confusing, as there's already too many ways to disable?
|
||||
if ((fcu->flag & (FCURVE_MUTED|FCURVE_DISABLED)) == 0)
|
||||
{
|
||||
/* check if driver itself is tagged for recalculation */
|
||||
@ -514,6 +553,10 @@ void animsys_evaluate_action_group (PointerRNA *ptr, bAction *act, bActionGroup
|
||||
if ELEM(NULL, act, agrp) return;
|
||||
if ((remap) && (remap->target != act)) remap= NULL;
|
||||
|
||||
/* if group is muted, don't evaluated any of the F-Curve */
|
||||
if (agrp->flag & AGRP_MUTED)
|
||||
return;
|
||||
|
||||
/* calculate then execute each curve */
|
||||
for (fcu= agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu= fcu->next)
|
||||
{
|
||||
@ -540,152 +583,590 @@ void animsys_evaluate_action (PointerRNA *ptr, bAction *act, AnimMapper *remap,
|
||||
/* ***************************************** */
|
||||
/* NLA System - Evaluation */
|
||||
|
||||
/* used for list of strips to accumulate at current time */
|
||||
typedef struct NlaEvalStrip {
|
||||
struct NlaEvalStrip *next, *prev;
|
||||
|
||||
NlaTrack *track; /* track that this strip belongs to */
|
||||
NlaStrip *strip; /* strip that's being used */
|
||||
NlaStrip *sblend; /* strip that's being blended towards (if applicable) */
|
||||
|
||||
short track_index; /* the index of the track within the list */
|
||||
short strip_mode; /* which end of the strip are we looking at */
|
||||
} NlaEvalStrip;
|
||||
|
||||
/* bNlaEvalStrip->strip_mode */
|
||||
enum {
|
||||
NES_TIME_BEFORE = -1,
|
||||
NES_TIME_WITHIN,
|
||||
NES_TIME_AFTER,
|
||||
NES_TIME_AFTER_BLEND
|
||||
} eNlaEvalStrip_StripMode;
|
||||
|
||||
|
||||
/* temp channel for accumulating data from NLA (avoids needing to clear all values first) */
|
||||
// TODO: maybe this will be used as the 'cache' stuff needed for editable values too?
|
||||
typedef struct NlaEvalChannel {
|
||||
struct NlaEvalChannel *next, *prev;
|
||||
|
||||
char *path; /* ready-to-use path (i.e. remapped already) */
|
||||
int array_index; /* if applicable... */
|
||||
|
||||
float value; /* value of this channel */
|
||||
} NlaEvalChannel;
|
||||
|
||||
|
||||
/* ---------------------- */
|
||||
|
||||
/* evaluate the F-Curves controlling settings for the NLA-strips (currently, not relinkable) */
|
||||
static void nlastrip_evaluate_fcurves (NlaStrip *strip, float ctime)
|
||||
/* calculate influence of strip based for given frame based on blendin/out values */
|
||||
static float nlastrip_get_influence (NlaStrip *strip, float cframe)
|
||||
{
|
||||
//PointerRNA actstrip_ptr;
|
||||
//FCurve *fcu;
|
||||
/* sanity checks - normalise the blendin/out values? */
|
||||
strip->blendin= (float)fabs(strip->blendin);
|
||||
strip->blendout= (float)fabs(strip->blendout);
|
||||
|
||||
/* create RNA-pointer needed to set values */
|
||||
//RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &actstrip_ptr);
|
||||
|
||||
/* execute these settings as per normal */
|
||||
//animsys_evaluate_fcurves(&actstrip_ptr, &strip->fcurves, NULL, ctime);
|
||||
/* result depends on where frame is in respect to blendin/out values */
|
||||
if (IS_EQ(strip->blendin, 0)==0 && (cframe <= (strip->start + strip->blendin))) {
|
||||
/* there is some blend-in */
|
||||
return (float)fabs(cframe - strip->start) / (strip->blendin);
|
||||
}
|
||||
else if (IS_EQ(strip->blendout, 0)==0 && (cframe >= (strip->end - strip->blendout))) {
|
||||
/* there is some blend-out */
|
||||
return (float)fabs(strip->end - cframe) / (strip->blendout);
|
||||
}
|
||||
else {
|
||||
/* in the middle of the strip, we should be full strength */
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* gets the strip active at the current time for a track */
|
||||
static void nlatrack_ctime_get_strip (ListBase *list, NlaTrack *nlt, short index, float ctime)
|
||||
/* evaluate the evaluation time and influence for the strip, storing the results in the strip */
|
||||
static void nlastrip_evaluate_controls (NlaStrip *strip, float ctime)
|
||||
{
|
||||
NlaStrip *strip, *astrip=NULL, *bstrip=NULL;
|
||||
/* firstly, analytically generate values for influence and time (if applicable) */
|
||||
if ((strip->flag & NLASTRIP_FLAG_USR_TIME) == 0)
|
||||
strip->strip_time= nlastrip_get_frame(strip, ctime, NLATIME_CONVERT_EVAL);
|
||||
if ((strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) == 0)
|
||||
strip->influence= nlastrip_get_influence(strip, ctime);
|
||||
|
||||
/* now strip's evaluate F-Curves for these settings (if applicable) */
|
||||
if (strip->fcurves.first) {
|
||||
PointerRNA strip_ptr;
|
||||
|
||||
/* create RNA-pointer needed to set values */
|
||||
RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
|
||||
|
||||
/* execute these settings as per normal */
|
||||
animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, NULL, ctime);
|
||||
}
|
||||
}
|
||||
|
||||
/* gets the strip active at the current time for a list of strips for evaluation purposes */
|
||||
NlaEvalStrip *nlastrips_ctime_get_strip (ListBase *list, ListBase *strips, short index, float ctime)
|
||||
{
|
||||
NlaStrip *strip, *estrip=NULL;
|
||||
NlaEvalStrip *nes;
|
||||
short side= 0;
|
||||
|
||||
/* skip if track is muted */
|
||||
if (nlt->flag & NLATRACK_MUTED)
|
||||
return;
|
||||
|
||||
/* loop over strips, checking if they fall within the range */
|
||||
for (strip= nlt->strips.first; strip; strip= strip->next) {
|
||||
/* only consider if:
|
||||
* - current time occurs within strip's extents
|
||||
* - current time occurs before strip (if it is the first)
|
||||
* - current time occurs after strip (if hold is on)
|
||||
* - current time occurs between strips (1st of those isn't holding) - blend!
|
||||
*/
|
||||
if (IN_RANGE(ctime, strip->start, strip->end)) {
|
||||
astrip= strip;
|
||||
for (strip= strips->first; strip; strip= strip->next) {
|
||||
/* check if current time occurs within this strip */
|
||||
if (IN_RANGE_INCL(ctime, strip->start, strip->end)) {
|
||||
/* this strip is active, so try to use it */
|
||||
estrip= strip;
|
||||
side= NES_TIME_WITHIN;
|
||||
break;
|
||||
}
|
||||
else if (ctime < strip->start) {
|
||||
if (strip == nlt->strips.first) {
|
||||
astrip= strip;
|
||||
|
||||
/* if time occurred before current strip... */
|
||||
if (ctime < strip->start) {
|
||||
if (strip == strips->first) {
|
||||
/* before first strip - only try to use it if it extends backwards in time too */
|
||||
if (strip->extendmode == NLASTRIP_EXTEND_HOLD)
|
||||
estrip= strip;
|
||||
|
||||
/* side is 'before' regardless of whether there's a useful strip */
|
||||
side= NES_TIME_BEFORE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
astrip= strip->prev;
|
||||
/* before next strip - previous strip has ended, but next hasn't begun,
|
||||
* so blending mode depends on whether strip is being held or not...
|
||||
* - only occurs when no transition strip added, otherwise the transition would have
|
||||
* been picked up above...
|
||||
*/
|
||||
strip= strip->prev;
|
||||
|
||||
if (strip->extendmode != NLASTRIP_EXTEND_NOTHING)
|
||||
estrip= strip;
|
||||
side= NES_TIME_AFTER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* if time occurred after current strip... */
|
||||
if (ctime > strip->end) {
|
||||
/* only if this is the last strip should we do anything, and only if that is being held */
|
||||
if (strip == strips->last) {
|
||||
if (strip->extendmode != NLASTRIP_EXTEND_NOTHING)
|
||||
estrip= strip;
|
||||
|
||||
if (astrip->flag & NLASTRIP_HOLDLASTFRAME) {
|
||||
side= NES_TIME_AFTER;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
bstrip= strip;
|
||||
side= NES_TIME_AFTER_BLEND;
|
||||
|
||||
/* otherwise, skip... as the 'before' case will catch it more elegantly! */
|
||||
}
|
||||
}
|
||||
|
||||
/* check if a valid strip was found
|
||||
* - must not be muted (i.e. will have contribution
|
||||
*/
|
||||
if ((estrip == NULL) || (estrip->flag & NLASTRIP_FLAG_MUTED))
|
||||
return NULL;
|
||||
|
||||
/* if ctime was not within the boundaries of the strip, clamp! */
|
||||
switch (side) {
|
||||
case NES_TIME_BEFORE: /* extend first frame only */
|
||||
ctime= estrip->start;
|
||||
break;
|
||||
case NES_TIME_AFTER: /* extend last frame only */
|
||||
ctime= estrip->end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* evaluate strip's evaluation controls
|
||||
* - skip if no influence (i.e. same effect as muting the strip)
|
||||
* - negative influence is not supported yet... how would that be defined?
|
||||
*/
|
||||
// TODO: this sounds a bit hacky having a few isolated F-Curves stuck on some data it operates on...
|
||||
nlastrip_evaluate_controls(estrip, ctime);
|
||||
if (estrip->influence <= 0.0f)
|
||||
return NULL;
|
||||
|
||||
/* check if strip has valid data to evaluate,
|
||||
* and/or perform any additional type-specific actions
|
||||
*/
|
||||
switch (estrip->type) {
|
||||
case NLASTRIP_TYPE_CLIP:
|
||||
/* clip must have some action to evaluate */
|
||||
if (estrip->act == NULL)
|
||||
return NULL;
|
||||
break;
|
||||
case NLASTRIP_TYPE_TRANSITION:
|
||||
/* there must be strips to transition from and to (i.e. prev and next required) */
|
||||
if (ELEM(NULL, estrip->prev, estrip->next))
|
||||
return NULL;
|
||||
|
||||
/* evaluate controls for the relevant extents of the bordering strips... */
|
||||
nlastrip_evaluate_controls(estrip->prev, estrip->start);
|
||||
nlastrip_evaluate_controls(estrip->next, estrip->end);
|
||||
break;
|
||||
}
|
||||
|
||||
/* check if strip has been found (and whether it has data worth considering) */
|
||||
if (ELEM(NULL, astrip, astrip->act))
|
||||
return;
|
||||
if (astrip->flag & NLASTRIP_MUTE)
|
||||
return;
|
||||
|
||||
/* check if blending between strips */
|
||||
if (side == NES_TIME_AFTER_BLEND) {
|
||||
/* blending between strips... so calculate influence+act_time of both */
|
||||
nlastrip_evaluate_fcurves(astrip, ctime);
|
||||
nlastrip_evaluate_fcurves(bstrip, ctime);
|
||||
|
||||
if ((astrip->influence <= 0.0f) && (bstrip->influence <= 0.0f))
|
||||
return;
|
||||
}
|
||||
else {
|
||||
/* calculate/set the influence+act_time of this strip - don't consider if 0 influence */
|
||||
nlastrip_evaluate_fcurves(astrip, ctime);
|
||||
|
||||
if (astrip->influence <= 0.0f)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* allocate new eval-strip for this strip + add to stack */
|
||||
/* add to list of strips we need to evaluate */
|
||||
nes= MEM_callocN(sizeof(NlaEvalStrip), "NlaEvalStrip");
|
||||
|
||||
nes->track= nlt;
|
||||
nes->strip= astrip;
|
||||
nes->sblend= bstrip;
|
||||
nes->track_index= index;
|
||||
nes->strip= estrip;
|
||||
nes->strip_mode= side;
|
||||
nes->track_index= index;
|
||||
nes->strip_time= estrip->strip_time;
|
||||
|
||||
if (list)
|
||||
BLI_addtail(list, nes);
|
||||
|
||||
return nes;
|
||||
}
|
||||
|
||||
/* ---------------------- */
|
||||
|
||||
/* evaluates the given evaluation strip */
|
||||
// FIXME: will we need the evaluation cache table set up to blend stuff in?
|
||||
// TODO: only evaluate here, but flush in one go using the accumulated channels at end...
|
||||
static void nlastrip_ctime_evaluate (ListBase *channels, NlaEvalStrip *nes, float ctime)
|
||||
/* find an NlaEvalChannel that matches the given criteria
|
||||
* - ptr and prop are the RNA data to find a match for
|
||||
*/
|
||||
static NlaEvalChannel *nlaevalchan_find_match (ListBase *channels, PointerRNA *ptr, PropertyRNA *prop, int array_index)
|
||||
{
|
||||
// 1. (in old code) was to extract 'IPO-channels' from actions
|
||||
// 2. blend between the 'accumulated' data, and the new data
|
||||
NlaEvalChannel *nec;
|
||||
|
||||
/* sanity check */
|
||||
if (channels == NULL)
|
||||
return NULL;
|
||||
|
||||
/* loop through existing channels, checking for a channel which affects the same property */
|
||||
for (nec= channels->first; nec; nec= nec->next) {
|
||||
/* - comparing the PointerRNA's is done by comparing the pointers
|
||||
* to the actual struct the property resides in, since that all the
|
||||
* other data stored in PointerRNA cannot allow us to definitively
|
||||
* identify the data
|
||||
*/
|
||||
if ((nec->ptr.data == ptr->data) && (nec->prop == prop) && (nec->index == array_index))
|
||||
return nec;
|
||||
}
|
||||
|
||||
/* not found */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* verify that an appropriate NlaEvalChannel for this F-Curve exists */
|
||||
static NlaEvalChannel *nlaevalchan_verify (PointerRNA *ptr, ListBase *channels, NlaEvalStrip *nes, FCurve *fcu, short *newChan)
|
||||
{
|
||||
NlaEvalChannel *nec;
|
||||
NlaStrip *strip= nes->strip;
|
||||
PropertyRNA *prop;
|
||||
PointerRNA new_ptr;
|
||||
char *path = NULL;
|
||||
short free_path=0;
|
||||
|
||||
/* sanity checks */
|
||||
if (channels == NULL)
|
||||
return NULL;
|
||||
|
||||
/* get RNA pointer+property info from F-Curve for more convenient handling */
|
||||
/* get path, remapped as appropriate to work in its new environment */
|
||||
free_path= animsys_remap_path(strip->remap, fcu->rna_path, &path);
|
||||
|
||||
/* a valid property must be available, and it must be animateable */
|
||||
if (RNA_path_resolve(ptr, path, &new_ptr, &prop) == 0) {
|
||||
if (G.f & G_DEBUG) printf("NLA Strip Eval: Cannot resolve path \n");
|
||||
return NULL;
|
||||
}
|
||||
/* only ok if animateable */
|
||||
else if (RNA_property_animateable(&new_ptr, prop) == 0) {
|
||||
if (G.f & G_DEBUG) printf("NLA Strip Eval: Property not animateable \n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* try to find a match */
|
||||
nec= nlaevalchan_find_match(channels, &new_ptr, prop, fcu->array_index);
|
||||
|
||||
/* allocate a new struct for this if none found */
|
||||
if (nec == NULL) {
|
||||
nec= MEM_callocN(sizeof(NlaEvalChannel), "NlaEvalChannel");
|
||||
*newChan= 1;
|
||||
BLI_addtail(channels, nec);
|
||||
|
||||
nec->ptr= new_ptr;
|
||||
nec->prop= prop;
|
||||
nec->index= fcu->array_index;
|
||||
}
|
||||
else
|
||||
*newChan= 0;
|
||||
|
||||
/* we can now return */
|
||||
return nec;
|
||||
}
|
||||
|
||||
/* accumulate (i.e. blend) the given value on to the channel it affects */
|
||||
static void nlaevalchan_accumulate (NlaEvalChannel *nec, NlaEvalStrip *nes, short newChan, float value)
|
||||
{
|
||||
NlaStrip *strip= nes->strip;
|
||||
short blendmode= strip->blendmode;
|
||||
float inf= strip->influence;
|
||||
|
||||
/* if channel is new, just store value regardless of blending factors, etc. */
|
||||
if (newChan) {
|
||||
nec->value= value;
|
||||
return;
|
||||
}
|
||||
|
||||
/* if this is being performed as part of transition evaluation, incorporate
|
||||
* an additional weighting factor for the influence
|
||||
*/
|
||||
if (nes->strip_mode == NES_TIME_TRANSITION_END)
|
||||
inf *= nes->strip_time;
|
||||
|
||||
/* premultiply the value by the weighting factor */
|
||||
if (IS_EQ(inf, 0)) return;
|
||||
value *= inf;
|
||||
|
||||
/* perform blending */
|
||||
switch (blendmode) {
|
||||
case NLASTRIP_MODE_ADD:
|
||||
/* simply add the scaled value on to the stack */
|
||||
nec->value += value;
|
||||
break;
|
||||
|
||||
case NLASTRIP_MODE_SUBTRACT:
|
||||
/* simply subtract the scaled value from the stack */
|
||||
nec->value -= value;
|
||||
break;
|
||||
|
||||
case NLASTRIP_MODE_MULTIPLY:
|
||||
/* multiply the scaled value with the stack */
|
||||
nec->value *= value;
|
||||
break;
|
||||
|
||||
case NLASTRIP_MODE_REPLACE:
|
||||
default: // TODO: do we really want to blend by default? it seems more uses might prefer add...
|
||||
/* do linear interpolation
|
||||
* - the influence of the accumulated data (elsewhere, that is called dstweight)
|
||||
* is 1 - influence, since the strip's influence is srcweight
|
||||
*/
|
||||
nec->value= nec->value * (1.0f - inf) + value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* accumulate the results of a temporary buffer with the results of the full-buffer */
|
||||
static void nlaevalchan_buffers_accumulate (ListBase *channels, ListBase *tmp_buffer, NlaEvalStrip *nes)
|
||||
{
|
||||
NlaEvalChannel *nec, *necn, *necd;
|
||||
|
||||
/* optimise - abort if no channels */
|
||||
if (tmp_buffer->first == NULL)
|
||||
return;
|
||||
|
||||
/* accumulate results in tmp_channels buffer to the accumulation buffer */
|
||||
for (nec= tmp_buffer->first; nec; nec= necn) {
|
||||
/* get pointer to next channel in case we remove the current channel from the temp-buffer */
|
||||
necn= nec->next;
|
||||
|
||||
/* try to find an existing matching channel for this setting in the accumulation buffer */
|
||||
necd= nlaevalchan_find_match(channels, &nec->ptr, nec->prop, nec->index);
|
||||
|
||||
/* if there was a matching channel already in the buffer, accumulate to it,
|
||||
* otherwise, add the current channel to the buffer for efficiency
|
||||
*/
|
||||
if (necd)
|
||||
nlaevalchan_accumulate(necd, nes, 0, nec->value);
|
||||
else {
|
||||
BLI_remlink(tmp_buffer, nec);
|
||||
BLI_addtail(channels, nec);
|
||||
}
|
||||
}
|
||||
|
||||
/* free temp-channels that haven't been assimilated into the buffer */
|
||||
BLI_freelistN(tmp_buffer);
|
||||
}
|
||||
|
||||
/* ---------------------- */
|
||||
/* F-Modifier stack joining/separation utilities - should we generalise these for BLI_listbase.h interface? */
|
||||
|
||||
/* Temporarily join two lists of modifiers together, storing the result in a third list */
|
||||
static void nlaeval_fmodifiers_join_stacks (ListBase *result, ListBase *list1, ListBase *list2)
|
||||
{
|
||||
FModifier *fcm1, *fcm2;
|
||||
|
||||
/* if list1 is invalid... */
|
||||
if ELEM(NULL, list1, list1->first) {
|
||||
if (list2 && list2->first) {
|
||||
result->first= list2->first;
|
||||
result->last= list2->last;
|
||||
}
|
||||
}
|
||||
/* if list 2 is invalid... */
|
||||
else if ELEM(NULL, list2, list2->first) {
|
||||
result->first= list1->first;
|
||||
result->last= list1->last;
|
||||
}
|
||||
else {
|
||||
/* list1 should be added first, and list2 second, with the endpoints of these being the endpoints for result
|
||||
* - the original lists must be left unchanged though, as we need that fact for restoring
|
||||
*/
|
||||
result->first= list1->first;
|
||||
result->last= list2->last;
|
||||
|
||||
fcm1= list1->last;
|
||||
fcm2= list2->first;
|
||||
|
||||
fcm1->next= fcm2;
|
||||
fcm2->prev= fcm1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Split two temporary lists of modifiers */
|
||||
static void nlaeval_fmodifiers_split_stacks (ListBase *list1, ListBase *list2)
|
||||
{
|
||||
FModifier *fcm1, *fcm2;
|
||||
|
||||
/* if list1/2 is invalid... just skip */
|
||||
if ELEM(NULL, list1, list2)
|
||||
return;
|
||||
if ELEM(NULL, list1->first, list2->first)
|
||||
return;
|
||||
|
||||
/* get endpoints */
|
||||
fcm1= list1->last;
|
||||
fcm2= list2->first;
|
||||
|
||||
/* clear their links */
|
||||
fcm1->next= NULL;
|
||||
fcm2->prev= NULL;
|
||||
}
|
||||
|
||||
/* ---------------------- */
|
||||
|
||||
/* evaluate action-clip strip */
|
||||
static void nlastrip_evaluate_actionclip (PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes)
|
||||
{
|
||||
ListBase tmp_modifiers = {NULL, NULL};
|
||||
NlaStrip *strip= nes->strip;
|
||||
FCurve *fcu;
|
||||
float evaltime;
|
||||
|
||||
/* join this strip's modifiers to the parent's modifiers (own modifiers first) */
|
||||
nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
|
||||
|
||||
/* evaluate strip's modifiers which modify time to evaluate the base curves at */
|
||||
evaltime= evaluate_time_fmodifiers(&tmp_modifiers, NULL, 0.0f, strip->strip_time);
|
||||
|
||||
/* evaluate all the F-Curves in the action, saving the relevant pointers to data that will need to be used */
|
||||
for (fcu= strip->act->curves.first; fcu; fcu= fcu->next) {
|
||||
NlaEvalChannel *nec;
|
||||
float value = 0.0f;
|
||||
short newChan = -1;
|
||||
|
||||
/* check if this curve should be skipped */
|
||||
if (fcu->flag & (FCURVE_MUTED|FCURVE_DISABLED))
|
||||
continue;
|
||||
if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED))
|
||||
continue;
|
||||
|
||||
/* evaluate the F-Curve's value for the time given in the strip
|
||||
* NOTE: we use the modified time here, since strip's F-Curve Modifiers are applied on top of this
|
||||
*/
|
||||
value= evaluate_fcurve(fcu, evaltime);
|
||||
|
||||
/* apply strip's F-Curve Modifiers on this value
|
||||
* NOTE: we apply the strip's original evaluation time not the modified one (as per standard F-Curve eval)
|
||||
*/
|
||||
evaluate_value_fmodifiers(&tmp_modifiers, fcu, &value, strip->strip_time);
|
||||
|
||||
|
||||
/* get an NLA evaluation channel to work with, and accumulate the evaluated value with the value(s)
|
||||
* stored in this channel if it has been used already
|
||||
*/
|
||||
nec= nlaevalchan_verify(ptr, channels, nes, fcu, &newChan);
|
||||
if (nec)
|
||||
nlaevalchan_accumulate(nec, nes, newChan, value);
|
||||
}
|
||||
|
||||
/* unlink this strip's modifiers from the parent's modifiers again */
|
||||
nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
|
||||
}
|
||||
|
||||
/* evaluate transition strip */
|
||||
static void nlastrip_evaluate_transition (PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes)
|
||||
{
|
||||
ListBase tmp_channels = {NULL, NULL};
|
||||
ListBase tmp_modifiers = {NULL, NULL};
|
||||
NlaEvalStrip tmp_nes;
|
||||
NlaStrip *s1, *s2;
|
||||
|
||||
/* join this strip's modifiers to the parent's modifiers (own modifiers first) */
|
||||
nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &nes->strip->modifiers, modifiers);
|
||||
|
||||
/* get the two strips to operate on
|
||||
* - we use the endpoints of the strips directly flanking our strip
|
||||
* using these as the endpoints of the transition (destination and source)
|
||||
* - these should have already been determined to be valid...
|
||||
* - if this strip is being played in reverse, we need to swap these endpoints
|
||||
* otherwise they will be interpolated wrong
|
||||
*/
|
||||
if (nes->strip->flag & NLASTRIP_FLAG_REVERSE) {
|
||||
s1= nes->strip->next;
|
||||
s2= nes->strip->prev;
|
||||
}
|
||||
else {
|
||||
s1= nes->strip->prev;
|
||||
s2= nes->strip->next;
|
||||
}
|
||||
|
||||
/* prepare template for 'evaluation strip'
|
||||
* - based on the transition strip's evaluation strip data
|
||||
* - strip_mode is NES_TIME_TRANSITION_* based on which endpoint
|
||||
* - strip_time is the 'normalised' (i.e. in-strip) time for evaluation,
|
||||
* which doubles up as an additional weighting factor for the strip influences
|
||||
* which allows us to appear to be 'interpolating' between the two extremes
|
||||
*/
|
||||
tmp_nes= *nes;
|
||||
|
||||
/* evaluate these strips into a temp-buffer (tmp_channels) */
|
||||
// FIXME: modifier evalation here needs some work...
|
||||
/* first strip */
|
||||
tmp_nes.strip_mode= NES_TIME_TRANSITION_START;
|
||||
tmp_nes.strip= s1;
|
||||
nlastrip_evaluate_actionclip(ptr, &tmp_channels, &tmp_modifiers, &tmp_nes);
|
||||
|
||||
/* second strip */
|
||||
tmp_nes.strip_mode= NES_TIME_TRANSITION_END;
|
||||
tmp_nes.strip= s2;
|
||||
nlastrip_evaluate_actionclip(ptr, &tmp_channels, &tmp_modifiers, &tmp_nes);
|
||||
|
||||
|
||||
/* assumulate temp-buffer and full-buffer, using the 'real' strip */
|
||||
nlaevalchan_buffers_accumulate(channels, &tmp_channels, nes);
|
||||
|
||||
/* unlink this strip's modifiers from the parent's modifiers again */
|
||||
nlaeval_fmodifiers_split_stacks(&nes->strip->modifiers, modifiers);
|
||||
}
|
||||
|
||||
/* evaluate meta-strip */
|
||||
static void nlastrip_evaluate_meta (PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes)
|
||||
{
|
||||
ListBase tmp_channels = {NULL, NULL};
|
||||
ListBase tmp_modifiers = {NULL, NULL};
|
||||
NlaStrip *strip= nes->strip;
|
||||
NlaEvalStrip *tmp_nes;
|
||||
float evaltime;
|
||||
|
||||
/* meta-strip was calculated normally to have some time to be evaluated at
|
||||
* and here we 'look inside' the meta strip, treating it as a decorated window to
|
||||
* it's child strips, which get evaluated as if they were some tracks on a strip
|
||||
* (but with some extra modifiers to apply).
|
||||
*
|
||||
* NOTE: keep this in sync with animsys_evaluate_nla()
|
||||
*/
|
||||
|
||||
/* join this strip's modifiers to the parent's modifiers (own modifiers first) */
|
||||
nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
|
||||
|
||||
/* find the child-strip to evaluate */
|
||||
evaltime= (nes->strip_time * (strip->end - strip->start)) + strip->start;
|
||||
tmp_nes= nlastrips_ctime_get_strip(NULL, &strip->strips, -1, evaltime);
|
||||
if (tmp_nes == NULL)
|
||||
return;
|
||||
|
||||
/* evaluate child-strip into tmp_channels buffer before accumulating
|
||||
* in the accumulation buffer
|
||||
*/
|
||||
nlastrip_evaluate(ptr, &tmp_channels, &tmp_modifiers, tmp_nes);
|
||||
|
||||
/* assumulate temp-buffer and full-buffer, using the 'real' strip */
|
||||
nlaevalchan_buffers_accumulate(channels, &tmp_channels, nes);
|
||||
|
||||
/* free temp eval-strip */
|
||||
MEM_freeN(tmp_nes);
|
||||
|
||||
/* unlink this strip's modifiers from the parent's modifiers again */
|
||||
nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
|
||||
}
|
||||
|
||||
/* evaluates the given evaluation strip */
|
||||
void nlastrip_evaluate (PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes)
|
||||
{
|
||||
/* actions to take depend on the type of strip */
|
||||
switch (nes->strip->type) {
|
||||
case NLASTRIP_TYPE_CLIP: /* action-clip */
|
||||
nlastrip_evaluate_actionclip(ptr, channels, modifiers, nes);
|
||||
break;
|
||||
case NLASTRIP_TYPE_TRANSITION: /* transition */
|
||||
nlastrip_evaluate_transition(ptr, channels, modifiers, nes);
|
||||
break;
|
||||
case NLASTRIP_TYPE_META: /* meta */
|
||||
nlastrip_evaluate_meta(ptr, channels, modifiers, nes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* write the accumulated settings to */
|
||||
static void nladata_flush_channels (PointerRNA *ptr, ListBase *channels)
|
||||
void nladata_flush_channels (ListBase *channels)
|
||||
{
|
||||
NlaEvalChannel *nec;
|
||||
|
||||
/* sanity checks */
|
||||
if (channels == NULL)
|
||||
return;
|
||||
|
||||
/* for each channel with accumulated values, write its value on the property it affects */
|
||||
for (nec= channels->first; nec; nec= nec->next) {
|
||||
PointerRNA *ptr= &nec->ptr;
|
||||
PropertyRNA *prop= nec->prop;
|
||||
int array_index= nec->index;
|
||||
float value= nec->value;
|
||||
|
||||
/* write values - see animsys_write_rna_setting() to sync the code */
|
||||
switch (RNA_property_type(prop))
|
||||
{
|
||||
case PROP_BOOLEAN:
|
||||
if (RNA_property_array_length(prop))
|
||||
RNA_property_boolean_set_index(ptr, prop, array_index, (int)value);
|
||||
else
|
||||
RNA_property_boolean_set(ptr, prop, (int)value);
|
||||
break;
|
||||
case PROP_INT:
|
||||
if (RNA_property_array_length(prop))
|
||||
RNA_property_int_set_index(ptr, prop, array_index, (int)value);
|
||||
else
|
||||
RNA_property_int_set(ptr, prop, (int)value);
|
||||
break;
|
||||
case PROP_FLOAT:
|
||||
if (RNA_property_array_length(prop))
|
||||
RNA_property_float_set_index(ptr, prop, array_index, value);
|
||||
else
|
||||
RNA_property_float_set(ptr, prop, value);
|
||||
break;
|
||||
case PROP_ENUM:
|
||||
RNA_property_enum_set(ptr, prop, (int)value);
|
||||
break;
|
||||
default:
|
||||
// can't do anything with other types of property....
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------- */
|
||||
@ -703,9 +1184,26 @@ static void animsys_evaluate_nla (PointerRNA *ptr, AnimData *adt, float ctime)
|
||||
ListBase echannels= {NULL, NULL};
|
||||
NlaEvalStrip *nes;
|
||||
|
||||
// TODO: need to zero out all channels used, otherwise we have problems with threadsafety
|
||||
// and also when the user jumps between different times instead of moving sequentially...
|
||||
|
||||
/* 1. get the stack of strips to evaluate at current time (influence calculated here) */
|
||||
for (nlt=adt->nla_tracks.first; nlt; nlt=nlt->next, track_index++)
|
||||
nlatrack_ctime_get_strip(&estrips, nlt, track_index, ctime);
|
||||
for (nlt=adt->nla_tracks.first; nlt; nlt=nlt->next, track_index++) {
|
||||
/* if tweaking is on and this strip is the tweaking track, stop on this one */
|
||||
if ((adt->flag & ADT_NLA_EDIT_ON) && (nlt->flag & NLATRACK_DISABLED))
|
||||
break;
|
||||
|
||||
/* skip if we're only considering a track tagged 'solo' */
|
||||
if ((adt->flag & ADT_NLA_SOLO_TRACK) && (nlt->flag & NLATRACK_SOLO)==0)
|
||||
continue;
|
||||
/* skip if track is muted */
|
||||
if (nlt->flag & NLATRACK_MUTED)
|
||||
continue;
|
||||
|
||||
/* otherwise, get strip to evaluate for this channel */
|
||||
nes= nlastrips_ctime_get_strip(&estrips, &nlt->strips, track_index, ctime);
|
||||
if (nes) nes->track= nlt;
|
||||
}
|
||||
|
||||
/* only continue if there are strips to evaluate */
|
||||
if (estrips.first == NULL)
|
||||
@ -714,10 +1212,10 @@ static void animsys_evaluate_nla (PointerRNA *ptr, AnimData *adt, float ctime)
|
||||
|
||||
/* 2. for each strip, evaluate then accumulate on top of existing channels, but don't set values yet */
|
||||
for (nes= estrips.first; nes; nes= nes->next)
|
||||
nlastrip_ctime_evaluate(&echannels, nes, ctime);
|
||||
nlastrip_evaluate(ptr, &echannels, NULL, nes);
|
||||
|
||||
/* 3. flush effects of accumulating channels in NLA to the actual data they affect */
|
||||
nladata_flush_channels(ptr, &echannels);
|
||||
nladata_flush_channels(&echannels);
|
||||
|
||||
/* 4. free temporary evaluation data */
|
||||
BLI_freelistN(&estrips);
|
||||
@ -799,17 +1297,23 @@ void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short re
|
||||
* - NLA before Active Action, as Active Action behaves as 'tweaking track'
|
||||
* that overrides 'rough' work in NLA
|
||||
*/
|
||||
// TODO: need to double check that this all works correctly
|
||||
if ((recalc & ADT_RECALC_ANIM) || (adt->recalc & ADT_RECALC_ANIM))
|
||||
{
|
||||
/* evaluate NLA data */
|
||||
if ((adt->nla_tracks.first) && !(adt->flag & ADT_NLA_EVAL_OFF))
|
||||
{
|
||||
/* evaluate NLA-stack */
|
||||
animsys_evaluate_nla(&id_ptr, adt, ctime);
|
||||
}
|
||||
|
||||
/* evaluate Action data */
|
||||
// FIXME: what if the solo track was not tweaking one, then nla-solo should be checked too?
|
||||
if (adt->action)
|
||||
/* evaluate 'active' Action (may be tweaking track) on top of results of NLA-evaluation
|
||||
* - only do this if we're not exclusively evaluating the 'solo' NLA-track
|
||||
*/
|
||||
if ((adt->action) && !(adt->flag & ADT_NLA_SOLO_TRACK))
|
||||
animsys_evaluate_action(&id_ptr, adt->action, adt->remap, ctime);
|
||||
}
|
||||
/* evaluate Active Action only */
|
||||
else if (adt->action)
|
||||
animsys_evaluate_action(&id_ptr, adt->action, adt->remap, ctime);
|
||||
|
||||
/* reset tag */
|
||||
@ -876,10 +1380,22 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
|
||||
EVAL_ANIM_IDS(main->camera.first, ADT_RECALC_ANIM);
|
||||
|
||||
/* shapekeys */
|
||||
// TODO: we probably need the same hack as for curves (ctime-hack)
|
||||
EVAL_ANIM_IDS(main->key.first, ADT_RECALC_ANIM);
|
||||
|
||||
/* curves */
|
||||
// TODO...
|
||||
/* we need to perform a special hack here to ensure that the ctime
|
||||
* value of the curve gets set in case there's no animation for that
|
||||
* - it needs to be set before animation is evaluated just so that
|
||||
* animation can successfully override...
|
||||
*/
|
||||
for (id= main->curve.first; id; id= id->next) {
|
||||
AnimData *adt= BKE_animdata_from_id(id);
|
||||
Curve *cu= (Curve *)id;
|
||||
|
||||
cu->ctime= ctime;
|
||||
BKE_animsys_evaluate_animdata(id, adt, ctime, ADT_RECALC_ANIM);
|
||||
}
|
||||
|
||||
/* meshes */
|
||||
// TODO...
|
||||
|
@ -341,24 +341,27 @@ void bvhselftree_update_from_cloth(ClothModifierData *clmd, int moving)
|
||||
}
|
||||
|
||||
int modifiers_indexInObject(Object *ob, ModifierData *md_seek);
|
||||
static void cloth_write_state(int index, Cloth *cloth, float *data)
|
||||
static void cloth_write_state(int index, void *cloth_v, float *data)
|
||||
{
|
||||
Cloth *cloth= cloth_v;
|
||||
ClothVertex *vert = cloth->verts + index;
|
||||
|
||||
memcpy(data, vert->x, 3 * sizeof(float));
|
||||
memcpy(data + 3, vert->xconst, 3 * sizeof(float));
|
||||
memcpy(data + 6, vert->v, 3 * sizeof(float));
|
||||
}
|
||||
static void cloth_read_state(int index, Cloth *cloth, float *data)
|
||||
static void cloth_read_state(int index, void *cloth_v, float *data)
|
||||
{
|
||||
Cloth *cloth= cloth_v;
|
||||
ClothVertex *vert = cloth->verts + index;
|
||||
|
||||
memcpy(vert->x, data, 3 * sizeof(float));
|
||||
memcpy(vert->xconst, data + 3, 3 * sizeof(float));
|
||||
memcpy(vert->v, data + 6, 3 * sizeof(float));
|
||||
}
|
||||
static void cloth_cache_interpolate(int index, Cloth *cloth, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2)
|
||||
static void cloth_cache_interpolate(int index, void *cloth_v, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2)
|
||||
{
|
||||
Cloth *cloth= cloth_v;
|
||||
ClothVertex *vert = cloth->verts + index;
|
||||
ParticleKey keys[4];
|
||||
float dfra;
|
||||
|
@ -378,7 +378,7 @@ PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, Stru
|
||||
{
|
||||
PointerRNA ptr = CTX_data_pointer_get(C, member);
|
||||
|
||||
if(ptr.data && ptr.type == type)
|
||||
if(ptr.data && RNA_struct_is_a(ptr.type, type))
|
||||
return ptr;
|
||||
|
||||
return PointerRNA_NULL;
|
||||
|
@ -568,14 +568,14 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
|
||||
dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA, "Particle Keyed Physics");
|
||||
}
|
||||
|
||||
if(part->draw_as == PART_DRAW_OB && part->dup_ob) {
|
||||
if(part->ren_as == PART_DRAW_OB && part->dup_ob) {
|
||||
node2 = dag_get_node(dag, part->dup_ob);
|
||||
dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualisation");
|
||||
if(part->dup_ob->type == OB_MBALL)
|
||||
dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Object Visualisation");
|
||||
}
|
||||
|
||||
if(part->draw_as == PART_DRAW_GR && part->dup_group) {
|
||||
if(part->ren_as == PART_DRAW_GR && part->dup_group) {
|
||||
for(go=part->dup_group->gobject.first; go; go=go->next) {
|
||||
node2 = dag_get_node(dag, go->ob);
|
||||
dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Group Visualisation");
|
||||
|
@ -56,6 +56,8 @@
|
||||
#include "BLI_jitter.h"
|
||||
#include "BLI_rand.h"
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_anim.h" /* needed for where_on_path */
|
||||
#include "BKE_armature.h"
|
||||
@ -93,6 +95,20 @@
|
||||
|
||||
//XXX #include "BIF_screen.h"
|
||||
|
||||
PartDeflect *object_add_collision_fields(void)
|
||||
{
|
||||
PartDeflect *pd;
|
||||
|
||||
pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
|
||||
|
||||
pd->pdef_sbdamp = 0.1f;
|
||||
pd->pdef_sbift = 0.2f;
|
||||
pd->pdef_sboft = 0.02f;
|
||||
pd->seed = ((unsigned int)(ceil(PIL_check_seconds_timer()))+1) % 128;
|
||||
|
||||
return pd;
|
||||
}
|
||||
|
||||
/* temporal struct, used for reading return of mesh_get_mapped_verts_nors() */
|
||||
|
||||
typedef struct VeNoCo {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,7 +34,9 @@
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_fluidsim.h"
|
||||
#include "DNA_object_force.h" // for pointcache
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_particle_types.h"
|
||||
#include "DNA_scene_types.h" // N_T
|
||||
|
||||
@ -78,7 +80,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
|
||||
if(!fss)
|
||||
return;
|
||||
|
||||
fss->type = OB_FSBND_NOSLIP;
|
||||
fss->type = OB_FLUIDSIM_ENABLE;
|
||||
fss->show_advancedoptions = 0;
|
||||
|
||||
fss->resolutionxyz = 50;
|
||||
@ -112,7 +114,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
|
||||
// no bounding box needed
|
||||
|
||||
// todo - reuse default init from elbeem!
|
||||
fss->typeFlags = 0;
|
||||
fss->typeFlags = OB_FSBND_NOSLIP;
|
||||
fss->domainNovecgen = 0;
|
||||
fss->volumeInitType = 1; // volume
|
||||
fss->partSlipValue = 0.0;
|
||||
@ -657,5 +659,20 @@ void initElbeemMesh(struct Scene *scene, struct Object *ob,
|
||||
dm->release(dm);
|
||||
}
|
||||
|
||||
void fluid_estimate_memory(Object *ob, FluidsimSettings *fss, char *value)
|
||||
{
|
||||
Mesh *mesh;
|
||||
|
||||
value[0]= '\0';
|
||||
|
||||
if(ob->type == OB_MESH) {
|
||||
/* use mesh bounding box and object scaling */
|
||||
mesh= ob->data;
|
||||
|
||||
fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize);
|
||||
elbeemEstimateMemreq(fss->resolutionxyz, fss->bbSize[0],fss->bbSize[1],fss->bbSize[2], fss->maxRefine, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DISABLE_ELBEEM
|
||||
|
||||
|
1197
source/blender/blenkernel/intern/fmodifier.c
Normal file
1197
source/blender/blenkernel/intern/fmodifier.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -253,6 +253,10 @@ void free_image(Image *ima)
|
||||
if (ima->preview) {
|
||||
BKE_previewimg_free(&ima->preview);
|
||||
}
|
||||
if (ima->render_text) {
|
||||
MEM_freeN(ima->render_text);
|
||||
ima->render_text= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* only image block itself */
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_nla_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_object_force.h"
|
||||
#include "DNA_particle_types.h"
|
||||
@ -85,6 +86,7 @@
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_nla.h"
|
||||
#include "BKE_object.h"
|
||||
|
||||
|
||||
@ -825,6 +827,10 @@ char *get_rna_access (int blocktype, int adrcode, char actname[], char constname
|
||||
char buf[512];
|
||||
int dummy_index= 0;
|
||||
|
||||
/* hack: if constname is set, we can only be dealing with an Constraint curve */
|
||||
if (constname)
|
||||
blocktype= ID_CO;
|
||||
|
||||
/* get property name based on blocktype */
|
||||
switch (blocktype) {
|
||||
case ID_OB: /* object */
|
||||
@ -870,7 +876,10 @@ char *get_rna_access (int blocktype, int adrcode, char actname[], char constname
|
||||
|
||||
/* XXX problematic blocktypes */
|
||||
case ID_CU: /* curve */
|
||||
propname= "speed"; // XXX this was a 'dummy curve' that didn't really correspond to any real var...
|
||||
/* this used to be a 'dummy' curve which got evaluated on the fly...
|
||||
* now we've got real var for this!
|
||||
*/
|
||||
propname= "eval_time";
|
||||
break;
|
||||
|
||||
case ID_SEQ: /* sequencer strip */
|
||||
@ -1144,7 +1153,7 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
|
||||
/* Add a new FModifier (Cyclic) instead of setting extend value
|
||||
* as that's the new equivilant of that option.
|
||||
*/
|
||||
FModifier *fcm= fcurve_add_modifier(fcu, FMODIFIER_TYPE_CYCLES);
|
||||
FModifier *fcm= add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES);
|
||||
FMod_Cycles *data= (FMod_Cycles *)fcm->data;
|
||||
|
||||
/* if 'offset' one is in use, set appropriate settings */
|
||||
@ -1463,6 +1472,87 @@ static void action_to_animdata (ID *id, bAction *act)
|
||||
action_to_animato(act, &adt->action->groups, &adt->action->curves, &adt->drivers);
|
||||
}
|
||||
|
||||
/* ------------------------- */
|
||||
|
||||
// TODO:
|
||||
// - NLA group duplicators info
|
||||
// - NLA curve/stride modifiers...
|
||||
|
||||
/* Convert NLA-Strip to new system */
|
||||
static void nlastrips_to_animdata (ID *id, ListBase *strips)
|
||||
{
|
||||
AnimData *adt= BKE_animdata_from_id(id);
|
||||
NlaTrack *nlt = NULL;
|
||||
NlaStrip *strip;
|
||||
bActionStrip *as, *asn;
|
||||
|
||||
/* for each one of the original strips, convert to a new strip and free the old... */
|
||||
for (as= strips->first; as; as= asn) {
|
||||
asn= as->next;
|
||||
|
||||
/* this old strip is only worth something if it had an action... */
|
||||
if (as->act) {
|
||||
/* convert Action data (if not yet converted), storing the results in the same Action */
|
||||
action_to_animato(as->act, &as->act->groups, &as->act->curves, &adt->drivers);
|
||||
|
||||
/* create a new-style NLA-strip which references this Action, then copy over relevant settings */
|
||||
{
|
||||
/* init a new strip, and assign the action to it
|
||||
* - no need to muck around with the user-counts, since this is just
|
||||
* passing over the ref to the new owner, not creating an additional ref
|
||||
*/
|
||||
strip= MEM_callocN(sizeof(NlaStrip), "NlaStrip");
|
||||
strip->act= as->act;
|
||||
|
||||
/* endpoints */
|
||||
strip->start= as->start;
|
||||
strip->end= as->end;
|
||||
strip->actstart= as->actstart;
|
||||
strip->actend= as->actend;
|
||||
|
||||
/* action reuse */
|
||||
strip->repeat= as->repeat;
|
||||
strip->scale= as->scale;
|
||||
if (as->flag & ACTSTRIP_LOCK_ACTION) strip->flag |= NLASTRIP_FLAG_SYNC_LENGTH;
|
||||
|
||||
/* blending */
|
||||
strip->blendin= as->blendin;
|
||||
strip->blendout= as->blendout;
|
||||
strip->blendmode= (as->mode==ACTSTRIPMODE_ADD) ? NLASTRIP_MODE_ADD : NLASTRIP_MODE_REPLACE;
|
||||
if (as->flag & ACTSTRIP_AUTO_BLENDS) strip->flag |= NLASTRIP_FLAG_AUTO_BLENDS;
|
||||
|
||||
/* assorted setting flags */
|
||||
if (as->flag & ACTSTRIP_SELECT) strip->flag |= NLASTRIP_FLAG_SELECT;
|
||||
if (as->flag & ACTSTRIP_ACTIVE) strip->flag |= NLASTRIP_FLAG_ACTIVE;
|
||||
|
||||
if (as->flag & ACTSTRIP_MUTE) strip->flag |= NLASTRIP_FLAG_MUTED;
|
||||
if (as->flag & ACTSTRIP_REVERSE) strip->flag |= NLASTRIP_FLAG_REVERSE;
|
||||
|
||||
/* by default, we now always extrapolate, while in the past this was optional */
|
||||
if ((as->flag & ACTSTRIP_HOLDLASTFRAME)==0)
|
||||
strip->extendmode= NLASTRIP_EXTEND_NOTHING;
|
||||
}
|
||||
|
||||
/* try to add this strip to the current NLA-Track (i.e. the 'last' one on the stack atm) */
|
||||
if (BKE_nlatrack_add_strip(nlt, strip) == 0) {
|
||||
/* trying to add to the current failed (no space),
|
||||
* so add a new track to the stack, and add to that...
|
||||
*/
|
||||
nlt= add_nlatrack(adt, NULL);
|
||||
BKE_nlatrack_add_strip(nlt, strip);
|
||||
}
|
||||
}
|
||||
|
||||
/* modifiers */
|
||||
// FIXME: for now, we just free them...
|
||||
if (as->modifiers.first)
|
||||
BLI_freelistN(&as->modifiers);
|
||||
|
||||
/* free the old strip */
|
||||
BLI_freelinkN(strips, as);
|
||||
}
|
||||
}
|
||||
|
||||
/* *************************************************** */
|
||||
/* External API - Only Called from do_versions() */
|
||||
|
||||
@ -1509,7 +1599,30 @@ void do_versions_ipos_to_animato(Main *main)
|
||||
if (G.f & G_DEBUG) printf("\tconverting ob %s \n", id->name+2);
|
||||
|
||||
/* check if object has any animation data */
|
||||
if ((ob->ipo) || (ob->action) || (ob->nlastrips.first)) {
|
||||
if (ob->nlastrips.first) {
|
||||
/* Add AnimData block */
|
||||
adt= BKE_id_add_animdata(id);
|
||||
|
||||
/* IPO first to take into any non-NLA'd Object Animation */
|
||||
if (ob->ipo) {
|
||||
ipo_to_animdata(id, ob->ipo, NULL, NULL);
|
||||
|
||||
ob->ipo->id.us--;
|
||||
ob->ipo= NULL;
|
||||
}
|
||||
|
||||
/* Action is skipped since it'll be used by some strip in the NLA anyway,
|
||||
* causing errors with evaluation in the new evaluation pipeline
|
||||
*/
|
||||
if (ob->action) {
|
||||
ob->action->id.us--;
|
||||
ob->action= NULL;
|
||||
}
|
||||
|
||||
/* finally NLA */
|
||||
nlastrips_to_animdata(id, &ob->nlastrips);
|
||||
}
|
||||
else if ((ob->ipo) || (ob->action)) {
|
||||
/* Add AnimData block */
|
||||
adt= BKE_id_add_animdata(id);
|
||||
|
||||
@ -1530,9 +1643,6 @@ void do_versions_ipos_to_animato(Main *main)
|
||||
ob->ipo->id.us--;
|
||||
ob->ipo= NULL;
|
||||
}
|
||||
|
||||
/* finally NLA */
|
||||
// XXX todo... for now, new NLA code not hooked up yet, so keep old stuff (but not for too long!)
|
||||
}
|
||||
|
||||
/* check PoseChannels for constraints with local data */
|
||||
|
@ -232,8 +232,8 @@ void free_lattice(Lattice *lt)
|
||||
if(lt->def) MEM_freeN(lt->def);
|
||||
if(lt->dvert) free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
|
||||
if(lt->editlatt) {
|
||||
if(lt->def) MEM_freeN(lt->def);
|
||||
if(lt->dvert) free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
|
||||
if(lt->editlatt->def) MEM_freeN(lt->editlatt->def);
|
||||
if(lt->editlatt->dvert) free_dverts(lt->editlatt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
|
||||
MEM_freeN(lt->editlatt);
|
||||
}
|
||||
}
|
||||
@ -817,6 +817,7 @@ void outside_lattice(Lattice *lt)
|
||||
int u, v, w;
|
||||
float fac1, du=0.0, dv=0.0, dw=0.0;
|
||||
|
||||
if(lt->flag & LT_OUTSIDE) {
|
||||
bp= lt->def;
|
||||
|
||||
if(lt->pntsu>1) du= 1.0f/((float)lt->pntsu-1);
|
||||
@ -869,7 +870,15 @@ void outside_lattice(Lattice *lt)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
bp= lt->def;
|
||||
|
||||
for(w=0; w<lt->pntsw; w++)
|
||||
for(v=0; v<lt->pntsv; v++)
|
||||
for(u=0; u<lt->pntsu; u++, bp++)
|
||||
bp->hide= 0;
|
||||
}
|
||||
}
|
||||
|
||||
float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3]
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_object_fluidsim.h"
|
||||
#include "DNA_object_force.h"
|
||||
#include "DNA_particle_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
@ -6389,6 +6390,7 @@ static void particleSystemModifier_deformVerts(
|
||||
}
|
||||
|
||||
if(psys){
|
||||
psmd->flag &= ~eParticleSystemFlag_psys_updated;
|
||||
particle_system_update(md->scene, ob, psys);
|
||||
psmd->flag |= eParticleSystemFlag_psys_updated;
|
||||
psmd->flag &= ~eParticleSystemFlag_DM_changed;
|
||||
@ -6420,6 +6422,8 @@ static void particleInstanceModifier_initData(ModifierData *md)
|
||||
pimd->flag = eParticleInstanceFlag_Parents|eParticleInstanceFlag_Unborn|
|
||||
eParticleInstanceFlag_Alive|eParticleInstanceFlag_Dead;
|
||||
pimd->psys = 1;
|
||||
pimd->position = 1.0f;
|
||||
pimd->axis = 2;
|
||||
|
||||
}
|
||||
static void particleInstanceModifier_copyData(ModifierData *md, ModifierData *target)
|
||||
@ -6430,6 +6434,8 @@ static void particleInstanceModifier_copyData(ModifierData *md, ModifierData *ta
|
||||
tpimd->ob = pimd->ob;
|
||||
tpimd->psys = pimd->psys;
|
||||
tpimd->flag = pimd->flag;
|
||||
tpimd->position = pimd->position;
|
||||
tpimd->random_position = pimd->random_position;
|
||||
}
|
||||
|
||||
static int particleInstanceModifier_dependsOnTime(ModifierData *md)
|
||||
@ -6469,8 +6475,9 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
|
||||
MFace *mface, *orig_mface;
|
||||
MVert *mvert, *orig_mvert;
|
||||
int i,totvert, totpart=0, totface, maxvert, maxface, first_particle=0;
|
||||
short track=ob->trackflag%3, trackneg;
|
||||
short track=ob->trackflag%3, trackneg, axis = pimd->axis;
|
||||
float max_co=0.0, min_co=0.0, temp_co[3], cross[3];
|
||||
float *size=NULL;
|
||||
|
||||
trackneg=((ob->trackflag>2)?1:0);
|
||||
|
||||
@ -6497,6 +6504,25 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
|
||||
if(totpart==0)
|
||||
return derivedData;
|
||||
|
||||
if(pimd->flag & eParticleInstanceFlag_UseSize) {
|
||||
int p;
|
||||
float *si;
|
||||
si = size = MEM_callocN(totpart * sizeof(float), "particle size array");
|
||||
|
||||
if(pimd->flag & eParticleInstanceFlag_Parents) {
|
||||
for(p=0, pa= psys->particles; p<psys->totpart; p++, pa++, si++)
|
||||
*si = pa->size;
|
||||
}
|
||||
|
||||
if(pimd->flag & eParticleInstanceFlag_Children) {
|
||||
ChildParticle *cpa = psys->child;
|
||||
|
||||
for(p=0; p<psys->totchild; p++, cpa++, si++) {
|
||||
*si = psys_get_child_size(psys, cpa, 0.0f, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pars=psys->particles;
|
||||
|
||||
totvert=dm->getNumVerts(dm);
|
||||
@ -6507,7 +6533,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
|
||||
|
||||
psys->lattice=psys_get_lattice(md->scene, ob, psys);
|
||||
|
||||
if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)){
|
||||
if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED){
|
||||
|
||||
float min_r[3], max_r[3];
|
||||
INIT_MINMAX(min_r, max_r);
|
||||
@ -6532,40 +6558,59 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
|
||||
|
||||
/*change orientation based on object trackflag*/
|
||||
VECCOPY(temp_co,mv->co);
|
||||
mv->co[0]=temp_co[track];
|
||||
mv->co[1]=temp_co[(track+1)%3];
|
||||
mv->co[2]=temp_co[(track+2)%3];
|
||||
mv->co[axis]=temp_co[track];
|
||||
mv->co[(axis+1)%3]=temp_co[(track+1)%3];
|
||||
mv->co[(axis+2)%3]=temp_co[(track+2)%3];
|
||||
|
||||
if((psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) && pimd->flag & eParticleInstanceFlag_Path){
|
||||
float ran = 0.0f;
|
||||
if(pimd->random_position != 0.0f) {
|
||||
/* just use some static collection of random numbers */
|
||||
/* TODO: use something else that's unique to each instanced object */
|
||||
pa = psys->particles + (i/totvert)%totpart;
|
||||
ran = pimd->random_position * 0.5 * (1.0f + pa->r_ave[0]);
|
||||
}
|
||||
|
||||
if(pimd->flag & eParticleInstanceFlag_KeepShape) {
|
||||
state.time = pimd->position * (1.0f - ran);
|
||||
}
|
||||
else {
|
||||
state.time=(mv->co[axis]-min_co)/(max_co-min_co) * pimd->position * (1.0f - ran);
|
||||
|
||||
if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) && pimd->flag & eParticleInstanceFlag_Path){
|
||||
state.time=(mv->co[0]-min_co)/(max_co-min_co);
|
||||
if(trackneg)
|
||||
state.time=1.0f-state.time;
|
||||
psys_get_particle_on_path(md->scene, pimd->ob, psys,first_particle + i/totvert, &state,1);
|
||||
|
||||
mv->co[0] = 0.0;
|
||||
mv->co[axis] = 0.0;
|
||||
}
|
||||
|
||||
psys_get_particle_on_path(md->scene, pimd->ob, psys,first_particle + i/totvert, &state,1);
|
||||
|
||||
Normalize(state.vel);
|
||||
|
||||
if(state.vel[0] < -0.9999 || state.vel[0] > 0.9999) {
|
||||
state.rot[0] = 1.0;
|
||||
/* TODO: incremental rotations somehow */
|
||||
if(state.vel[axis] < -0.9999 || state.vel[axis] > 0.9999) {
|
||||
state.rot[0] = 1;
|
||||
state.rot[1] = state.rot[2] = state.rot[3] = 0.0f;
|
||||
}
|
||||
else {
|
||||
/* a cross product of state.vel and a unit vector in x-direction */
|
||||
cross[0] = 0.0f;
|
||||
cross[1] = -state.vel[2];
|
||||
cross[2] = state.vel[1];
|
||||
float temp[3] = {0.0f,0.0f,0.0f};
|
||||
temp[axis] = 1.0f;
|
||||
|
||||
/* state.vel[0] is the only component surviving from a dot product with a vector in x-direction*/
|
||||
VecRotToQuat(cross,saacos(state.vel[0]),state.rot);
|
||||
Crossf(cross, temp, state.vel);
|
||||
|
||||
/* state.vel[axis] is the only component surviving from a dot product with the axis */
|
||||
VecRotToQuat(cross,saacos(state.vel[axis]),state.rot);
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
state.time=-1.0;
|
||||
psys_get_particle_state(md->scene, pimd->ob, psys, i/totvert, &state,1);
|
||||
psys_get_particle_state(md->scene, pimd->ob, psys, first_particle + i/totvert, &state,1);
|
||||
}
|
||||
|
||||
QuatMulVecf(state.rot,mv->co);
|
||||
if(pimd->flag & eParticleInstanceFlag_UseSize)
|
||||
VecMulf(mv->co, size[i/totvert]);
|
||||
VECADD(mv->co,mv->co,state.co);
|
||||
}
|
||||
|
||||
@ -6618,6 +6663,9 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
|
||||
psys->lattice= NULL;
|
||||
}
|
||||
|
||||
if(size)
|
||||
MEM_freeN(size);
|
||||
|
||||
return result;
|
||||
}
|
||||
static DerivedMesh *particleInstanceModifier_applyModifierEM(
|
||||
@ -7256,10 +7304,10 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
|
||||
|
||||
timestep= psys_get_timestep(part);
|
||||
|
||||
if(part->flag & PART_GLOB_TIME)
|
||||
//if(part->flag & PART_GLOB_TIME)
|
||||
cfra=bsystem_time(scene, 0,(float)scene->r.cfra,0.0);
|
||||
else
|
||||
cfra=bsystem_time(scene, ob,(float)scene->r.cfra,0.0);
|
||||
//else
|
||||
// cfra=bsystem_time(scene, ob,(float)scene->r.cfra,0.0);
|
||||
|
||||
/* hash table for vertice <-> particle relations */
|
||||
vertpahash= BLI_edgehash_new();
|
||||
@ -8387,7 +8435,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
|
||||
mti = INIT_TYPE(Softbody);
|
||||
mti->type = eModifierTypeType_OnlyDeform;
|
||||
mti->flags = eModifierTypeFlag_AcceptsCVs
|
||||
| eModifierTypeFlag_RequiresOriginalData;
|
||||
| eModifierTypeFlag_RequiresOriginalData
|
||||
| eModifierTypeFlag_Single;
|
||||
mti->deformVerts = softbodyModifier_deformVerts;
|
||||
mti->dependsOnTime = softbodyModifier_dependsOnTime;
|
||||
|
||||
@ -8395,7 +8444,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
|
||||
mti->type = eModifierTypeType_Nonconstructive;
|
||||
mti->initData = clothModifier_initData;
|
||||
mti->flags = eModifierTypeFlag_AcceptsMesh
|
||||
| eModifierTypeFlag_UsesPointCache;
|
||||
| eModifierTypeFlag_UsesPointCache
|
||||
| eModifierTypeFlag_Single;
|
||||
mti->dependsOnTime = clothModifier_dependsOnTime;
|
||||
mti->freeData = clothModifier_freeData;
|
||||
mti->requiredDataMask = clothModifier_requiredDataMask;
|
||||
@ -8406,7 +8456,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
|
||||
mti = INIT_TYPE(Collision);
|
||||
mti->type = eModifierTypeType_OnlyDeform;
|
||||
mti->initData = collisionModifier_initData;
|
||||
mti->flags = eModifierTypeFlag_AcceptsMesh;
|
||||
mti->flags = eModifierTypeFlag_AcceptsMesh
|
||||
| eModifierTypeFlag_Single;
|
||||
mti->dependsOnTime = collisionModifier_dependsOnTime;
|
||||
mti->freeData = collisionModifier_freeData;
|
||||
mti->deformVerts = collisionModifier_deformVerts;
|
||||
@ -8489,7 +8540,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
|
||||
|
||||
mti = INIT_TYPE(Fluidsim);
|
||||
mti->type = eModifierTypeType_Nonconstructive
|
||||
| eModifierTypeFlag_RequiresOriginalData;
|
||||
| eModifierTypeFlag_RequiresOriginalData
|
||||
| eModifierTypeFlag_Single;
|
||||
mti->flags = eModifierTypeFlag_AcceptsMesh;
|
||||
mti->initData = fluidsimModifier_initData;
|
||||
mti->freeData = fluidsimModifier_freeData;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1198,18 +1198,12 @@ Object *copy_object(Object *ob)
|
||||
armature_rebuild_pose(obn, obn->data);
|
||||
}
|
||||
copy_defgroups(&obn->defbase, &ob->defbase);
|
||||
#if 0 // XXX old animation system
|
||||
copy_nlastrips(&obn->nlastrips, &ob->nlastrips);
|
||||
#endif // XXX old animation system
|
||||
copy_constraints(&obn->constraints, &ob->constraints);
|
||||
|
||||
/* increase user numbers */
|
||||
id_us_plus((ID *)obn->data);
|
||||
#if 0 // XXX old animation system
|
||||
id_us_plus((ID *)obn->ipo);
|
||||
id_us_plus((ID *)obn->action);
|
||||
#endif // XXX old animation system
|
||||
id_us_plus((ID *)obn->dup_group);
|
||||
// FIXME: add this for animdata too...
|
||||
|
||||
for(a=0; a<obn->totcol; a++) id_us_plus((ID *)obn->mat[a]);
|
||||
|
||||
@ -1575,15 +1569,15 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
|
||||
}
|
||||
/* catch exceptions: curve paths used as a duplicator */
|
||||
else if(enable_cu_speed) {
|
||||
ctime= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0);
|
||||
|
||||
#if 0 // XXX old animation system
|
||||
if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
|
||||
ctime /= cu->pathlen;
|
||||
/* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated,
|
||||
* but this will only work if it actually is animated...
|
||||
*
|
||||
* we firstly calculate the modulus of cu->ctime/cu->pathlen to clamp ctime within the 0.0 to 1.0 times pathlen
|
||||
* range, then divide this (the modulus) by pathlen to get a value between 0.0 and 1.0
|
||||
*/
|
||||
ctime= fmod(cu->ctime, cu->pathlen) / cu->pathlen;
|
||||
CLAMP(ctime, 0.0, 1.0);
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
}
|
||||
else {
|
||||
ctime= scene->r.cfra - give_timeoffset(ob);
|
||||
ctime /= cu->pathlen;
|
||||
|
@ -377,8 +377,6 @@ there was an error or when the user desides to cancel the operation.
|
||||
|
||||
char *unpackFile(ReportList *reports, char *abs_name, char *local_name, PackedFile *pf, int how)
|
||||
{
|
||||
char menu[6 *(FILE_MAXDIR + FILE_MAXFILE + 100)];
|
||||
char line[FILE_MAXDIR + FILE_MAXFILE + 100];
|
||||
char *newname = NULL, *temp = NULL;
|
||||
|
||||
// char newabs[FILE_MAXDIR + FILE_MAXFILE];
|
||||
|
@ -81,6 +81,10 @@
|
||||
static void key_from_object(Object *ob, ParticleKey *key);
|
||||
static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index,
|
||||
float *fuv, float *orco, ParticleTexture *ptex, int event);
|
||||
static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx,
|
||||
ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex);
|
||||
static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSettings *part,
|
||||
ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa, float *orco, ParticleKey *state, float t);
|
||||
|
||||
/* few helpers for countall etc. */
|
||||
int count_particles(ParticleSystem *psys){
|
||||
@ -230,7 +234,7 @@ void psys_set_current_num(Object *ob, int index)
|
||||
if(ob==0) return;
|
||||
|
||||
for(psys=ob->particlesystem.first, i=0; psys; psys=psys->next, i++) {
|
||||
if(i == index - 1)
|
||||
if(i == index)
|
||||
psys->flag |= PSYS_CURRENT;
|
||||
else
|
||||
psys->flag &= ~PSYS_CURRENT;
|
||||
@ -452,7 +456,7 @@ void psys_free(Object *ob, ParticleSystem * psys)
|
||||
for(tpsys=ob->particlesystem.first; tpsys; tpsys=tpsys->next){
|
||||
if(tpsys->part)
|
||||
{
|
||||
if(ELEM(tpsys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
|
||||
if(ELEM(tpsys->part->ren_as,PART_DRAW_OB,PART_DRAW_GR))
|
||||
{
|
||||
nr++;
|
||||
break;
|
||||
@ -491,6 +495,7 @@ typedef struct ParticleRenderData {
|
||||
ChildParticle *child;
|
||||
ParticleCacheKey **pathcache;
|
||||
ParticleCacheKey **childcache;
|
||||
ListBase pathcachebufs, childcachebufs;
|
||||
int totchild, totcached, totchildcache;
|
||||
DerivedMesh *dm;
|
||||
int totdmvert, totdmedge, totdmface;
|
||||
@ -577,8 +582,12 @@ void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float
|
||||
data->child= psys->child;
|
||||
data->totchild= psys->totchild;
|
||||
data->pathcache= psys->pathcache;
|
||||
data->pathcachebufs.first = psys->pathcachebufs.first;
|
||||
data->pathcachebufs.last = psys->pathcachebufs.last;
|
||||
data->totcached= psys->totcached;
|
||||
data->childcache= psys->childcache;
|
||||
data->childcachebufs.first = psys->childcachebufs.first;
|
||||
data->childcachebufs.last = psys->childcachebufs.last;
|
||||
data->totchildcache= psys->totchildcache;
|
||||
|
||||
if(psmd->dm)
|
||||
@ -591,6 +600,8 @@ void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float
|
||||
psys->pathcache= NULL;
|
||||
psys->childcache= NULL;
|
||||
psys->totchild= psys->totcached= psys->totchildcache= 0;
|
||||
psys->pathcachebufs.first = psys->pathcachebufs.last = NULL;
|
||||
psys->childcachebufs.first = psys->childcachebufs.last = NULL;
|
||||
|
||||
Mat4CpyMat4(data->winmat, winmat);
|
||||
Mat4MulMat4(data->viewmat, ob->obmat, viewmat);
|
||||
@ -631,8 +642,12 @@ void psys_render_restore(Object *ob, ParticleSystem *psys)
|
||||
psys->child= data->child;
|
||||
psys->totchild= data->totchild;
|
||||
psys->pathcache= data->pathcache;
|
||||
psys->pathcachebufs.first = data->pathcachebufs.first;
|
||||
psys->pathcachebufs.last = data->pathcachebufs.last;
|
||||
psys->totcached= data->totcached;
|
||||
psys->childcache= data->childcache;
|
||||
psys->childcachebufs.first = data->childcachebufs.first;
|
||||
psys->childcachebufs.last = data->childcachebufs.last;
|
||||
psys->totchildcache= data->totchildcache;
|
||||
|
||||
psmd->dm= data->dm;
|
||||
@ -663,7 +678,7 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
|
||||
int *origindex, *facetotvert;
|
||||
int a, b, totorigface, totface, newtot, skipped;
|
||||
|
||||
if(part->draw_as!=PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND))
|
||||
if(part->ren_as!=PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND))
|
||||
return tot;
|
||||
if(!ctx->psys->renderdata)
|
||||
return tot;
|
||||
@ -1992,13 +2007,11 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
ParticleData *pa=NULL;
|
||||
ParticleTexture ptex;
|
||||
float *cpa_fuv=0, *par_rot=0;
|
||||
float co[3], orco[3], ornor[3], t, rough_t, cpa_1st[3], dvec[3];
|
||||
float branch_begin, branch_end, branch_prob, branchfac, rough_rand;
|
||||
float pa_rough1, pa_rough2, pa_roughe;
|
||||
float length, pa_length, pa_clump, pa_kink, pa_effector;
|
||||
float max_length = 1.0f, cur_length = 0.0f;
|
||||
float co[3], orco[3], ornor[3], t, cpa_1st[3], dvec[3];
|
||||
float branch_begin, branch_end, branch_prob, rough_rand;
|
||||
float length, max_length = 1.0f, cur_length = 0.0f;
|
||||
float eff_length, eff_vec[3];
|
||||
int k, cpa_num, guided = 0;
|
||||
int k, cpa_num;
|
||||
short cpa_from;
|
||||
|
||||
if(part->flag & PART_BRANCHING) {
|
||||
@ -2059,9 +2072,11 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
|
||||
psys_particle_on_emitter(ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,ornor,0,0,orco,0);
|
||||
|
||||
if(part->path_start==0.0f) {
|
||||
/* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */
|
||||
VECCOPY(cpa_1st,co);
|
||||
Mat4MulVecfl(ob->obmat,cpa_1st);
|
||||
}
|
||||
|
||||
pa=0;
|
||||
}
|
||||
@ -2098,43 +2113,13 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
#endif // XXX old animation system
|
||||
|
||||
/* get different child parameters from textures & vgroups */
|
||||
ptex.length=part->length*(1.0f - part->randlength*cpa->rand[0]);
|
||||
ptex.clump=1.0;
|
||||
ptex.kink=1.0;
|
||||
ptex.rough= 1.0;
|
||||
ptex.exist= 1.0;
|
||||
|
||||
get_cpa_texture(ctx->dm,ctx->ma,cpa_num,cpa_fuv,orco,&ptex,
|
||||
MAP_PA_DENS|MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH);
|
||||
|
||||
pa_length=ptex.length;
|
||||
pa_clump=ptex.clump;
|
||||
pa_kink=ptex.kink;
|
||||
pa_rough1=ptex.rough;
|
||||
pa_rough2=ptex.rough;
|
||||
pa_roughe=ptex.rough;
|
||||
pa_effector= 1.0f;
|
||||
get_child_modifier_parameters(part, ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex);
|
||||
|
||||
if(ptex.exist < cpa->rand[1]) {
|
||||
keys->steps = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if(ctx->vg_length)
|
||||
pa_length*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_length);
|
||||
if(ctx->vg_clump)
|
||||
pa_clump*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_clump);
|
||||
if(ctx->vg_kink)
|
||||
pa_kink*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_kink);
|
||||
if(ctx->vg_rough1)
|
||||
pa_rough1*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_rough1);
|
||||
if(ctx->vg_rough2)
|
||||
pa_rough2*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_rough2);
|
||||
if(ctx->vg_roughe)
|
||||
pa_roughe*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_roughe);
|
||||
if(ctx->vg_effector)
|
||||
pa_effector*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_effector);
|
||||
|
||||
/* create the child path */
|
||||
for(k=0,state=keys; k<=ctx->steps; k++,state++){
|
||||
if(ctx->between){
|
||||
@ -2158,6 +2143,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
key[w]++;
|
||||
w++;
|
||||
}
|
||||
if(part->path_start==0.0f) {
|
||||
if(k==0){
|
||||
/* calculate the offset between actual child root position and first position interpolated from parents */
|
||||
VECSUB(cpa_1st,cpa_1st,state->co);
|
||||
@ -2165,6 +2151,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
/* apply offset for correct positioning */
|
||||
VECADD(state->co,state->co,cpa_1st);
|
||||
}
|
||||
}
|
||||
else{
|
||||
/* offset the child from the parent position */
|
||||
offset_child(cpa, (ParticleKey*)key[0], (ParticleKey*)state, part->childflat, part->childrad);
|
||||
@ -2177,7 +2164,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
if(part->flag & PART_CHILD_EFFECT) {
|
||||
for(k=0,state=keys; k<=ctx->steps; k++,state++) {
|
||||
if(k) {
|
||||
do_path_effectors(ctx->scene, ob, psys, cpa->pa[0], state, k, ctx->steps, keys->co, pa_effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
|
||||
do_path_effectors(ctx->scene, ob, psys, cpa->pa[0], state, k, ctx->steps, keys->co, ptex.effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
|
||||
}
|
||||
else {
|
||||
VecSubf(eff_vec,(state+1)->co,state->co);
|
||||
@ -2203,67 +2190,50 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
}
|
||||
|
||||
/* apply different deformations to the child path */
|
||||
if(part->flag & PART_CHILD_EFFECT)
|
||||
/* state is safe to cast, since only co and vel are used */
|
||||
guided = do_guide(ctx->scene, (ParticleKey*)state, cpa->parent, t, &(psys->effectors));
|
||||
do_child_modifiers(ctx->scene, ob, psys, part, &ptex, (ParticleKey *)par, par_rot, cpa, orco, (ParticleKey *)state, t);
|
||||
|
||||
if(guided==0){
|
||||
if(part->kink)
|
||||
do_prekink((ParticleKey*)state, (ParticleKey*)par, par_rot, t,
|
||||
part->kink_freq * pa_kink, part->kink_shape, part->kink_amp, part->kink, part->kink_axis, ob->obmat);
|
||||
/* TODO: better branching */
|
||||
//if(part->flag & PART_BRANCHING && ctx->between == 0 && part->flag & PART_ANIM_BRANCHING)
|
||||
// rough_t = t * rough_rand;
|
||||
//else
|
||||
// rough_t = t;
|
||||
|
||||
do_clump((ParticleKey*)state, (ParticleKey*)par, t, part->clumpfac, part->clumppow, pa_clump);
|
||||
}
|
||||
/* TODO: better branching */
|
||||
//if(part->flag & PART_BRANCHING && ctx->between==0){
|
||||
// if(branch_prob > part->branch_thres){
|
||||
// branchfac=0.0f;
|
||||
// }
|
||||
// else{
|
||||
// if(part->flag & PART_SYMM_BRANCHING){
|
||||
// if(t < branch_begin || t > branch_end)
|
||||
// branchfac=0.0f;
|
||||
// else{
|
||||
// if((t-branch_begin)/(branch_end-branch_begin)<0.5)
|
||||
// branchfac=2.0f*(t-branch_begin)/(branch_end-branch_begin);
|
||||
// else
|
||||
// branchfac=2.0f*(branch_end-t)/(branch_end-branch_begin);
|
||||
|
||||
if(part->flag & PART_BRANCHING && ctx->between == 0 && part->flag & PART_ANIM_BRANCHING)
|
||||
rough_t = t * rough_rand;
|
||||
else
|
||||
rough_t = t;
|
||||
// CLAMP(branchfac,0.0f,1.0f);
|
||||
// }
|
||||
// }
|
||||
// else{
|
||||
// if(t < branch_begin){
|
||||
// branchfac=0.0f;
|
||||
// }
|
||||
// else{
|
||||
// branchfac=(t-branch_begin)/((1.0f-branch_begin)*0.5f);
|
||||
// CLAMP(branchfac,0.0f,1.0f);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if(part->rough1 != 0.0 && pa_rough1 != 0.0)
|
||||
do_rough(orco, rough_t, pa_rough1*part->rough1, part->rough1_size, 0.0, (ParticleKey*)state);
|
||||
|
||||
if(part->rough2 != 0.0 && pa_rough2 != 0.0)
|
||||
do_rough(cpa->rand, rough_t, pa_rough2*part->rough2, part->rough2_size, part->rough2_thres, (ParticleKey*)state);
|
||||
|
||||
if(part->rough_end != 0.0 && pa_roughe != 0.0)
|
||||
do_rough_end(cpa->rand, rough_t, pa_roughe*part->rough_end, part->rough_end_shape, (ParticleKey*)state, (ParticleKey*)par);
|
||||
|
||||
if(part->flag & PART_BRANCHING && ctx->between==0){
|
||||
if(branch_prob > part->branch_thres){
|
||||
branchfac=0.0f;
|
||||
}
|
||||
else{
|
||||
if(part->flag & PART_SYMM_BRANCHING){
|
||||
if(t < branch_begin || t > branch_end)
|
||||
branchfac=0.0f;
|
||||
else{
|
||||
if((t-branch_begin)/(branch_end-branch_begin)<0.5)
|
||||
branchfac=2.0f*(t-branch_begin)/(branch_end-branch_begin);
|
||||
else
|
||||
branchfac=2.0f*(branch_end-t)/(branch_end-branch_begin);
|
||||
|
||||
CLAMP(branchfac,0.0f,1.0f);
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(t < branch_begin){
|
||||
branchfac=0.0f;
|
||||
}
|
||||
else{
|
||||
branchfac=(t-branch_begin)/((1.0f-branch_begin)*0.5f);
|
||||
CLAMP(branchfac,0.0f,1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(i<psys->totpart)
|
||||
VecLerpf(state->co, (pcache[i] + k)->co, state->co, branchfac);
|
||||
else
|
||||
/* this is not threadsafe, but should only happen for
|
||||
* branching particles particles, which are not threaded */
|
||||
VecLerpf(state->co, (cache[i - psys->totpart] + k)->co, state->co, branchfac);
|
||||
}
|
||||
// if(i<psys->totpart)
|
||||
// VecLerpf(state->co, (pcache[i] + k)->co, state->co, branchfac);
|
||||
// else
|
||||
// /* this is not threadsafe, but should only happen for
|
||||
// * branching particles particles, which are not threaded */
|
||||
// VecLerpf(state->co, (cache[i - psys->totpart] + k)->co, state->co, branchfac);
|
||||
//}
|
||||
|
||||
/* we have to correct velocity because of kink & clump */
|
||||
if(k>1){
|
||||
@ -2287,9 +2257,9 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
else{
|
||||
/* initialize length calculation */
|
||||
if(part->flag&PART_ABS_LENGTH)
|
||||
max_length= part->abslength*pa_length;
|
||||
max_length= part->abslength*ptex.length;
|
||||
else
|
||||
max_length= pa_length;
|
||||
max_length= ptex.length;
|
||||
|
||||
cur_length= 0.0f;
|
||||
}
|
||||
@ -2383,7 +2353,36 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa
|
||||
|
||||
psys_threads_free(pthreads);
|
||||
}
|
||||
static void get_pointcache_keys_for_time(ParticleSystem *psys, int index, float t, ParticleKey *key1, ParticleKey *key2)
|
||||
{
|
||||
PointCache *cache = psys->pointcache;
|
||||
static PTCacheMem *pm = NULL;
|
||||
|
||||
if(cache->flag & PTCACHE_DISK_CACHE) {
|
||||
/* TODO */
|
||||
}
|
||||
else {
|
||||
if(index < 0) { /* initialize */
|
||||
pm = cache->mem_cache.first;
|
||||
if(pm)
|
||||
pm = pm->next;
|
||||
}
|
||||
else {
|
||||
if(pm) {
|
||||
while(pm && pm->next && (float)pm->frame < t)
|
||||
pm = pm->next;
|
||||
|
||||
copy_particle_key(key2, ((ParticleKey *)pm->data) + index, 1);
|
||||
copy_particle_key(key1, ((ParticleKey *)(pm->prev)->data) + index, 1);
|
||||
}
|
||||
else if(cache->mem_cache.first) {
|
||||
pm = cache->mem_cache.first;
|
||||
copy_particle_key(key2, ((ParticleKey *)pm->data) + index, 1);
|
||||
copy_particle_key(key1, ((ParticleKey *)pm->data) + index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Calculates paths ready for drawing/rendering. */
|
||||
/* -Usefull for making use of opengl vertex arrays for super fast strand drawing. */
|
||||
/* -Makes child strands possible and creates them too into the cache. */
|
||||
@ -2409,7 +2408,7 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
|
||||
float birthtime = 0.0, dietime = 0.0;
|
||||
float t, time = 0.0, keytime = 0.0, dfra = 1.0, frs_sec = scene->r.frs_sec;
|
||||
float col[3] = {0.5f, 0.5f, 0.5f};
|
||||
float col[4] = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
float prev_tangent[3], hairmat[4][4];
|
||||
int k,i;
|
||||
int steps = (int)pow(2.0, (double)psys->part->draw_step);
|
||||
@ -2418,13 +2417,18 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
float nosel_col[3];
|
||||
float length, vec[3];
|
||||
float *vg_effector= NULL, effector=0.0f;
|
||||
float *vg_length= NULL, pa_length=1.0f, max_length=1.0f, cur_length=0.0f;
|
||||
float len, dvec[3];
|
||||
float *vg_length= NULL, pa_length=1.0f;
|
||||
int keyed, baked;
|
||||
|
||||
/* we don't have anything valid to create paths from so let's quit here */
|
||||
if((psys->flag & PSYS_HAIR_DONE)==0 && (psys->flag & PSYS_KEYED)==0)
|
||||
if((psys->flag & PSYS_HAIR_DONE)==0 && (psys->flag & PSYS_KEYED)==0 && (psys->pointcache->flag & PTCACHE_BAKED)==0)
|
||||
return;
|
||||
|
||||
BLI_srandom(psys->seed);
|
||||
|
||||
keyed = psys->flag & PSYS_KEYED;
|
||||
baked = psys->pointcache->flag & PTCACHE_BAKED;
|
||||
|
||||
if(psys->renderdata) {
|
||||
steps = (int)pow(2.0, (double)psys->part->ren_step);
|
||||
}
|
||||
@ -2488,7 +2492,8 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
else memset(cache[i], 0, sizeof(*cache[i])*(steps+1));
|
||||
|
||||
if(!edit && !psys->totchild) {
|
||||
pa_length = part->length * (1.0f - part->randlength*pa->r_ave[0]);
|
||||
//pa_length = part->length * (1.0f - part->randlength*pa->r_ave[0]);
|
||||
pa_length = 1.0f - part->randlength * 0.5 * (1.0f + pa->r_ave[0]);
|
||||
if(vg_length)
|
||||
pa_length *= psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_length);
|
||||
}
|
||||
@ -2499,13 +2504,19 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
ekey = edit->keys[i];
|
||||
|
||||
/*--get the first data points--*/
|
||||
if(psys->flag & PSYS_KEYED) {
|
||||
if(keyed) {
|
||||
kkey[0] = pa->keys;
|
||||
kkey[1] = kkey[0] + 1;
|
||||
|
||||
birthtime = kkey[0]->time;
|
||||
dietime = kkey[0][pa->totkey-1].time;
|
||||
}
|
||||
else if(baked) {
|
||||
get_pointcache_keys_for_time(psys, -1, 0.0f, NULL, NULL);
|
||||
|
||||
birthtime = pa->time;
|
||||
dietime = pa->dietime;
|
||||
}
|
||||
else {
|
||||
hkey[0] = pa->hair;
|
||||
hkey[1] = hkey[0] + 1;
|
||||
@ -2516,6 +2527,25 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
|
||||
}
|
||||
|
||||
if(!edit) {
|
||||
if(part->draw & PART_ABS_PATH_TIME) {
|
||||
birthtime = MAX2(birthtime, part->path_start);
|
||||
dietime = MIN2(dietime, part->path_end);
|
||||
}
|
||||
else {
|
||||
float tb = birthtime;
|
||||
birthtime = tb + part->path_start * (dietime - tb);
|
||||
dietime = tb + part->path_end * (dietime - tb);
|
||||
}
|
||||
|
||||
if(birthtime >= dietime) {
|
||||
cache[i]->steps = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
dietime = birthtime + pa_length * (dietime - birthtime);
|
||||
}
|
||||
|
||||
if(soft){
|
||||
bp[0] = soft->bpoint + pa->bpi;
|
||||
bp[1] = bp[0] + 1;
|
||||
@ -2527,13 +2557,16 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
|
||||
t = birthtime + time * (dietime - birthtime);
|
||||
|
||||
if(psys->flag & PSYS_KEYED) {
|
||||
if(keyed) {
|
||||
while(kkey[1]->time < t) {
|
||||
kkey[1]++;
|
||||
}
|
||||
|
||||
kkey[0] = kkey[1] - 1;
|
||||
}
|
||||
else if(baked) {
|
||||
get_pointcache_keys_for_time(psys, i, t, keys+1, keys+2);
|
||||
}
|
||||
else {
|
||||
while(hkey[1]->time < t) {
|
||||
hkey[1]++;
|
||||
@ -2548,17 +2581,19 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
bp_to_particle(keys + 1, bp[0], hkey[0]);
|
||||
bp_to_particle(keys + 2, bp[1], hkey[1]);
|
||||
}
|
||||
else if(psys->flag & PSYS_KEYED) {
|
||||
else if(keyed) {
|
||||
memcpy(keys + 1, kkey[0], sizeof(ParticleKey));
|
||||
memcpy(keys + 2, kkey[1], sizeof(ParticleKey));
|
||||
}
|
||||
else if(baked)
|
||||
; /* keys already set */
|
||||
else {
|
||||
hair_to_particle(keys + 1, hkey[0]);
|
||||
hair_to_particle(keys + 2, hkey[1]);
|
||||
}
|
||||
|
||||
|
||||
if((psys->flag & PSYS_KEYED)==0) {
|
||||
if(!keyed && !baked) {
|
||||
if(soft) {
|
||||
if(hkey[0] != pa->hair)
|
||||
bp_to_particle(keys, bp[0] - 1, hkey[0] - 1);
|
||||
@ -2591,18 +2626,18 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
keytime = (t - keys[1].time) / dfra;
|
||||
|
||||
/* convert velocity to timestep size */
|
||||
if(psys->flag & PSYS_KEYED){
|
||||
if(keyed || baked){
|
||||
VecMulf(keys[1].vel, dfra / frs_sec);
|
||||
VecMulf(keys[2].vel, dfra / frs_sec);
|
||||
}
|
||||
|
||||
/* now we should have in chronologiacl order k1<=k2<=t<=k3<=k4 with keytime between [0,1]->[k2,k3] (k1 & k4 used for cardinal & bspline interpolation)*/
|
||||
psys_interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
|
||||
psys_interpolate_particle((keyed || baked) ? -1 /* signal for cubic interpolation */
|
||||
: ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL)
|
||||
,keys, keytime, &result, 0);
|
||||
|
||||
/* the velocity needs to be converted back from cubic interpolation */
|
||||
if(psys->flag & PSYS_KEYED){
|
||||
if(keyed || baked){
|
||||
VecMulf(result.vel, frs_sec / dfra);
|
||||
}
|
||||
else if(soft==NULL) { /* softbody and keyed are allready in global space */
|
||||
@ -2717,28 +2752,6 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!edit && !psys->totchild) {
|
||||
/* check if path needs to be cut before actual end of data points */
|
||||
if(k){
|
||||
VECSUB(dvec,ca->co,(ca-1)->co);
|
||||
if(part->flag&PART_ABS_LENGTH)
|
||||
len=VecLength(dvec);
|
||||
else
|
||||
len=1.0f/(float)steps;
|
||||
|
||||
k=check_path_length(k,cache[i],ca,max_length,&cur_length,len,dvec);
|
||||
}
|
||||
else{
|
||||
/* initialize length calculation */
|
||||
if(part->flag&PART_ABS_LENGTH)
|
||||
max_length= part->abslength*pa_length;
|
||||
else
|
||||
max_length= pa_length;
|
||||
|
||||
cur_length= 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2990,7 +3003,8 @@ static void default_particle_settings(ParticleSettings *part)
|
||||
|
||||
part->type= PART_EMITTER;
|
||||
part->distr= PART_DISTR_JIT;
|
||||
part->draw_as=PART_DRAW_DOT;
|
||||
part->draw_as = PART_DRAW_REND;
|
||||
part->ren_as = PART_DRAW_HALO;
|
||||
part->bb_uv_split=1;
|
||||
part->bb_align=PART_BB_VIEW;
|
||||
part->bb_split_offset=PART_BB_OFF_LINEAR;
|
||||
@ -3046,6 +3060,8 @@ static void default_particle_settings(ParticleSettings *part)
|
||||
part->rough_end_shape=1.0;
|
||||
|
||||
part->draw_line[0]=0.5;
|
||||
part->path_start = 0.0f;
|
||||
part->path_end = 1.0f;
|
||||
|
||||
part->banking=1.0;
|
||||
part->max_bank=1.0;
|
||||
@ -3282,7 +3298,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
|
||||
if((event & mtex->pmapto) & MAP_PA_KINK)
|
||||
ptex->kink= texture_value_blend(def,ptex->kink,value,var,blend,neg & MAP_PA_KINK);
|
||||
if((event & mtex->pmapto) & MAP_PA_ROUGH)
|
||||
ptex->rough= texture_value_blend(def,ptex->rough,value,var,blend,neg & MAP_PA_ROUGH);
|
||||
ptex->rough1= ptex->rough2= ptex->roughe= texture_value_blend(def,ptex->rough1,value,var,blend,neg & MAP_PA_ROUGH);
|
||||
if((event & mtex->pmapto) & MAP_PA_DENS)
|
||||
ptex->exist= texture_value_blend(def,ptex->exist,value,var,blend,neg & MAP_PA_DENS);
|
||||
}
|
||||
@ -3291,7 +3307,11 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
|
||||
if(event & MAP_PA_LENGTH) { CLAMP(ptex->length,0.0,1.0); }
|
||||
if(event & MAP_PA_CLUMP) { CLAMP(ptex->clump,0.0,1.0); }
|
||||
if(event & MAP_PA_KINK) { CLAMP(ptex->kink,0.0,1.0); }
|
||||
if(event & MAP_PA_ROUGH) { CLAMP(ptex->rough,0.0,1.0); }
|
||||
if(event & MAP_PA_ROUGH) {
|
||||
CLAMP(ptex->rough1,0.0,1.0);
|
||||
CLAMP(ptex->rough2,0.0,1.0);
|
||||
CLAMP(ptex->roughe,0.0,1.0);
|
||||
}
|
||||
if(event & MAP_PA_DENS) { CLAMP(ptex->exist,0.0,1.0); }
|
||||
}
|
||||
void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleData *pa, ParticleTexture *ptex, int event)
|
||||
@ -3392,12 +3412,12 @@ float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd,
|
||||
|
||||
return size*part->size;
|
||||
}
|
||||
float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra)
|
||||
float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra, float *birthtime, float *dietime)
|
||||
{
|
||||
ParticleSettings *part = psys->part;
|
||||
float time, life;
|
||||
|
||||
if(part->childtype==PART_CHILD_FACES){
|
||||
float time;
|
||||
int w=0;
|
||||
time=0.0;
|
||||
while(w<4 && cpa->pa[w]>=0){
|
||||
@ -3405,12 +3425,21 @@ float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra)
|
||||
w++;
|
||||
}
|
||||
|
||||
return (cfra-time)/(part->lifetime*(1.0f-part->randlife*cpa->rand[1]));
|
||||
life = part->lifetime*(1.0f-part->randlife*cpa->rand[1]);
|
||||
}
|
||||
else{
|
||||
ParticleData *pa = psys->particles + cpa->parent;
|
||||
return (cfra-pa->time)/pa->lifetime;
|
||||
|
||||
time = pa->time;
|
||||
life = pa->lifetime;
|
||||
}
|
||||
|
||||
if(birthtime)
|
||||
*birthtime = time;
|
||||
if(dietime)
|
||||
*dietime = time+life;
|
||||
|
||||
return (cfra-time)/life;
|
||||
}
|
||||
float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra, float *pa_time)
|
||||
{
|
||||
@ -3427,7 +3456,7 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra,
|
||||
if(pa_time)
|
||||
time=*pa_time;
|
||||
else
|
||||
time=psys_get_child_time(psys,cpa,cfra);
|
||||
time=psys_get_child_time(psys,cpa,cfra,NULL,NULL);
|
||||
|
||||
/* correction for lifetime */
|
||||
calc_ipo(part->ipo, 100*time);
|
||||
@ -3449,6 +3478,64 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra,
|
||||
|
||||
return size;
|
||||
}
|
||||
static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx, ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex)
|
||||
{
|
||||
ptex->length=part->length*(1.0f - part->randlength*cpa->rand[0]);
|
||||
ptex->clump=1.0;
|
||||
ptex->kink=1.0;
|
||||
ptex->rough1= 1.0;
|
||||
ptex->rough2= 1.0;
|
||||
ptex->roughe= 1.0;
|
||||
ptex->exist= 1.0;
|
||||
ptex->effector= 1.0;
|
||||
|
||||
get_cpa_texture(ctx->dm,ctx->ma,cpa_num,cpa_fuv,orco,ptex,
|
||||
MAP_PA_DENS|MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH);
|
||||
|
||||
|
||||
if(ptex->exist < cpa->rand[1])
|
||||
return;
|
||||
|
||||
if(ctx->vg_length)
|
||||
ptex->length*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_length);
|
||||
if(ctx->vg_clump)
|
||||
ptex->clump*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_clump);
|
||||
if(ctx->vg_kink)
|
||||
ptex->kink*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_kink);
|
||||
if(ctx->vg_rough1)
|
||||
ptex->rough1*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_rough1);
|
||||
if(ctx->vg_rough2)
|
||||
ptex->rough2*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_rough2);
|
||||
if(ctx->vg_roughe)
|
||||
ptex->roughe*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_roughe);
|
||||
if(ctx->vg_effector)
|
||||
ptex->effector*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_effector);
|
||||
}
|
||||
static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSettings *part, ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa, float *orco, ParticleKey *state, float t)
|
||||
{
|
||||
int guided = 0;
|
||||
|
||||
if(part->flag & PART_CHILD_EFFECT)
|
||||
/* state is safe to cast, since only co and vel are used */
|
||||
guided = do_guide(scene, (ParticleKey*)state, cpa->parent, t, &(psys->effectors));
|
||||
|
||||
if(guided==0){
|
||||
if(part->kink)
|
||||
do_prekink(state, par, par_rot, t, part->kink_freq * ptex->kink, part->kink_shape,
|
||||
part->kink_amp, part->kink, part->kink_axis, ob->obmat);
|
||||
|
||||
do_clump(state, par, t, part->clumpfac, part->clumppow, ptex->clump);
|
||||
}
|
||||
|
||||
if(part->rough1 != 0.0 && ptex->rough1 != 0.0)
|
||||
do_rough(orco, t, ptex->rough1*part->rough1, part->rough1_size, 0.0, state);
|
||||
|
||||
if(part->rough2 != 0.0 && ptex->rough2 != 0.0)
|
||||
do_rough(cpa->rand, t, ptex->rough2*part->rough2, part->rough2_size, part->rough2_thres, state);
|
||||
|
||||
if(part->rough_end != 0.0 && ptex->roughe != 0.0)
|
||||
do_rough_end(cpa->rand, t, ptex->roughe*part->rough_end, part->rough_end_shape, state, par);
|
||||
}
|
||||
/* get's hair (or keyed) particles state at the "path time" specified in state->time */
|
||||
void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, int p, ParticleKey *state, int vel)
|
||||
{
|
||||
@ -3460,17 +3547,20 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
ParticleTexture ptex;
|
||||
ParticleKey *kkey[2] = {NULL, NULL};
|
||||
HairKey *hkey[2] = {NULL, NULL};
|
||||
ParticleKey *par=0, keys[4];
|
||||
ParticleKey *par=0, keys[4], tstate;
|
||||
ParticleThreadContext ctx; /* fake thread context for child modifiers */
|
||||
|
||||
float t, real_t, dfra, keytime, frs_sec = scene->r.frs_sec;
|
||||
float co[3], orco[3];
|
||||
float hairmat[4][4];
|
||||
float pa_clump = 0.0, pa_kink = 0.0;
|
||||
int totparent = 0;
|
||||
int totpart = psys->totpart;
|
||||
int totchild = psys->totchild;
|
||||
short between = 0, edit = 0;
|
||||
|
||||
int keyed = psys->flag & PSYS_KEYED;
|
||||
int cached = !keyed && part->type != PART_HAIR;
|
||||
|
||||
float *cpa_fuv; int cpa_num; short cpa_from;
|
||||
|
||||
//if(psys_in_edit_mode(scene, psys)){
|
||||
@ -3479,12 +3569,6 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
// edit=1;
|
||||
//}
|
||||
|
||||
/* user want's cubic interpolation but only without sb it possible */
|
||||
//if(interpolation==PART_INTER_CUBIC && baked && psys->softflag==OB_SB_ENABLE)
|
||||
// interpolation=PART_INTER_BSPLINE;
|
||||
//else if(baked==0) /* it doesn't make sense to use other types for keyed */
|
||||
// interpolation=PART_INTER_CUBIC;
|
||||
|
||||
t=state->time;
|
||||
CLAMP(t, 0.0, 1.0);
|
||||
|
||||
@ -3497,20 +3581,29 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
return;
|
||||
}
|
||||
|
||||
if(psys->flag & PSYS_KEYED) {
|
||||
if(keyed) {
|
||||
kkey[0] = pa->keys;
|
||||
kkey[1] = kkey[0] + 1;
|
||||
|
||||
if(state->time < 0.0f)
|
||||
real_t = -state->time;
|
||||
else
|
||||
real_t = kkey[0]->time + t * (kkey[0][pa->totkey-1].time - kkey[0]->time);
|
||||
}
|
||||
else if(cached) {
|
||||
get_pointcache_keys_for_time(psys, -1, 0.0f, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
hkey[0] = pa->hair;
|
||||
hkey[1] = pa->hair + 1;
|
||||
|
||||
real_t = hkey[0]->time + (hkey[0][pa->totkey-1].time - hkey[0]->time) * t;
|
||||
if(state->time < 0.0f)
|
||||
real_t = -state->time;
|
||||
else
|
||||
real_t = hkey[0]->time + t * (hkey[0][pa->totkey-1].time - hkey[0]->time);
|
||||
}
|
||||
|
||||
if(psys->flag & PSYS_KEYED) {
|
||||
if(keyed) {
|
||||
while(kkey[1]->time < real_t) {
|
||||
kkey[1]++;
|
||||
}
|
||||
@ -3519,6 +3612,14 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
memcpy(keys + 1, kkey[0], sizeof(ParticleKey));
|
||||
memcpy(keys + 2, kkey[1], sizeof(ParticleKey));
|
||||
}
|
||||
else if(cached) {
|
||||
if(state->time < 0.0f) /* flag for time in frames */
|
||||
real_t = -state->time;
|
||||
else
|
||||
real_t = pa->time + t * (pa->dietime - pa->time);
|
||||
|
||||
get_pointcache_keys_for_time(psys, p, real_t, keys+1, keys+2);
|
||||
}
|
||||
else {
|
||||
while(hkey[1]->time < real_t)
|
||||
hkey[1]++;
|
||||
@ -3529,63 +3630,35 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
hair_to_particle(keys + 2, hkey[1]);
|
||||
}
|
||||
|
||||
if((psys->flag & PSYS_KEYED)==0) {
|
||||
//if(soft){
|
||||
// if(key[0] != sbel.keys)
|
||||
// DB_copy_key(&k1,key[0]-1);
|
||||
// else
|
||||
// DB_copy_key(&k1,&k2);
|
||||
//}
|
||||
//else{
|
||||
if(!keyed && !cached) {
|
||||
if(hkey[0] != pa->hair)
|
||||
hair_to_particle(keys, hkey[0] - 1);
|
||||
else
|
||||
hair_to_particle(keys, hkey[0]);
|
||||
//}
|
||||
|
||||
//if(soft){
|
||||
// if(key[1] != sbel.keys + sbel.totkey-1)
|
||||
// DB_copy_key(&k4,key[1]+1);
|
||||
// else
|
||||
// DB_copy_key(&k4,&k3);
|
||||
//}
|
||||
//else {
|
||||
if(hkey[1] != pa->hair + pa->totkey - 1)
|
||||
hair_to_particle(keys + 3, hkey[1] + 1);
|
||||
else
|
||||
hair_to_particle(keys + 3, hkey[1]);
|
||||
}
|
||||
//}
|
||||
|
||||
//psys_get_particle_on_path(scene, bsys,p,t,bkey,ckey[0]);
|
||||
|
||||
//if(part->rotfrom==PART_ROT_KEYS)
|
||||
// QuatInterpol(state->rot,k2.rot,k3.rot,keytime);
|
||||
//else{
|
||||
// /* TODO: different rotations */
|
||||
// float nvel[3];
|
||||
// VECCOPY(nvel,state->vel);
|
||||
// VecMulf(nvel,-1.0f);
|
||||
// vectoquat(nvel, OB_POSX, OB_POSZ, state->rot);
|
||||
//}
|
||||
|
||||
dfra = keys[2].time - keys[1].time;
|
||||
|
||||
keytime = (real_t - keys[1].time) / dfra;
|
||||
|
||||
/* convert velocity to timestep size */
|
||||
if(psys->flag & PSYS_KEYED){
|
||||
if(keyed || cached){
|
||||
VecMulf(keys[1].vel, dfra / frs_sec);
|
||||
VecMulf(keys[2].vel, dfra / frs_sec);
|
||||
QuatInterpol(state->rot,keys[1].rot,keys[2].rot,keytime);
|
||||
}
|
||||
|
||||
psys_interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
|
||||
psys_interpolate_particle((keyed || cached) ? -1 /* signal for cubic interpolation */
|
||||
: ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL)
|
||||
,keys, keytime, state, 1);
|
||||
|
||||
/* the velocity needs to be converted back from cubic interpolation */
|
||||
if(psys->flag & PSYS_KEYED){
|
||||
if(keyed || cached){
|
||||
VecMulf(state->vel, frs_sec / dfra);
|
||||
}
|
||||
else {
|
||||
@ -3609,6 +3682,9 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
|
||||
cpa=psys->child+p-totpart;
|
||||
|
||||
if(state->time < 0.0f)
|
||||
t = psys_get_child_time(psys, cpa, -state->time, NULL, NULL);
|
||||
|
||||
if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
|
||||
totparent=(int)(totchild*part->parents*0.3);
|
||||
|
||||
@ -3624,7 +3700,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
|
||||
/* get parent states */
|
||||
while(w<4 && cpa->pa[w]>=0){
|
||||
keys[w].time = t;
|
||||
keys[w].time = state->time;
|
||||
psys_get_particle_on_path(scene, ob, psys, cpa->pa[w], keys+w, 1);
|
||||
w++;
|
||||
}
|
||||
@ -3650,7 +3726,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
else{
|
||||
/* get the parent state */
|
||||
|
||||
keys->time = t;
|
||||
keys->time = state->time;
|
||||
psys_get_particle_on_path(scene, ob, psys, cpa->parent, keys,1);
|
||||
|
||||
/* get the original coordinates (orco) for texture usage */
|
||||
@ -3672,15 +3748,11 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
#endif // XXX old animation system
|
||||
|
||||
/* get different child parameters from textures & vgroups */
|
||||
ptex.clump=1.0;
|
||||
ptex.kink=1.0;
|
||||
|
||||
get_cpa_texture(psmd->dm,ma,cpa_num,cpa_fuv,orco,&ptex,MAP_PA_CLUMP|MAP_PA_KINK);
|
||||
|
||||
pa_clump=ptex.clump;
|
||||
pa_kink=ptex.kink;
|
||||
|
||||
/* TODO: vertex groups */
|
||||
memset(&ctx, 0, sizeof(ParticleThreadContext));
|
||||
ctx.dm = psmd->dm;
|
||||
ctx.ma = ma;
|
||||
/* TODO: assign vertex groups */
|
||||
get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex);
|
||||
|
||||
if(between){
|
||||
int w=0;
|
||||
@ -3708,46 +3780,33 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
}
|
||||
|
||||
par = keys;
|
||||
//if(totparent){
|
||||
// if(p-totpart>=totparent){
|
||||
// key.time=t;
|
||||
// psys_get_particle_on_path(ob,psys,totpart+cpa->parent,&key,1);
|
||||
// bti->convert_dynamic_key(bsys,&key,par,cpar);
|
||||
// }
|
||||
// else
|
||||
// par=0;
|
||||
//}
|
||||
//else
|
||||
// DB_get_key_on_path(bsys,cpa->parent,t,par,cpar);
|
||||
|
||||
if(vel)
|
||||
copy_particle_key(&tstate, state, 1);
|
||||
|
||||
/* apply different deformations to the child path */
|
||||
if(part->kink)
|
||||
do_prekink(state, par, par->rot, t, part->kink_freq * pa_kink, part->kink_shape,
|
||||
part->kink_amp, part->kink, part->kink_axis, ob->obmat);
|
||||
do_child_modifiers(scene, ob, psys, part, &ptex, par, par->rot, cpa, orco, state, t);
|
||||
|
||||
do_clump(state, par, t, part->clumpfac, part->clumppow, 1.0f);
|
||||
/* try to estimate correct velocity */
|
||||
if(vel){
|
||||
ParticleKey tstate;
|
||||
float length = VecLength(state->vel);
|
||||
|
||||
if(part->rough1 != 0.0)
|
||||
do_rough(orco, t, part->rough1, part->rough1_size, 0.0, state);
|
||||
if(t>=0.001f){
|
||||
tstate.time=t-0.001f;
|
||||
psys_get_particle_on_path(scene,ob,psys,p,&tstate,0);
|
||||
VECSUB(state->vel,state->co,tstate.co);
|
||||
Normalize(state->vel);
|
||||
}
|
||||
else{
|
||||
tstate.time=t+0.001f;
|
||||
psys_get_particle_on_path(scene, ob,psys,p,&tstate,0);
|
||||
VECSUB(state->vel,tstate.co,state->co);
|
||||
Normalize(state->vel);
|
||||
}
|
||||
|
||||
if(part->rough2 != 0.0)
|
||||
do_rough(cpa->rand, t, part->rough2, part->rough2_size, part->rough2_thres, state);
|
||||
|
||||
if(part->rough_end != 0.0)
|
||||
do_rough_end(cpa->rand, t, part->rough_end, part->rough_end_shape, state, par);
|
||||
|
||||
//if(vel){
|
||||
// if(t>=0.001f){
|
||||
// tstate.time=t-0.001f;
|
||||
// psys_get_particle_on_path(scene,ob,psys,p,&tstate,0);
|
||||
// VECSUB(state->vel,state->co,tstate.co);
|
||||
// }
|
||||
// else{
|
||||
// tstate.time=t+0.001f;
|
||||
// psys_get_particle_on_path(scene, ob,psys,p,&tstate,0);
|
||||
// VECSUB(state->vel,tstate.co,state->co);
|
||||
// }
|
||||
//}
|
||||
VecMulf(state->vel, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* gets particle's state at a time, returns 1 if particle exists and can be seen and 0 if not */
|
||||
@ -3774,7 +3833,7 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
|
||||
pa=psys->particles+p;
|
||||
|
||||
if(between){
|
||||
state->time = psys_get_child_time(psys,&psys->child[p-totpart],cfra);
|
||||
state->time = psys_get_child_time(psys,&psys->child[p-totpart],cfra,NULL,NULL);
|
||||
|
||||
if(always==0)
|
||||
if((state->time<0.0 && (part->flag & PART_UNBORN)==0)
|
||||
|
@ -2205,8 +2205,10 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra
|
||||
*sfra = MAX2(1, (int)part->sta);
|
||||
*efra = MIN2((int)(part->end + part->lifetime + 1.0), scene->r.efra);
|
||||
}
|
||||
static void particle_write_state(int index, ParticleSystem *psys, float *data)
|
||||
static void particle_write_state(int index, void *psys_ptr, float *data)
|
||||
{
|
||||
ParticleSystem *psys= psys_ptr;
|
||||
|
||||
memcpy(data, (float *)(&(psys->particles+index)->state), sizeof(ParticleKey));
|
||||
}
|
||||
static void particle_read_state(int index, void *psys_ptr, float *data)
|
||||
@ -2225,7 +2227,7 @@ static void particle_cache_interpolate(int index, void *psys_ptr, float frs_sec,
|
||||
ParticleSystem *psys= psys_ptr;
|
||||
ParticleData *pa = psys->particles + index;
|
||||
ParticleKey keys[4];
|
||||
float dfra, cfra1f = (float)cfra1, cfra2f(float);
|
||||
float dfra;
|
||||
|
||||
cfra = MIN2(cfra, pa->dietime);
|
||||
cfra1 = MIN2(cfra1, pa->dietime);
|
||||
@ -4254,7 +4256,7 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif
|
||||
}
|
||||
}
|
||||
|
||||
if((part->type==PART_HAIR || psys->flag&PSYS_KEYED) && ( psys_in_edit_mode(scene, psys) || (part->type==PART_HAIR
|
||||
if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED) && ( psys_in_edit_mode(scene, psys) || (part->type==PART_HAIR
|
||||
|| (part->ren_as == PART_DRAW_PATH && (part->draw_as == PART_DRAW_REND || psys->renderdata))))){
|
||||
|
||||
psys_cache_paths(scene, ob, psys, cfra, 0);
|
||||
@ -4371,8 +4373,10 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
|
||||
dietime = birthtime + (1 + pa->loop) * (pa->dietime - pa->time);
|
||||
|
||||
/* update alive status and push events */
|
||||
if(pa->time > cfra)
|
||||
if(pa->time > cfra) {
|
||||
pa->alive = PARS_UNBORN;
|
||||
reset_particle(scene, pa, psys, psmd, ob, 0.0f, cfra, NULL, NULL, NULL);
|
||||
}
|
||||
else if(dietime <= cfra){
|
||||
if(dietime > psys->cfra){
|
||||
state.time = dietime;
|
||||
@ -4406,6 +4410,8 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
|
||||
distribute_particles(scene, ob, psys, PART_FROM_CHILD);
|
||||
}
|
||||
|
||||
psys_update_path_cache(scene, ob,psmd,psys,cfra);
|
||||
|
||||
if(vg_size)
|
||||
MEM_freeN(vg_size);
|
||||
}
|
||||
@ -4433,10 +4439,17 @@ void psys_changed_type(ParticleSystem *psys)
|
||||
|
||||
if(ELEM3(part->draw_as, PART_DRAW_NOT, PART_DRAW_REND, PART_DRAW_PATH)==0)
|
||||
part->draw_as = PART_DRAW_REND;
|
||||
|
||||
CLAMP(part->path_start, 0.0f, 100.0f);
|
||||
CLAMP(part->path_end, 0.0f, 100.0f);
|
||||
}
|
||||
else
|
||||
else {
|
||||
free_hair(psys, 1);
|
||||
|
||||
CLAMP(part->path_start, part->sta, part->end + part->lifetime);
|
||||
CLAMP(part->path_end, part->sta, part->end + part->lifetime);
|
||||
}
|
||||
|
||||
psys->softflag= 0;
|
||||
|
||||
psys_reset(psys, PSYS_RESET_ALL);
|
||||
@ -4629,9 +4642,8 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
||||
totpart = psys->part->totpart;
|
||||
totchild = get_psys_tot_child(scene, psys);
|
||||
|
||||
if(oldtotpart != totpart || (psys->part->childtype && oldtotchild != totchild)) {
|
||||
if(oldtotpart != totpart || oldtotchild != totchild) {
|
||||
only_children_changed = (oldtotpart == totpart);
|
||||
realloc_particles(ob, psys, totpart);
|
||||
alloc = 1;
|
||||
distr= 1;
|
||||
init= 1;
|
||||
@ -4647,10 +4659,11 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
||||
if(alloc) {
|
||||
realloc_particles(ob, psys, totpart);
|
||||
|
||||
if(usecache)
|
||||
if(usecache && !only_children_changed)
|
||||
BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
|
||||
}
|
||||
|
||||
if(!only_children_changed)
|
||||
distribute_particles(scene, ob, psys, part->from);
|
||||
|
||||
if((psys->part->type == PART_HAIR) && !(psys->flag & PSYS_HAIR_DONE))
|
||||
@ -4660,7 +4673,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
||||
distribute_particles(scene, ob, psys, PART_FROM_CHILD);
|
||||
}
|
||||
|
||||
if(only_children_changed==0) {
|
||||
if(!only_children_changed) {
|
||||
free_keyed_keys(psys);
|
||||
|
||||
initialize_all_particles(ob, psys, psmd);
|
||||
@ -4680,19 +4693,10 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
||||
int result = get_particles_from_cache(scene, ob, psys, (float)framenr, &old_framenr);
|
||||
|
||||
if(result == PTCACHE_READ_EXACT || result == PTCACHE_READ_INTERPOLATED) {
|
||||
//if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
|
||||
// psys_count_keyed_targets(ob,psys);
|
||||
// set_keyed_keys(scene, ob, psys);
|
||||
//}
|
||||
|
||||
cached_step(scene, ob, psmd, psys, cfra);
|
||||
psys->cfra=cfra;
|
||||
psys->recalc = 0;
|
||||
|
||||
//if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
|
||||
// psys_update_path_cache(scene, ob, psmd, psys, framenr);
|
||||
//}
|
||||
|
||||
cache->simframe= framenr;
|
||||
cache->flag |= PTCACHE_SIMULATION_VALID;
|
||||
|
||||
|
@ -643,8 +643,8 @@ int BKE_ptcache_write_cache(PTCacheWriter *writer)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<writer->totelem; i++) {
|
||||
writer->set_elem(i, writer->calldata, &temp);
|
||||
BKE_ptcache_file_write_floats(pf, &temp, incr);
|
||||
writer->set_elem(i, writer->calldata, temp);
|
||||
BKE_ptcache_file_write_floats(pf, temp, incr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -677,8 +677,8 @@ int BKE_ptcache_write_cache(PTCacheWriter *writer)
|
||||
pmdata = pm->data;
|
||||
|
||||
for(i=0; i<writer->totelem; i++, pmdata+=incr) {
|
||||
writer->set_elem(i, writer->calldata, &temp);
|
||||
memcpy(pmdata, &temp, elemsize);
|
||||
writer->set_elem(i, writer->calldata, temp);
|
||||
memcpy(pmdata, temp, elemsize);
|
||||
}
|
||||
|
||||
pm->frame = writer->cfra;
|
||||
@ -689,8 +689,8 @@ int BKE_ptcache_write_cache(PTCacheWriter *writer)
|
||||
pmdata = pm->data;
|
||||
|
||||
for(i=0; i<writer->totelem; i++, pmdata+=incr) {
|
||||
writer->set_elem(i, writer->calldata, &temp);
|
||||
memcpy(pmdata, &temp, elemsize);
|
||||
writer->set_elem(i, writer->calldata, temp);
|
||||
memcpy(pmdata, temp, elemsize);
|
||||
}
|
||||
|
||||
pm->frame = writer->cfra;
|
||||
@ -1154,6 +1154,7 @@ void BKE_ptcache_quick_cache_all(Scene *scene)
|
||||
baker.progressbar=NULL;
|
||||
baker.progresscontext=NULL;
|
||||
baker.render=0;
|
||||
baker.anim_init = 0;
|
||||
baker.scene=scene;
|
||||
|
||||
if(count_quick_cache(scene, &baker.quick_step))
|
||||
@ -1171,7 +1172,7 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
|
||||
float frameleno = scene->r.framelen;
|
||||
int cfrao = CFRA;
|
||||
int startframe = MAXFRAME;
|
||||
int endframe = CFRA;
|
||||
int endframe = baker->anim_init ? scene->r.sfra : CFRA;
|
||||
int bake = baker->bake;
|
||||
int render = baker->render;
|
||||
int step = baker->quick_step;
|
||||
@ -1209,8 +1210,13 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
|
||||
for(pid=pidlist.first; pid; pid=pid->next) {
|
||||
cache = pid->cache;
|
||||
if((cache->flag & PTCACHE_BAKED)==0) {
|
||||
if(pid->type==PTCACHE_TYPE_PARTICLES)
|
||||
if(pid->type==PTCACHE_TYPE_PARTICLES) {
|
||||
/* skip hair particles */
|
||||
if(((ParticleSystem*)pid->data)->part->type == PART_HAIR)
|
||||
continue;
|
||||
|
||||
psys_get_pointcache_start_end(scene, pid->data, &cache->startframe, &cache->endframe);
|
||||
}
|
||||
|
||||
if((cache->flag & PTCACHE_REDO_NEEDED || (cache->flag & PTCACHE_SIMULATION_VALID)==0)
|
||||
&& ((cache->flag & PTCACHE_QUICK_CACHE)==0 || render || bake))
|
||||
@ -1265,6 +1271,10 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
|
||||
BKE_ptcache_ids_from_object(&pidlist, base->object);
|
||||
|
||||
for(pid=pidlist.first; pid; pid=pid->next) {
|
||||
/* skip hair particles */
|
||||
if(pid->type==PTCACHE_TYPE_PARTICLES && ((ParticleSystem*)pid->data)->part->type == PART_HAIR)
|
||||
continue;
|
||||
|
||||
cache = pid->cache;
|
||||
|
||||
if(step > 1)
|
||||
@ -1282,6 +1292,8 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
|
||||
|
||||
scene->r.framelen = frameleno;
|
||||
CFRA = cfrao;
|
||||
|
||||
if(bake) /* already on cfra unless baking */
|
||||
scene_update_for_newframe(scene, scene->lay);
|
||||
|
||||
/* TODO: call redraw all windows somehow */
|
||||
|
@ -78,6 +78,8 @@ static void spacetype_free(SpaceType *st)
|
||||
}
|
||||
|
||||
BLI_freelistN(&st->regiontypes);
|
||||
BLI_freelistN(&st->toolshelf);
|
||||
|
||||
}
|
||||
|
||||
void BKE_spacetypes_free(void)
|
||||
|
@ -184,11 +184,11 @@ void seq_free_sequence(Editing *ed, Sequence *seq)
|
||||
if(seq->anim) IMB_free_anim(seq->anim);
|
||||
//XXX if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio);
|
||||
|
||||
/* XXX if (seq->type & SEQ_EFFECT) {
|
||||
if (seq->type & SEQ_EFFECT) {
|
||||
struct SeqEffectHandle sh = get_sequence_effect(seq);
|
||||
|
||||
sh.free(seq);
|
||||
}*/
|
||||
}
|
||||
|
||||
if (ed->act_seq==seq)
|
||||
ed->act_seq= NULL;
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "BLI_edgehash.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_extensions.h"
|
||||
|
85
source/blender/blenkernel/nla_private.h
Normal file
85
source/blender/blenkernel/nla_private.h
Normal file
@ -0,0 +1,85 @@
|
||||
/**
|
||||
* $Id: BKE_nla.h 20999 2009-06-19 04:45:56Z aligorith $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Joshua Leung (full recode)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef NLA_PRIVATE
|
||||
#define NLA_PRIVATE
|
||||
|
||||
/* --------------- NLA Evaluation DataTypes ----------------------- */
|
||||
|
||||
/* used for list of strips to accumulate at current time */
|
||||
typedef struct NlaEvalStrip {
|
||||
struct NlaEvalStrip *next, *prev;
|
||||
|
||||
NlaTrack *track; /* track that this strip belongs to */
|
||||
NlaStrip *strip; /* strip that's being used */
|
||||
|
||||
short track_index; /* the index of the track within the list */
|
||||
short strip_mode; /* which end of the strip are we looking at */
|
||||
|
||||
float strip_time; /* time at which which strip is being evaluated */
|
||||
} NlaEvalStrip;
|
||||
|
||||
/* NlaEvalStrip->strip_mode */
|
||||
enum {
|
||||
/* standard evaluation */
|
||||
NES_TIME_BEFORE = -1,
|
||||
NES_TIME_WITHIN,
|
||||
NES_TIME_AFTER,
|
||||
|
||||
/* transition-strip evaluations */
|
||||
NES_TIME_TRANSITION_START,
|
||||
NES_TIME_TRANSITION_END,
|
||||
} eNlaEvalStrip_StripMode;
|
||||
|
||||
|
||||
/* temp channel for accumulating data from NLA (avoids needing to clear all values first) */
|
||||
// TODO: maybe this will be used as the 'cache' stuff needed for editable values too?
|
||||
typedef struct NlaEvalChannel {
|
||||
struct NlaEvalChannel *next, *prev;
|
||||
|
||||
PointerRNA ptr; /* pointer to struct containing property to use */
|
||||
PropertyRNA *prop; /* RNA-property type to use (should be in the struct given) */
|
||||
int index; /* array index (where applicable) */
|
||||
|
||||
float value; /* value of this channel */
|
||||
} NlaEvalChannel;
|
||||
|
||||
/* --------------- NLA Functions (not to be used as a proper API) ----------------------- */
|
||||
|
||||
/* convert from strip time <-> global time */
|
||||
float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode);
|
||||
|
||||
/* --------------- NLA Evaluation (very-private stuff) ----------------------- */
|
||||
/* these functions are only defined here to avoid problems with the order in which they get defined... */
|
||||
|
||||
NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list, ListBase *strips, short index, float ctime);
|
||||
void nlastrip_evaluate(PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes);
|
||||
void nladata_flush_channels(ListBase *channels);
|
||||
|
||||
#endif // NLA_PRIVATE
|
@ -88,6 +88,7 @@ typedef struct BArcIterator {
|
||||
StoppedFct stopped;
|
||||
|
||||
float *p, *no;
|
||||
float size;
|
||||
|
||||
int length;
|
||||
int index;
|
||||
|
@ -72,6 +72,9 @@ void BLI_cleanup_dir(const char *relabase, char *dir); /* same as above but adds
|
||||
/* go back one directory */
|
||||
int BLI_parent_dir(char *path);
|
||||
|
||||
/* return whether directory is root and thus has no parent dir */
|
||||
int BLI_has_parent(char *path);
|
||||
|
||||
/**
|
||||
* Blender's path code replacement function.
|
||||
* Bases @a path strings leading with "//" by the
|
||||
|
@ -218,7 +218,7 @@ void BLI_builddir(char *dirname, char *relname)
|
||||
{
|
||||
struct dirent *fname;
|
||||
struct dirlink *dlink;
|
||||
int rellen, newnum = 0, ignore;
|
||||
int rellen, newnum = 0;
|
||||
char buf[256];
|
||||
DIR *dir;
|
||||
|
||||
|
@ -494,6 +494,22 @@ void BLI_makestringcode(const char *relfile, char *file)
|
||||
}
|
||||
}
|
||||
|
||||
int BLI_has_parent(char *path)
|
||||
{
|
||||
int len;
|
||||
int slashes = 0;
|
||||
BLI_clean(path);
|
||||
BLI_add_slash(path);
|
||||
|
||||
len = strlen(path)-1;
|
||||
while (len) {
|
||||
if ((path[len] == '\\') || (path[len] == '/'))
|
||||
slashes++;
|
||||
len--;
|
||||
}
|
||||
return slashes > 1;
|
||||
}
|
||||
|
||||
int BLI_parent_dir(char *path)
|
||||
{
|
||||
#ifdef WIN32
|
||||
@ -738,9 +754,9 @@ void BLI_splitdirstring(char *di, char *fi)
|
||||
|
||||
void BLI_getlastdir(const char* dir, char *last, int maxlen)
|
||||
{
|
||||
char *s = dir;
|
||||
char *lslash = NULL;
|
||||
char *prevslash = NULL;
|
||||
const char *s = dir;
|
||||
const char *lslash = NULL;
|
||||
const char *prevslash = NULL;
|
||||
while (*s) {
|
||||
if ((*s == '\\') || (*s == '/')) {
|
||||
prevslash = lslash;
|
||||
|
@ -1667,10 +1667,26 @@ static void lib_link_constraint_channels(FileData *fd, ID *id, ListBase *chanbas
|
||||
|
||||
/* Data Linking ----------------------------- */
|
||||
|
||||
static void lib_link_fmodifiers(FileData *fd, ID *id, ListBase *list)
|
||||
{
|
||||
FModifier *fcm;
|
||||
|
||||
for (fcm= list->first; fcm; fcm= fcm->next) {
|
||||
/* data for specific modifiers */
|
||||
switch (fcm->type) {
|
||||
case FMODIFIER_TYPE_PYTHON:
|
||||
{
|
||||
FMod_Python *data= (FMod_Python *)fcm->data;
|
||||
data->script = newlibadr(fd, id->lib, data->script);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list)
|
||||
{
|
||||
FCurve *fcu;
|
||||
FModifier *fcm;
|
||||
|
||||
/* relink ID-block references... */
|
||||
for (fcu= list->first; fcu; fcu= fcu->next) {
|
||||
@ -1684,53 +1700,17 @@ static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list)
|
||||
}
|
||||
|
||||
/* modifiers */
|
||||
for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
|
||||
/* data for specific modifiers */
|
||||
switch (fcm->type) {
|
||||
case FMODIFIER_TYPE_PYTHON:
|
||||
{
|
||||
FMod_Python *data= (FMod_Python *)fcm->data;
|
||||
data->script = newlibadr(fd, id->lib, data->script);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
lib_link_fmodifiers(fd, id, &fcu->modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* NOTE: this assumes that link_list has already been called on the list */
|
||||
static void direct_link_fcurves(FileData *fd, ListBase *list)
|
||||
static void direct_link_fmodifiers(FileData *fd, ListBase *list)
|
||||
{
|
||||
FCurve *fcu;
|
||||
FModifier *fcm;
|
||||
|
||||
/* link F-Curve data to F-Curve again (non ID-libs) */
|
||||
for (fcu= list->first; fcu; fcu= fcu->next) {
|
||||
/* curve data */
|
||||
fcu->bezt= newdataadr(fd, fcu->bezt);
|
||||
fcu->fpt= newdataadr(fd, fcu->fpt);
|
||||
|
||||
/* rna path */
|
||||
fcu->rna_path= newdataadr(fd, fcu->rna_path);
|
||||
|
||||
/* group */
|
||||
fcu->grp= newdataadr(fd, fcu->grp);
|
||||
|
||||
/* driver */
|
||||
fcu->driver= newdataadr(fd, fcu->driver);
|
||||
if (fcu->driver) {
|
||||
ChannelDriver *driver= fcu->driver;
|
||||
DriverTarget *dtar;
|
||||
|
||||
/* relink targets and their paths */
|
||||
link_list(fd, &driver->targets);
|
||||
for (dtar= driver->targets.first; dtar; dtar= dtar->next)
|
||||
dtar->rna_path= newdataadr(fd, dtar->rna_path);
|
||||
}
|
||||
|
||||
/* modifiers */
|
||||
link_list(fd, &fcu->modifiers);
|
||||
for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
|
||||
for (fcm= list->first; fcm; fcm= fcm->next) {
|
||||
/* relink general data */
|
||||
fcm->data = newdataadr(fd, fcm->data);
|
||||
fcm->edata= NULL;
|
||||
@ -1762,6 +1742,40 @@ static void direct_link_fcurves(FileData *fd, ListBase *list)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: this assumes that link_list has already been called on the list */
|
||||
static void direct_link_fcurves(FileData *fd, ListBase *list)
|
||||
{
|
||||
FCurve *fcu;
|
||||
|
||||
/* link F-Curve data to F-Curve again (non ID-libs) */
|
||||
for (fcu= list->first; fcu; fcu= fcu->next) {
|
||||
/* curve data */
|
||||
fcu->bezt= newdataadr(fd, fcu->bezt);
|
||||
fcu->fpt= newdataadr(fd, fcu->fpt);
|
||||
|
||||
/* rna path */
|
||||
fcu->rna_path= newdataadr(fd, fcu->rna_path);
|
||||
|
||||
/* group */
|
||||
fcu->grp= newdataadr(fd, fcu->grp);
|
||||
|
||||
/* driver */
|
||||
fcu->driver= newdataadr(fd, fcu->driver);
|
||||
if (fcu->driver) {
|
||||
ChannelDriver *driver= fcu->driver;
|
||||
DriverTarget *dtar;
|
||||
|
||||
/* relink targets and their paths */
|
||||
link_list(fd, &driver->targets);
|
||||
for (dtar= driver->targets.first; dtar; dtar= dtar->next)
|
||||
dtar->rna_path= newdataadr(fd, dtar->rna_path);
|
||||
}
|
||||
|
||||
/* modifiers */
|
||||
link_list(fd, &fcu->modifiers);
|
||||
direct_link_fmodifiers(fd, &fcu->modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1812,6 +1826,65 @@ static void direct_link_action(FileData *fd, bAction *act)
|
||||
}
|
||||
}
|
||||
|
||||
static void lib_link_nladata_strips(FileData *fd, ID *id, ListBase *list)
|
||||
{
|
||||
NlaStrip *strip;
|
||||
|
||||
for (strip= list->first; strip; strip= strip->next) {
|
||||
/* check strip's children */
|
||||
lib_link_nladata_strips(fd, id, &strip->strips);
|
||||
|
||||
/* reassign the counted-reference to action */
|
||||
strip->act = newlibadr_us(fd, id->lib, strip->act);
|
||||
}
|
||||
}
|
||||
|
||||
static void lib_link_nladata(FileData *fd, ID *id, ListBase *list)
|
||||
{
|
||||
NlaTrack *nlt;
|
||||
|
||||
/* we only care about the NLA strips inside the tracks */
|
||||
for (nlt= list->first; nlt; nlt= nlt->next) {
|
||||
lib_link_nladata_strips(fd, id, &nlt->strips);
|
||||
}
|
||||
}
|
||||
|
||||
/* This handles Animato NLA-Strips linking
|
||||
* NOTE: this assumes that link_list has already been called on the list
|
||||
*/
|
||||
static void direct_link_nladata_strips(FileData *fd, ListBase *list)
|
||||
{
|
||||
NlaStrip *strip;
|
||||
|
||||
for (strip= list->first; strip; strip= strip->next) {
|
||||
/* strip's child strips */
|
||||
link_list(fd, &strip->strips);
|
||||
direct_link_nladata_strips(fd, &strip->strips);
|
||||
|
||||
/* strip's F-Curves */
|
||||
link_list(fd, &strip->fcurves);
|
||||
direct_link_fcurves(fd, &strip->fcurves);
|
||||
|
||||
/* strip's F-Modifiers */
|
||||
link_list(fd, &strip->modifiers);
|
||||
direct_link_fcurves(fd, &strip->modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: this assumes that link_list has already been called on the list */
|
||||
static void direct_link_nladata(FileData *fd, ListBase *list)
|
||||
{
|
||||
NlaTrack *nlt;
|
||||
|
||||
for (nlt= list->first; nlt; nlt= nlt->next) {
|
||||
/* relink list of strips */
|
||||
link_list(fd, &nlt->strips);
|
||||
|
||||
/* relink strip data */
|
||||
direct_link_nladata_strips(fd, &nlt->strips);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------- */
|
||||
|
||||
static void lib_link_keyingsets(FileData *fd, ID *id, ListBase *list)
|
||||
@ -1854,6 +1927,7 @@ static void lib_link_animdata(FileData *fd, ID *id, AnimData *adt)
|
||||
|
||||
/* link action data */
|
||||
adt->action= newlibadr_us(fd, id->lib, adt->action);
|
||||
adt->tmpact= newlibadr_us(fd, id->lib, adt->tmpact);
|
||||
|
||||
/* link drivers */
|
||||
lib_link_fcurves(fd, id, &adt->drivers);
|
||||
@ -1861,7 +1935,7 @@ static void lib_link_animdata(FileData *fd, ID *id, AnimData *adt)
|
||||
/* overrides don't have lib-link for now, so no need to do anything */
|
||||
|
||||
/* link NLA-data */
|
||||
// TODO...
|
||||
lib_link_nladata(fd, id, &adt->nla_tracks);
|
||||
}
|
||||
|
||||
static void direct_link_animdata(FileData *fd, AnimData *adt)
|
||||
@ -1878,7 +1952,12 @@ static void direct_link_animdata(FileData *fd, AnimData *adt)
|
||||
// TODO...
|
||||
|
||||
/* link NLA-data */
|
||||
// TODO...
|
||||
link_list(fd, &adt->nla_tracks);
|
||||
direct_link_nladata(fd, &adt->nla_tracks);
|
||||
|
||||
/* clear temp pointers that may have been set... */
|
||||
// TODO: it's probably only a small cost to reload this anyway...
|
||||
adt->actstrip= NULL;
|
||||
}
|
||||
|
||||
/* ************ READ NODE TREE *************** */
|
||||
@ -2641,6 +2720,7 @@ static void direct_link_image(FileData *fd, Image *ima)
|
||||
ima->anim= NULL;
|
||||
ima->rr= NULL;
|
||||
ima->repbind= NULL;
|
||||
ima->render_text= newdataadr(fd, ima->render_text);
|
||||
|
||||
ima->packedfile = direct_link_packedfile(fd, ima->packedfile);
|
||||
ima->preview = direct_link_preview_image(fd, ima->preview);
|
||||
@ -4472,13 +4552,10 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
|
||||
|
||||
SpaceFile *sfile= (SpaceFile *)sl;
|
||||
sfile->files= NULL;
|
||||
sfile->folders_prev= NULL;
|
||||
sfile->folders_next= NULL;
|
||||
sfile->params= NULL;
|
||||
sfile->op= NULL;
|
||||
/* XXX needs checking - best solve in filesel itself
|
||||
if(sfile->libfiledata)
|
||||
BLO_blendhandle_close(sfile->libfiledata);
|
||||
sfile->libfiledata= 0;
|
||||
*/
|
||||
}
|
||||
else if(sl->spacetype==SPACE_IMASEL) {
|
||||
SpaceImaSel *simasel= (SpaceImaSel *)sl;
|
||||
@ -4710,6 +4787,11 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
|
||||
sipo->ads= newdataadr(fd, sipo->ads);
|
||||
sipo->ghostCurves.first= sipo->ghostCurves.last= NULL;
|
||||
}
|
||||
else if (sl->spacetype==SPACE_NLA) {
|
||||
SpaceNla *snla= (SpaceNla*)sl;
|
||||
|
||||
snla->ads= newdataadr(fd, snla->ads);
|
||||
}
|
||||
else if (sl->spacetype==SPACE_OUTLINER) {
|
||||
SpaceOops *soops= (SpaceOops*) sl;
|
||||
|
||||
@ -9011,14 +9093,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
*/
|
||||
//do_versions_ipos_to_animato(main);
|
||||
|
||||
/* struct audio data moved to renderdata */
|
||||
for(scene= main->scene.first; scene; scene= scene->id.next) {
|
||||
/* toolsettings */
|
||||
for(scene= main->scene.first; scene; scene= scene->id.next)
|
||||
scene->r.audio = scene->audio;
|
||||
|
||||
if(!scene->toolsettings->uv_selectmode)
|
||||
scene->toolsettings->uv_selectmode= UV_SELECT_VERTEX;
|
||||
}
|
||||
|
||||
/* shader, composit and texture node trees have id.name empty, put something in
|
||||
* to have them show in RNA viewer and accessible otherwise.
|
||||
*/
|
||||
@ -9057,6 +9135,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
part->draw_as = PART_DRAW_REND;
|
||||
}
|
||||
}
|
||||
part->path_end = 1.0f;
|
||||
}
|
||||
/* set old pointcaches to have disk cache flag */
|
||||
for(ob = main->object.first; ob; ob= ob->id.next) {
|
||||
@ -9086,7 +9165,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
void *olddata = ob->data;
|
||||
ob->data = me;
|
||||
|
||||
if(me && me->mr) {
|
||||
if(me && me->id.lib==NULL && me->mr) { /* XXX - library meshes crash on loading most yoFrankie levels, the multires pointer gets invalid - Campbell */
|
||||
MultiresLevel *lvl;
|
||||
ModifierData *md;
|
||||
MultiresModifierData *mmd;
|
||||
@ -9152,10 +9231,19 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
|
||||
for(sce = main->scene.first; sce; sce = sce->id.next) {
|
||||
ts= sce->toolsettings;
|
||||
if(ts->normalsize == 0.0) {
|
||||
if(ts->normalsize == 0.0 || !ts->uv_selectmode || ts->vgroup_weight == 0.0) {
|
||||
ts->normalsize= 0.1f;
|
||||
ts->selectmode= SCE_SELECT_VERTEX;
|
||||
|
||||
/* autokeying - setting should be taken from the user-prefs
|
||||
* but the userprefs version may not have correct flags set
|
||||
* (i.e. will result in blank box when enabled)
|
||||
*/
|
||||
ts->autokey_mode= U.autokey_mode;
|
||||
if (ts->autokey_mode == 0)
|
||||
ts->autokey_mode= 2; /* 'add/replace' but not on */
|
||||
ts->uv_selectmode= UV_SELECT_VERTEX;
|
||||
ts->vgroup_weight= 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9488,12 +9576,27 @@ static void expand_keyingsets(FileData *fd, Main *mainvar, ListBase *list)
|
||||
}
|
||||
}
|
||||
|
||||
static void expand_animdata_nlastrips(FileData *fd, Main *mainvar, ListBase *list)
|
||||
{
|
||||
NlaStrip *strip;
|
||||
|
||||
for (strip= list->first; strip; strip= strip->next) {
|
||||
/* check child strips */
|
||||
expand_animdata_nlastrips(fd, mainvar, &strip->strips);
|
||||
|
||||
/* relink referenced action */
|
||||
expand_doit(fd, mainvar, strip->act);
|
||||
}
|
||||
}
|
||||
|
||||
static void expand_animdata(FileData *fd, Main *mainvar, AnimData *adt)
|
||||
{
|
||||
FCurve *fcd;
|
||||
NlaTrack *nlt;
|
||||
|
||||
/* own action */
|
||||
expand_doit(fd, mainvar, adt->action);
|
||||
expand_doit(fd, mainvar, adt->tmpact);
|
||||
|
||||
/* drivers - assume that these F-Curves have driver data to be in this list... */
|
||||
for (fcd= adt->drivers.first; fcd; fcd= fcd->next) {
|
||||
@ -9503,6 +9606,10 @@ static void expand_animdata(FileData *fd, Main *mainvar, AnimData *adt)
|
||||
for (dtar= driver->targets.first; dtar; dtar= dtar->next)
|
||||
expand_doit(fd, mainvar, dtar->id);
|
||||
}
|
||||
|
||||
/* nla-data - referenced actions */
|
||||
for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next)
|
||||
expand_animdata_nlastrips(fd, mainvar, &nlt->strips);
|
||||
}
|
||||
|
||||
static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSettings *part)
|
||||
|
@ -781,42 +781,12 @@ static void write_actuators(WriteData *wd, ListBase *lb)
|
||||
}
|
||||
}
|
||||
|
||||
static void write_fcurves(WriteData *wd, ListBase *fcurves)
|
||||
static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers)
|
||||
{
|
||||
FCurve *fcu;
|
||||
FModifier *fcm;
|
||||
|
||||
for (fcu=fcurves->first; fcu; fcu=fcu->next) {
|
||||
/* F-Curve */
|
||||
writestruct(wd, DATA, "FCurve", 1, fcu);
|
||||
|
||||
/* curve data */
|
||||
if (fcu->bezt)
|
||||
writestruct(wd, DATA, "BezTriple", fcu->totvert, fcu->bezt);
|
||||
if (fcu->fpt)
|
||||
writestruct(wd, DATA, "FPoint", fcu->totvert, fcu->fpt);
|
||||
|
||||
if (fcu->rna_path)
|
||||
writedata(wd, DATA, strlen(fcu->rna_path)+1, fcu->rna_path);
|
||||
|
||||
/* driver data */
|
||||
if (fcu->driver) {
|
||||
ChannelDriver *driver= fcu->driver;
|
||||
DriverTarget *dtar;
|
||||
|
||||
writestruct(wd, DATA, "ChannelDriver", 1, driver);
|
||||
|
||||
/* targets */
|
||||
for (dtar= driver->targets.first; dtar; dtar= dtar->next) {
|
||||
writestruct(wd, DATA, "DriverTarget", 1, dtar);
|
||||
|
||||
if (dtar->rna_path)
|
||||
writedata(wd, DATA, strlen(dtar->rna_path)+1, dtar->rna_path);
|
||||
}
|
||||
}
|
||||
|
||||
/* Modifiers */
|
||||
for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
|
||||
for (fcm= fmodifiers->first; fcm; fcm= fcm->next) {
|
||||
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
|
||||
|
||||
/* Write the specific data */
|
||||
@ -860,6 +830,43 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves)
|
||||
writestruct(wd, DATA, "FModifier", 1, fcm);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_fcurves(WriteData *wd, ListBase *fcurves)
|
||||
{
|
||||
FCurve *fcu;
|
||||
|
||||
for (fcu=fcurves->first; fcu; fcu=fcu->next) {
|
||||
/* F-Curve */
|
||||
writestruct(wd, DATA, "FCurve", 1, fcu);
|
||||
|
||||
/* curve data */
|
||||
if (fcu->bezt)
|
||||
writestruct(wd, DATA, "BezTriple", fcu->totvert, fcu->bezt);
|
||||
if (fcu->fpt)
|
||||
writestruct(wd, DATA, "FPoint", fcu->totvert, fcu->fpt);
|
||||
|
||||
if (fcu->rna_path)
|
||||
writedata(wd, DATA, strlen(fcu->rna_path)+1, fcu->rna_path);
|
||||
|
||||
/* driver data */
|
||||
if (fcu->driver) {
|
||||
ChannelDriver *driver= fcu->driver;
|
||||
DriverTarget *dtar;
|
||||
|
||||
writestruct(wd, DATA, "ChannelDriver", 1, driver);
|
||||
|
||||
/* targets */
|
||||
for (dtar= driver->targets.first; dtar; dtar= dtar->next) {
|
||||
writestruct(wd, DATA, "DriverTarget", 1, dtar);
|
||||
|
||||
if (dtar->rna_path)
|
||||
writedata(wd, DATA, strlen(dtar->rna_path)+1, dtar->rna_path);
|
||||
}
|
||||
}
|
||||
|
||||
/* write F-Modifiers */
|
||||
write_fmodifiers(wd, &fcu->modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_actions(WriteData *wd, ListBase *idbase)
|
||||
@ -909,6 +916,37 @@ static void write_keyingsets(WriteData *wd, ListBase *list)
|
||||
}
|
||||
}
|
||||
|
||||
static void write_nlastrips(WriteData *wd, ListBase *strips)
|
||||
{
|
||||
NlaStrip *strip;
|
||||
|
||||
for (strip= strips->first; strip; strip= strip->next) {
|
||||
/* write the strip first */
|
||||
writestruct(wd, DATA, "NlaStrip", 1, strip);
|
||||
|
||||
/* write the strip's F-Curves and modifiers */
|
||||
write_fcurves(wd, &strip->fcurves);
|
||||
write_fmodifiers(wd, &strip->modifiers);
|
||||
|
||||
/* write the strip's children */
|
||||
write_nlastrips(wd, &strip->strips);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_nladata(WriteData *wd, ListBase *nlabase)
|
||||
{
|
||||
NlaTrack *nlt;
|
||||
|
||||
/* write all the tracks */
|
||||
for (nlt= nlabase->first; nlt; nlt= nlt->next) {
|
||||
/* write the track first */
|
||||
writestruct(wd, DATA, "NlaTrack", 1, nlt);
|
||||
|
||||
/* write the track's strips */
|
||||
write_nlastrips(wd, &nlt->strips);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_animdata(WriteData *wd, AnimData *adt)
|
||||
{
|
||||
AnimOverride *aor;
|
||||
@ -920,14 +958,17 @@ static void write_animdata(WriteData *wd, AnimData *adt)
|
||||
write_fcurves(wd, &adt->drivers);
|
||||
|
||||
/* write overrides */
|
||||
// FIXME: are these needed?
|
||||
for (aor= adt->overrides.first; aor; aor= aor->next) {
|
||||
/* overrides consist of base data + rna_path */
|
||||
writestruct(wd, DATA, "AnimOverride", 1, aor);
|
||||
writedata(wd, DATA, strlen(aor->rna_path)+1, aor->rna_path);
|
||||
}
|
||||
|
||||
// TODO write the remaps (if they are needed)
|
||||
|
||||
/* write NLA data */
|
||||
// XXX todo...
|
||||
write_nladata(wd, &adt->nla_tracks);
|
||||
}
|
||||
|
||||
static void write_constraints(WriteData *wd, ListBase *conlist)
|
||||
@ -1439,6 +1480,9 @@ static void write_images(WriteData *wd, ListBase *idbase)
|
||||
|
||||
write_previews(wd, ima->preview);
|
||||
|
||||
/* exception: render text only saved in undo files (wd->current) */
|
||||
if (ima->render_text && wd->current)
|
||||
writedata(wd, DATA, IMA_RW_MAXTEXT, ima->render_text);
|
||||
}
|
||||
ima= ima->id.next;
|
||||
}
|
||||
@ -1896,7 +1940,10 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
|
||||
writestruct(wd, DATA, "SpaceSound", 1, sl);
|
||||
}
|
||||
else if(sl->spacetype==SPACE_NLA){
|
||||
writestruct(wd, DATA, "SpaceNla", 1, sl);
|
||||
SpaceNla *snla= (SpaceNla *)sl;
|
||||
|
||||
writestruct(wd, DATA, "SpaceNla", 1, snla);
|
||||
if(snla->ads) writestruct(wd, DATA, "bDopeSheet", 1, snla->ads);
|
||||
}
|
||||
else if(sl->spacetype==SPACE_TIME){
|
||||
writestruct(wd, DATA, "SpaceTime", 1, sl);
|
||||
|
@ -64,6 +64,10 @@ IF(WITH_FFMPEG)
|
||||
ADD_DEFINITIONS(-DWITH_FFMPEG)
|
||||
ENDIF(WITH_FFMPEG)
|
||||
|
||||
IF(NOT WITH_ELBEEM)
|
||||
ADD_DEFINITIONS(-DDISABLE_ELBEEM)
|
||||
ENDIF(NOT WITH_ELBEEM)
|
||||
|
||||
IF(WITH_PYTHON)
|
||||
SET(INC ${INC} ${PYTHON_INC})
|
||||
ELSE(WITH_PYTHON)
|
||||
|
@ -63,9 +63,10 @@
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_ipo.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_object.h"
|
||||
@ -87,43 +88,16 @@
|
||||
/* ************************************************************************** */
|
||||
/* CHANNELS API */
|
||||
|
||||
/* -------------------------- Internal Macros ------------------------------- */
|
||||
|
||||
/* set/clear/toggle macro
|
||||
* - channel - channel with a 'flag' member that we're setting
|
||||
* - smode - 0=clear, 1=set, 2=toggle
|
||||
* - sflag - bitflag to set
|
||||
*/
|
||||
#define ACHANNEL_SET_FLAG(channel, smode, sflag) \
|
||||
{ \
|
||||
if (smode == ACHANNEL_SETFLAG_TOGGLE) (channel)->flag ^= (sflag); \
|
||||
else if (smode == ACHANNEL_SETFLAG_ADD) (channel)->flag |= (sflag); \
|
||||
else (channel)->flag &= ~(sflag); \
|
||||
}
|
||||
|
||||
/* set/clear/toggle macro, where the flag is negative
|
||||
* - channel - channel with a 'flag' member that we're setting
|
||||
* - smode - 0=clear, 1=set, 2=toggle
|
||||
* - sflag - bitflag to set
|
||||
*/
|
||||
#define ACHANNEL_SET_FLAG_NEG(channel, smode, sflag) \
|
||||
{ \
|
||||
if (smode == ACHANNEL_SETFLAG_TOGGLE) (channel)->flag ^= (sflag); \
|
||||
else if (smode == ACHANNEL_SETFLAG_ADD) (channel)->flag &= ~(sflag); \
|
||||
else (channel)->flag |= (sflag); \
|
||||
}
|
||||
|
||||
/* -------------------------- Exposed API ----------------------------------- */
|
||||
|
||||
/* Set the given animation-channel as the active one for the active context */
|
||||
void ANIM_set_active_channel (void *data, short datatype, int filter, void *channel_data, short channel_type)
|
||||
void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int filter, void *channel_data, short channel_type)
|
||||
{
|
||||
ListBase anim_data = {NULL, NULL};
|
||||
bAnimListElem *ale;
|
||||
|
||||
/* try to build list of filtered items */
|
||||
// XXX we don't need/supply animcontext for now, since in this case, there's nothing really essential there that isn't already covered
|
||||
ANIM_animdata_filter(NULL, &anim_data, filter, data, datatype);
|
||||
ANIM_animdata_filter(ac, &anim_data, filter, data, datatype);
|
||||
if (anim_data.first == NULL)
|
||||
return;
|
||||
|
||||
@ -149,11 +123,18 @@ void ANIM_set_active_channel (void *data, short datatype, int filter, void *chan
|
||||
ACHANNEL_SET_FLAG(fcu, ACHANNEL_SETFLAG_CLEAR, FCURVE_ACTIVE);
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_NLATRACK:
|
||||
{
|
||||
NlaTrack *nlt= (NlaTrack *)ale->data;
|
||||
|
||||
ACHANNEL_SET_FLAG(nlt, ACHANNEL_SETFLAG_CLEAR, NLATRACK_ACTIVE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* set active flag */
|
||||
if (channel_data) {
|
||||
if (channel_data != NULL) {
|
||||
switch (channel_type) {
|
||||
case ANIMTYPE_GROUP:
|
||||
{
|
||||
@ -167,6 +148,12 @@ void ANIM_set_active_channel (void *data, short datatype, int filter, void *chan
|
||||
fcu->flag |= FCURVE_ACTIVE;
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_NLATRACK:
|
||||
{
|
||||
NlaTrack *nlt= (NlaTrack *)channel_data;
|
||||
nlt->flag |= NLATRACK_ACTIVE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,6 +204,10 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
|
||||
if (ale->flag & FCURVE_SELECTED)
|
||||
sel= ACHANNEL_SETFLAG_CLEAR;
|
||||
break;
|
||||
case ANIMTYPE_NLATRACK:
|
||||
if (ale->flag & NLATRACK_SELECTED)
|
||||
sel= ACHANNEL_SETFLAG_CLEAR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -263,6 +254,14 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
|
||||
fcu->flag &= ~FCURVE_ACTIVE;
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_NLATRACK:
|
||||
{
|
||||
NlaTrack *nlt= (NlaTrack *)ale->data;
|
||||
|
||||
ACHANNEL_SET_FLAG(nlt, sel, NLATRACK_SELECTED);
|
||||
nlt->flag &= ~NLATRACK_ACTIVE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,6 +272,47 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
|
||||
/* ************************************************************************** */
|
||||
/* OPERATORS */
|
||||
|
||||
/* ****************** Operator Utilities ********************************** */
|
||||
|
||||
/* poll callback for being in an Animation Editor channels list region */
|
||||
int animedit_poll_channels_active (bContext *C)
|
||||
{
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
|
||||
/* channels region test */
|
||||
// TODO: could enhance with actually testing if channels region?
|
||||
if (ELEM(NULL, sa, CTX_wm_region(C)))
|
||||
return 0;
|
||||
/* animation editor test */
|
||||
if (ELEM3(sa->spacetype, SPACE_ACTION, SPACE_IPO, SPACE_NLA) == 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* poll callback for Animation Editor channels list region + not in NLA-tweakmode for NLA */
|
||||
int animedit_poll_channels_nla_tweakmode_off (bContext *C)
|
||||
{
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
/* channels region test */
|
||||
// TODO: could enhance with actually testing if channels region?
|
||||
if (ELEM(NULL, sa, CTX_wm_region(C)))
|
||||
return 0;
|
||||
/* animation editor test */
|
||||
if (ELEM3(sa->spacetype, SPACE_ACTION, SPACE_IPO, SPACE_NLA) == 0)
|
||||
return 0;
|
||||
|
||||
/* NLA TweakMode test */
|
||||
if (sa->spacetype == SPACE_NLA) {
|
||||
if ((scene == NULL) || (scene->flag & SCE_NLA_EDIT_ON))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ****************** Rearrange Channels Operator ******************* */
|
||||
/* This operator only works for Action Editor mode for now, as having it elsewhere makes things difficult */
|
||||
|
||||
@ -575,8 +615,8 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
|
||||
mode= RNA_enum_get(op->ptr, "direction");
|
||||
rearrange_action_channels(&ac, mode);
|
||||
|
||||
/* set notifier tha things have changed */
|
||||
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
||||
/* send notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@ -652,6 +692,121 @@ void ANIM_OT_channels_move_bottom (wmOperatorType *ot)
|
||||
|
||||
#endif // XXX old animation system - needs to be updated for new system...
|
||||
|
||||
/* ******************** Delete Channel Operator *********************** */
|
||||
|
||||
static int animchannels_delete_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
bAnimContext ac;
|
||||
ListBase anim_data = {NULL, NULL};
|
||||
bAnimListElem *ale;
|
||||
int filter;
|
||||
|
||||
/* get editor data */
|
||||
if (ANIM_animdata_get_context(C, &ac) == 0)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
/* cannot delete in shapekey */
|
||||
if (ac.datatype == ANIMCONT_SHAPEKEY)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
|
||||
/* do groups only first (unless in Drivers mode, where there are none) */
|
||||
if (ac.datatype != ANIMCONT_DRIVERS) {
|
||||
/* filter data */
|
||||
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CHANNELS | ANIMFILTER_FOREDIT);
|
||||
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
|
||||
|
||||
/* delete selected groups and their associated channels */
|
||||
for (ale= anim_data.first; ale; ale= ale->next) {
|
||||
/* only groups - don't check other types yet, since they may no-longer exist */
|
||||
if (ale->type == ANIMTYPE_GROUP) {
|
||||
bActionGroup *agrp= (bActionGroup *)ale->data;
|
||||
AnimData *adt= BKE_animdata_from_id(ale->id);
|
||||
FCurve *fcu, *fcn;
|
||||
|
||||
/* skip this group if no AnimData available, as we can't safely remove the F-Curves */
|
||||
if (adt == NULL)
|
||||
continue;
|
||||
|
||||
/* delete all of the Group's F-Curves, but no others */
|
||||
for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcn) {
|
||||
fcn= fcu->next;
|
||||
|
||||
/* remove from group and action, then free */
|
||||
action_groups_remove_channel(adt->action, fcu);
|
||||
free_fcurve(fcu);
|
||||
}
|
||||
|
||||
/* free the group itself */
|
||||
if (adt->action)
|
||||
BLI_freelinkN(&adt->action->groups, agrp);
|
||||
else
|
||||
MEM_freeN(agrp);
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
BLI_freelistN(&anim_data);
|
||||
}
|
||||
|
||||
/* now do F-Curves */
|
||||
if (ac.datatype != ANIMCONT_GPENCIL) {
|
||||
/* filter data */
|
||||
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT);
|
||||
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
|
||||
|
||||
/* delete selected F-Curves */
|
||||
for (ale= anim_data.first; ale; ale= ale->next) {
|
||||
/* only F-Curves, and only if we can identify its parent */
|
||||
if (ale->type == ANIMTYPE_FCURVE) {
|
||||
AnimData *adt= BKE_animdata_from_id(ale->id);
|
||||
FCurve *fcu= (FCurve *)ale->data;
|
||||
|
||||
/* if no AnimData, we've got nowhere to remove the F-Curve from */
|
||||
if (adt == NULL)
|
||||
continue;
|
||||
|
||||
/* remove from whatever list it came from
|
||||
* - Action Group
|
||||
* - Action
|
||||
* - Drivers
|
||||
* - TODO... some others?
|
||||
*/
|
||||
if (fcu->grp)
|
||||
action_groups_remove_channel(adt->action, fcu);
|
||||
else if (adt->action)
|
||||
BLI_remlink(&adt->action->curves, fcu);
|
||||
else if (ac.datatype == ANIMCONT_DRIVERS)
|
||||
BLI_remlink(&adt->drivers, fcu);
|
||||
|
||||
/* free the F-Curve itself */
|
||||
free_fcurve(fcu);
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
BLI_freelistN(&anim_data);
|
||||
}
|
||||
|
||||
/* send notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void ANIM_OT_channels_delete (wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Delete Channels";
|
||||
ot->idname= "ANIM_OT_channels_delete";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= animchannels_delete_exec;
|
||||
ot->poll= animedit_poll_channels_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
/* ******************** Toggle Channel Visibility Operator *********************** */
|
||||
|
||||
@ -668,7 +823,7 @@ static int animchannels_visibility_toggle_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
/* filter data */
|
||||
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY);
|
||||
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL);
|
||||
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
|
||||
|
||||
/* See if we should be making showing all selected or hiding */
|
||||
@ -676,21 +831,35 @@ static int animchannels_visibility_toggle_exec(bContext *C, wmOperator *op)
|
||||
if (vis == ACHANNEL_SETFLAG_CLEAR)
|
||||
break;
|
||||
|
||||
if (ale->flag & FCURVE_VISIBLE)
|
||||
if ((ale->type == ANIMTYPE_FCURVE) && (ale->flag & FCURVE_VISIBLE))
|
||||
vis= ACHANNEL_SETFLAG_CLEAR;
|
||||
else if ((ale->type == ANIMTYPE_GROUP) && !(ale->flag & AGRP_NOTVISIBLE))
|
||||
vis= ACHANNEL_SETFLAG_CLEAR;
|
||||
}
|
||||
|
||||
/* Now set the flags */
|
||||
for (ale= anim_data.first; ale; ale= ale->next) {
|
||||
switch (ale->type) {
|
||||
case ANIMTYPE_FCURVE: /* F-Curve */
|
||||
{
|
||||
FCurve *fcu= (FCurve *)ale->data;
|
||||
ACHANNEL_SET_FLAG(fcu, vis, FCURVE_VISIBLE);
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_GROUP: /* Group */
|
||||
{
|
||||
bActionGroup *agrp= (bActionGroup *)ale->data;
|
||||
ACHANNEL_SET_FLAG_NEG(agrp, vis, AGRP_NOTVISIBLE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
BLI_freelistN(&anim_data);
|
||||
|
||||
/* set notifier tha things have changed */
|
||||
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
||||
/* send notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@ -889,6 +1058,12 @@ static void setflag_anim_channels (bAnimContext *ac, short setting, short mode,
|
||||
case ACHANNEL_SETTING_EXPAND:
|
||||
ACHANNEL_SET_FLAG(agrp, mode, AGRP_EXPANDED);
|
||||
break;
|
||||
case ACHANNEL_SETTING_MUTE:
|
||||
ACHANNEL_SET_FLAG(agrp, mode, AGRP_MUTED);
|
||||
break;
|
||||
case ACHANNEL_SETTING_VISIBLE:
|
||||
ACHANNEL_SET_FLAG_NEG(agrp, mode, AGRP_NOTVISIBLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -947,8 +1122,8 @@ static int animchannels_setflag_exec(bContext *C, wmOperator *op)
|
||||
/* modify setting */
|
||||
setflag_anim_channels(&ac, setting, mode, 1);
|
||||
|
||||
/* set notifier tha things have changed */
|
||||
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
||||
/* send notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@ -963,7 +1138,7 @@ void ANIM_OT_channels_setting_enable (wmOperatorType *ot)
|
||||
/* api callbacks */
|
||||
ot->invoke= WM_menu_invoke;
|
||||
ot->exec= animchannels_setflag_exec;
|
||||
ot->poll= ED_operator_areaactive;
|
||||
ot->poll= animedit_poll_channels_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
@ -984,7 +1159,7 @@ void ANIM_OT_channels_setting_disable (wmOperatorType *ot)
|
||||
/* api callbacks */
|
||||
ot->invoke= WM_menu_invoke;
|
||||
ot->exec= animchannels_setflag_exec;
|
||||
ot->poll= ED_operator_areaactive;
|
||||
ot->poll= animedit_poll_channels_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
@ -1005,7 +1180,7 @@ void ANIM_OT_channels_setting_toggle (wmOperatorType *ot)
|
||||
/* api callbacks */
|
||||
ot->invoke= WM_menu_invoke;
|
||||
ot->exec= animchannels_setflag_exec;
|
||||
ot->poll= ED_operator_areaactive;
|
||||
ot->poll= animedit_poll_channels_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
@ -1026,7 +1201,7 @@ void ANIM_OT_channels_editable_toggle (wmOperatorType *ot)
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= animchannels_setflag_exec;
|
||||
ot->poll= ED_operator_areaactive;
|
||||
ot->poll= animedit_poll_channels_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
@ -1056,8 +1231,8 @@ static int animchannels_expand_exec (bContext *C, wmOperator *op)
|
||||
/* modify setting */
|
||||
setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_ADD, onlysel);
|
||||
|
||||
/* set notifier that things have changed */
|
||||
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
||||
/* send notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@ -1070,7 +1245,7 @@ void ANIM_OT_channels_expand (wmOperatorType *ot)
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= animchannels_expand_exec;
|
||||
ot->poll= ED_operator_areaactive;
|
||||
ot->poll= animedit_poll_channels_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
@ -1097,8 +1272,8 @@ static int animchannels_collapse_exec (bContext *C, wmOperator *op)
|
||||
/* modify setting */
|
||||
setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_CLEAR, onlysel);
|
||||
|
||||
/* set notifier that things have changed */
|
||||
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
||||
/* send notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@ -1111,7 +1286,7 @@ void ANIM_OT_channels_collapse (wmOperatorType *ot)
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= animchannels_collapse_exec;
|
||||
ot->poll= ED_operator_areaactive;
|
||||
ot->poll= animedit_poll_channels_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
@ -1136,8 +1311,8 @@ static int animchannels_deselectall_exec(bContext *C, wmOperator *op)
|
||||
else
|
||||
ANIM_deselect_anim_channels(ac.data, ac.datatype, 1, ACHANNEL_SETFLAG_ADD);
|
||||
|
||||
/* set notifier tha things have changed */
|
||||
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
||||
/* send notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_SELECT, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@ -1150,7 +1325,7 @@ void ANIM_OT_channels_select_all_toggle (wmOperatorType *ot)
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= animchannels_deselectall_exec;
|
||||
ot->poll= ED_operator_areaactive;
|
||||
ot->poll= animedit_poll_channels_nla_tweakmode_off;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
@ -1218,6 +1393,14 @@ static void borderselect_anim_channels (bAnimContext *ac, rcti *rect, short sele
|
||||
ACHANNEL_SET_FLAG(gpl, selectmode, GP_LAYER_SELECT);
|
||||
}
|
||||
break;
|
||||
|
||||
case ANIMTYPE_NLATRACK: /* nla-track */
|
||||
{
|
||||
NlaTrack *nlt= (NlaTrack *)ale->data;
|
||||
|
||||
ACHANNEL_SET_FLAG(nlt, selectmode, NLATRACK_SELECTED);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1257,6 +1440,9 @@ static int animchannels_borderselect_exec(bContext *C, wmOperator *op)
|
||||
/* apply borderselect animation channels */
|
||||
borderselect_anim_channels(&ac, &rect, selectmode);
|
||||
|
||||
/* send notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_SELECT, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@ -1271,7 +1457,7 @@ void ANIM_OT_channels_select_border(wmOperatorType *ot)
|
||||
ot->exec= animchannels_borderselect_exec;
|
||||
ot->modal= WM_border_select_modal;
|
||||
|
||||
ot->poll= ED_operator_areaactive;
|
||||
ot->poll= animedit_poll_channels_nla_tweakmode_off;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
@ -1291,11 +1477,12 @@ void ANIM_OT_channels_select_border(wmOperatorType *ot)
|
||||
* NOTE: eventually, this should probably be phased out when many of these things are replaced with buttons
|
||||
*/
|
||||
|
||||
static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, short selectmode)
|
||||
static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, short selectmode)
|
||||
{
|
||||
ListBase anim_data = {NULL, NULL};
|
||||
bAnimListElem *ale;
|
||||
int filter;
|
||||
int notifierFlags = 0;
|
||||
|
||||
/* get the channel that was clicked on */
|
||||
/* filter channels */
|
||||
@ -1309,7 +1496,7 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
printf("Error: animation channel (index = %d) not found in mouse_anim_channels() \n", channel_index);
|
||||
|
||||
BLI_freelistN(&anim_data);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* selectmode -1 is a special case for ActionGroups only, which selects all of the channels underneath it only... */
|
||||
@ -1317,7 +1504,7 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
if ((selectmode == -1) && (ale->type != ANIMTYPE_GROUP)) {
|
||||
/* normal channels should not behave normally in this case */
|
||||
BLI_freelistN(&anim_data);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* action to take depends on what channel we've got */
|
||||
@ -1329,6 +1516,8 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
if (x < 16) {
|
||||
/* toggle expand */
|
||||
sce->flag ^= SCE_DS_COLLAPSED;
|
||||
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
else {
|
||||
/* set selection status */
|
||||
@ -1339,6 +1528,8 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
else {
|
||||
sce->flag |= SCE_DS_SELECTED;
|
||||
}
|
||||
|
||||
notifierFlags |= ND_ANIMCHAN_SELECT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1352,6 +1543,8 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
if (x < 16) {
|
||||
/* toggle expand */
|
||||
ob->nlaflag ^= OB_ADS_COLLAPSED; // XXX
|
||||
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
else {
|
||||
/* set selection status */
|
||||
@ -1376,6 +1569,8 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
|
||||
/* xxx should be ED_base_object_activate(), but we need context pointer for that... */
|
||||
//set_active_base(base);
|
||||
|
||||
notifierFlags |= ND_ANIMCHAN_SELECT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1383,18 +1578,21 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
{
|
||||
bAction *act= (bAction *)ale->data;
|
||||
act->flag ^= ACT_COLLAPSED;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_FILLDRIVERS:
|
||||
{
|
||||
AnimData *adt= (AnimData* )ale->data;
|
||||
adt->flag ^= ADT_DRIVERS_COLLAPSED;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_FILLMATD:
|
||||
{
|
||||
Object *ob= (Object *)ale->data;
|
||||
ob->nlaflag ^= OB_ADS_SHOWMATS; // XXX
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1402,36 +1600,42 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
{
|
||||
Material *ma= (Material *)ale->data;
|
||||
ma->flag ^= MA_DS_EXPAND;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_DSLAM:
|
||||
{
|
||||
Lamp *la= (Lamp *)ale->data;
|
||||
la->flag ^= LA_DS_EXPAND;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_DSCAM:
|
||||
{
|
||||
Camera *ca= (Camera *)ale->data;
|
||||
ca->flag ^= CAM_DS_EXPAND;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_DSCUR:
|
||||
{
|
||||
Curve *cu= (Curve *)ale->data;
|
||||
cu->flag ^= CU_DS_EXPAND;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_DSSKEY:
|
||||
{
|
||||
Key *key= (Key *)ale->data;
|
||||
key->flag ^= KEYBLOCK_DS_EXPAND;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_DSWOR:
|
||||
{
|
||||
World *wo= (World *)ale->data;
|
||||
wo->flag ^= WO_DS_EXPAND;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1443,10 +1647,22 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
if ((x < (offset+17)) && (agrp->channels.first)) {
|
||||
/* toggle expand */
|
||||
agrp->flag ^= AGRP_EXPANDED;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
else if ((x < (offset+32)) && (ac->spacetype==SPACE_IPO)) {
|
||||
/* toggle visibility (of grouped F-Curves in Graph editor) */
|
||||
agrp->flag ^= AGRP_NOTVISIBLE;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
else if (x >= (ACHANNEL_NAMEWIDTH-ACHANNEL_BUTTON_WIDTH)) {
|
||||
/* toggle protection/locking */
|
||||
agrp->flag ^= AGRP_PROTECTED;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
else if (x >= (ACHANNEL_NAMEWIDTH-2*ACHANNEL_BUTTON_WIDTH)) {
|
||||
/* toggle mute */
|
||||
agrp->flag ^= AGRP_MUTED;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
else {
|
||||
/* select/deselect group */
|
||||
@ -1474,7 +1690,9 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
|
||||
/* if group is selected now, make group the 'active' one in the visible list */
|
||||
if (agrp->flag & AGRP_SELECTED)
|
||||
ANIM_set_active_channel(ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
|
||||
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
|
||||
|
||||
notifierFlags |= ND_ANIMCHAN_SELECT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1495,16 +1713,20 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
|
||||
if (x >= (ACHANNEL_NAMEWIDTH-ACHANNEL_BUTTON_WIDTH)) {
|
||||
/* toggle protection (only if there's a toggle there) */
|
||||
if (fcu->bezt)
|
||||
if (fcu->bezt) {
|
||||
fcu->flag ^= FCURVE_PROTECTED;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
}
|
||||
else if (x >= (ACHANNEL_NAMEWIDTH-2*ACHANNEL_BUTTON_WIDTH)) {
|
||||
/* toggle mute */
|
||||
fcu->flag ^= FCURVE_MUTED;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
else if ((x < (offset+17)) && (ac->spacetype==SPACE_IPO)) {
|
||||
/* toggle visibility */
|
||||
fcu->flag ^= FCURVE_VISIBLE;
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
else {
|
||||
/* select/deselect */
|
||||
@ -1520,7 +1742,9 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
|
||||
/* if F-Curve is selected now, make F-Curve the 'active' one in the visible list */
|
||||
if (fcu->flag & FCURVE_SELECTED)
|
||||
ANIM_set_active_channel(ac->data, ac->datatype, filter, fcu, ANIMTYPE_FCURVE);
|
||||
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ANIMTYPE_FCURVE);
|
||||
|
||||
notifierFlags |= ND_ANIMCHAN_SELECT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1530,6 +1754,8 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
|
||||
/* toggle expand */
|
||||
gpd->flag ^= GP_DATA_EXPAND;
|
||||
|
||||
notifierFlags |= ND_ANIMCHAN_EDIT;
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_GPLAYER:
|
||||
@ -1568,6 +1794,9 @@ static void mouse_anim_channels (bAnimContext *ac, float x, int channel_index, s
|
||||
|
||||
/* free channels */
|
||||
BLI_freelistN(&anim_data);
|
||||
|
||||
/* return notifier flags */
|
||||
return notifierFlags;
|
||||
}
|
||||
|
||||
/* ------------------- */
|
||||
@ -1580,6 +1809,7 @@ static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, wmEvent *
|
||||
ARegion *ar;
|
||||
View2D *v2d;
|
||||
int mval[2], channel_index;
|
||||
int notifierFlags = 0;
|
||||
short selectmode;
|
||||
float x, y;
|
||||
|
||||
@ -1614,10 +1844,10 @@ static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, wmEvent *
|
||||
UI_view2d_listview_view_to_cell(v2d, ACHANNEL_NAMEWIDTH, ACHANNEL_STEP, 0, (float)ACHANNEL_HEIGHT_HALF, x, y, NULL, &channel_index);
|
||||
|
||||
/* handle mouse-click in the relevant channel then */
|
||||
mouse_anim_channels(&ac, x, channel_index, selectmode);
|
||||
notifierFlags= mouse_anim_channels(&ac, x, channel_index, selectmode);
|
||||
|
||||
/* set notifier tha things have changed */
|
||||
ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_CHANNELS);
|
||||
/* set notifier that things have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|notifierFlags, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@ -1630,7 +1860,7 @@ void ANIM_OT_channels_click (wmOperatorType *ot)
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke= animchannels_mouseclick_invoke;
|
||||
ot->poll= ED_operator_areaactive;
|
||||
ot->poll= animedit_poll_channels_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
@ -1653,6 +1883,8 @@ void ED_operatortypes_animchannels(void)
|
||||
WM_operatortype_append(ANIM_OT_channels_setting_disable);
|
||||
WM_operatortype_append(ANIM_OT_channels_setting_toggle);
|
||||
|
||||
WM_operatortype_append(ANIM_OT_channels_delete);
|
||||
|
||||
// XXX does this need to be a separate operator?
|
||||
WM_operatortype_append(ANIM_OT_channels_editable_toggle);
|
||||
|
||||
@ -1686,6 +1918,10 @@ void ED_keymap_animchannels(wmWindowManager *wm)
|
||||
/* borderselect */
|
||||
WM_keymap_add_item(keymap, "ANIM_OT_channels_select_border", BKEY, KM_PRESS, 0, 0);
|
||||
|
||||
/* delete */
|
||||
WM_keymap_add_item(keymap, "ANIM_OT_channels_delete", XKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "ANIM_OT_channels_delete", DELKEY, KM_PRESS, 0, 0);
|
||||
|
||||
/* settings */
|
||||
WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_toggle", WKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_enable", WKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
|
||||
|
@ -77,72 +77,6 @@ void ED_anim_object_flush_update(const bContext *C, Object *ob)
|
||||
}
|
||||
|
||||
|
||||
/* **************************** animation tool notifiers ******************************** */
|
||||
|
||||
/* Send notifiers on behalf of animation editing tools, based on various context info
|
||||
* - data_changed: eAnimData_Changed
|
||||
*/
|
||||
void ANIM_animdata_send_notifiers (bContext *C, bAnimContext *ac, short data_changed)
|
||||
{
|
||||
/* types of notifiers to send, depends on the editor context */
|
||||
switch (ac->datatype) {
|
||||
case ANIMCONT_DOPESHEET: /* dopesheet */
|
||||
case ANIMCONT_FCURVES: /* fcurve editor */
|
||||
case ANIMCONT_DRIVERS: /* drivers editor */ // XXX probably this will need separate handling, since these are part of dependency system
|
||||
{
|
||||
/* what action was taken */
|
||||
switch (data_changed) {
|
||||
case ANIM_CHANGED_KEYFRAMES_VALUES:
|
||||
/* keyframe values changed, so transform may have changed */
|
||||
// XXX what about other cases? maybe we need general ND_KEYFRAMES or ND_ANIMATION?
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS|ND_TRANSFORM, NULL);
|
||||
break;
|
||||
case ANIM_CHANGED_KEYFRAMES_SELECT:
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, NULL);
|
||||
break;
|
||||
case ANIM_CHANGED_CHANNELS:
|
||||
// XXX err... check available datatypes in dopesheet first?
|
||||
// FIXME: this currently doesn't work (to update own view)
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE|ND_OB_SELECT, ac->scene);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE|ND_BONE_SELECT, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
// XXX for now, at least update own editor!
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
}
|
||||
break;
|
||||
|
||||
case ANIMCONT_ACTION: /* action editor */
|
||||
{
|
||||
Object *obact= CTX_data_active_object(C);
|
||||
|
||||
switch (data_changed) {
|
||||
case ANIM_CHANGED_KEYFRAMES_VALUES:
|
||||
/* keyframe values changed, so transform may have changed */
|
||||
// XXX what about other cases? maybe we need general ND_KEYFRAMES or ND_ANIMATION?
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS|ND_TRANSFORM, obact);
|
||||
break;
|
||||
case ANIM_CHANGED_KEYFRAMES_SELECT:
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, obact);
|
||||
break;
|
||||
case ANIM_CHANGED_CHANNELS:
|
||||
// XXX err... check available datatypes in dopesheet first?
|
||||
// FIXME: this currently doesn't work (to update own view)
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE|ND_BONE_SELECT, obact);
|
||||
break;
|
||||
}
|
||||
|
||||
// XXX for now, at least update own editor!
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* some other data... just update area for now */
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
}
|
||||
}
|
||||
|
||||
/* **************************** pose <-> action syncing ******************************** */
|
||||
/* Summary of what needs to be synced between poses and actions:
|
||||
* 1) Flags
|
||||
@ -152,6 +86,10 @@ void ANIM_animdata_send_notifiers (bContext *C, bAnimContext *ac, short data_cha
|
||||
* 3) Grouping (only for pose to action for now)
|
||||
*/
|
||||
|
||||
/* XXX OBSOLETE CODE WARNING:
|
||||
* With the Animato system, the code below is somewhat obsolete now...
|
||||
*/
|
||||
|
||||
/* Notifier from Action/Dopesheet (this may be extended to include other things such as Python...)
|
||||
* Channels in action changed, so update pose channels/groups to reflect changes.
|
||||
*
|
||||
|
@ -43,10 +43,12 @@
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_nla.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_utildefines.h"
|
||||
@ -165,7 +167,7 @@ void ANIM_draw_cfra (const bContext *C, View2D *v2d, short flag)
|
||||
glLineWidth(2.0);
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
vec[1]= v2d->cur.ymin;
|
||||
vec[1]= v2d->cur.ymin-500.0f; /* XXX arbitrary... want it go to bottom */
|
||||
glVertex2fv(vec);
|
||||
|
||||
vec[1]= v2d->cur.ymax;
|
||||
@ -232,37 +234,16 @@ void ANIM_draw_previewrange (const bContext *C, View2D *v2d)
|
||||
/* *************************************************** */
|
||||
/* NLA-MAPPING UTILITIES (required for drawing and also editing keyframes) */
|
||||
|
||||
/* Obtain the Object providing NLA-scaling for the given channel (if applicable) */
|
||||
Object *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale)
|
||||
/* Obtain the AnimData block providing NLA-mapping for the given channel (if applicable) */
|
||||
AnimData *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale)
|
||||
{
|
||||
/* sanity checks */
|
||||
if (ac == NULL)
|
||||
return NULL;
|
||||
|
||||
/* handling depends on the type of animation-context we've got */
|
||||
if (ac->datatype == ANIMCONT_ACTION) {
|
||||
/* Action Editor (action mode) or Graph Editor (ipo mode):
|
||||
* Only use if editor is not pinned, and active object has action
|
||||
*/
|
||||
if (ac->obact && ac->obact->action) {
|
||||
SpaceAction *saction= (SpaceAction *)ac->sa->spacedata.first;
|
||||
|
||||
if (saction->pin == 0)
|
||||
return ac->obact;
|
||||
}
|
||||
}
|
||||
else if ((ac->datatype == ANIMCONT_DOPESHEET) && (ale)) {
|
||||
/* Dopesheet:
|
||||
* Only if channel is available, and is owned by an Object with an Action
|
||||
*/
|
||||
if ((ale->id) && (GS(ale->id->name) == ID_OB)) {
|
||||
Object *ob= (Object *)ale->id;
|
||||
|
||||
if (ob->action)
|
||||
return ob;
|
||||
}
|
||||
}
|
||||
// XXX todo: add F-Curves mode (Graph Editor) ...
|
||||
if (ale && ale->id)
|
||||
return BKE_animdata_from_id(ale->id);
|
||||
|
||||
/* no appropriate object found */
|
||||
return NULL;
|
||||
@ -273,7 +254,8 @@ Object *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale)
|
||||
* (where this is called) is single-threaded anyway
|
||||
*/
|
||||
// XXX was called: map_active_strip()
|
||||
void ANIM_nla_mapping_draw(gla2DDrawInfo *di, Object *ob, short restore)
|
||||
// TODO: should this be depreceated?
|
||||
void ANIM_nla_mapping_draw(gla2DDrawInfo *di, AnimData *adt, short restore)
|
||||
{
|
||||
static rctf stored;
|
||||
|
||||
@ -288,8 +270,8 @@ void ANIM_nla_mapping_draw(gla2DDrawInfo *di, Object *ob, short restore)
|
||||
gla2DGetMap(di, &stored);
|
||||
map= stored;
|
||||
|
||||
map.xmin= get_action_frame(ob, map.xmin);
|
||||
map.xmax= get_action_frame(ob, map.xmax);
|
||||
map.xmin= BKE_nla_tweakedit_remap(adt, map.xmin, NLATIME_CONVERT_MAP);
|
||||
map.xmax= BKE_nla_tweakedit_remap(adt, map.xmax, NLATIME_CONVERT_MAP);
|
||||
|
||||
if (map.xmin == map.xmax) map.xmax += 1.0f;
|
||||
gla2DSetMap(di, &map);
|
||||
@ -298,36 +280,38 @@ void ANIM_nla_mapping_draw(gla2DDrawInfo *di, Object *ob, short restore)
|
||||
|
||||
/* ------------------- */
|
||||
|
||||
/* helper function for ANIM_nla_mapping_apply_ipocurve() -> "restore", i.e. mapping points back to IPO-time */
|
||||
/* helper function for ANIM_nla_mapping_apply_fcurve() -> "restore", i.e. mapping points back to action-time */
|
||||
static short bezt_nlamapping_restore(BeztEditData *bed, BezTriple *bezt)
|
||||
{
|
||||
/* object providing scaling is stored in 'data', only_keys option is stored in i1 */
|
||||
Object *ob= (Object *)bed->data;
|
||||
/* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */
|
||||
AnimData *adt= (AnimData *)bed->data;
|
||||
short only_keys= (short)bed->i1;
|
||||
|
||||
/* adjust BezTriple handles only if allowed to */
|
||||
if (only_keys == 0) {
|
||||
bezt->vec[0][0]= get_action_frame(ob, bezt->vec[0][0]);
|
||||
bezt->vec[2][0]= get_action_frame(ob, bezt->vec[2][0]);
|
||||
bezt->vec[0][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[0][0], NLATIME_CONVERT_UNMAP);
|
||||
bezt->vec[2][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[2][0], NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
bezt->vec[1][0]= get_action_frame(ob, bezt->vec[1][0]);
|
||||
|
||||
bezt->vec[1][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[1][0], NLATIME_CONVERT_UNMAP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* helper function for ANIM_nla_mapping_apply_ipocurve() -> "apply", i.e. mapping points to NLA-mapped global time */
|
||||
/* helper function for ANIM_nla_mapping_apply_fcurve() -> "apply", i.e. mapping points to NLA-mapped global time */
|
||||
static short bezt_nlamapping_apply(BeztEditData *bed, BezTriple *bezt)
|
||||
{
|
||||
/* object providing scaling is stored in 'data', only_keys option is stored in i1 */
|
||||
Object *ob= (Object *)bed->data;
|
||||
/* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */
|
||||
AnimData *adt= (AnimData *)bed->data;
|
||||
short only_keys= (short)bed->i1;
|
||||
|
||||
/* adjust BezTriple handles only if allowed to */
|
||||
if (only_keys == 0) {
|
||||
bezt->vec[0][0]= get_action_frame_inv(ob, bezt->vec[0][0]);
|
||||
bezt->vec[2][0]= get_action_frame_inv(ob, bezt->vec[2][0]);
|
||||
bezt->vec[0][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[0][0], NLATIME_CONVERT_MAP);
|
||||
bezt->vec[2][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[2][0], NLATIME_CONVERT_MAP);
|
||||
}
|
||||
bezt->vec[1][0]= get_action_frame_inv(ob, bezt->vec[1][0]);
|
||||
|
||||
bezt->vec[1][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[1][0], NLATIME_CONVERT_MAP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -338,17 +322,17 @@ static short bezt_nlamapping_apply(BeztEditData *bed, BezTriple *bezt)
|
||||
* - restore = whether to map points back to non-mapped time
|
||||
* - only_keys = whether to only adjust the location of the center point of beztriples
|
||||
*/
|
||||
void ANIM_nla_mapping_apply_fcurve(Object *ob, FCurve *fcu, short restore, short only_keys)
|
||||
void ANIM_nla_mapping_apply_fcurve (AnimData *adt, FCurve *fcu, short restore, short only_keys)
|
||||
{
|
||||
BeztEditData bed;
|
||||
BeztEditFunc map_cb;
|
||||
|
||||
/* init edit data
|
||||
* - ob is stored in 'data'
|
||||
* - AnimData is stored in 'data'
|
||||
* - only_keys is stored in 'i1'
|
||||
*/
|
||||
memset(&bed, 0, sizeof(BeztEditData));
|
||||
bed.data= (void *)ob;
|
||||
bed.data= (void *)adt;
|
||||
bed.i1= (int)only_keys;
|
||||
|
||||
/* get editing callback */
|
||||
|
@ -195,7 +195,7 @@ static short actedit_get_context (bAnimContext *ac, SpaceAction *saction)
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------- Private Stuff - IPO Editor ------------- */
|
||||
/* ----------- Private Stuff - Graph Editor ------------- */
|
||||
|
||||
/* Get data being edited in Graph Editor (depending on current 'mode') */
|
||||
static short graphedit_get_context (bAnimContext *ac, SpaceIpo *sipo)
|
||||
@ -237,6 +237,26 @@ static short graphedit_get_context (bAnimContext *ac, SpaceIpo *sipo)
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------- Private Stuff - NLA Editor ------------- */
|
||||
|
||||
/* Get data being edited in Graph Editor (depending on current 'mode') */
|
||||
static short nlaedit_get_context (bAnimContext *ac, SpaceNla *snla)
|
||||
{
|
||||
/* init dopesheet data if non-existant (i.e. for old files) */
|
||||
if (snla->ads == NULL)
|
||||
snla->ads= MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet");
|
||||
|
||||
/* sync settings with current view status, then return appropriate data */
|
||||
/* update scene-pointer (no need to check for pinning yet, as not implemented) */
|
||||
snla->ads->source= (ID *)ac->scene;
|
||||
snla->ads->filterflag |= ADS_FILTER_ONLYNLA;
|
||||
|
||||
ac->datatype= ANIMCONT_NLA;
|
||||
ac->data= snla->ads;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ----------- Public API --------------- */
|
||||
|
||||
/* Obtain current anim-data context, given that context info from Blender context has already been set
|
||||
@ -264,6 +284,13 @@ short ANIM_animdata_context_getdata (bAnimContext *ac)
|
||||
ok= graphedit_get_context(ac, sipo);
|
||||
}
|
||||
break;
|
||||
|
||||
case SPACE_NLA:
|
||||
{
|
||||
SpaceNla *snla= (SpaceNla *)sa->spacedata.first;
|
||||
ok= nlaedit_get_context(ac, snla);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -313,6 +340,68 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
|
||||
/* quick macro to test if AnimData is usable for drivers */
|
||||
#define ANIMDATA_HAS_DRIVERS(id) ((id)->adt && (id)->adt->drivers.first)
|
||||
|
||||
/* quick macro to test if AnimData is usable for NLA */
|
||||
#define ANIMDATA_HAS_NLA(id) ((id)->adt && (id)->adt->nla_tracks.first)
|
||||
|
||||
|
||||
/* Quick macro to test for all three avove usability tests, performing the appropriate provided
|
||||
* action for each when the AnimData context is appropriate.
|
||||
*
|
||||
* Priority order for this goes (most important, to least): AnimData blocks, NLA, Drivers, Keyframes.
|
||||
*
|
||||
* For this to work correctly, a standard set of data needs to be available within the scope that this
|
||||
* gets called in:
|
||||
* - ListBase anim_data;
|
||||
* - bDopeSheet *ads;
|
||||
* - bAnimListElem *ale;
|
||||
* - int items;
|
||||
*
|
||||
* - id: ID block which should have an AnimData pointer following it immediately, to use
|
||||
* - adtOk: line or block of code to execute for AnimData-blocks case (usually ANIMDATA_ADD_ANIMDATA)
|
||||
* - nlaOk: line or block of code to execute for NLA case
|
||||
* - driversOk: line or block of code to execute for Drivers case
|
||||
* - keysOk: line or block of code for Keyframes case
|
||||
*/
|
||||
#define ANIMDATA_FILTER_CASES(id, adtOk, nlaOk, driversOk, keysOk) \
|
||||
{\
|
||||
if (filter_mode & ANIMFILTER_ANIMDATA) {\
|
||||
if ((id)->adt) {\
|
||||
adtOk\
|
||||
}\
|
||||
}\
|
||||
else if (ads->filterflag & ADS_FILTER_ONLYNLA) {\
|
||||
if (ANIMDATA_HAS_NLA(id)) {\
|
||||
nlaOk\
|
||||
}\
|
||||
else if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) && ANIMDATA_HAS_KEYS(id)) {\
|
||||
nlaOk\
|
||||
}\
|
||||
}\
|
||||
else if (ads->filterflag & ADS_FILTER_ONLYDRIVERS) {\
|
||||
if (ANIMDATA_HAS_DRIVERS(id)) {\
|
||||
driversOk\
|
||||
}\
|
||||
}\
|
||||
else {\
|
||||
if (ANIMDATA_HAS_KEYS(id)) {\
|
||||
keysOk\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
/* quick macro to add a pointer to an AnimData block as a channel */
|
||||
#define ANIMDATA_ADD_ANIMDATA(id) \
|
||||
{\
|
||||
ale= make_new_animlistelem((id)->adt, ANIMTYPE_ANIMDATA, NULL, ANIMTYPE_NONE, (ID *)id);\
|
||||
if (ale) {\
|
||||
BLI_addtail(anim_data, ale);\
|
||||
items++;\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* quick macro to test if a anim-channel (F-Curve, Group, etc.) is selected in an acceptable way */
|
||||
#define ANIMCHANNEL_SELOK(test_func) \
|
||||
( !(filter_mode & (ANIMFILTER_SEL|ANIMFILTER_UNSEL)) || \
|
||||
@ -494,6 +583,25 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s
|
||||
ale->datatype= ALE_GPFRAME;
|
||||
}
|
||||
break;
|
||||
|
||||
case ANIMTYPE_NLATRACK:
|
||||
{
|
||||
NlaTrack *nlt= (NlaTrack *)data;
|
||||
|
||||
ale->flag= nlt->flag;
|
||||
|
||||
// XXX or should this be done some other way?
|
||||
ale->key_data= &nlt->strips;
|
||||
ale->datatype= ALE_NLASTRIP;
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_NLAACTION:
|
||||
{
|
||||
/* nothing to include for now... nothing editable from NLA-perspective here */
|
||||
ale->key_data= NULL;
|
||||
ale->datatype= ALE_NONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -522,7 +630,6 @@ static int animdata_filter_fcurves (ListBase *anim_data, FCurve *first, bActionG
|
||||
if ( ANIMCHANNEL_SELOK(SEL_FCU(fcu)) ) {
|
||||
/* only include if this curve is active */
|
||||
if (!(filter_mode & ANIMFILTER_ACTIVE) || (fcu->flag & FCURVE_ACTIVE)) {
|
||||
/* owner/ownertype will be either object or action-channel, depending if it was dopesheet or part of an action */
|
||||
ale= make_new_animlistelem(fcu, ANIMTYPE_FCURVE, owner, ownertype, owner_id);
|
||||
|
||||
if (ale) {
|
||||
@ -575,11 +682,15 @@ static int animdata_filter_action (ListBase *anim_data, bAction *act, int filter
|
||||
* cases when we should include F-Curves inside group:
|
||||
* - we don't care about visibility
|
||||
* - group is expanded
|
||||
* - we're interested in keyframes, but not if they appear in selected channels
|
||||
* - we just need the F-Curves present
|
||||
*/
|
||||
// XXX what was the selection check here for again?
|
||||
if ( (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_AGRP(agrp)) ||
|
||||
( /*ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) &&*/ (filter_mode & ANIMFILTER_CURVESONLY) ) )
|
||||
if ( (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_AGRP(agrp)) || (filter_mode & ANIMFILTER_CURVESONLY) )
|
||||
{
|
||||
/* for the Graph Editor, curves may be set to not be visible in the view to lessen clutter,
|
||||
* but to do this, we need to check that the group doesn't have it's not-visible flag set preventing
|
||||
* all its sub-curves to be shown
|
||||
*/
|
||||
if ( !(filter_mode & ANIMFILTER_CURVEVISIBLE) || !(agrp->flag & AGRP_NOTVISIBLE) )
|
||||
{
|
||||
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {
|
||||
// XXX the 'owner' info here needs review...
|
||||
@ -599,6 +710,7 @@ static int animdata_filter_action (ListBase *anim_data, bAction *act, int filter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* loop over un-grouped F-Curves (only if we're not only considering those channels in the animive group) */
|
||||
if (!(filter_mode & ANIMFILTER_ACTGROUPED)) {
|
||||
@ -610,6 +722,83 @@ static int animdata_filter_action (ListBase *anim_data, bAction *act, int filter
|
||||
return items;
|
||||
}
|
||||
|
||||
/* Include NLA-Data for NLA-Editor:
|
||||
* - when ANIMFILTER_CHANNELS is used, that means we should be filtering the list for display
|
||||
* Although the evaluation order is from the first track to the last and then apply the Action on top,
|
||||
* we present this in the UI as the Active Action followed by the last track to the first so that we
|
||||
* get the evaluation order presented as per a stack.
|
||||
* - for normal filtering (i.e. for editing), we only need the NLA-tracks but they can be in 'normal' evaluation
|
||||
* order, i.e. first to last. Otherwise, some tools may get screwed up.
|
||||
*/
|
||||
static int animdata_filter_nla (ListBase *anim_data, AnimData *adt, int filter_mode, void *owner, short ownertype, ID *owner_id)
|
||||
{
|
||||
bAnimListElem *ale;
|
||||
NlaTrack *nlt;
|
||||
NlaTrack *first=NULL, *next=NULL;
|
||||
int items = 0;
|
||||
|
||||
/* if showing channels, include active action */
|
||||
if (filter_mode & ANIMFILTER_CHANNELS) {
|
||||
/* there isn't really anything editable here, so skip if need editable */
|
||||
// TODO: currently, selection isn't checked since it doesn't matter
|
||||
if ((filter_mode & ANIMFILTER_FOREDIT) == 0) {
|
||||
/* just add the action track now (this MUST appear for drawing)
|
||||
* - as AnimData may not have an action, we pass a dummy pointer just to get the list elem created, then
|
||||
* overwrite this with the real value - REVIEW THIS...
|
||||
*/
|
||||
ale= make_new_animlistelem((void *)(&adt->action), ANIMTYPE_NLAACTION, owner, ownertype, owner_id);
|
||||
ale->data= (adt->action) ? adt->action : NULL;
|
||||
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
}
|
||||
}
|
||||
|
||||
/* first track to include will be the last one if we're filtering by channels */
|
||||
first= adt->nla_tracks.last;
|
||||
}
|
||||
else {
|
||||
/* first track to include will the the first one (as per normal) */
|
||||
first= adt->nla_tracks.first;
|
||||
}
|
||||
|
||||
/* loop over NLA Tracks - assume that the caller of this has already checked that these should be included */
|
||||
for (nlt= first; nlt; nlt= next) {
|
||||
/* 'next' NLA-Track to use depends on whether we're filtering for drawing or not */
|
||||
if (filter_mode & ANIMFILTER_CHANNELS)
|
||||
next= nlt->prev;
|
||||
else
|
||||
next= nlt->next;
|
||||
|
||||
/* if we're in NLA-tweakmode, don't show this track if it was disabled (due to tweaking) for now
|
||||
* - active track should still get shown though (even though it has disabled flag set)
|
||||
*/
|
||||
// FIXME: the channels after should still get drawn, just 'differently', and after an active-action channel
|
||||
if ((adt->flag & ADT_NLA_EDIT_ON) && (nlt->flag & NLATRACK_DISABLED) && !(nlt->flag & NLATRACK_ACTIVE))
|
||||
continue;
|
||||
|
||||
/* only work with this channel and its subchannels if it is editable */
|
||||
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_NLT(nlt)) {
|
||||
/* only include this track if selected in a way consistent with the filtering requirements */
|
||||
if ( ANIMCHANNEL_SELOK(SEL_NLT(nlt)) ) {
|
||||
/* only include if this track is active */
|
||||
if (!(filter_mode & ANIMFILTER_ACTIVE) || (nlt->flag & NLATRACK_ACTIVE)) {
|
||||
ale= make_new_animlistelem(nlt, ANIMTYPE_NLATRACK, owner, ownertype, owner_id);
|
||||
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* return the number of items added to the list */
|
||||
return items;
|
||||
}
|
||||
|
||||
static int animdata_filter_shapekey (ListBase *anim_data, Key *key, int filter_mode, void *owner, short ownertype, ID *owner_id)
|
||||
{
|
||||
bAnimListElem *ale;
|
||||
@ -752,19 +941,19 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads,
|
||||
/* firstly check that we actuallly have some materials, by gathering all materials in a temp list */
|
||||
for (a=0; a < ob->totcol; a++) {
|
||||
Material *ma= give_current_material(ob, a);
|
||||
short ok = 0;
|
||||
|
||||
/* for now, if no material returned, skip (this shouldn't confuse the user I hope) */
|
||||
if (ELEM(NULL, ma, ma->adt))
|
||||
continue;
|
||||
|
||||
if ((ads->filterflag & ADS_FILTER_ONLYDRIVERS)==0) {
|
||||
if (ANIMDATA_HAS_KEYS(ma) == 0)
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if (ANIMDATA_HAS_DRIVERS(ma) == 0)
|
||||
continue;
|
||||
}
|
||||
/* check if ok */
|
||||
ANIMDATA_FILTER_CASES(ma,
|
||||
{ /* AnimData blocks - do nothing... */ },
|
||||
ok=1;,
|
||||
ok=1;,
|
||||
ok=1;)
|
||||
if (ok == 0) continue;
|
||||
|
||||
/* make a temp list elem for this */
|
||||
ld= MEM_callocN(sizeof(LinkData), "DopeSheet-MaterialCache");
|
||||
@ -801,16 +990,13 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads,
|
||||
}
|
||||
}
|
||||
|
||||
/* add material's F-Curve or Driver channels? */
|
||||
/* add material's animation data */
|
||||
if (FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
if ((ads->filterflag & ADS_FILTER_ONLYDRIVERS)==0) {
|
||||
// XXX the 'owner' info here is still subject to improvement
|
||||
items += animdata_filter_action(anim_data, ma->adt->action, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);
|
||||
}
|
||||
else {
|
||||
// need to make the ownertype normal object here... (maybe type should be a separate one for clarity?)
|
||||
items += animdata_filter_fcurves(anim_data, ma->adt->drivers.first, NULL, ma, ANIMTYPE_DSMAT, filter_mode, (ID *)ma);
|
||||
}
|
||||
ANIMDATA_FILTER_CASES(ma,
|
||||
{ /* AnimData blocks - do nothing... */ },
|
||||
items += animdata_filter_nla(anim_data, ma->adt, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);,
|
||||
items += animdata_filter_fcurves(anim_data, ma->adt->drivers.first, NULL, ma, ANIMTYPE_DSMAT, filter_mode, (ID *)ma);,
|
||||
items += animdata_filter_action(anim_data, ma->adt->action, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -871,15 +1057,12 @@ static int animdata_filter_dopesheet_obdata (ListBase *anim_data, bDopeSheet *ad
|
||||
|
||||
/* add object-data animation channels? */
|
||||
if ((expanded) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
/* Action or Drivers? */
|
||||
if ((ads->filterflag & ADS_FILTER_ONLYDRIVERS) == 0) {
|
||||
// XXX the 'owner' info here is still subject to improvement
|
||||
items += animdata_filter_action(anim_data, iat->adt->action, filter_mode, iat, type, (ID *)iat);
|
||||
}
|
||||
else {
|
||||
// need to make the ownertype normal object here... (maybe type should be a separate one for clarity?)
|
||||
items += animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, iat, type, filter_mode, (ID *)iat);
|
||||
}
|
||||
/* filtering for channels - nla, drivers, keyframes */
|
||||
ANIMDATA_FILTER_CASES(iat,
|
||||
{ /* AnimData blocks - do nothing... */ },
|
||||
items+= animdata_filter_nla(anim_data, iat->adt, filter_mode, iat, type, (ID *)iat);,
|
||||
items+= animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, iat, type, filter_mode, (ID *)iat);,
|
||||
items += animdata_filter_action(anim_data, iat->adt->action, filter_mode, iat, type, (ID *)iat);)
|
||||
}
|
||||
|
||||
/* return the number of items added to the list */
|
||||
@ -889,12 +1072,14 @@ static int animdata_filter_dopesheet_obdata (ListBase *anim_data, bDopeSheet *ad
|
||||
static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
|
||||
{
|
||||
bAnimListElem *ale=NULL;
|
||||
AnimData *adt = NULL;
|
||||
Object *ob= base->object;
|
||||
Key *key= ob_get_key(ob);
|
||||
short obdata_ok = 0;
|
||||
int items = 0;
|
||||
|
||||
/* add this object as a channel first */
|
||||
if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {
|
||||
if ((filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) == 0) {
|
||||
/* check if filtering by selection */
|
||||
if ANIMCHANNEL_SELOK((base->flag & SELECT)) {
|
||||
ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE, NULL);
|
||||
@ -906,15 +1091,35 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
||||
}
|
||||
|
||||
/* if collapsed, don't go any further (unless adding keyframes only) */
|
||||
if ( (EXPANDED_OBJC(ob) == 0) && !(filter_mode & ANIMFILTER_CURVESONLY) )
|
||||
if ( (EXPANDED_OBJC(ob) == 0) && !(filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) )
|
||||
return items;
|
||||
|
||||
/* Action or Drivers */
|
||||
if ((ads->filterflag & ADS_FILTER_ONLYDRIVERS) == 0) {
|
||||
/* Action? */
|
||||
if (ANIMDATA_HAS_KEYS(ob) /*&& !(ads->filterflag & ADS_FILTER_NOACTS)*/) {
|
||||
AnimData *adt= ob->adt;
|
||||
/* Action, Drivers, or NLA */
|
||||
if (ob->adt) {
|
||||
adt= ob->adt;
|
||||
ANIMDATA_FILTER_CASES(ob,
|
||||
{ /* AnimData blocks - do nothing... */ },
|
||||
{ /* nla */
|
||||
/* add NLA tracks */
|
||||
items += animdata_filter_nla(anim_data, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
},
|
||||
{ /* drivers */
|
||||
/* include drivers-expand widget? */
|
||||
if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLDRIVERS, base, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
}
|
||||
}
|
||||
|
||||
/* add F-Curve channels (drivers are F-Curves) */
|
||||
if (EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) {
|
||||
// need to make the ownertype normal object here... (maybe type should be a separate one for clarity?)
|
||||
items += animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, ob, ANIMTYPE_OBJECT, filter_mode, (ID *)ob);
|
||||
}
|
||||
},
|
||||
{ /* action (keyframes) */
|
||||
/* include action-expand widget? */
|
||||
if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLACTD, base, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
@ -930,33 +1135,35 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
||||
items += animdata_filter_action(anim_data, adt->action, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
/* Drivers */
|
||||
if (ANIMDATA_HAS_DRIVERS(ob)) {
|
||||
AnimData *adt= ob->adt;
|
||||
|
||||
/* include drivers-expand widget? */
|
||||
|
||||
/* ShapeKeys? */
|
||||
if ((key) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
|
||||
adt= key->adt;
|
||||
ANIMDATA_FILTER_CASES(key,
|
||||
{ /* AnimData blocks - do nothing... */ },
|
||||
{ /* nla */
|
||||
/* add NLA tracks */
|
||||
items += animdata_filter_nla(anim_data, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
},
|
||||
{ /* drivers */
|
||||
/* include shapekey-expand widget? */
|
||||
if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLDRIVERS, base, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
}
|
||||
}
|
||||
|
||||
/* add F-Curve channels (drivers are F-Curves) */
|
||||
if (EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) {
|
||||
// need to make the ownertype normal object here... (maybe type should be a separate one for clarity?)
|
||||
items += animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, ob, ANIMTYPE_OBJECT, filter_mode, (ID *)ob);
|
||||
/* add channels */
|
||||
if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
items += animdata_filter_shapekey(anim_data, key, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ShapeKeys? */
|
||||
if ((key) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
|
||||
/* Animation or Drivers */
|
||||
if ((ads->filterflag & ADS_FILTER_ONLYDRIVERS) == 0) {
|
||||
},
|
||||
{ /* action (keyframes) */
|
||||
/* include shapekey-expand widget? */
|
||||
if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
@ -971,29 +1178,8 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
||||
items += animdata_filter_shapekey(anim_data, key, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Drivers */
|
||||
if (ANIMDATA_HAS_DRIVERS(key)) {
|
||||
AnimData *adt= key->adt;
|
||||
|
||||
/* include shapekey-expand widget? */
|
||||
if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* add F-Curve channels (drivers are F-Curves) */
|
||||
if (FILTER_SKE_OBJD(key)/*EXPANDED_DRVD(adt)*/ || !(filter_mode & ANIMFILTER_CHANNELS)) {
|
||||
// XXX owner info is messed up now...
|
||||
items += animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, ob, ANIMTYPE_OBJECT, filter_mode, (ID *)key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Materials? */
|
||||
if ((ob->totcol) && !(ads->filterflag & ADS_FILTER_NOMAT))
|
||||
@ -1006,14 +1192,11 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
||||
Camera *ca= (Camera *)ob->data;
|
||||
|
||||
if ((ads->filterflag & ADS_FILTER_NOCAM) == 0) {
|
||||
if ((ads->filterflag & ADS_FILTER_ONLYDRIVERS)==0) {
|
||||
if (ANIMDATA_HAS_KEYS(ca))
|
||||
items += animdata_filter_dopesheet_obdata(anim_data, ads, base, filter_mode);
|
||||
}
|
||||
else {
|
||||
if (ANIMDATA_HAS_DRIVERS(ca))
|
||||
items += animdata_filter_dopesheet_obdata(anim_data, ads, base, filter_mode);
|
||||
}
|
||||
ANIMDATA_FILTER_CASES(ca,
|
||||
{ /* AnimData blocks - do nothing... */ },
|
||||
obdata_ok= 1;,
|
||||
obdata_ok= 1;,
|
||||
obdata_ok= 1;)
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1022,14 +1205,11 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
||||
Lamp *la= (Lamp *)ob->data;
|
||||
|
||||
if ((ads->filterflag & ADS_FILTER_NOLAM) == 0) {
|
||||
if ((ads->filterflag & ADS_FILTER_ONLYDRIVERS)==0) {
|
||||
if (ANIMDATA_HAS_KEYS(la))
|
||||
items += animdata_filter_dopesheet_obdata(anim_data, ads, base, filter_mode);
|
||||
}
|
||||
else {
|
||||
if (ANIMDATA_HAS_DRIVERS(la))
|
||||
items += animdata_filter_dopesheet_obdata(anim_data, ads, base, filter_mode);
|
||||
}
|
||||
ANIMDATA_FILTER_CASES(la,
|
||||
{ /* AnimData blocks - do nothing... */ },
|
||||
obdata_ok= 1;,
|
||||
obdata_ok= 1;,
|
||||
obdata_ok= 1;)
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1038,18 +1218,17 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
||||
Curve *cu= (Curve *)ob->data;
|
||||
|
||||
if ((ads->filterflag & ADS_FILTER_NOCUR) == 0) {
|
||||
if ((ads->filterflag & ADS_FILTER_ONLYDRIVERS)==0) {
|
||||
if (ANIMDATA_HAS_KEYS(cu))
|
||||
items += animdata_filter_dopesheet_obdata(anim_data, ads, base, filter_mode);
|
||||
}
|
||||
else {
|
||||
if (ANIMDATA_HAS_DRIVERS(cu))
|
||||
items += animdata_filter_dopesheet_obdata(anim_data, ads, base, filter_mode);
|
||||
}
|
||||
ANIMDATA_FILTER_CASES(cu,
|
||||
{ /* AnimData blocks - do nothing... */ },
|
||||
obdata_ok= 1;,
|
||||
obdata_ok= 1;,
|
||||
obdata_ok= 1;)
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (obdata_ok)
|
||||
items += animdata_filter_dopesheet_obdata(anim_data, ads, base, filter_mode);
|
||||
|
||||
/* return the number of items added to the list */
|
||||
return items;
|
||||
@ -1058,11 +1237,12 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
||||
static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
|
||||
{
|
||||
World *wo= sce->world;
|
||||
AnimData *adt= NULL;
|
||||
bAnimListElem *ale;
|
||||
int items = 0;
|
||||
|
||||
/* add scene as a channel first (even if we aren't showing scenes we still need to show the scene's sub-data */
|
||||
if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {
|
||||
if ((filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) == 0) {
|
||||
/* check if filtering by selection */
|
||||
if (ANIMCHANNEL_SELOK( (sce->flag & SCE_DS_SELECTED) )) {
|
||||
ale= make_new_animlistelem(sce, ANIMTYPE_SCENE, NULL, ANIMTYPE_NONE, NULL);
|
||||
@ -1074,15 +1254,34 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads
|
||||
}
|
||||
|
||||
/* if collapsed, don't go any further (unless adding keyframes only) */
|
||||
if ( (EXPANDED_SCEC(sce) == 0) && !(filter_mode & ANIMFILTER_CURVESONLY) )
|
||||
if ( (EXPANDED_SCEC(sce) == 0) && !(filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) )
|
||||
return items;
|
||||
|
||||
/* Action or Drivers */
|
||||
if ((ads->filterflag & ADS_FILTER_ONLYDRIVERS) == 0) {
|
||||
/* Action? */
|
||||
if (ANIMDATA_HAS_KEYS(sce) && !(ads->filterflag & ADS_FILTER_NOSCE)) {
|
||||
AnimData *adt= sce->adt;
|
||||
/* Action, Drivers, or NLA for Scene */
|
||||
if ((ads->filterflag & ADS_FILTER_NOSCE) == 0) {
|
||||
adt= sce->adt;
|
||||
ANIMDATA_FILTER_CASES(sce,
|
||||
{ /* AnimData blocks - do nothing... */ },
|
||||
{ /* nla */
|
||||
/* add NLA tracks */
|
||||
items += animdata_filter_nla(anim_data, adt, filter_mode, sce, ANIMTYPE_SCENE, (ID *)sce);
|
||||
},
|
||||
{ /* drivers */
|
||||
/* include drivers-expand widget? */
|
||||
if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLDRIVERS, sce, ANIMTYPE_SCENE, (ID *)sce);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
}
|
||||
}
|
||||
|
||||
/* add F-Curve channels (drivers are F-Curves) */
|
||||
if (EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) {
|
||||
items += animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, sce, ANIMTYPE_SCENE, filter_mode, (ID *)sce);
|
||||
}
|
||||
},
|
||||
{ /* action */
|
||||
/* include action-expand widget? */
|
||||
if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLACTD, sce, ANIMTYPE_SCENE, (ID *)sce);
|
||||
@ -1097,15 +1296,23 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads
|
||||
items += animdata_filter_action(anim_data, adt->action, filter_mode, sce, ANIMTYPE_SCENE, (ID *)sce);
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
else {
|
||||
/* Drivers */
|
||||
if (ANIMDATA_HAS_DRIVERS(sce) && !(ads->filterflag & ADS_FILTER_NOSCE)) {
|
||||
AnimData *adt= sce->adt;
|
||||
|
||||
/* include drivers-expand widget? */
|
||||
/* world */
|
||||
if ((wo && wo->adt) && !(ads->filterflag & ADS_FILTER_NOWOR)) {
|
||||
/* Action, Drivers, or NLA for World */
|
||||
adt= wo->adt;
|
||||
ANIMDATA_FILTER_CASES(wo,
|
||||
{ /* AnimData blocks - do nothing... */ },
|
||||
{ /* nla */
|
||||
/* add NLA tracks */
|
||||
items += animdata_filter_nla(anim_data, adt, filter_mode, wo, ANIMTYPE_DSWOR, (ID *)wo);
|
||||
},
|
||||
{ /* drivers */
|
||||
/* include world-expand widget? */
|
||||
if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLDRIVERS, sce, ANIMTYPE_SCENE, (ID *)sce);
|
||||
ale= make_new_animlistelem(wo, ANIMTYPE_DSWOR, sce, ANIMTYPE_SCENE, (ID *)wo);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
@ -1113,18 +1320,12 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads
|
||||
}
|
||||
|
||||
/* add F-Curve channels (drivers are F-Curves) */
|
||||
if (EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) {
|
||||
items += animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, sce, ANIMTYPE_SCENE, filter_mode, (ID *)sce);
|
||||
if (FILTER_WOR_SCED(wo)/*EXPANDED_DRVD(adt)*/ || !(filter_mode & ANIMFILTER_CHANNELS)) {
|
||||
// XXX owner info is messed up now...
|
||||
items += animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, wo, ANIMTYPE_DSWOR, filter_mode, (ID *)wo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* world */
|
||||
if ((wo && wo->adt) && !(ads->filterflag & ADS_FILTER_NOWOR)) {
|
||||
/* Animation or Drivers */
|
||||
if ((ads->filterflag & ADS_FILTER_ONLYDRIVERS) == 0) {
|
||||
AnimData *adt= wo->adt;
|
||||
|
||||
},
|
||||
{ /* action */
|
||||
/* include world-expand widget? */
|
||||
if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
ale= make_new_animlistelem(wo, ANIMTYPE_DSWOR, sce, ANIMTYPE_SCENE, (ID *)sce);
|
||||
@ -1139,27 +1340,7 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads
|
||||
items += animdata_filter_action(anim_data, adt->action, filter_mode, wo, ANIMTYPE_DSWOR, (ID *)wo);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Drivers */
|
||||
if (ANIMDATA_HAS_DRIVERS(wo)) {
|
||||
AnimData *adt= wo->adt;
|
||||
|
||||
/* include shapekey-expand widget? */
|
||||
if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
ale= make_new_animlistelem(wo, ANIMTYPE_DSWOR, sce, ANIMTYPE_SCENE, (ID *)wo);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
}
|
||||
}
|
||||
|
||||
/* add F-Curve channels (drivers are F-Curves) */
|
||||
if (FILTER_WOR_SCED(wo)/*EXPANDED_DRVD(adt)*/ || !(filter_mode & ANIMFILTER_CHANNELS)) {
|
||||
// XXX owner info is messed up now...
|
||||
items += animdata_filter_fcurves(anim_data, adt->drivers.first, NULL, wo, ANIMTYPE_DSWOR, filter_mode, (ID *)wo);
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/* return the number of items added to the list */
|
||||
@ -1171,6 +1352,7 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
|
||||
{
|
||||
Scene *sce= (Scene *)ads->source;
|
||||
Base *base;
|
||||
bAnimListElem *ale;
|
||||
int items = 0;
|
||||
|
||||
/* check that we do indeed have a scene */
|
||||
@ -1182,22 +1364,32 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
|
||||
/* scene-linked animation */
|
||||
// TODO: sequencer, composite nodes - are we to include those here too?
|
||||
{
|
||||
short sceOk, worOk;
|
||||
short sceOk= 0, worOk= 0;
|
||||
|
||||
/* check filtering-flags if ok */
|
||||
if (ads->filterflag) {
|
||||
if (ads->filterflag & ADS_FILTER_ONLYDRIVERS) {
|
||||
sceOk= (ANIMDATA_HAS_DRIVERS(sce) && !(ads->filterflag & ADS_FILTER_NOSCE));
|
||||
worOk= ((sce->world) && ANIMDATA_HAS_DRIVERS(sce->world) && !(ads->filterflag & ADS_FILTER_NOWOR));
|
||||
}
|
||||
else {
|
||||
sceOk= (ANIMDATA_HAS_KEYS(sce) && !(ads->filterflag & ADS_FILTER_NOSCE));
|
||||
worOk= ((sce->world) && ANIMDATA_HAS_KEYS(sce->world) && !(ads->filterflag & ADS_FILTER_NOWOR));
|
||||
}
|
||||
}
|
||||
else {
|
||||
sceOk= (ANIMDATA_HAS_KEYS(sce));
|
||||
worOk= ((sce->world) && ANIMDATA_HAS_KEYS(sce->world));
|
||||
ANIMDATA_FILTER_CASES(sce,
|
||||
{
|
||||
/* for the special AnimData blocks only case, we only need to add
|
||||
* the block if it is valid... then other cases just get skipped (hence ok=0)
|
||||
*/
|
||||
ANIMDATA_ADD_ANIMDATA(sce);
|
||||
sceOk=0;
|
||||
},
|
||||
sceOk= !(ads->filterflag & ADS_FILTER_NOSCE);,
|
||||
sceOk= !(ads->filterflag & ADS_FILTER_NOSCE);,
|
||||
sceOk= !(ads->filterflag & ADS_FILTER_NOSCE);)
|
||||
if (sce->world) {
|
||||
ANIMDATA_FILTER_CASES(sce->world,
|
||||
{
|
||||
/* for the special AnimData blocks only case, we only need to add
|
||||
* the block if it is valid... then other cases just get skipped (hence ok=0)
|
||||
*/
|
||||
ANIMDATA_ADD_ANIMDATA(sce->world);
|
||||
worOk=0;
|
||||
},
|
||||
worOk= !(ads->filterflag & ADS_FILTER_NOWOR);,
|
||||
worOk= !(ads->filterflag & ADS_FILTER_NOWOR);,
|
||||
worOk= !(ads->filterflag & ADS_FILTER_NOWOR);)
|
||||
}
|
||||
|
||||
/* check if not all bad (i.e. so there is something to show) */
|
||||
@ -1239,13 +1431,33 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
|
||||
}
|
||||
|
||||
/* check filters for datatypes */
|
||||
if (ads->filterflag & ADS_FILTER_ONLYDRIVERS) {
|
||||
actOk= (ANIMDATA_HAS_DRIVERS(ob));
|
||||
keyOk= ((key) && ANIMDATA_HAS_DRIVERS(key) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS));
|
||||
}
|
||||
else {
|
||||
actOk= ANIMDATA_HAS_KEYS(ob);
|
||||
keyOk= ((key) && ANIMDATA_HAS_KEYS(key) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS));
|
||||
/* object */
|
||||
actOk= 0;
|
||||
keyOk= 0;
|
||||
ANIMDATA_FILTER_CASES(ob,
|
||||
{
|
||||
/* for the special AnimData blocks only case, we only need to add
|
||||
* the block if it is valid... then other cases just get skipped (hence ok=0)
|
||||
*/
|
||||
ANIMDATA_ADD_ANIMDATA(ob);
|
||||
actOk=0;
|
||||
},
|
||||
actOk= 1;,
|
||||
actOk= 1;,
|
||||
actOk= 1;)
|
||||
if (key) {
|
||||
/* shapekeys */
|
||||
ANIMDATA_FILTER_CASES(key,
|
||||
{
|
||||
/* for the special AnimData blocks only case, we only need to add
|
||||
* the block if it is valid... then other cases just get skipped (hence ok=0)
|
||||
*/
|
||||
ANIMDATA_ADD_ANIMDATA(key);
|
||||
keyOk=0;
|
||||
},
|
||||
keyOk= 1;,
|
||||
keyOk= 1;,
|
||||
keyOk= 1;)
|
||||
}
|
||||
|
||||
/* materials - only for geometric types */
|
||||
@ -1260,39 +1472,74 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int
|
||||
Material *ma= give_current_material(ob, a);
|
||||
|
||||
/* if material has relevant animation data, break */
|
||||
if (ads->filterflag & ADS_FILTER_ONLYDRIVERS) {
|
||||
if (ANIMDATA_HAS_DRIVERS(ma)) {
|
||||
matOk= 1;
|
||||
ANIMDATA_FILTER_CASES(ma,
|
||||
{
|
||||
/* for the special AnimData blocks only case, we only need to add
|
||||
* the block if it is valid... then other cases just get skipped (hence ok=0)
|
||||
*/
|
||||
ANIMDATA_ADD_ANIMDATA(ma);
|
||||
matOk=0;
|
||||
},
|
||||
matOk= 1;,
|
||||
matOk= 1;,
|
||||
matOk= 1;)
|
||||
|
||||
if (matOk)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ANIMDATA_HAS_KEYS(ma)) {
|
||||
matOk= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* data */
|
||||
switch (ob->type) {
|
||||
case OB_CAMERA: /* ------- Camera ------------ */
|
||||
{
|
||||
Camera *ca= (Camera *)ob->data;
|
||||
if (ads->filterflag & ADS_FILTER_ONLYDRIVERS)
|
||||
dataOk= (ANIMDATA_HAS_DRIVERS(ca) && !(ads->filterflag & ADS_FILTER_NOCAM));
|
||||
else
|
||||
dataOk= (ANIMDATA_HAS_KEYS(ca) && !(ads->filterflag & ADS_FILTER_NOCAM));
|
||||
dataOk= 0;
|
||||
ANIMDATA_FILTER_CASES(ca,
|
||||
if ((ads->filterflag & ADS_FILTER_NOCAM)==0) {
|
||||
/* for the special AnimData blocks only case, we only need to add
|
||||
* the block if it is valid... then other cases just get skipped (hence ok=0)
|
||||
*/
|
||||
ANIMDATA_ADD_ANIMDATA(ca);
|
||||
dataOk=0;
|
||||
},
|
||||
dataOk= !(ads->filterflag & ADS_FILTER_NOCAM);,
|
||||
dataOk= !(ads->filterflag & ADS_FILTER_NOCAM);,
|
||||
dataOk= !(ads->filterflag & ADS_FILTER_NOCAM);)
|
||||
}
|
||||
break;
|
||||
case OB_LAMP: /* ---------- Lamp ----------- */
|
||||
{
|
||||
Lamp *la= (Lamp *)ob->data;
|
||||
if (ads->filterflag & ADS_FILTER_ONLYDRIVERS)
|
||||
dataOk= (ANIMDATA_HAS_DRIVERS(la) && !(ads->filterflag & ADS_FILTER_NOLAM));
|
||||
else
|
||||
dataOk= (ANIMDATA_HAS_KEYS(la) && !(ads->filterflag & ADS_FILTER_NOLAM));
|
||||
dataOk= 0;
|
||||
ANIMDATA_FILTER_CASES(la,
|
||||
if ((ads->filterflag & ADS_FILTER_NOLAM)==0) {
|
||||
/* for the special AnimData blocks only case, we only need to add
|
||||
* the block if it is valid... then other cases just get skipped (hence ok=0)
|
||||
*/
|
||||
ANIMDATA_ADD_ANIMDATA(la);
|
||||
dataOk=0;
|
||||
},
|
||||
dataOk= !(ads->filterflag & ADS_FILTER_NOLAM);,
|
||||
dataOk= !(ads->filterflag & ADS_FILTER_NOLAM);,
|
||||
dataOk= !(ads->filterflag & ADS_FILTER_NOLAM);)
|
||||
}
|
||||
break;
|
||||
case OB_CURVE: /* ------- Curve ---------- */
|
||||
{
|
||||
Curve *cu= (Curve *)ob->data;
|
||||
dataOk= 0;
|
||||
ANIMDATA_FILTER_CASES(cu,
|
||||
if ((ads->filterflag & ADS_FILTER_NOCUR)==0) {
|
||||
/* for the special AnimData blocks only case, we only need to add
|
||||
* the block if it is valid... then other cases just get skipped (hence ok=0)
|
||||
*/
|
||||
ANIMDATA_ADD_ANIMDATA(cu);
|
||||
dataOk=0;
|
||||
},
|
||||
dataOk= !(ads->filterflag & ADS_FILTER_NOCUR);,
|
||||
dataOk= !(ads->filterflag & ADS_FILTER_NOCUR);,
|
||||
dataOk= !(ads->filterflag & ADS_FILTER_NOCUR);)
|
||||
}
|
||||
break;
|
||||
default: /* --- other --- */
|
||||
@ -1400,6 +1647,7 @@ int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode
|
||||
case ANIMCONT_DOPESHEET:
|
||||
case ANIMCONT_FCURVES:
|
||||
case ANIMCONT_DRIVERS:
|
||||
case ANIMCONT_NLA:
|
||||
items= animdata_filter_dopesheet(anim_data, data, filter_mode);
|
||||
break;
|
||||
}
|
||||
|
@ -976,7 +976,7 @@ static void MARKER_OT_delete(wmOperatorType *ot)
|
||||
/* ************************** registration **********************************/
|
||||
|
||||
/* called in screen_ops.c:ED_operatortypes_screen() */
|
||||
void ED_marker_operatortypes(void)
|
||||
void ED_operatortypes_marker(void)
|
||||
{
|
||||
WM_operatortype_append(MARKER_OT_add);
|
||||
WM_operatortype_append(MARKER_OT_move);
|
||||
|
@ -83,10 +83,12 @@ static void change_frame_apply(bContext *C, wmOperator *op)
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
int cfra;
|
||||
|
||||
/* get frame, and clamp to MINFRAME */
|
||||
/* get frame, and clamp to MINAFRAME
|
||||
* - not MINFRAME, since it's useful to be able to key a few-frames back
|
||||
*/
|
||||
cfra= RNA_int_get(op->ptr, "frame");
|
||||
|
||||
if (cfra < MINFRAME) cfra= MINFRAME;
|
||||
if (cfra < MINAFRAME) cfra= MINAFRAME;
|
||||
CFRA= cfra;
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
|
||||
@ -209,7 +211,7 @@ void ANIM_OT_change_frame(wmOperatorType *ot)
|
||||
ot->modal= change_frame_modal;
|
||||
|
||||
/* rna */
|
||||
RNA_def_int(ot->srna, "frame", 0, 1, MAXFRAME, "Frame", "", 1, MAXFRAME);
|
||||
RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
|
||||
}
|
||||
|
||||
/* ****************** set preview range operator ****************************/
|
||||
|
@ -1,5 +1,30 @@
|
||||
/* Testing code for 2.5 animation system
|
||||
* Copyright 2009, Joshua Leung
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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) 2009 Blender Foundation, Joshua Leung
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Joshua Leung (full recode)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -94,7 +119,7 @@ FCurve *verify_driver_fcurve (ID *id, const char rna_path[], const int array_ind
|
||||
fcu->driver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
|
||||
|
||||
/* add simple generator modifier for driver so that there is some visible representation */
|
||||
fcurve_add_modifier(fcu, FMODIFIER_TYPE_GENERATOR);
|
||||
add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR);
|
||||
|
||||
/* just add F-Curve to end of driver list */
|
||||
BLI_addtail(&adt->drivers, fcu);
|
||||
|
679
source/blender/editors/animation/fmodifier_ui.c
Normal file
679
source/blender/editors/animation/fmodifier_ui.c
Normal file
@ -0,0 +1,679 @@
|
||||
/**
|
||||
* $Id:
|
||||
*
|
||||
* ***** 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) 2009 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Contributor(s): Blender Foundation, Joshua Leung
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/* User-Interface Stuff for F-Modifiers:
|
||||
* This file defines the (C-Coded) templates + editing callbacks needed
|
||||
* by the interface stuff or F-Modifiers, as used by F-Curves in the Graph Editor,
|
||||
* and NLA-Strips in the NLA Editor.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_editVert.h"
|
||||
#include "BLI_rand.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_nla.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "ED_anim_api.h"
|
||||
#include "ED_keyframing.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_types.h"
|
||||
#include "ED_util.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
#include "UI_view2d.h"
|
||||
|
||||
// XXX! --------------------------------
|
||||
/* temporary definition for limits of float number buttons (FLT_MAX tends to infinity with old system) */
|
||||
#define UI_FLT_MAX 10000.0f
|
||||
|
||||
/* ********************************************** */
|
||||
|
||||
#define B_REDR 1
|
||||
#define B_FMODIFIER_REDRAW 20
|
||||
|
||||
/* macro for use here to draw background box and set height */
|
||||
// XXX for now, roundbox has it's callback func set to NULL to not intercept events
|
||||
#define DRAW_BACKDROP(height) \
|
||||
{ \
|
||||
uiDefBut(block, ROUNDBOX, B_REDR, "", -3, yco-height, width+3, height-1, NULL, 5.0, 0.0, 12.0, (float)rb_col, ""); \
|
||||
}
|
||||
|
||||
/* callback to verify modifier data */
|
||||
static void validate_fmodifier_cb (bContext *C, void *fcm_v, void *dummy)
|
||||
{
|
||||
FModifier *fcm= (FModifier *)fcm_v;
|
||||
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
|
||||
|
||||
/* call the verify callback on the modifier if applicable */
|
||||
if (fmi && fmi->verify_data)
|
||||
fmi->verify_data(fcm);
|
||||
}
|
||||
|
||||
/* callback to set the active modifier */
|
||||
static void activate_fmodifier_cb (bContext *C, void *fmods_v, void *fcm_v)
|
||||
{
|
||||
ListBase *modifiers = (ListBase *)fmods_v;
|
||||
FModifier *fcm= (FModifier *)fcm_v;
|
||||
|
||||
/* call API function to set the active modifier for active modifier-stack */
|
||||
set_active_fmodifier(modifiers, fcm);
|
||||
}
|
||||
|
||||
/* callback to remove the given modifier */
|
||||
static void delete_fmodifier_cb (bContext *C, void *fmods_v, void *fcm_v)
|
||||
{
|
||||
ListBase *modifiers = (ListBase *)fmods_v;
|
||||
FModifier *fcm= (FModifier *)fcm_v;
|
||||
|
||||
/* remove the given F-Modifier from the active modifier-stack */
|
||||
remove_fmodifier(modifiers, fcm);
|
||||
}
|
||||
|
||||
/* --------------- */
|
||||
|
||||
/* draw settings for generator modifier */
|
||||
static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, short width)
|
||||
{
|
||||
FMod_Generator *data= (FMod_Generator *)fcm->data;
|
||||
uiLayout *col, *row;
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
PointerRNA ptr;
|
||||
|
||||
/* init the RNA-pointer */
|
||||
RNA_pointer_create(id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
|
||||
|
||||
/* basic settings (backdrop + mode selector + some padding) */
|
||||
col= uiLayoutColumn(layout, 1);
|
||||
block= uiLayoutGetBlock(layout);
|
||||
uiBlockBeginAlign(block);
|
||||
but= uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, width-30, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL);
|
||||
uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL);
|
||||
|
||||
uiDefButR(block, TOG, B_FMODIFIER_REDRAW, NULL, 0, 0, width-30, UI_UNIT_Y, &ptr, "additive", -1, 0, 0, -1, -1, NULL);
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
/* now add settings for individual modes */
|
||||
switch (data->mode) {
|
||||
case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
|
||||
{
|
||||
float *cp = NULL;
|
||||
char xval[32];
|
||||
unsigned int i;
|
||||
|
||||
/* draw polynomial order selector */
|
||||
row= uiLayoutRow(layout, 0);
|
||||
block= uiLayoutGetBlock(row);
|
||||
but= uiDefButI(block, NUM, B_FMODIFIER_REDRAW, "Poly Order: ", 10,0,width-30,19, &data->poly_order, 1, 100, 0, 0, "'Order' of the Polynomial - for a polynomial with n terms, 'order' is n-1");
|
||||
uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL);
|
||||
|
||||
|
||||
/* draw controls for each coefficient and a + sign at end of row */
|
||||
row= uiLayoutRow(layout, 1);
|
||||
block= uiLayoutGetBlock(row);
|
||||
uiDefBut(block, LABEL, 1, "y = ", 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
cp= data->coefficients;
|
||||
for (i=0; (i < data->arraysize) && (cp); i++, cp++) {
|
||||
/* coefficient */
|
||||
uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 150, 20, cp, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, "Coefficient for polynomial");
|
||||
|
||||
/* 'x' param (and '+' if necessary) */
|
||||
if (i) {
|
||||
if (i == 1)
|
||||
strcpy(xval, "x");
|
||||
else
|
||||
sprintf(xval, "x^%d", i);
|
||||
uiDefBut(block, LABEL, 1, xval, 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, "Power of x");
|
||||
}
|
||||
|
||||
if ( (i != (data->arraysize - 1)) || ((i==0) && data->arraysize==2) ) {
|
||||
uiDefBut(block, LABEL, 1, "+", 0,0 , 30, 20, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
/* next coefficient on a new row */
|
||||
row= uiLayoutRow(layout, 1);
|
||||
block= uiLayoutGetBlock(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* factorised polynomial expression */
|
||||
{
|
||||
float *cp = NULL;
|
||||
unsigned int i;
|
||||
|
||||
/* draw polynomial order selector */
|
||||
row= uiLayoutRow(layout, 0);
|
||||
block= uiLayoutGetBlock(row);
|
||||
but= uiDefButI(block, NUM, B_FMODIFIER_REDRAW, "Poly Order: ", 0,0,width-30,19, &data->poly_order, 1, 100, 0, 0, "'Order' of the Polynomial - for a polynomial with n terms, 'order' is n-1");
|
||||
uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL);
|
||||
|
||||
|
||||
/* draw controls for each pair of coefficients */
|
||||
row= uiLayoutRow(layout, 1);
|
||||
block= uiLayoutGetBlock(row);
|
||||
uiDefBut(block, LABEL, 1, "y=", 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
cp= data->coefficients;
|
||||
for (i=0; (i < data->poly_order) && (cp); i++, cp+=2) {
|
||||
/* opening bracket */
|
||||
uiDefBut(block, LABEL, 1, "(", 0, 0, 20, 20, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
/* coefficients */
|
||||
uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 100, 20, cp, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, "Coefficient of x");
|
||||
|
||||
uiDefBut(block, LABEL, 1, "x+", 0, 0, 40, 20, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 100, 20, cp+1, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, "Second coefficient");
|
||||
|
||||
/* closing bracket and '+' sign */
|
||||
if ( (i != (data->poly_order - 1)) || ((i==0) && data->poly_order==2) ) {
|
||||
uiDefBut(block, LABEL, 1, ") +", 0, 0, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
/* set up new row for the next pair of coefficients*/
|
||||
row= uiLayoutRow(layout, 1);
|
||||
block= uiLayoutGetBlock(row);
|
||||
}
|
||||
else
|
||||
uiDefBut(block, LABEL, 1, ")", 0, 0, 20, 20, NULL, 0.0, 0.0, 0, 0, "");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------- */
|
||||
|
||||
/* draw settings for noise modifier */
|
||||
static void draw_modifier__fn_generator(uiLayout *layout, ID *id, FModifier *fcm, short width)
|
||||
{
|
||||
uiLayout *col;
|
||||
PointerRNA ptr;
|
||||
|
||||
/* init the RNA-pointer */
|
||||
RNA_pointer_create(id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
|
||||
|
||||
/* add the settings */
|
||||
col= uiLayoutColumn(layout, 1);
|
||||
uiItemR(col, "", 0, &ptr, "type", 0, 0, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "additive", 0, 0, 1);
|
||||
|
||||
col= uiLayoutColumn(layout, 0); // no grouping for now
|
||||
uiItemR(col, NULL, 0, &ptr, "amplitude", 0, 0, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "phase_multiplier", 0, 0, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "phase_offset", 0, 0, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "value_offset", 0, 0, 0);
|
||||
}
|
||||
|
||||
/* --------------- */
|
||||
|
||||
/* draw settings for cycles modifier */
|
||||
static void draw_modifier__cycles(uiLayout *layout, ID *id, FModifier *fcm, short width)
|
||||
{
|
||||
uiLayout *split, *col;
|
||||
PointerRNA ptr;
|
||||
|
||||
/* init the RNA-pointer */
|
||||
RNA_pointer_create(id, &RNA_FModifierCycles, fcm, &ptr);
|
||||
|
||||
/* split into 2 columns
|
||||
* NOTE: the mode comboboxes shouldn't get labels, otherwise there isn't enough room
|
||||
*/
|
||||
split= uiLayoutSplit(layout, 0.5f);
|
||||
|
||||
/* before range */
|
||||
col= uiLayoutColumn(split, 1);
|
||||
uiItemL(col, "Before:", 0);
|
||||
uiItemR(col, "", 0, &ptr, "before_mode", 0, 0, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "before_cycles", 0, 0, 0);
|
||||
|
||||
/* after range */
|
||||
col= uiLayoutColumn(split, 1);
|
||||
uiItemL(col, "After:", 0);
|
||||
uiItemR(col, "", 0, &ptr, "after_mode", 0, 0, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "after_cycles", 0, 0, 0);
|
||||
}
|
||||
|
||||
/* --------------- */
|
||||
|
||||
/* draw settings for noise modifier */
|
||||
static void draw_modifier__noise(uiLayout *layout, ID *id, FModifier *fcm, short width)
|
||||
{
|
||||
uiLayout *split, *col;
|
||||
PointerRNA ptr;
|
||||
|
||||
/* init the RNA-pointer */
|
||||
RNA_pointer_create(id, &RNA_FModifierNoise, fcm, &ptr);
|
||||
|
||||
/* blending mode */
|
||||
uiItemR(layout, NULL, 0, &ptr, "modification", 0, 0, 0);
|
||||
|
||||
/* split into 2 columns */
|
||||
split= uiLayoutSplit(layout, 0.5f);
|
||||
|
||||
/* col 1 */
|
||||
col= uiLayoutColumn(split, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "size", 0, 0, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "strength", 0, 0, 0);
|
||||
|
||||
/* col 2 */
|
||||
col= uiLayoutColumn(split, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "phase", 0, 0, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "depth", 0, 0, 0);
|
||||
}
|
||||
|
||||
/* --------------- */
|
||||
|
||||
#define BINARYSEARCH_FRAMEEQ_THRESH 0.0001
|
||||
|
||||
/* Binary search algorithm for finding where to insert Envelope Data Point.
|
||||
* Returns the index to insert at (data already at that index will be offset if replace is 0)
|
||||
*/
|
||||
static int binarysearch_fcm_envelopedata_index (FCM_EnvelopeData array[], float frame, int arraylen, short *exists)
|
||||
{
|
||||
int start=0, end=arraylen;
|
||||
int loopbreaker= 0, maxloop= arraylen * 2;
|
||||
|
||||
/* initialise exists-flag first */
|
||||
*exists= 0;
|
||||
|
||||
/* sneaky optimisations (don't go through searching process if...):
|
||||
* - keyframe to be added is to be added out of current bounds
|
||||
* - keyframe to be added would replace one of the existing ones on bounds
|
||||
*/
|
||||
if ((arraylen <= 0) || (array == NULL)) {
|
||||
printf("Warning: binarysearch_fcm_envelopedata_index() encountered invalid array \n");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
/* check whether to add before/after/on */
|
||||
float framenum;
|
||||
|
||||
/* 'First' Point (when only one point, this case is used) */
|
||||
framenum= array[0].time;
|
||||
if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
|
||||
*exists = 1;
|
||||
return 0;
|
||||
}
|
||||
else if (frame < framenum)
|
||||
return 0;
|
||||
|
||||
/* 'Last' Point */
|
||||
framenum= array[(arraylen-1)].time;
|
||||
if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
|
||||
*exists= 1;
|
||||
return (arraylen - 1);
|
||||
}
|
||||
else if (frame > framenum)
|
||||
return arraylen;
|
||||
}
|
||||
|
||||
|
||||
/* most of the time, this loop is just to find where to put it
|
||||
* - 'loopbreaker' is just here to prevent infinite loops
|
||||
*/
|
||||
for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
|
||||
/* compute and get midpoint */
|
||||
int mid = start + ((end - start) / 2); /* we calculate the midpoint this way to avoid int overflows... */
|
||||
float midfra= array[mid].time;
|
||||
|
||||
/* check if exactly equal to midpoint */
|
||||
if (IS_EQT(frame, midfra, BINARYSEARCH_FRAMEEQ_THRESH)) {
|
||||
*exists = 1;
|
||||
return mid;
|
||||
}
|
||||
|
||||
/* repeat in upper/lower half */
|
||||
if (frame > midfra)
|
||||
start= mid + 1;
|
||||
else if (frame < midfra)
|
||||
end= mid - 1;
|
||||
}
|
||||
|
||||
/* print error if loop-limit exceeded */
|
||||
if (loopbreaker == (maxloop-1)) {
|
||||
printf("Error: binarysearch_fcm_envelopedata_index() was taking too long \n");
|
||||
|
||||
// include debug info
|
||||
printf("\tround = %d: start = %d, end = %d, arraylen = %d \n", loopbreaker, start, end, arraylen);
|
||||
}
|
||||
|
||||
/* not found, so return where to place it */
|
||||
return start;
|
||||
}
|
||||
|
||||
/* callback to add new envelope data point */
|
||||
// TODO: should we have a separate file for things like this?
|
||||
static void fmod_envelope_addpoint_cb (bContext *C, void *fcm_dv, void *dummy)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
FMod_Envelope *env= (FMod_Envelope *)fcm_dv;
|
||||
FCM_EnvelopeData *fedn;
|
||||
FCM_EnvelopeData fed;
|
||||
|
||||
/* init template data */
|
||||
fed.min= -1.0f;
|
||||
fed.max= 1.0f;
|
||||
fed.time= (float)scene->r.cfra; // XXX make this int for ease of use?
|
||||
fed.f1= fed.f2= 0;
|
||||
|
||||
/* check that no data exists for the current frame... */
|
||||
if (env->data) {
|
||||
short exists = -1;
|
||||
int i= binarysearch_fcm_envelopedata_index(env->data, (float)(scene->r.cfra), env->totvert, &exists);
|
||||
|
||||
/* binarysearch_...() will set exists by default to 0, so if it is non-zero, that means that the point exists already */
|
||||
if (exists)
|
||||
return;
|
||||
|
||||
/* add new */
|
||||
fedn= MEM_callocN((env->totvert+1)*sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
|
||||
|
||||
/* add the points that should occur before the point to be pasted */
|
||||
if (i > 0)
|
||||
memcpy(fedn, env->data, i*sizeof(FCM_EnvelopeData));
|
||||
|
||||
/* add point to paste at index i */
|
||||
*(fedn + i)= fed;
|
||||
|
||||
/* add the points that occur after the point to be pasted */
|
||||
if (i < env->totvert)
|
||||
memcpy(fedn+i+1, env->data+i, (env->totvert-i)*sizeof(FCM_EnvelopeData));
|
||||
|
||||
/* replace (+ free) old with new */
|
||||
MEM_freeN(env->data);
|
||||
env->data= fedn;
|
||||
|
||||
env->totvert++;
|
||||
}
|
||||
else {
|
||||
env->data= MEM_callocN(sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
|
||||
*(env->data)= fed;
|
||||
|
||||
env->totvert= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* callback to remove envelope data point */
|
||||
// TODO: should we have a separate file for things like this?
|
||||
static void fmod_envelope_deletepoint_cb (bContext *C, void *fcm_dv, void *ind_v)
|
||||
{
|
||||
FMod_Envelope *env= (FMod_Envelope *)fcm_dv;
|
||||
FCM_EnvelopeData *fedn;
|
||||
int index= GET_INT_FROM_POINTER(ind_v);
|
||||
|
||||
/* check that no data exists for the current frame... */
|
||||
if (env->totvert > 1) {
|
||||
/* allocate a new smaller array */
|
||||
fedn= MEM_callocN(sizeof(FCM_EnvelopeData)*(env->totvert-1), "FCM_EnvelopeData");
|
||||
|
||||
memcpy(fedn, &env->data, sizeof(FCM_EnvelopeData)*(index));
|
||||
memcpy(&fedn[index], &env->data[index+1], sizeof(FCM_EnvelopeData)*(env->totvert-index-1));
|
||||
|
||||
/* free old array, and set the new */
|
||||
MEM_freeN(env->data);
|
||||
env->data= fedn;
|
||||
env->totvert--;
|
||||
}
|
||||
else {
|
||||
/* just free array, since the only vert was deleted */
|
||||
if (env->data)
|
||||
MEM_freeN(env->data);
|
||||
env->totvert= 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* draw settings for envelope modifier */
|
||||
static void draw_modifier__envelope(uiLayout *layout, ID *id, FModifier *fcm, short width)
|
||||
{
|
||||
FMod_Envelope *env= (FMod_Envelope *)fcm->data;
|
||||
FCM_EnvelopeData *fed;
|
||||
uiLayout *col, *row;
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
PointerRNA ptr;
|
||||
int i;
|
||||
|
||||
/* init the RNA-pointer */
|
||||
RNA_pointer_create(id, &RNA_FModifierEnvelope, fcm, &ptr);
|
||||
|
||||
/* general settings */
|
||||
col= uiLayoutColumn(layout, 1);
|
||||
uiItemL(col, "Envelope:", 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "reference_value", 0, 0, 0);
|
||||
|
||||
row= uiLayoutRow(col, 1);
|
||||
uiItemR(row, "Min", 0, &ptr, "default_minimum", 0, 0, 0);
|
||||
uiItemR(row, "Max", 0, &ptr, "default_maximum", 0, 0, 0);
|
||||
|
||||
/* control points header */
|
||||
// TODO: move this control-point control stuff to using the new special widgets for lists
|
||||
// the current way is far too cramped
|
||||
row= uiLayoutRow(layout, 0);
|
||||
block= uiLayoutGetBlock(row);
|
||||
|
||||
uiDefBut(block, LABEL, 1, "Control Points:", 0, 0, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
but= uiDefBut(block, BUT, B_FMODIFIER_REDRAW, "Add Point", 0,0,150,19, NULL, 0, 0, 0, 0, "Adds a new control-point to the envelope on the current frame");
|
||||
uiButSetFunc(but, fmod_envelope_addpoint_cb, env, NULL);
|
||||
|
||||
/* control points list */
|
||||
for (i=0, fed=env->data; i < env->totvert; i++, fed++) {
|
||||
/* get a new row to operate on */
|
||||
row= uiLayoutRow(layout, 1);
|
||||
block= uiLayoutGetBlock(row);
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
but=uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Fra:", 0, 0, 90, 20, &fed->time, -UI_FLT_MAX, UI_FLT_MAX, 10, 1, "Frame that envelope point occurs");
|
||||
uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL);
|
||||
|
||||
uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Min:", 0, 0, 100, 20, &fed->min, -UI_FLT_MAX, UI_FLT_MAX, 10, 2, "Minimum bound of envelope at this point");
|
||||
uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Max:", 0, 0, 100, 20, &fed->max, -UI_FLT_MAX, UI_FLT_MAX, 10, 2, "Maximum bound of envelope at this point");
|
||||
|
||||
but= uiDefIconBut(block, BUT, B_FMODIFIER_REDRAW, ICON_X, 0, 0, 18, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Delete envelope control point");
|
||||
uiButSetFunc(but, fmod_envelope_deletepoint_cb, env, SET_INT_IN_POINTER(i));
|
||||
uiBlockBeginAlign(block);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------- */
|
||||
|
||||
/* draw settings for limits modifier */
|
||||
static void draw_modifier__limits(uiLayout *layout, ID *id, FModifier *fcm, short width)
|
||||
{
|
||||
uiLayout *split, *col, *row;
|
||||
PointerRNA ptr;
|
||||
|
||||
/* init the RNA-pointer */
|
||||
RNA_pointer_create(id, &RNA_FModifierLimits, fcm, &ptr);
|
||||
|
||||
/* row 1: minimum */
|
||||
{
|
||||
row= uiLayoutRow(layout, 0);
|
||||
|
||||
/* split into 2 columns */
|
||||
split= uiLayoutSplit(layout, 0.5f);
|
||||
|
||||
/* x-minimum */
|
||||
col= uiLayoutColumn(split, 1);
|
||||
uiItemR(col, NULL, 0, &ptr, "use_minimum_x", 0, 0, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "minimum_x", 0, 0, 0);
|
||||
|
||||
/* y-minimum*/
|
||||
col= uiLayoutColumn(split, 1);
|
||||
uiItemR(col, NULL, 0, &ptr, "use_minimum_y", 0, 0, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "minimum_y", 0, 0, 0);
|
||||
}
|
||||
|
||||
/* row 2: minimum */
|
||||
{
|
||||
row= uiLayoutRow(layout, 0);
|
||||
|
||||
/* split into 2 columns */
|
||||
split= uiLayoutSplit(layout, 0.5f);
|
||||
|
||||
/* x-minimum */
|
||||
col= uiLayoutColumn(split, 1);
|
||||
uiItemR(col, NULL, 0, &ptr, "use_maximum_x", 0, 0, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "maximum_x", 0, 0, 0);
|
||||
|
||||
/* y-minimum*/
|
||||
col= uiLayoutColumn(split, 1);
|
||||
uiItemR(col, NULL, 0, &ptr, "use_maximum_y", 0, 0, 0);
|
||||
uiItemR(col, NULL, 0, &ptr, "maximum_y", 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------- */
|
||||
|
||||
|
||||
void ANIM_uiTemplate_fmodifier_draw (uiLayout *layout, ID *id, ListBase *modifiers, FModifier *fcm)
|
||||
{
|
||||
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
|
||||
uiLayout *box, *row, *subrow;
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
short width= 314;
|
||||
|
||||
/* draw header */
|
||||
{
|
||||
/* get layout-row + UI-block for this */
|
||||
box= uiLayoutBox(layout);
|
||||
|
||||
row= uiLayoutRow(box, 0);
|
||||
block= uiLayoutGetBlock(row); // err...
|
||||
|
||||
uiBlockSetEmboss(block, UI_EMBOSSN);
|
||||
|
||||
/* left-align -------------------------------------------- */
|
||||
subrow= uiLayoutRow(row, 0);
|
||||
uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_LEFT);
|
||||
|
||||
/* expand */
|
||||
uiDefIconButBitS(block, ICONTOG, FMODIFIER_FLAG_EXPANDED, B_REDR, ICON_TRIA_RIGHT, 0, -1, UI_UNIT_X, UI_UNIT_Y, &fcm->flag, 0.0, 0.0, 0, 0, "Modifier is expanded.");
|
||||
|
||||
/* checkbox for 'active' status (for now) */
|
||||
but= uiDefIconButBitS(block, ICONTOG, FMODIFIER_FLAG_ACTIVE, B_REDR, ICON_RADIOBUT_OFF, 0, -1, UI_UNIT_X, UI_UNIT_Y, &fcm->flag, 0.0, 0.0, 0, 0, "Modifier is active one.");
|
||||
uiButSetFunc(but, activate_fmodifier_cb, modifiers, fcm);
|
||||
|
||||
/* name */
|
||||
if (fmi)
|
||||
uiDefBut(block, LABEL, 1, fmi->name, 0, 0, 150, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "F-Curve Modifier Type. Click to make modifier active one.");
|
||||
else
|
||||
uiDefBut(block, LABEL, 1, "<Unknown Modifier>", 0, 0, 150, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "F-Curve Modifier Type. Click to make modifier active one.");
|
||||
|
||||
/* right-align ------------------------------------------- */
|
||||
subrow= uiLayoutRow(row, 0);
|
||||
uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_RIGHT);
|
||||
|
||||
/* 'mute' button */
|
||||
uiDefIconButBitS(block, ICONTOG, FMODIFIER_FLAG_MUTED, B_REDR, ICON_MUTE_IPO_OFF, 0, 0, UI_UNIT_X, UI_UNIT_Y, &fcm->flag, 0.0, 0.0, 0, 0, "Modifier is temporarily muted (not evaluated).");
|
||||
|
||||
/* delete button */
|
||||
but= uiDefIconBut(block, BUT, B_REDR, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Delete F-Curve Modifier.");
|
||||
uiButSetFunc(but, delete_fmodifier_cb, modifiers, fcm);
|
||||
|
||||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
}
|
||||
|
||||
/* when modifier is expanded, draw settings */
|
||||
if (fcm->flag & FMODIFIER_FLAG_EXPANDED) {
|
||||
/* set up the flexible-box layout which acts as the backdrop for the modifier settings */
|
||||
box= uiLayoutBox(layout);
|
||||
|
||||
/* draw settings for individual modifiers */
|
||||
switch (fcm->type) {
|
||||
case FMODIFIER_TYPE_GENERATOR: /* Generator */
|
||||
draw_modifier__generator(box, id, fcm, width);
|
||||
break;
|
||||
|
||||
case FMODIFIER_TYPE_FN_GENERATOR: /* Built-In Function Generator */
|
||||
draw_modifier__fn_generator(box, id, fcm, width);
|
||||
break;
|
||||
|
||||
case FMODIFIER_TYPE_CYCLES: /* Cycles */
|
||||
draw_modifier__cycles(box, id, fcm, width);
|
||||
break;
|
||||
|
||||
case FMODIFIER_TYPE_ENVELOPE: /* Envelope */
|
||||
draw_modifier__envelope(box, id, fcm, width);
|
||||
break;
|
||||
|
||||
case FMODIFIER_TYPE_LIMITS: /* Limits */
|
||||
draw_modifier__limits(box, id, fcm, width);
|
||||
break;
|
||||
|
||||
case FMODIFIER_TYPE_NOISE: /* Noise */
|
||||
draw_modifier__noise(box, id, fcm, width);
|
||||
break;
|
||||
|
||||
default: /* unknown type */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ********************************************** */
|
@ -51,7 +51,6 @@
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_ipo_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
@ -64,6 +63,7 @@
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
#include "DNA_world_types.h"
|
||||
#include "DNA_view2d_types.h"
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
@ -234,45 +234,87 @@ static ActKeyColumn *cfra_find_actkeycolumn (ListBase *keys, float cframe)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0 // disabled, as some intel cards have problems with this
|
||||
/* Draw a simple diamond shape with a filled in center (in screen space) */
|
||||
static void draw_key_but(int x, int y, short w, short h, int sel)
|
||||
/* coordinates for diamond shape */
|
||||
static const float _unit_diamond_shape[4][2] = {
|
||||
{0.0f, 1.0f}, /* top vert */
|
||||
{1.0f, 0.0f}, /* mid-right */
|
||||
{0.0f, -1.0f}, /* bottom vert */
|
||||
{-1.0f, 0.0f} /* mid-left */
|
||||
};
|
||||
|
||||
/* draw a simple diamond shape with OpenGL */
|
||||
void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short mode)
|
||||
{
|
||||
int xmin= x, ymin= y;
|
||||
int xmax= x+w-1, ymax= y+h-1;
|
||||
int xc= (xmin+xmax)/2, yc= (ymin+ymax)/2;
|
||||
static GLuint displist1=0;
|
||||
static GLuint displist2=0;
|
||||
|
||||
/* interior - hardcoded colors (for selected and unselected only) */
|
||||
if (sel) glColor3ub(0xF1, 0xCA, 0x13);
|
||||
else glColor3ub(0xE9, 0xE9, 0xE9);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2i(xc, ymin);
|
||||
glVertex2i(xmax, yc);
|
||||
glVertex2i(xc, ymax);
|
||||
glVertex2i(xmin, yc);
|
||||
glEnd();
|
||||
|
||||
|
||||
/* outline */
|
||||
glColor3ub(0, 0, 0);
|
||||
/* initialise 2 display lists for diamond shape - one empty, one filled */
|
||||
if (displist1 == 0) {
|
||||
displist1= glGenLists(1);
|
||||
glNewList(displist1, GL_COMPILE);
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2i(xc, ymin);
|
||||
glVertex2i(xmax, yc);
|
||||
glVertex2i(xc, ymax);
|
||||
glVertex2i(xmin, yc);
|
||||
glVertex2fv(_unit_diamond_shape[0]);
|
||||
glVertex2fv(_unit_diamond_shape[1]);
|
||||
glVertex2fv(_unit_diamond_shape[2]);
|
||||
glVertex2fv(_unit_diamond_shape[3]);
|
||||
glEnd();
|
||||
glEndList();
|
||||
}
|
||||
#endif
|
||||
if (displist2 == 0) {
|
||||
displist2= glGenLists(1);
|
||||
glNewList(displist2, GL_COMPILE);
|
||||
|
||||
static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, float ypos)
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2fv(_unit_diamond_shape[0]);
|
||||
glVertex2fv(_unit_diamond_shape[1]);
|
||||
glVertex2fv(_unit_diamond_shape[2]);
|
||||
glVertex2fv(_unit_diamond_shape[3]);
|
||||
glEnd();
|
||||
glEndList();
|
||||
}
|
||||
|
||||
/* adjust view transform before starting */
|
||||
glTranslatef(x, y, 0.0f);
|
||||
glScalef(1.0f/xscale*hsize, hsize, 1.0f);
|
||||
|
||||
/* anti-aliased lines for more consistent appearance */
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
|
||||
/* draw! */
|
||||
if ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH) {
|
||||
/* interior - hardcoded colors (for selected and unselected only) */
|
||||
if (sel) UI_ThemeColorShade(TH_STRIP_SELECT, 50);
|
||||
else glColor3ub(0xE9, 0xE9, 0xE9);
|
||||
|
||||
glCallList(displist2);
|
||||
}
|
||||
|
||||
if ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH) {
|
||||
/* exterior - black frame */
|
||||
glColor3ub(0, 0, 0);
|
||||
|
||||
glCallList(displist1);
|
||||
}
|
||||
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
|
||||
/* restore view transform */
|
||||
glScalef(xscale/hsize, 1.0f/hsize, 1.0);
|
||||
glTranslatef(-x, -y, 0.0f);
|
||||
}
|
||||
|
||||
static void draw_keylist(View2D *v2d, ListBase *keys, ListBase *blocks, float ypos)
|
||||
{
|
||||
ActKeyColumn *ak;
|
||||
ActKeyBlock *ab;
|
||||
float xscale;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
/* get View2D scaling factor */
|
||||
UI_view2d_getscale(v2d, &xscale, NULL);
|
||||
|
||||
/* draw keyblocks */
|
||||
if (blocks) {
|
||||
for (ab= blocks->first; ab; ab= ab->next) {
|
||||
@ -292,18 +334,13 @@ static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, fl
|
||||
totCurves = (startCurves>endCurves)? endCurves: startCurves;
|
||||
|
||||
if (ab->totcurve >= totCurves) {
|
||||
int sc_xa, sc_xb, sc_ya, sc_yb;
|
||||
|
||||
/* get co-ordinates of block */
|
||||
gla2DDrawTranslatePt(di, ab->start, ypos, &sc_xa, &sc_ya);
|
||||
gla2DDrawTranslatePt(di, ab->end, ypos, &sc_xb, &sc_yb);
|
||||
|
||||
/* draw block */
|
||||
if (ab->sel)
|
||||
UI_ThemeColor4(TH_STRIP_SELECT);
|
||||
else
|
||||
UI_ThemeColor4(TH_STRIP);
|
||||
glRectf((float)sc_xa, (float)sc_ya-3, (float)sc_xb, (float)sc_yb+5);
|
||||
|
||||
glRectf(ab->start, ypos-5, ab->end, ypos+5);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -311,18 +348,28 @@ static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, fl
|
||||
/* draw keys */
|
||||
if (keys) {
|
||||
for (ak= keys->first; ak; ak= ak->next) {
|
||||
int sc_x, sc_y;
|
||||
/* draw using OpenGL - uglier but faster */
|
||||
// NOTE: a previous version of this didn't work nice for some intel cards
|
||||
draw_keyframe_shape(ak->cfra, ypos, xscale, 5.0f, (ak->sel & SELECT), KEYFRAME_SHAPE_BOTH);
|
||||
|
||||
#if 0 // OLD CODE
|
||||
//int sc_x, sc_y;
|
||||
|
||||
/* get co-ordinate to draw at */
|
||||
gla2DDrawTranslatePt(di, ak->cfra, ypos, &sc_x, &sc_y);
|
||||
//gla2DDrawTranslatePt(di, ak->cfra, ypos, &sc_x, &sc_y);
|
||||
|
||||
/* draw using icons - old way which is slower but more proven */
|
||||
if (ak->sel & SELECT) UI_icon_draw_aspect((float)sc_x-7, (float)sc_y-6, ICON_SPACE2, 1.0f);
|
||||
else UI_icon_draw_aspect((float)sc_x-7, (float)sc_y-6, ICON_SPACE3, 1.0f);
|
||||
//if (ak->sel & SELECT) UI_icon_draw_aspect((float)sc_x-7, (float)sc_y-6, ICON_SPACE2, 1.0f);
|
||||
//else UI_icon_draw_aspect((float)sc_x-7, (float)sc_y-6, ICON_SPACE3, 1.0f);
|
||||
#endif // OLD CODE
|
||||
#if 0 // NEW NON-WORKING CODE
|
||||
/* draw icon */
|
||||
// FIXME: this draws slightly wrong, as we need to apply some offset for icon, but that depends on scaling
|
||||
// so for now disabled
|
||||
//int icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3;
|
||||
//UI_icon_draw_aspect(ak->cfra, ypos-6, icon, 1.0f);
|
||||
#endif // NEW NON-WORKING CODE
|
||||
|
||||
/* draw using OpenGL - slightly uglier but faster */
|
||||
// NOTE: disabled for now, as some intel cards seem to have problems with this
|
||||
//draw_key_but(sc_x-5, sc_y-4, 11, 11, (ak->sel & SELECT));
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,89 +378,86 @@ static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, fl
|
||||
|
||||
/* *************************** Channel Drawing Funcs *************************** */
|
||||
|
||||
void draw_scene_channel(gla2DDrawInfo *di, ActKeysInc *aki, Scene *sce, float ypos)
|
||||
void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos)
|
||||
{
|
||||
ListBase keys = {0, 0};
|
||||
ListBase blocks = {0, 0};
|
||||
|
||||
scene_to_keylist(sce, &keys, &blocks, aki);
|
||||
draw_keylist(di, &keys, &blocks, ypos);
|
||||
scene_to_keylist(ads, sce, &keys, &blocks);
|
||||
draw_keylist(v2d, &keys, &blocks, ypos);
|
||||
|
||||
BLI_freelistN(&keys);
|
||||
BLI_freelistN(&blocks);
|
||||
}
|
||||
|
||||
void draw_object_channel(gla2DDrawInfo *di, ActKeysInc *aki, Object *ob, float ypos)
|
||||
void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos)
|
||||
{
|
||||
ListBase keys = {0, 0};
|
||||
ListBase blocks = {0, 0};
|
||||
|
||||
ob_to_keylist(ob, &keys, &blocks, aki);
|
||||
draw_keylist(di, &keys, &blocks, ypos);
|
||||
ob_to_keylist(ads, ob, &keys, &blocks);
|
||||
draw_keylist(v2d, &keys, &blocks, ypos);
|
||||
|
||||
BLI_freelistN(&keys);
|
||||
BLI_freelistN(&blocks);
|
||||
}
|
||||
|
||||
void draw_fcurve_channel(gla2DDrawInfo *di, ActKeysInc *aki, FCurve *fcu, float ypos)
|
||||
void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos)
|
||||
{
|
||||
ListBase keys = {0, 0};
|
||||
ListBase blocks = {0, 0};
|
||||
|
||||
fcurve_to_keylist(fcu, &keys, &blocks, aki);
|
||||
draw_keylist(di, &keys, &blocks, ypos);
|
||||
fcurve_to_keylist(adt, fcu, &keys, &blocks);
|
||||
draw_keylist(v2d, &keys, &blocks, ypos);
|
||||
|
||||
BLI_freelistN(&keys);
|
||||
BLI_freelistN(&blocks);
|
||||
}
|
||||
|
||||
void draw_agroup_channel(gla2DDrawInfo *di, ActKeysInc *aki, bActionGroup *agrp, float ypos)
|
||||
void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos)
|
||||
{
|
||||
ListBase keys = {0, 0};
|
||||
ListBase blocks = {0, 0};
|
||||
|
||||
agroup_to_keylist(agrp, &keys, &blocks, aki);
|
||||
draw_keylist(di, &keys, &blocks, ypos);
|
||||
agroup_to_keylist(adt, agrp, &keys, &blocks);
|
||||
draw_keylist(v2d, &keys, &blocks, ypos);
|
||||
|
||||
BLI_freelistN(&keys);
|
||||
BLI_freelistN(&blocks);
|
||||
}
|
||||
|
||||
void draw_action_channel(gla2DDrawInfo *di, ActKeysInc *aki, bAction *act, float ypos)
|
||||
void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos)
|
||||
{
|
||||
ListBase keys = {0, 0};
|
||||
ListBase blocks = {0, 0};
|
||||
|
||||
action_to_keylist(act, &keys, &blocks, aki);
|
||||
draw_keylist(di, &keys, &blocks, ypos);
|
||||
action_to_keylist(adt, act, &keys, &blocks);
|
||||
draw_keylist(v2d, &keys, &blocks, ypos);
|
||||
|
||||
BLI_freelistN(&keys);
|
||||
BLI_freelistN(&blocks);
|
||||
}
|
||||
|
||||
void draw_gpl_channel(gla2DDrawInfo *di, ActKeysInc *aki, bGPDlayer *gpl, float ypos)
|
||||
void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos)
|
||||
{
|
||||
ListBase keys = {0, 0};
|
||||
|
||||
gpl_to_keylist(gpl, &keys, NULL, aki);
|
||||
draw_keylist(di, &keys, NULL, ypos);
|
||||
gpl_to_keylist(ads, gpl, &keys, NULL);
|
||||
draw_keylist(v2d, &keys, NULL, ypos);
|
||||
BLI_freelistN(&keys);
|
||||
}
|
||||
|
||||
/* *************************** Keyframe List Conversions *************************** */
|
||||
|
||||
void scene_to_keylist(Scene *sce, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
|
||||
void scene_to_keylist(bDopeSheet *ads, Scene *sce, ListBase *keys, ListBase *blocks)
|
||||
{
|
||||
if (sce) {
|
||||
bDopeSheet *ads= (aki)? (aki->ads) : NULL;
|
||||
AnimData *adt;
|
||||
int filterflag;
|
||||
|
||||
/* get filterflag */
|
||||
if (ads)
|
||||
filterflag= ads->filterflag;
|
||||
else if ((aki) && (aki->actmode == -1)) /* only set like this by NLA */
|
||||
filterflag= ADS_FILTER_NLADUMMY;
|
||||
else
|
||||
filterflag= 0;
|
||||
|
||||
@ -423,7 +467,7 @@ void scene_to_keylist(Scene *sce, ListBase *keys, ListBase *blocks, ActKeysInc *
|
||||
|
||||
// TODO: when we adapt NLA system, this needs to be the NLA-scaled version
|
||||
if (adt->action)
|
||||
action_to_keylist(adt->action, keys, blocks, aki);
|
||||
action_to_keylist(adt, adt->action, keys, blocks);
|
||||
}
|
||||
|
||||
/* world animdata */
|
||||
@ -432,17 +476,16 @@ void scene_to_keylist(Scene *sce, ListBase *keys, ListBase *blocks, ActKeysInc *
|
||||
|
||||
// TODO: when we adapt NLA system, this needs to be the NLA-scaled version
|
||||
if (adt->action)
|
||||
action_to_keylist(adt->action, keys, blocks, aki);
|
||||
action_to_keylist(adt, adt->action, keys, blocks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
|
||||
void ob_to_keylist(bDopeSheet *ads, Object *ob, ListBase *keys, ListBase *blocks)
|
||||
{
|
||||
Key *key= ob_get_key(ob);
|
||||
|
||||
if (ob) {
|
||||
bDopeSheet *ads= (aki)? (aki->ads) : NULL;
|
||||
int filterflag;
|
||||
|
||||
/* get filterflag */
|
||||
@ -453,79 +496,18 @@ void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks, ActKeysInc *aki
|
||||
|
||||
/* Add action keyframes */
|
||||
if (ob->adt && ob->adt->action)
|
||||
action_nlascaled_to_keylist(ob, ob->adt->action, keys, blocks, aki);
|
||||
action_to_keylist(ob->adt, ob->adt->action, keys, blocks);
|
||||
|
||||
/* Add shapekey keyframes (only if dopesheet allows, if it is available) */
|
||||
// TODO: when we adapt NLA system, this needs to be the NLA-scaled version
|
||||
if ((key && key->adt && key->adt->action) && !(filterflag & ADS_FILTER_NOSHAPEKEYS))
|
||||
action_to_keylist(key->adt->action, keys, blocks, aki);
|
||||
action_to_keylist(key->adt, key->adt->action, keys, blocks);
|
||||
|
||||
#if 0 // XXX old animation system
|
||||
/* Add material keyframes (only if dopesheet allows, if it is available) */
|
||||
if ((ob->totcol) && !(filterflag & ADS_FILTER_NOMAT)) {
|
||||
short a;
|
||||
|
||||
for (a=0; a<ob->totcol; a++) {
|
||||
Material *ma= give_current_material(ob, a);
|
||||
|
||||
if (ELEM(NULL, ma, ma->ipo) == 0)
|
||||
ipo_to_keylist(ma->ipo, keys, blocks, aki);
|
||||
// TODO: restore materials, and object data, etc.
|
||||
}
|
||||
}
|
||||
|
||||
/* Add object data keyframes */
|
||||
switch (ob->type) {
|
||||
case OB_CAMERA: /* ------- Camera ------------ */
|
||||
{
|
||||
Camera *ca= (Camera *)ob->data;
|
||||
if ((ca->ipo) && !(filterflag & ADS_FILTER_NOCAM))
|
||||
ipo_to_keylist(ca->ipo, keys, blocks, aki);
|
||||
}
|
||||
break;
|
||||
case OB_LAMP: /* ---------- Lamp ----------- */
|
||||
{
|
||||
Lamp *la= (Lamp *)ob->data;
|
||||
if ((la->ipo) && !(filterflag & ADS_FILTER_NOLAM))
|
||||
ipo_to_keylist(la->ipo, keys, blocks, aki);
|
||||
}
|
||||
break;
|
||||
case OB_CURVE: /* ------- Curve ---------- */
|
||||
{
|
||||
Curve *cu= (Curve *)ob->data;
|
||||
if ((cu->ipo) && !(filterflag & ADS_FILTER_NOCUR))
|
||||
ipo_to_keylist(cu->ipo, keys, blocks, aki);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
}
|
||||
}
|
||||
|
||||
static short bezt_in_aki_range (ActKeysInc *aki, BezTriple *bezt)
|
||||
{
|
||||
/* when aki == NULL, we don't care about range */
|
||||
if (aki == NULL)
|
||||
return 1;
|
||||
|
||||
/* if start and end are both 0, then don't care about range */
|
||||
if (IS_EQ(aki->start, 0) && IS_EQ(aki->end, 0))
|
||||
return 1;
|
||||
|
||||
/* if nla-scaling is in effect, apply appropriate scaling adjustments */
|
||||
#if 0 // XXX this was from some buggy code... do not port for now
|
||||
if (aki->ob) {
|
||||
float frame= get_action_frame_inv(aki->ob, bezt->vec[1][0]);
|
||||
return IN_RANGE(frame, aki->start, aki->end);
|
||||
}
|
||||
else {
|
||||
/* check if in range */
|
||||
return IN_RANGE(bezt->vec[1][0], aki->start, aki->end);
|
||||
}
|
||||
#endif // XXX this was from some buggy code... do not port for now
|
||||
return 1;
|
||||
}
|
||||
|
||||
void fcurve_to_keylist(FCurve *fcu, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
|
||||
void fcurve_to_keylist(AnimData *adt, FCurve *fcu, ListBase *keys, ListBase *blocks)
|
||||
{
|
||||
BezTriple *bezt;
|
||||
ActKeyColumn *ak, *ak2;
|
||||
@ -533,16 +515,18 @@ void fcurve_to_keylist(FCurve *fcu, ListBase *keys, ListBase *blocks, ActKeysInc
|
||||
int v;
|
||||
|
||||
if (fcu && fcu->totvert && fcu->bezt) {
|
||||
/* apply NLA-mapping (if applicable) */
|
||||
if (adt)
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1);
|
||||
|
||||
/* loop through beztriples, making ActKeys and ActKeyBlocks */
|
||||
bezt= fcu->bezt;
|
||||
|
||||
for (v=0; v < fcu->totvert; v++, bezt++) {
|
||||
/* only if keyframe is in range (optimisation) */
|
||||
if (bezt_in_aki_range(aki, bezt)) {
|
||||
add_bezt_to_keycolumnslist(keys, bezt);
|
||||
if (blocks) add_bezt_to_keyblockslist(blocks, fcu, v);
|
||||
}
|
||||
}
|
||||
|
||||
/* update the number of curves that elements have appeared in */
|
||||
if (keys) {
|
||||
@ -577,65 +561,38 @@ void fcurve_to_keylist(FCurve *fcu, ListBase *keys, ListBase *blocks, ActKeysInc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* unapply NLA-mapping if applicable */
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void agroup_to_keylist(bActionGroup *agrp, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
|
||||
void agroup_to_keylist(AnimData *adt, bActionGroup *agrp, ListBase *keys, ListBase *blocks)
|
||||
{
|
||||
FCurve *fcu;
|
||||
|
||||
if (agrp) {
|
||||
/* loop through F-Curves */
|
||||
for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcu->next) {
|
||||
fcurve_to_keylist(fcu, keys, blocks, aki);
|
||||
fcurve_to_keylist(adt, fcu, keys, blocks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
|
||||
void action_to_keylist(AnimData *adt, bAction *act, ListBase *keys, ListBase *blocks)
|
||||
{
|
||||
FCurve *fcu;
|
||||
|
||||
if (act) {
|
||||
/* loop through F-Curves */
|
||||
for (fcu= act->curves.first; fcu; fcu= fcu->next) {
|
||||
fcurve_to_keylist(fcu, keys, blocks, aki);
|
||||
fcurve_to_keylist(adt, fcu, keys, blocks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void action_nlascaled_to_keylist(Object *ob, bAction *act, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
|
||||
{
|
||||
FCurve *fcu;
|
||||
Object *oldob= NULL;
|
||||
|
||||
/* although apply and clearing NLA-scaling pre-post creating keylist does impact on performance,
|
||||
* the effects should be fairly minimal, as we're already going through the keyframes multiple times
|
||||
* already for blocks too...
|
||||
*/
|
||||
if (act) {
|
||||
/* if 'aki' is provided, store it's current ob to restore later as it might not be the same */
|
||||
if (aki) {
|
||||
oldob= aki->ob;
|
||||
aki->ob= ob;
|
||||
}
|
||||
|
||||
/* loop through F-Curves
|
||||
* - scaling correction only does times for center-points, so should be faster
|
||||
*/
|
||||
for (fcu= act->curves.first; fcu; fcu= fcu->next) {
|
||||
ANIM_nla_mapping_apply_fcurve(ob, fcu, 0, 1);
|
||||
fcurve_to_keylist(fcu, keys, blocks, aki);
|
||||
ANIM_nla_mapping_apply_fcurve(ob, fcu, 1, 1);
|
||||
}
|
||||
|
||||
/* if 'aki' is provided, restore ob */
|
||||
if (aki)
|
||||
aki->ob= oldob;
|
||||
}
|
||||
}
|
||||
|
||||
void gpl_to_keylist(bGPDlayer *gpl, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
|
||||
void gpl_to_keylist(bDopeSheet *ads, bGPDlayer *gpl, ListBase *keys, ListBase *blocks)
|
||||
{
|
||||
bGPDframe *gpf;
|
||||
ActKeyColumn *ak;
|
||||
|
@ -128,6 +128,10 @@ static short agrp_keys_bezier_loop(BeztEditData *bed, bActionGroup *agrp, BeztEd
|
||||
{
|
||||
FCurve *fcu;
|
||||
|
||||
/* sanity check */
|
||||
if (agrp == NULL)
|
||||
return 0;
|
||||
|
||||
/* only iterate over the F-Curves that are in this group */
|
||||
for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcu->next) {
|
||||
if (ANIM_fcurve_keys_bezier_loop(bed, fcu, bezt_ok, bezt_cb, fcu_cb))
|
||||
@ -142,6 +146,10 @@ static short act_keys_bezier_loop(BeztEditData *bed, bAction *act, BeztEditFunc
|
||||
{
|
||||
FCurve *fcu;
|
||||
|
||||
/* sanity check */
|
||||
if (act == NULL)
|
||||
return 0;
|
||||
|
||||
/* just loop through all F-Curves */
|
||||
for (fcu= act->curves.first; fcu; fcu= fcu->next) {
|
||||
if (ANIM_fcurve_keys_bezier_loop(bed, fcu, bezt_ok, bezt_cb, fcu_cb))
|
||||
@ -154,6 +162,10 @@ static short act_keys_bezier_loop(BeztEditData *bed, bAction *act, BeztEditFunc
|
||||
/* This function is used to loop over the keyframe data of an AnimData block */
|
||||
static short adt_keys_bezier_loop(BeztEditData *bed, AnimData *adt, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, FcuEditFunc fcu_cb, int filterflag)
|
||||
{
|
||||
/* sanity check */
|
||||
if (adt == NULL)
|
||||
return 0;
|
||||
|
||||
/* drivers or actions? */
|
||||
if (filterflag & ADS_FILTER_ONLYDRIVERS) {
|
||||
FCurve *fcu;
|
||||
@ -178,6 +190,10 @@ static short ob_keys_bezier_loop(BeztEditData *bed, Object *ob, BeztEditFunc bez
|
||||
{
|
||||
Key *key= ob_get_key(ob);
|
||||
|
||||
/* sanity check */
|
||||
if (ob == NULL)
|
||||
return 0;
|
||||
|
||||
/* firstly, Object's own AnimData */
|
||||
if (ob->adt)
|
||||
adt_keys_bezier_loop(bed, ob->adt, bezt_ok, bezt_cb, fcu_cb, filterflag);
|
||||
@ -194,7 +210,11 @@ static short ob_keys_bezier_loop(BeztEditData *bed, Object *ob, BeztEditFunc bez
|
||||
/* This function is used to loop over the keyframe data in a Scene */
|
||||
static short scene_keys_bezier_loop(BeztEditData *bed, Scene *sce, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, FcuEditFunc fcu_cb, int filterflag)
|
||||
{
|
||||
World *wo= sce->world;
|
||||
World *wo= (sce) ? sce->world : NULL;
|
||||
|
||||
/* sanity check */
|
||||
if (sce == NULL)
|
||||
return 0;
|
||||
|
||||
/* Scene's own animation */
|
||||
if (sce->adt)
|
||||
@ -231,7 +251,7 @@ short ANIM_animchannel_keys_bezier_loop(BeztEditData *bed, bAnimListElem *ale, B
|
||||
return act_keys_bezier_loop(bed, (bAction *)ale->data, bezt_ok, bezt_cb, fcu_cb);
|
||||
|
||||
case ALE_OB: /* object */
|
||||
return ob_keys_bezier_loop(bed, (Object *)ale->data, bezt_ok, bezt_cb, fcu_cb, filterflag);
|
||||
return ob_keys_bezier_loop(bed, (Object *)ale->key_data, bezt_ok, bezt_cb, fcu_cb, filterflag);
|
||||
case ALE_SCE: /* scene */
|
||||
return scene_keys_bezier_loop(bed, (Scene *)ale->data, bezt_ok, bezt_cb, fcu_cb, filterflag);
|
||||
}
|
||||
|
@ -52,6 +52,8 @@
|
||||
#include "ED_keyframing.h"
|
||||
#include "ED_keyframes_edit.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
/* This file contains code for various keyframe-editing tools which are 'destructive'
|
||||
* (i.e. they will modify the order of the keyframes, and change the size of the array).
|
||||
* While some of these tools may eventually be moved out into blenkernel, for now, it is
|
||||
|
@ -1,5 +1,30 @@
|
||||
/* Testing code for 2.5 animation system
|
||||
* Copyright 2009, Joshua Leung
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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) 2009 Blender Foundation, Joshua Leung
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Joshua Leung (full recode)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -29,6 +54,7 @@
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_constraint.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_nla.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_context.h"
|
||||
@ -697,35 +723,45 @@ static float visualkey_get_value (PointerRNA *ptr, PropertyRNA *prop, int array_
|
||||
|
||||
/* ------------------------- Insert Key API ------------------------- */
|
||||
|
||||
/* Main Keyframing API call:
|
||||
* Use this when validation of necessary animation data isn't necessary as it
|
||||
* already exists. It will insert a keyframe using the current value being keyframed.
|
||||
/* Secondary Keyframing API call:
|
||||
* Use this when validation of necessary animation data is not necessary, since an RNA-pointer to the necessary
|
||||
* data being keyframed, and a pointer to the F-Curve to use have both been provided.
|
||||
*
|
||||
* The flag argument is used for special settings that alter the behaviour of
|
||||
* the keyframe insertion. These include the 'visual' keyframing modes, quick refresh,
|
||||
* and extra keyframe filtering.
|
||||
*/
|
||||
short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag)
|
||||
short insert_keyframe_direct (PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float cfra, short flag)
|
||||
{
|
||||
PointerRNA id_ptr, ptr;
|
||||
PropertyRNA *prop;
|
||||
FCurve *fcu;
|
||||
float curval= 0.0f;
|
||||
|
||||
/* validate pointer first - exit if failure */
|
||||
RNA_id_pointer_create(id, &id_ptr);
|
||||
if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
|
||||
printf("Insert Key: Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path);
|
||||
/* no F-Curve to add keyframe to? */
|
||||
if (fcu == NULL) {
|
||||
printf("ERROR: no F-Curve to add keyframes to \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get F-Curve - if no action is provided, keyframe to the default one attached to this ID-block */
|
||||
if (act == NULL)
|
||||
act= verify_adt_action(id, 1);
|
||||
fcu= verify_fcurve(act, group, rna_path, array_index, 1);
|
||||
/* if no property given yet, try to validate from F-Curve info */
|
||||
if ((ptr.id.data == NULL) && (ptr.data==NULL)) {
|
||||
printf("ERROR: no RNA-pointer available to retrieve values for keyframing from\n");
|
||||
return 0;
|
||||
}
|
||||
if (prop == NULL) {
|
||||
PointerRNA tmp_ptr;
|
||||
|
||||
/* only continue if we have an F-Curve to add keyframe to */
|
||||
if (fcu) {
|
||||
float curval= 0.0f;
|
||||
/* try to get property we should be affecting */
|
||||
if ((RNA_path_resolve(&ptr, fcu->rna_path, &tmp_ptr, &prop) == 0) || (prop == NULL)) {
|
||||
/* property not found... */
|
||||
char *idname= (ptr.id.data) ? ((ID *)ptr.id.data)->name : "<No ID-Pointer>";
|
||||
|
||||
printf("Insert Key: Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", idname, fcu->rna_path);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
/* property found, so overwrite 'ptr' to make later code easier */
|
||||
ptr= tmp_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* set additional flags for the F-Curve (i.e. only integer values) */
|
||||
fcu->flag &= ~(FCURVE_INT_VALUES|FCURVE_DISCRETE_VALUES);
|
||||
@ -746,21 +782,6 @@ short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_
|
||||
break;
|
||||
}
|
||||
|
||||
/* apply special time tweaking */
|
||||
// XXX check on this stuff...
|
||||
if (GS(id->name) == ID_OB) {
|
||||
//Object *ob= (Object *)id;
|
||||
|
||||
/* apply NLA-scaling (if applicable) */
|
||||
//cfra= get_action_frame(ob, cfra);
|
||||
|
||||
/* ancient time-offset cruft */
|
||||
//if ( (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)) ) {
|
||||
// /* actually frametofloat calc again! */
|
||||
// cfra-= give_timeoffset(ob)*scene->r.framelen;
|
||||
//}
|
||||
}
|
||||
|
||||
/* obtain value to give keyframe */
|
||||
if ( (flag & INSERTKEY_MATRIX) &&
|
||||
(visualkey_can_use(&ptr, prop)) )
|
||||
@ -769,11 +790,11 @@ short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_
|
||||
* it works by keyframing using a value extracted from the final matrix
|
||||
* instead of using the kt system to extract a value.
|
||||
*/
|
||||
curval= visualkey_get_value(&ptr, prop, array_index);
|
||||
curval= visualkey_get_value(&ptr, prop, fcu->array_index);
|
||||
}
|
||||
else {
|
||||
/* read value from system */
|
||||
curval= setting_get_rna_value(&ptr, prop, array_index);
|
||||
curval= setting_get_rna_value(&ptr, prop, fcu->array_index);
|
||||
}
|
||||
|
||||
/* only insert keyframes where they are needed */
|
||||
@ -808,15 +829,59 @@ short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_
|
||||
/* return success */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* failed */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* no F-Curve to add keyframes to */
|
||||
printf("ERROR: no F-Curve to add keyframes to \n");
|
||||
/* Main Keyframing API call:
|
||||
* Use this when validation of necessary animation data is necessary, since it may not exist yet.
|
||||
*
|
||||
* The flag argument is used for special settings that alter the behaviour of
|
||||
* the keyframe insertion. These include the 'visual' keyframing modes, quick refresh,
|
||||
* and extra keyframe filtering.
|
||||
*/
|
||||
short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag)
|
||||
{
|
||||
PointerRNA id_ptr, ptr;
|
||||
PropertyRNA *prop;
|
||||
FCurve *fcu;
|
||||
|
||||
/* return failure */
|
||||
/* validate pointer first - exit if failure */
|
||||
RNA_id_pointer_create(id, &id_ptr);
|
||||
if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
|
||||
printf("Insert Key: Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get F-Curve - if no action is provided, keyframe to the default one attached to this ID-block */
|
||||
if (act == NULL) {
|
||||
AnimData *adt= BKE_animdata_from_id(id);
|
||||
|
||||
/* get action to add F-Curve+keyframe to */
|
||||
act= verify_adt_action(id, 1);
|
||||
|
||||
/* apply NLA-mapping to frame to use (if applicable) */
|
||||
cfra= BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
fcu= verify_fcurve(act, group, rna_path, array_index, 1);
|
||||
|
||||
/* apply special time tweaking */
|
||||
// XXX check on this stuff...
|
||||
if (GS(id->name) == ID_OB) {
|
||||
//Object *ob= (Object *)id;
|
||||
|
||||
/* ancient time-offset cruft */
|
||||
//if ( (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)) ) {
|
||||
// /* actually frametofloat calc again! */
|
||||
// cfra-= give_timeoffset(ob)*scene->r.framelen;
|
||||
//}
|
||||
}
|
||||
|
||||
/* insert keyframe */
|
||||
return insert_keyframe_direct(ptr, prop, fcu, cfra, flag);
|
||||
}
|
||||
|
||||
/* ************************************************** */
|
||||
/* KEYFRAME DELETION */
|
||||
|
||||
@ -839,6 +904,9 @@ short delete_keyframe (ID *id, bAction *act, const char group[], const char rna_
|
||||
/* if no action is provided, use the default one attached to this ID-block */
|
||||
AnimData *adt= BKE_animdata_from_id(id);
|
||||
act= adt->action;
|
||||
|
||||
/* apply NLA-mapping to frame to use (if applicable) */
|
||||
cfra= BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
/* we don't check the validity of the path here yet, but it should be ok... */
|
||||
fcu= verify_fcurve(act, group, rna_path, array_index, 0);
|
||||
@ -852,9 +920,6 @@ short delete_keyframe (ID *id, bAction *act, const char group[], const char rna_
|
||||
if (GS(id->name) == ID_OB) {
|
||||
//Object *ob= (Object *)id;
|
||||
|
||||
/* apply NLA-scaling (if applicable) */
|
||||
// cfra= get_action_frame(ob, cfra);
|
||||
|
||||
/* ancient time-offset cruft */
|
||||
//if ( (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)) ) {
|
||||
// /* actually frametofloat calc again! */
|
||||
@ -1241,6 +1306,13 @@ static int insert_key_button_exec (bContext *C, wmOperator *op)
|
||||
|
||||
MEM_freeN(path);
|
||||
}
|
||||
else if (ptr.type == &RNA_NlaStrip) {
|
||||
/* handle special vars for NLA-strips */
|
||||
NlaStrip *strip= (NlaStrip *)ptr.data;
|
||||
FCurve *fcu= list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), 0);
|
||||
|
||||
success+= insert_keyframe_direct(ptr, prop, fcu, cfra, 0);
|
||||
}
|
||||
else {
|
||||
if (G.f & G_DEBUG)
|
||||
printf("Button Insert-Key: no path to property \n");
|
||||
@ -1358,6 +1430,31 @@ void ANIM_OT_delete_keyframe_button (wmOperatorType *ot)
|
||||
|
||||
/* --------------- API/Per-Datablock Handling ------------------- */
|
||||
|
||||
/* Checks if some F-Curve has a keyframe for a given frame */
|
||||
short fcurve_frame_has_keyframe (FCurve *fcu, float frame, short filter)
|
||||
{
|
||||
/* quick sanity check */
|
||||
if (fcu == NULL)
|
||||
return 0;
|
||||
|
||||
/* we either include all regardless of muting, or only non-muted */
|
||||
if ((filter & ANIMFILTER_KEYS_MUTED) || (fcu->flag & FCURVE_MUTED)==0) {
|
||||
short replace = -1;
|
||||
int i = binarysearch_bezt_index(fcu->bezt, frame, fcu->totvert, &replace);
|
||||
|
||||
/* binarysearch_bezt_index will set replace to be 0 or 1
|
||||
* - obviously, 1 represents a match
|
||||
*/
|
||||
if (replace) {
|
||||
/* sanity check: 'i' may in rare cases exceed arraylen */
|
||||
if ((i >= 0) && (i < fcu->totvert))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Checks whether an Action has a keyframe for a given frame
|
||||
* Since we're only concerned whether a keyframe exists, we can simply loop until a match is found...
|
||||
*/
|
||||
@ -1379,22 +1476,10 @@ short action_frame_has_keyframe (bAction *act, float frame, short filter)
|
||||
for (fcu= act->curves.first; fcu; fcu= fcu->next) {
|
||||
/* only check if there are keyframes (currently only of type BezTriple) */
|
||||
if (fcu->bezt && fcu->totvert) {
|
||||
/* we either include all regardless of muting, or only non-muted */
|
||||
if ((filter & ANIMFILTER_KEYS_MUTED) || (fcu->flag & FCURVE_MUTED)==0) {
|
||||
short replace = -1;
|
||||
int i = binarysearch_bezt_index(fcu->bezt, frame, fcu->totvert, &replace);
|
||||
|
||||
/* binarysearch_bezt_index will set replace to be 0 or 1
|
||||
* - obviously, 1 represents a match
|
||||
*/
|
||||
if (replace) {
|
||||
/* sanity check: 'i' may in rare cases exceed arraylen */
|
||||
if ((i >= 0) && (i < fcu->totvert))
|
||||
if (fcurve_frame_has_keyframe(fcu, frame, filter))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* nothing found */
|
||||
return 0;
|
||||
|
@ -1,5 +1,30 @@
|
||||
/* Testing code for 2.5 animation system
|
||||
* Copyright 2009, Joshua Leung
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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) 2009 Blender Foundation, Joshua Leung
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Joshua Leung (full recode)
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -1060,6 +1085,9 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet *
|
||||
case ID_MA: /* Material Keyframes */
|
||||
WM_event_add_notifier(C, NC_MATERIAL|ND_KEYS, ksp->id);
|
||||
break;
|
||||
default: /* Any keyframes */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1166,6 +1194,9 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet *
|
||||
case ID_MA: /* Material Keyframes */
|
||||
WM_event_add_notifier(C, NC_MATERIAL|ND_KEYS, cks->id);
|
||||
break;
|
||||
default: /* Any keyframes */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ typedef struct RigControl {
|
||||
} RigControl;
|
||||
|
||||
void BIF_retargetArc(struct bContext *C, ReebArc *earc, RigGraph *template_rigg);
|
||||
RigGraph *RIG_graphFromArmature(struct bContext *C, struct Object *ob, struct bArmature *arm);
|
||||
RigGraph *RIG_graphFromArmature(const struct bContext *C, struct Object *ob, struct bArmature *arm);
|
||||
int RIG_nbJoints(RigGraph *rg);
|
||||
char *RIG_nameBone(RigGraph *rg, int arc_index, int bone_index);
|
||||
void RIG_freeRigGraph(BGraph *rg);
|
||||
|
@ -42,7 +42,7 @@ void ARMATURE_OT_subdivide_multi(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_parent_set(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_parent_clear(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_select_all_toggle(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_select_invert(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_select_inverse(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_select_hierarchy(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_select_linked(struct wmOperatorType *ot);
|
||||
void ARMATURE_OT_delete(struct wmOperatorType *ot);
|
||||
@ -56,10 +56,11 @@ void POSE_OT_rot_clear(struct wmOperatorType *ot);
|
||||
void POSE_OT_loc_clear(struct wmOperatorType *ot);
|
||||
void POSE_OT_scale_clear(struct wmOperatorType *ot);
|
||||
void POSE_OT_select_all_toggle(struct wmOperatorType *ot);
|
||||
void POSE_OT_select_invert(struct wmOperatorType *ot);
|
||||
void POSE_OT_select_inverse(struct wmOperatorType *ot);
|
||||
void POSE_OT_select_parent(struct wmOperatorType *ot);
|
||||
void POSE_OT_select_hierarchy(struct wmOperatorType *ot);
|
||||
void POSE_OT_select_linked(struct wmOperatorType *ot);
|
||||
void POSE_OT_select_constraint_target(struct wmOperatorType *ot);
|
||||
|
||||
void SKETCH_OT_gesture(struct wmOperatorType *ot);
|
||||
void SKETCH_OT_delete(struct wmOperatorType *ot);
|
||||
|
@ -121,7 +121,7 @@ void ED_operatortypes_armature(void)
|
||||
WM_operatortype_append(ARMATURE_OT_parent_clear);
|
||||
|
||||
WM_operatortype_append(ARMATURE_OT_select_all_toggle);
|
||||
WM_operatortype_append(ARMATURE_OT_select_invert);
|
||||
WM_operatortype_append(ARMATURE_OT_select_inverse);
|
||||
WM_operatortype_append(ARMATURE_OT_select_hierarchy);
|
||||
WM_operatortype_append(ARMATURE_OT_select_linked);
|
||||
|
||||
@ -148,11 +148,12 @@ void ED_operatortypes_armature(void)
|
||||
WM_operatortype_append(POSE_OT_scale_clear);
|
||||
|
||||
WM_operatortype_append(POSE_OT_select_all_toggle);
|
||||
WM_operatortype_append(POSE_OT_select_invert);
|
||||
WM_operatortype_append(POSE_OT_select_inverse);
|
||||
|
||||
WM_operatortype_append(POSE_OT_select_parent);
|
||||
WM_operatortype_append(POSE_OT_select_hierarchy);
|
||||
WM_operatortype_append(POSE_OT_select_linked);
|
||||
WM_operatortype_append(POSE_OT_select_constraint_target);
|
||||
|
||||
/* POSELIB */
|
||||
WM_operatortype_append(POSELIB_OT_browse_interactive);
|
||||
@ -188,20 +189,18 @@ void ED_keymap_armature(wmWindowManager *wm)
|
||||
WM_keymap_add_item(keymap, "ARMATURE_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "ARMATURE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "ARMATURE_OT_select_invert", IKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "ARMATURE_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "ARMATURE_OT_test", TKEY, KM_PRESS, 0, 0); // XXX temp test for context iterators... to be removed
|
||||
|
||||
kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0);
|
||||
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
|
||||
RNA_boolean_set(kmi->ptr, "extend", 0);
|
||||
kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
|
||||
RNA_boolean_set(kmi->ptr, "extend", 1);
|
||||
|
||||
kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
|
||||
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
|
||||
RNA_boolean_set(kmi->ptr, "extend", 0);
|
||||
kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
|
||||
RNA_boolean_set(kmi->ptr, "extend", 1);
|
||||
@ -234,20 +233,18 @@ void ED_keymap_armature(wmWindowManager *wm)
|
||||
WM_keymap_add_item(keymap, "POSE_OT_scale_clear", SKEY, KM_PRESS, KM_ALT, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "POSE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "POSE_OT_select_invert", IKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "POSE_OT_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "POSE_OT_select_parent", PKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
|
||||
kmi= WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0);
|
||||
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
|
||||
RNA_boolean_set(kmi->ptr, "extend", 0);
|
||||
kmi= WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
|
||||
RNA_boolean_set(kmi->ptr, "extend", 1);
|
||||
|
||||
kmi= WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
|
||||
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
|
||||
RNA_boolean_set(kmi->ptr, "extend", 0);
|
||||
kmi= WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
|
||||
RNA_boolean_set(kmi->ptr, "extend", 1);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user