forked from bartvdbraak/blender
Merge from trunk -r 24247:24313, -r 24313:24390.
This commit is contained in:
parent
7c80440dda
commit
58e44463fb
@ -518,9 +518,9 @@ IF(APPLE)
|
||||
ENDIF (WITH_COCOA)
|
||||
|
||||
IF(WITH_OPENMP)
|
||||
SET(LLIBS "${LLIBS} -lgomp ")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ")
|
||||
SET(LLIBS "${LLIBS} -lgomp")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
|
||||
ENDIF(WITH_OPENMP)
|
||||
|
||||
IF (WITH_OPENCOLLADA)
|
||||
@ -555,6 +555,16 @@ IF(APPLE)
|
||||
SET(TIFF_INC ${TIFF}/include)
|
||||
|
||||
SET(EXETYPE MACOSX_BUNDLE)
|
||||
|
||||
|
||||
IF(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "-O3 -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
|
||||
ELSEIF(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "-O3 -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
|
||||
ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
|
||||
|
||||
ENDIF(APPLE)
|
||||
|
||||
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
|
@ -124,7 +124,10 @@ if toolset:
|
||||
#if env:
|
||||
# btools.SetupSpawn(env)
|
||||
else:
|
||||
env = BlenderEnvironment(ENV = os.environ)
|
||||
if bitness==64 and platform=='win32':
|
||||
env = BlenderEnvironment(ENV = os.environ, MSVS_ARCH='amd64')
|
||||
else:
|
||||
env = BlenderEnvironment(ENV = os.environ)
|
||||
|
||||
if not env:
|
||||
print "Could not create a build environment"
|
||||
|
@ -158,7 +158,7 @@ BF_COLLADA_LIB = 'bf_collada'
|
||||
|
||||
BF_OPENCOLLADA = LIBDIR + '/opencollada'
|
||||
BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
|
||||
BF_OPENCOLLADA_LIB = 'opencollada'
|
||||
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver xml2 pcre'
|
||||
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
|
||||
|
||||
WITH_BF_STATICOPENGL = False
|
||||
|
@ -202,7 +202,6 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
|
||||
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
|
||||
}
|
||||
|
||||
input.m_stackAlloc = dispatchInfo.m_stackAllocator;
|
||||
input.m_transformA = body0->getWorldTransform();
|
||||
input.m_transformB = body1->getWorldTransform();
|
||||
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
const btConvexShape* convexA,const btConvexShape* convexB,
|
||||
const btTransform& transA,const btTransform& transB,
|
||||
btVector3& v, btVector3& pa, btVector3& pb,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
|
||||
class btIDebugDraw* debugDraw
|
||||
) = 0;
|
||||
|
||||
|
||||
|
4
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
vendored
4
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
vendored
@ -41,15 +41,13 @@ struct btDiscreteCollisionDetectorInterface
|
||||
struct ClosestPointInput
|
||||
{
|
||||
ClosestPointInput()
|
||||
:m_maximumDistanceSquared(btScalar(1e30)),
|
||||
m_stackAlloc(0)
|
||||
:m_maximumDistanceSquared(btScalar(1e30))
|
||||
{
|
||||
}
|
||||
|
||||
btTransform m_transformA;
|
||||
btTransform m_transformB;
|
||||
btScalar m_maximumDistanceSquared;
|
||||
btStackAlloc* m_stackAlloc;
|
||||
};
|
||||
|
||||
virtual ~btDiscreteCollisionDetectorInterface() {};
|
||||
|
2
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
vendored
2
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
vendored
@ -25,7 +25,7 @@ bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& sim
|
||||
const btConvexShape* pConvexA, const btConvexShape* pConvexB,
|
||||
const btTransform& transformA, const btTransform& transformB,
|
||||
btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB,
|
||||
class btIDebugDraw* debugDraw, btStackAlloc* stackAlloc )
|
||||
class btIDebugDraw* debugDraw )
|
||||
{
|
||||
|
||||
(void)debugDraw;
|
||||
|
@ -29,7 +29,7 @@ class btGjkEpaPenetrationDepthSolver : public btConvexPenetrationDepthSolver
|
||||
const btConvexShape* pConvexA, const btConvexShape* pConvexB,
|
||||
const btTransform& transformA, const btTransform& transformB,
|
||||
btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc );
|
||||
class btIDebugDraw* debugDraw );
|
||||
|
||||
private :
|
||||
|
||||
|
@ -293,7 +293,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
|
||||
m_minkowskiA,m_minkowskiB,
|
||||
localTransA,localTransB,
|
||||
m_cachedSeparatingAxis, tmpPointOnA, tmpPointOnB,
|
||||
debugDraw,input.m_stackAlloc
|
||||
debugDraw
|
||||
);
|
||||
|
||||
if (isValid2)
|
||||
|
3
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
vendored
3
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
vendored
@ -71,11 +71,10 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
|
||||
const btConvexShape* convexA,const btConvexShape* convexB,
|
||||
const btTransform& transA,const btTransform& transB,
|
||||
btVector3& v, btVector3& pa, btVector3& pb,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
|
||||
class btIDebugDraw* debugDraw
|
||||
)
|
||||
{
|
||||
|
||||
(void)stackAlloc;
|
||||
(void)v;
|
||||
|
||||
|
||||
|
2
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
vendored
2
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
vendored
@ -28,7 +28,7 @@ public:
|
||||
const btConvexShape* convexA,const btConvexShape* convexB,
|
||||
const btTransform& transA,const btTransform& transB,
|
||||
btVector3& v, btVector3& pa, btVector3& pb,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
|
||||
class btIDebugDraw* debugDraw
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -365,10 +365,6 @@ double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float
|
||||
btPointCollector gjkOutput;
|
||||
btGjkPairDetector::ClosestPointInput input;
|
||||
|
||||
btStackAlloc gStackAlloc(1024*1024*2);
|
||||
|
||||
input.m_stackAlloc = &gStackAlloc;
|
||||
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
|
||||
|
@ -5,8 +5,5 @@ sources = env.Glob('intern/*.cpp')
|
||||
|
||||
incs = 'intern ../container ../moto/include ../memutil'
|
||||
|
||||
if (env['OURPLATFORM'] == 'win32-mingw'):
|
||||
env.BlenderLib ('blender_BSP', sources, Split(incs), [], libtype='core', priority=26 )
|
||||
else:
|
||||
env.BlenderLib ('blender_BSP', sources, Split(incs), [], libtype='core', priority=20 )
|
||||
env.BlenderLib ('blender_BSP', sources, Split(incs), [], libtype='core', priority=200 )
|
||||
|
||||
|
@ -5,4 +5,4 @@ sources = env.Glob('intern/*.cpp')
|
||||
|
||||
incs = '. ../moto/include ../container ../memutil'
|
||||
|
||||
env.BlenderLib ('bf_decimation', sources, Split(incs) , [], libtype=['core'], priority = [10] )
|
||||
env.BlenderLib ('bf_decimation', sources, Split(incs) , [], libtype=['core'], priority = [200] )
|
||||
|
@ -786,7 +786,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
|
||||
case NSFlagsChanged:
|
||||
handleKeyEvent(event);
|
||||
|
||||
/* Support system-wide keyboard shortcuts, like Exposé, ...) =>included in always NSApp sendEvent */
|
||||
/* Support system-wide keyboard shortcuts, like Exposé, ...) =>included in always NSApp sendEvent */
|
||||
/* if (([event modifierFlags] & NSCommandKeyMask) || [event type] == NSFlagsChanged) {
|
||||
[NSApp sendEvent:event];
|
||||
}*/
|
||||
@ -891,8 +891,8 @@ GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest()
|
||||
//Check open windows if some changes are not saved
|
||||
if (m_windowManager->getAnyModifiedState())
|
||||
{
|
||||
int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes have not been saved. Do you really want to quit ?",
|
||||
@"Cancel", @"Quit anyway", nil);
|
||||
int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes have not been saved.\nDo you really want to quit ?",
|
||||
@"Cancel", @"Quit Anyway", nil);
|
||||
if (shouldQuit == NSAlertAlternateReturn)
|
||||
{
|
||||
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );
|
||||
|
@ -132,8 +132,8 @@
|
||||
|
||||
GHOST_SystemWin32::GHOST_SystemWin32()
|
||||
: m_hasPerformanceCounter(false), m_freq(0), m_start(0),
|
||||
m_seperateLeftRight(false),
|
||||
m_seperateLeftRightInitialized(false)
|
||||
m_separateLeftRight(false),
|
||||
m_separateLeftRightInitialized(false)
|
||||
{
|
||||
m_displayManager = new GHOST_DisplayManagerWin32 ();
|
||||
GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n");
|
||||
@ -274,7 +274,7 @@ GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys& keys) cons
|
||||
It didn't work all that well on some newer hardware, and worked less
|
||||
well with the passage of time, so it was fully disabled in ME.
|
||||
*/
|
||||
if (m_seperateLeftRight && m_seperateLeftRightInitialized) {
|
||||
if (m_separateLeftRight && m_separateLeftRightInitialized) {
|
||||
bool down = HIBYTE(::GetKeyState(VK_LSHIFT)) != 0;
|
||||
keys.set(GHOST_kModifierKeyLeftShift, down);
|
||||
down = HIBYTE(::GetKeyState(VK_RSHIFT)) != 0;
|
||||
@ -581,29 +581,29 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
case VK_SHIFT:
|
||||
case VK_CONTROL:
|
||||
case VK_MENU:
|
||||
if (!system->m_seperateLeftRightInitialized) {
|
||||
if (!system->m_separateLeftRightInitialized) {
|
||||
// Check whether this system supports seperate left and right keys
|
||||
switch (wParam) {
|
||||
case VK_SHIFT:
|
||||
system->m_seperateLeftRight =
|
||||
system->m_separateLeftRight =
|
||||
(HIBYTE(::GetKeyState(VK_LSHIFT)) != 0) ||
|
||||
(HIBYTE(::GetKeyState(VK_RSHIFT)) != 0) ?
|
||||
true : false;
|
||||
break;
|
||||
case VK_CONTROL:
|
||||
system->m_seperateLeftRight =
|
||||
system->m_separateLeftRight =
|
||||
(HIBYTE(::GetKeyState(VK_LCONTROL)) != 0) ||
|
||||
(HIBYTE(::GetKeyState(VK_RCONTROL)) != 0) ?
|
||||
true : false;
|
||||
break;
|
||||
case VK_MENU:
|
||||
system->m_seperateLeftRight =
|
||||
system->m_separateLeftRight =
|
||||
(HIBYTE(::GetKeyState(VK_LMENU)) != 0) ||
|
||||
(HIBYTE(::GetKeyState(VK_RMENU)) != 0) ?
|
||||
true : false;
|
||||
break;
|
||||
}
|
||||
system->m_seperateLeftRightInitialized = true;
|
||||
system->m_separateLeftRightInitialized = true;
|
||||
}
|
||||
system->processModifierKeys(window);
|
||||
// Bypass call to DefWindowProc
|
||||
|
@ -283,9 +283,9 @@ protected:
|
||||
/** High frequency timer variable. */
|
||||
__int64 m_start;
|
||||
/** Stores the capability of this system to distinguish left and right modifier keys. */
|
||||
bool m_seperateLeftRight;
|
||||
bool m_separateLeftRight;
|
||||
/** Stores the initialization state of the member m_leftRightDistinguishable. */
|
||||
bool m_seperateLeftRightInitialized;
|
||||
bool m_separateLeftRightInitialized;
|
||||
|
||||
};
|
||||
|
||||
|
@ -68,7 +68,7 @@ extern "C" {
|
||||
- (void)windowWillClose:(NSNotification *)notification;
|
||||
- (void)windowDidBecomeKey:(NSNotification *)notification;
|
||||
- (void)windowDidResignKey:(NSNotification *)notification;
|
||||
- (void)windowDidUpdate:(NSNotification *)notification;
|
||||
- (void)windowDidExpose:(NSNotification *)notification;
|
||||
- (void)windowDidResize:(NSNotification *)notification;
|
||||
@end
|
||||
|
||||
@ -91,13 +91,10 @@ extern "C" {
|
||||
|
||||
- (void)windowDidResignKey:(NSNotification *)notification
|
||||
{
|
||||
//The window is no more key when its own view becomes fullscreen
|
||||
//but ghost doesn't know the view/window difference, so hide this fact
|
||||
if (associatedWindow->getState() != GHOST_kWindowStateFullScreen)
|
||||
systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow);
|
||||
systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow);
|
||||
}
|
||||
|
||||
- (void)windowDidUpdate:(NSNotification *)notification
|
||||
- (void)windowDidExpose:(NSNotification *)notification
|
||||
{
|
||||
systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow);
|
||||
}
|
||||
@ -622,6 +619,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
|
||||
//Make window normal and resize it
|
||||
[m_window setStyleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)];
|
||||
[m_window setFrame:[[m_window screen] visibleFrame] display:YES];
|
||||
//TODO for 10.6 only : window title is forgotten after the style change
|
||||
[m_window makeFirstResponder:m_openGLView];
|
||||
#else
|
||||
//With 10.5, we need to create a new window to change its style to borderless
|
||||
|
@ -76,7 +76,7 @@ abort();
|
||||
#endif /* breakpoint */
|
||||
|
||||
|
||||
#if defined(WIN32) && !defined(__GNUC__)
|
||||
#if defined(_WIN32) && !defined(__GNUC__)
|
||||
#define MT_assert(predicate) assert(predicate)
|
||||
#else
|
||||
|
||||
|
@ -74,7 +74,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="libsamplerate.lib SDL.lib freetype2ST.lib gnu_gettext.lib qtmlClient.lib OpenAL32.lib wrap_oal.lib ws2_32.lib dxguid.lib opengl32.lib libjpeg.lib glu32.lib vfw32.lib winmm.lib libpng_st.lib zlib.lib python31.lib pthreadVSE2.lib pthreadVC2.lib libtiff.lib Half.lib Iex.lib IlmImf.lib Imath.lib IlmThread.lib avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib avdevice-52.lib libsndfile-1.lib opencollada.lib"
|
||||
AdditionalDependencies="libsamplerate.lib SDL.lib freetype2ST.lib gnu_gettext.lib qtmlClient.lib OpenAL32.lib wrap_oal.lib ws2_32.lib dxguid.lib opengl32.lib libjpeg.lib glu32.lib vfw32.lib winmm.lib libpng_st.lib zlib.lib python31.lib pthreadVSE2.lib pthreadVC2.lib libtiff.lib Half.lib Iex.lib IlmImf.lib Imath.lib IlmThread.lib avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib avdevice-52.lib libsndfile-1.lib OpenCOLLADABaseUtils.lib OpenCOLLADAFramework.lib OpenCOLLADAStreamWriter.lib OpenCOLLADASaxFrameworkLoader.lib pcre.lib UTF.lib GeneratedSaxParser.lib MathMLSolver.lib xml2.lib"
|
||||
ShowProgress="0"
|
||||
OutputFile="..\..\..\install\msvc_9\blender.exe"
|
||||
LinkIncremental="1"
|
||||
@ -169,7 +169,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386
"
|
||||
AdditionalDependencies="libsamplerate.lib SDL.lib freetype2ST.lib gnu_gettext.lib qtmlClient.lib OpenAL32.lib wrap_oal.lib ws2_32.lib dxguid.lib opengl32.lib libjpeg.lib glu32.lib vfw32.lib winmm.lib libpng_st.lib zlib.lib python31_d.lib pthreadVSE2.lib pthreadVC2.lib libtiff.lib Half_d.lib Iex_d.lib Imath_d.lib IlmImf_d.lib IlmThread_d.lib avcodec-52.lib avformat-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib libsndfile-1.lib opencollada.lib"
|
||||
AdditionalDependencies="libsamplerate.lib SDL.lib freetype2ST.lib gnu_gettext.lib qtmlClient.lib OpenAL32.lib wrap_oal.lib ws2_32.lib dxguid.lib opengl32.lib libjpeg.lib glu32.lib vfw32.lib winmm.lib libpng_st.lib zlib.lib python31_d.lib pthreadVSE2.lib pthreadVC2.lib libtiff.lib Half_d.lib Iex_d.lib Imath_d.lib IlmImf_d.lib IlmThread_d.lib avcodec-52.lib avformat-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib libsndfile-1.lib OpenCOLLADABaseUtils.lib OpenCOLLADAFramework.lib OpenCOLLADAStreamWriter.lib OpenCOLLADASaxFrameworkLoader.lib pcre.lib UTF.lib GeneratedSaxParser.lib MathMLSolver.lib xml2.lib"
|
||||
ShowProgress="0"
|
||||
OutputFile="..\..\..\install\msvc_9d\blender.exe"
|
||||
LinkIncremental="2"
|
||||
|
@ -1109,7 +1109,7 @@ def save_3ds(filename, context):
|
||||
# Blender.Draw.PupMenu("Error%t|This script requires a full python installation")
|
||||
# # save_3ds('/test_b.3ds')
|
||||
from bpy.props import *
|
||||
class EXPORT_OT_autodesk_3ds(bpy.types.Operator):
|
||||
class Export3DS(bpy.types.Operator):
|
||||
'''Export to 3DS file format (.3ds).'''
|
||||
bl_idname = "export.autodesk_3ds"
|
||||
bl_label = 'Export 3DS'
|
||||
@ -1135,9 +1135,13 @@ class EXPORT_OT_autodesk_3ds(bpy.types.Operator):
|
||||
print("Poll")
|
||||
return context.active_object != None
|
||||
|
||||
bpy.ops.add(EXPORT_OT_autodesk_3ds)
|
||||
bpy.ops.add(Export3DS)
|
||||
|
||||
# Add to a menu
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("export.autodesk_3ds", text="Autodesk 3DS...")
|
||||
|
||||
def menu_func(self, context):
|
||||
default_path = bpy.data.filename.replace(".blend", ".3ds")
|
||||
self.layout.item_stringO(Export3DS.bl_idname, "path", default_path, text="Autodesk 3DS...")
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
||||
|
@ -237,14 +237,14 @@ def sane_groupname(data): return sane_name(data, sane_name_mapping_group)
|
||||
# FORCE_CWD - dont use the basepath, just add a ./ to the filename.
|
||||
# use when we know the file will be in the basepath.
|
||||
# '''
|
||||
# fname = bpy.sys.expandpath(fname_orig)
|
||||
# fname = bpy.utils.expandpath(fname_orig)
|
||||
# # fname = Blender.sys.expandpath(fname_orig)
|
||||
# fname_strip = os.path.basename(fname)
|
||||
# # fname_strip = strip_path(fname)
|
||||
# if FORCE_CWD:
|
||||
# fname_rel = '.' + os.sep + fname_strip
|
||||
# else:
|
||||
# fname_rel = bpy.sys.relpath(fname, basepath)
|
||||
# fname_rel = bpy.utils.relpath(fname, basepath)
|
||||
# # fname_rel = Blender.sys.relpath(fname, basepath)
|
||||
# if fname_rel.startswith('//'): fname_rel = '.' + os.sep + fname_rel[2:]
|
||||
# return fname, fname_strip, fname_rel
|
||||
@ -349,7 +349,7 @@ def write(filename, batch_objects = None, \
|
||||
fbxpath = filename
|
||||
|
||||
# get the path component of filename
|
||||
tmp_exists = bpy.sys.exists(fbxpath)
|
||||
tmp_exists = bpy.utils.exists(fbxpath)
|
||||
# tmp_exists = Blender.sys.exists(fbxpath)
|
||||
|
||||
if tmp_exists != 2: # a file, we want a path
|
||||
@ -363,7 +363,7 @@ def write(filename, batch_objects = None, \
|
||||
# Draw.PupMenu('Error%t|Directory does not exist!')
|
||||
return
|
||||
|
||||
tmp_exists = bpy.sys.exists(fbxpath)
|
||||
tmp_exists = bpy.utils.exists(fbxpath)
|
||||
# tmp_exists = Blender.sys.exists(fbxpath)
|
||||
|
||||
if tmp_exists != 2:
|
||||
@ -398,7 +398,7 @@ def write(filename, batch_objects = None, \
|
||||
# path may alredy exist
|
||||
# TODO - might exist but be a file. unlikely but should probably account for it.
|
||||
|
||||
if bpy.sys.exists(new_fbxpath) == 0:
|
||||
if bpy.utils.exists(new_fbxpath) == 0:
|
||||
# if Blender.sys.exists(new_fbxpath) == 0:
|
||||
os.mkdir(new_fbxpath)
|
||||
|
||||
@ -3351,7 +3351,7 @@ def write_ui():
|
||||
|
||||
# GLOBALS.clear()
|
||||
from bpy.props import *
|
||||
class EXPORT_OT_fbx(bpy.types.Operator):
|
||||
class ExportFBX(bpy.types.Operator):
|
||||
'''Selection to an ASCII Autodesk FBX'''
|
||||
bl_idname = "export.fbx"
|
||||
bl_label = "Export FBX"
|
||||
@ -3433,7 +3433,7 @@ class EXPORT_OT_fbx(bpy.types.Operator):
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
|
||||
bpy.ops.add(EXPORT_OT_fbx)
|
||||
bpy.ops.add(ExportFBX)
|
||||
|
||||
# if __name__ == "__main__":
|
||||
# bpy.ops.EXPORT_OT_ply(filename="/tmp/test.ply")
|
||||
@ -3456,7 +3456,7 @@ bpy.ops.add(EXPORT_OT_fbx)
|
||||
# - bpy.data.remove_scene: line 366
|
||||
# - bpy.sys.time move to bpy.sys.util?
|
||||
# - new scene creation, activation: lines 327-342, 368
|
||||
# - uses bpy.sys.expandpath, *.relpath - replace at least relpath
|
||||
# - uses bpy.utils.expandpath, *.relpath - replace at least relpath
|
||||
|
||||
# SMALL or COSMETICAL
|
||||
# - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version')
|
||||
@ -3464,6 +3464,10 @@ bpy.ops.add(EXPORT_OT_fbx)
|
||||
|
||||
# Add to a menu
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("export.fbx", text="Autodesk FBX...")
|
||||
|
||||
def menu_func(self, context):
|
||||
default_path = bpy.data.filename.replace(".blend", ".fbx")
|
||||
self.layout.item_stringO(ExportFBX.bl_idname, "path", default_path, text="Autodesk FBX...")
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
||||
|
||||
|
@ -54,148 +54,148 @@ import os
|
||||
#from Blender import *
|
||||
#import BPyMessages
|
||||
try:
|
||||
from struct import pack
|
||||
from struct import pack
|
||||
except:
|
||||
pack = None
|
||||
pack = None
|
||||
|
||||
def zero_file(filepath):
|
||||
'''
|
||||
If a file fails, this replaces it with 1 char, better not remove it?
|
||||
'''
|
||||
file = open(filepath, 'w')
|
||||
file.write('\n') # apparently macosx needs some data in a blank file?
|
||||
file.close()
|
||||
'''
|
||||
If a file fails, this replaces it with 1 char, better not remove it?
|
||||
'''
|
||||
file = open(filepath, 'w')
|
||||
file.write('\n') # apparently macosx needs some data in a blank file?
|
||||
file.close()
|
||||
|
||||
def check_vertcount(mesh,vertcount):
|
||||
'''
|
||||
check and make sure the vertcount is consistent throughout the frame range
|
||||
'''
|
||||
if len(mesh.verts) != vertcount:
|
||||
raise Exception('Error, number of verts has changed during animation, cannot export')
|
||||
f.close()
|
||||
zero_file(filepath)
|
||||
return
|
||||
|
||||
|
||||
'''
|
||||
check and make sure the vertcount is consistent throughout the frame range
|
||||
'''
|
||||
if len(mesh.verts) != vertcount:
|
||||
raise Exception('Error, number of verts has changed during animation, cannot export')
|
||||
f.close()
|
||||
zero_file(filepath)
|
||||
return
|
||||
|
||||
|
||||
def write(filename, sce, ob, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS):
|
||||
if not pack:
|
||||
raise Exception('Error, this script requires the "pack" module')
|
||||
|
||||
if ob.type != 'MESH':
|
||||
raise Exception('Error, active object is not a mesh')
|
||||
"""
|
||||
Window.EditMode(0)
|
||||
Blender.Window.WaitCursor(1)
|
||||
"""
|
||||
Blender.Window.WaitCursor(1)
|
||||
|
||||
mesh_orig = Mesh.New()
|
||||
mesh_orig.getFromObject(ob.name)
|
||||
"""
|
||||
orig_frame = sce.current_frame
|
||||
sce.set_frame(PREF_STARTFRAME)
|
||||
me = ob.create_mesh(True, 'PREVIEW')
|
||||
mesh_orig = Mesh.New()
|
||||
mesh_orig.getFromObject(ob.name)
|
||||
"""
|
||||
|
||||
#Flip y and z
|
||||
mat_flip= Mathutils.Matrix(\
|
||||
[1.0, 0.0, 0.0, 0.0],\
|
||||
[0.0, 0.0, 1.0, 0.0],\
|
||||
[0.0, 1.0, 0.0, 0.0],\
|
||||
[0.0, 0.0, 0.0, 1.0],\
|
||||
)
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
numverts = len(me.verts)
|
||||
orig_frame = sce.current_frame
|
||||
sce.set_frame(PREF_STARTFRAME)
|
||||
me = ob.create_mesh(True, 'PREVIEW')
|
||||
|
||||
numframes = PREF_ENDFRAME-PREF_STARTFRAME+1
|
||||
PREF_FPS= float(PREF_FPS)
|
||||
f = open(filename, 'wb') #no Errors yet:Safe to create file
|
||||
|
||||
# Write the header
|
||||
f.write(pack(">2i", numframes, numverts))
|
||||
|
||||
# Write the frame times (should we use the time IPO??)
|
||||
f.write( pack(">%df" % (numframes), *[frame/PREF_FPS for frame in range(numframes)]) ) # seconds
|
||||
|
||||
#rest frame needed to keep frames in sync
|
||||
"""
|
||||
Blender.Set('curframe', PREF_STARTFRAME)
|
||||
me_tmp.getFromObject(ob.name)
|
||||
"""
|
||||
#Flip y and z
|
||||
mat_flip= Mathutils.Matrix(\
|
||||
[1.0, 0.0, 0.0, 0.0],\
|
||||
[0.0, 0.0, 1.0, 0.0],\
|
||||
[0.0, 1.0, 0.0, 0.0],\
|
||||
[0.0, 0.0, 0.0, 1.0],\
|
||||
)
|
||||
|
||||
check_vertcount(me,numverts)
|
||||
me.transform(mat_flip * ob.matrix)
|
||||
f.write(pack(">%df" % (numverts*3), *[axis for v in me.verts for axis in v.co]))
|
||||
|
||||
for frame in range(PREF_STARTFRAME,PREF_ENDFRAME+1):#in order to start at desired frame
|
||||
"""
|
||||
Blender.Set('curframe', frame)
|
||||
me_tmp.getFromObject(ob.name)
|
||||
"""
|
||||
numverts = len(me.verts)
|
||||
|
||||
sce.set_frame(frame)
|
||||
me = ob.create_mesh(True, 'PREVIEW')
|
||||
check_vertcount(me,numverts)
|
||||
me.transform(mat_flip * ob.matrix)
|
||||
|
||||
# Write the vertex data
|
||||
f.write(pack(">%df" % (numverts*3), *[axis for v in me.verts for axis in v.co]))
|
||||
|
||||
"""
|
||||
me_tmp.verts= None
|
||||
"""
|
||||
f.close()
|
||||
|
||||
print ('MDD Exported: %s frames:%d\n'% (filename, numframes-1))
|
||||
"""
|
||||
Blender.Window.WaitCursor(0)
|
||||
Blender.Set('curframe', orig_frame)
|
||||
"""
|
||||
sce.set_frame(orig_frame)
|
||||
numframes = PREF_ENDFRAME-PREF_STARTFRAME+1
|
||||
PREF_FPS= float(PREF_FPS)
|
||||
f = open(filename, 'wb') #no Errors yet:Safe to create file
|
||||
|
||||
# Write the header
|
||||
f.write(pack(">2i", numframes, numverts))
|
||||
|
||||
# Write the frame times (should we use the time IPO??)
|
||||
f.write( pack(">%df" % (numframes), *[frame/PREF_FPS for frame in range(numframes)]) ) # seconds
|
||||
|
||||
#rest frame needed to keep frames in sync
|
||||
"""
|
||||
Blender.Set('curframe', PREF_STARTFRAME)
|
||||
me_tmp.getFromObject(ob.name)
|
||||
"""
|
||||
|
||||
check_vertcount(me,numverts)
|
||||
me.transform(mat_flip * ob.matrix)
|
||||
f.write(pack(">%df" % (numverts*3), *[axis for v in me.verts for axis in v.co]))
|
||||
|
||||
for frame in range(PREF_STARTFRAME,PREF_ENDFRAME+1):#in order to start at desired frame
|
||||
"""
|
||||
Blender.Set('curframe', frame)
|
||||
me_tmp.getFromObject(ob.name)
|
||||
"""
|
||||
|
||||
sce.set_frame(frame)
|
||||
me = ob.create_mesh(True, 'PREVIEW')
|
||||
check_vertcount(me,numverts)
|
||||
me.transform(mat_flip * ob.matrix)
|
||||
|
||||
# Write the vertex data
|
||||
f.write(pack(">%df" % (numverts*3), *[axis for v in me.verts for axis in v.co]))
|
||||
|
||||
"""
|
||||
me_tmp.verts= None
|
||||
"""
|
||||
f.close()
|
||||
|
||||
print ('MDD Exported: %s frames:%d\n'% (filename, numframes-1))
|
||||
"""
|
||||
Blender.Window.WaitCursor(0)
|
||||
Blender.Set('curframe', orig_frame)
|
||||
"""
|
||||
sce.set_frame(orig_frame)
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class EXPORT_OT_mdd(bpy.types.Operator):
|
||||
'''Animated mesh to MDD vertex keyframe file.'''
|
||||
bl_idname = "export.mdd"
|
||||
bl_label = "Export MDD"
|
||||
class ExportMDD(bpy.types.Operator):
|
||||
'''Animated mesh to MDD vertex keyframe file.'''
|
||||
bl_idname = "export.mdd"
|
||||
bl_label = "Export MDD"
|
||||
|
||||
# get first scene to get min and max properties for frames, fps
|
||||
# get first scene to get min and max properties for frames, fps
|
||||
|
||||
sce = bpy.data.scenes[bpy.data.scenes.keys()[0]]
|
||||
minframe = sce.rna_type.properties["current_frame"].soft_min
|
||||
maxframe = sce.rna_type.properties["current_frame"].soft_max
|
||||
minfps = sce.render_data.rna_type.properties["fps"].soft_min
|
||||
maxfps = sce.render_data.rna_type.properties["fps"].soft_max
|
||||
sce = bpy.data.scenes[bpy.data.scenes.keys()[0]]
|
||||
minframe = sce.rna_type.properties["current_frame"].soft_min
|
||||
maxframe = sce.rna_type.properties["current_frame"].soft_max
|
||||
minfps = sce.render_data.rna_type.properties["fps"].soft_min
|
||||
maxfps = sce.render_data.rna_type.properties["fps"].soft_max
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
path = StringProperty(name="File Path", description="File path used for exporting the MDD file", maxlen= 1024, default= "tmp.mdd")
|
||||
fps = IntProperty(name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default= 25)
|
||||
start_frame = IntProperty(name="Start Frame", description="Start frame for baking", min=minframe,max=maxframe,default=1)
|
||||
end_frame = IntProperty(name="End Frame", description="End frame for baking", min=minframe, max=maxframe, default= 250)
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
path = StringProperty(name="File Path", description="File path used for exporting the MDD file", maxlen= 1024, default= "tmp.mdd")
|
||||
fps = IntProperty(name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default= 25)
|
||||
start_frame = IntProperty(name="Start Frame", description="Start frame for baking", min=minframe,max=maxframe,default=1)
|
||||
end_frame = IntProperty(name="End Frame", description="End frame for baking", min=minframe, max=maxframe, default= 250)
|
||||
|
||||
def poll(self, context):
|
||||
return context.active_object != None
|
||||
def poll(self, context):
|
||||
ob = context.active_object
|
||||
return (ob and ob.type=='MESH')
|
||||
|
||||
def execute(self, context):
|
||||
if not self.path:
|
||||
raise Exception("filename not set")
|
||||
write(self.path, context.scene, context.active_object,
|
||||
self.start_frame, self.end_frame, self.fps )
|
||||
return ('FINISHED',)
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
def execute(self, context):
|
||||
if not self.path:
|
||||
raise Exception("filename not set")
|
||||
write(self.path, context.scene, context.active_object,
|
||||
self.start_frame, self.end_frame, self.fps )
|
||||
return ('FINISHED',)
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
bpy.ops.add(EXPORT_OT_mdd)
|
||||
bpy.ops.add(ExportMDD)
|
||||
|
||||
# Add to a menu
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("export.mdd", text="Vertex Keyframe Animation (.mdd)...")
|
||||
|
||||
def menu_func(self, context):
|
||||
default_path = bpy.data.filename.replace(".blend", ".mdd")
|
||||
self.layout.item_stringO(ExportMDD.bl_idname, "path", default_path, text="Vertex Keyframe Animation (.mdd)...")
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
||||
|
||||
if __name__=='__main__':
|
||||
#if not pack:
|
||||
# Draw.PupMenu('Error%t|This script requires a full python install')
|
||||
#Blender.Window.FileSelector(mdd_export_ui, 'EXPORT MDD', sys.makename(ext='.mdd'))
|
||||
bpy.ops.EXPORT_OT_mdd(path="/tmp/test.mdd")
|
||||
#Blender.Window.FileSelector(mdd_export_ui, 'EXPORT MDD', sys.makename(ext='.mdd'))
|
||||
bpy.ops.EXPORT_OT_mdd(path="/tmp/test.mdd")
|
||||
|
@ -223,11 +223,11 @@ def copy_images(dest_dir):
|
||||
copyCount = 0
|
||||
|
||||
# for bImage in uniqueImages.values():
|
||||
# image_path = bpy.sys.expandpath(bImage.filename)
|
||||
# image_path = bpy.utils.expandpath(bImage.filename)
|
||||
# if bpy.sys.exists(image_path):
|
||||
# # Make a name for the target path.
|
||||
# dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
|
||||
# if not bpy.sys.exists(dest_image_path): # Image isnt alredy there
|
||||
# if not bpy.utils.exists(dest_image_path): # Image isnt alredy there
|
||||
# print('\tCopying "%s" > "%s"' % (image_path, dest_image_path))
|
||||
# copy_file(image_path, dest_image_path)
|
||||
# copyCount+=1
|
||||
@ -932,7 +932,7 @@ Currently the exporter lacks these features:
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class EXPORT_OT_obj(bpy.types.Operator):
|
||||
class ExportOBJ(bpy.types.Operator):
|
||||
'''Save a Wavefront OBJ File'''
|
||||
|
||||
bl_idname = "export.obj"
|
||||
@ -1002,10 +1002,14 @@ class EXPORT_OT_obj(bpy.types.Operator):
|
||||
print("Poll")
|
||||
return context.active_object != None
|
||||
|
||||
bpy.ops.add(EXPORT_OT_obj)
|
||||
bpy.ops.add(ExportOBJ)
|
||||
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("export.obj", text="Wavefront (.obj)...")
|
||||
|
||||
def menu_func(self, context):
|
||||
default_path = bpy.data.filename.replace(".blend", ".obj")
|
||||
self.layout.item_stringO(ExportOBJ.bl_idname, "path", default_path, text="Wavefront (.obj)...")
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -252,7 +252,7 @@ def write(filename, scene, ob, \
|
||||
from bpy.props import *
|
||||
|
||||
|
||||
class EXPORT_OT_ply(bpy.types.Operator):
|
||||
class ExportPLY(bpy.types.Operator):
|
||||
'''Export a single object as a stanford PLY with normals, colours and texture coordinates.'''
|
||||
bl_idname = "export.ply"
|
||||
bl_label = "Export PLY"
|
||||
@ -292,10 +292,14 @@ class EXPORT_OT_ply(bpy.types.Operator):
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
|
||||
bpy.ops.add(EXPORT_OT_ply)
|
||||
bpy.ops.add(ExportPLY)
|
||||
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("export.ply", text="Stanford (.ply)...")
|
||||
|
||||
def menu_func(self, context):
|
||||
default_path = bpy.data.filename.replace(".blend", ".ply")
|
||||
self.layout.item_stringO(ExportPLY.bl_idname, "path", default_path, text="Stanford (.ply)...")
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -1215,7 +1215,7 @@ def x3d_export_ui(filename):
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class EXPORT_OT_x3d(bpy.types.Operator):
|
||||
class ExportX3D(bpy.types.Operator):
|
||||
'''Export selection to Extensible 3D file (.x3d)'''
|
||||
bl_idname = "export.x3d"
|
||||
bl_label = 'Export X3D'
|
||||
@ -1238,10 +1238,14 @@ class EXPORT_OT_x3d(bpy.types.Operator):
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
bpy.ops.add(EXPORT_OT_x3d)
|
||||
bpy.ops.add(ExportX3D)
|
||||
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("export.x3d", text="X3D Extensible 3D (.x3d)...")
|
||||
|
||||
def menu_func(self, context):
|
||||
default_path = bpy.data.filename.replace(".blend", ".x3d")
|
||||
self.layout.item_stringO(ExportX3D.bl_idname, "path", default_path, text="X3D Extensible 3D (.x3d)...")
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
||||
|
||||
# NOTES
|
||||
|
881
release/scripts/io/import_anim_bvh.py
Normal file
881
release/scripts/io/import_anim_bvh.py
Normal file
@ -0,0 +1,881 @@
|
||||
import math
|
||||
|
||||
# import Blender
|
||||
import bpy
|
||||
# import BPyMessages
|
||||
import Mathutils
|
||||
Vector= Mathutils.Vector
|
||||
Euler= Mathutils.Euler
|
||||
Matrix= Mathutils.Matrix
|
||||
RotationMatrix= Mathutils.RotationMatrix
|
||||
TranslationMatrix= Mathutils.TranslationMatrix
|
||||
|
||||
# NASTY GLOBAL
|
||||
ROT_STYLE = 'QUAT'
|
||||
|
||||
DEG2RAD = 0.017453292519943295
|
||||
|
||||
class bvh_node_class(object):
|
||||
__slots__=(\
|
||||
'name',# bvh joint name
|
||||
'parent',# bvh_node_class type or None for no parent
|
||||
'children',# a list of children of this type.
|
||||
'rest_head_world',# worldspace rest location for the head of this node
|
||||
'rest_head_local',# localspace rest location for the head of this node
|
||||
'rest_tail_world',# # worldspace rest location for the tail of this node
|
||||
'rest_tail_local',# # worldspace rest location for the tail of this node
|
||||
'channels',# list of 6 ints, -1 for an unused channel, otherwise an index for the BVH motion data lines, lock triple then rot triple
|
||||
'rot_order',# a triple of indicies as to the order rotation is applied. [0,1,2] is x/y/z - [None, None, None] if no rotation.
|
||||
'anim_data',# a list one tuple's one for each frame. (locx, locy, locz, rotx, roty, rotz)
|
||||
'has_loc',# Conveinience function, bool, same as (channels[0]!=-1 or channels[1]!=-1 channels[2]!=-1)
|
||||
'has_rot',# Conveinience function, bool, same as (channels[3]!=-1 or channels[4]!=-1 channels[5]!=-1)
|
||||
'temp')# use this for whatever you want
|
||||
|
||||
def __init__(self, name, rest_head_world, rest_head_local, parent, channels, rot_order):
|
||||
self.name= name
|
||||
self.rest_head_world= rest_head_world
|
||||
self.rest_head_local= rest_head_local
|
||||
self.rest_tail_world= None
|
||||
self.rest_tail_local= None
|
||||
self.parent= parent
|
||||
self.channels= channels
|
||||
self.rot_order= rot_order
|
||||
|
||||
# convenience functions
|
||||
self.has_loc= channels[0] != -1 or channels[1] != -1 or channels[2] != -1
|
||||
self.has_rot= channels[3] != -1 or channels[4] != -1 or channels[5] != -1
|
||||
|
||||
|
||||
self.children= []
|
||||
|
||||
# list of 6 length tuples: (lx,ly,lz, rx,ry,rz)
|
||||
# even if the channels arnt used they will just be zero
|
||||
#
|
||||
self.anim_data= [(0,0,0,0,0,0)]
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return 'BVH name:"%s", rest_loc:(%.3f,%.3f,%.3f), rest_tail:(%.3f,%.3f,%.3f)' %\
|
||||
(self.name,\
|
||||
self.rest_head_world.x, self.rest_head_world.y, self.rest_head_world.z,\
|
||||
self.rest_head_world.x, self.rest_head_world.y, self.rest_head_world.z)
|
||||
|
||||
|
||||
|
||||
# Change the order rotation is applied.
|
||||
MATRIX_IDENTITY_3x3 = Matrix([1,0,0],[0,1,0],[0,0,1])
|
||||
MATRIX_IDENTITY_4x4 = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1])
|
||||
|
||||
def eulerRotate(x,y,z, rot_order):
|
||||
|
||||
# Clamp all values between 0 and 360, values outside this raise an error.
|
||||
mats=[RotationMatrix(math.radians(x%360),3,'x'), RotationMatrix(math.radians(y%360),3,'y'), RotationMatrix(math.radians(z%360),3,'z')]
|
||||
# print rot_order
|
||||
# Standard BVH multiplication order, apply the rotation in the order Z,X,Y
|
||||
|
||||
#XXX, order changes???
|
||||
#eul = (mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))).toEuler()
|
||||
eul = (MATRIX_IDENTITY_3x3*mats[rot_order[0]]*(mats[rot_order[1]]* (mats[rot_order[2]]))).toEuler()
|
||||
|
||||
eul = math.degrees(eul.x), math.degrees(eul.y), math.degrees(eul.z)
|
||||
|
||||
return eul
|
||||
|
||||
def read_bvh(context, file_path, GLOBAL_SCALE=1.0):
|
||||
# File loading stuff
|
||||
# Open the file for importing
|
||||
file = open(file_path, 'rU')
|
||||
|
||||
# Seperate into a list of lists, each line a list of words.
|
||||
file_lines = file.readlines()
|
||||
# Non standard carrage returns?
|
||||
if len(file_lines) == 1:
|
||||
file_lines = file_lines[0].split('\r')
|
||||
|
||||
# Split by whitespace.
|
||||
file_lines =[ll for ll in [ l.split() for l in file_lines] if ll]
|
||||
|
||||
|
||||
# Create Hirachy as empties
|
||||
|
||||
if file_lines[0][0].lower() == 'hierarchy':
|
||||
#print 'Importing the BVH Hierarchy for:', file_path
|
||||
pass
|
||||
else:
|
||||
raise 'ERROR: This is not a BVH file'
|
||||
|
||||
bvh_nodes= {None:None}
|
||||
bvh_nodes_serial = [None]
|
||||
|
||||
channelIndex = -1
|
||||
|
||||
|
||||
lineIdx = 0 # An index for the file.
|
||||
while lineIdx < len(file_lines) -1:
|
||||
#...
|
||||
if file_lines[lineIdx][0].lower() == 'root' or file_lines[lineIdx][0].lower() == 'joint':
|
||||
|
||||
# Join spaces into 1 word with underscores joining it.
|
||||
if len(file_lines[lineIdx]) > 2:
|
||||
file_lines[lineIdx][1] = '_'.join(file_lines[lineIdx][1:])
|
||||
file_lines[lineIdx] = file_lines[lineIdx][:2]
|
||||
|
||||
# MAY NEED TO SUPPORT MULTIPLE ROOT's HERE!!!, Still unsure weather multiple roots are possible.??
|
||||
|
||||
# Make sure the names are unique- Object names will match joint names exactly and both will be unique.
|
||||
name = file_lines[lineIdx][1]
|
||||
|
||||
#print '%snode: %s, parent: %s' % (len(bvh_nodes_serial) * ' ', name, bvh_nodes_serial[-1])
|
||||
|
||||
lineIdx += 2 # Incriment to the next line (Offset)
|
||||
rest_head_local = Vector( GLOBAL_SCALE*float(file_lines[lineIdx][1]), GLOBAL_SCALE*float(file_lines[lineIdx][2]), GLOBAL_SCALE*float(file_lines[lineIdx][3]) )
|
||||
lineIdx += 1 # Incriment to the next line (Channels)
|
||||
|
||||
# newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation]
|
||||
# newChannel references indecies to the motiondata,
|
||||
# if not assigned then -1 refers to the last value that will be added on loading at a value of zero, this is appended
|
||||
# We'll add a zero value onto the end of the MotionDATA so this is always refers to a value.
|
||||
my_channel = [-1, -1, -1, -1, -1, -1]
|
||||
my_rot_order= [None, None, None]
|
||||
rot_count= 0
|
||||
for channel in file_lines[lineIdx][2:]:
|
||||
channel= channel.lower()
|
||||
channelIndex += 1 # So the index points to the right channel
|
||||
if channel == 'xposition': my_channel[0] = channelIndex
|
||||
elif channel == 'yposition': my_channel[1] = channelIndex
|
||||
elif channel == 'zposition': my_channel[2] = channelIndex
|
||||
|
||||
elif channel == 'xrotation':
|
||||
my_channel[3] = channelIndex
|
||||
my_rot_order[rot_count]= 0
|
||||
rot_count+=1
|
||||
elif channel == 'yrotation':
|
||||
my_channel[4] = channelIndex
|
||||
my_rot_order[rot_count]= 1
|
||||
rot_count+=1
|
||||
elif channel == 'zrotation':
|
||||
my_channel[5] = channelIndex
|
||||
my_rot_order[rot_count]= 2
|
||||
rot_count+=1
|
||||
|
||||
channels = file_lines[lineIdx][2:]
|
||||
|
||||
my_parent= bvh_nodes_serial[-1] # account for none
|
||||
|
||||
|
||||
# Apply the parents offset accumletivly
|
||||
if my_parent==None:
|
||||
rest_head_world= Vector(rest_head_local)
|
||||
else:
|
||||
rest_head_world= my_parent.rest_head_world + rest_head_local
|
||||
|
||||
bvh_node= bvh_nodes[name]= bvh_node_class(name, rest_head_world, rest_head_local, my_parent, my_channel, my_rot_order)
|
||||
|
||||
# If we have another child then we can call ourselves a parent, else
|
||||
bvh_nodes_serial.append(bvh_node)
|
||||
|
||||
# Account for an end node
|
||||
if file_lines[lineIdx][0].lower() == 'end' and file_lines[lineIdx][1].lower() == 'site': # There is somtimes a name after 'End Site' but we will ignore it.
|
||||
lineIdx += 2 # Incriment to the next line (Offset)
|
||||
rest_tail = Vector( GLOBAL_SCALE*float(file_lines[lineIdx][1]), GLOBAL_SCALE*float(file_lines[lineIdx][2]), GLOBAL_SCALE*float(file_lines[lineIdx][3]) )
|
||||
|
||||
bvh_nodes_serial[-1].rest_tail_world= bvh_nodes_serial[-1].rest_head_world + rest_tail
|
||||
bvh_nodes_serial[-1].rest_tail_local= rest_tail
|
||||
|
||||
|
||||
# Just so we can remove the Parents in a uniform way- End end never has kids
|
||||
# so this is a placeholder
|
||||
bvh_nodes_serial.append(None)
|
||||
|
||||
if len(file_lines[lineIdx]) == 1 and file_lines[lineIdx][0] == '}': # == ['}']
|
||||
bvh_nodes_serial.pop() # Remove the last item
|
||||
|
||||
if len(file_lines[lineIdx]) == 1 and file_lines[lineIdx][0].lower() == 'motion':
|
||||
#print '\nImporting motion data'
|
||||
lineIdx += 3 # Set the cursor to the first frame
|
||||
break
|
||||
|
||||
lineIdx += 1
|
||||
|
||||
|
||||
# Remove the None value used for easy parent reference
|
||||
del bvh_nodes[None]
|
||||
# Dont use anymore
|
||||
del bvh_nodes_serial
|
||||
|
||||
bvh_nodes_list= bvh_nodes.values()
|
||||
|
||||
while lineIdx < len(file_lines):
|
||||
line= file_lines[lineIdx]
|
||||
for bvh_node in bvh_nodes_list:
|
||||
#for bvh_node in bvh_nodes_serial:
|
||||
lx= ly= lz= rx= ry= rz= 0.0
|
||||
channels= bvh_node.channels
|
||||
anim_data= bvh_node.anim_data
|
||||
if channels[0] != -1:
|
||||
lx= GLOBAL_SCALE * float( line[channels[0]] )
|
||||
|
||||
if channels[1] != -1:
|
||||
ly= GLOBAL_SCALE * float( line[channels[1]] )
|
||||
|
||||
if channels[2] != -1:
|
||||
lz= GLOBAL_SCALE * float( line[channels[2]] )
|
||||
|
||||
if channels[3] != -1 or channels[4] != -1 or channels[5] != -1:
|
||||
rx, ry, rz = float( line[channels[3]] ), float( line[channels[4]] ), float( line[channels[5]] )
|
||||
|
||||
if ROT_STYLE != 'NATIVE':
|
||||
rx, ry, rz = eulerRotate(rx, ry, rz, bvh_node.rot_order)
|
||||
|
||||
#x,y,z = x/10.0, y/10.0, z/10.0 # For IPO's 36 is 360d
|
||||
|
||||
# Make interpolation not cross between 180d, thjis fixes sub frame interpolation and time scaling.
|
||||
# Will go from (355d to 365d) rather then to (355d to 5d) - inbetween these 2 there will now be a correct interpolation.
|
||||
|
||||
while anim_data[-1][3] - rx > 180: rx+=360
|
||||
while anim_data[-1][3] - rx < -180: rx-=360
|
||||
|
||||
while anim_data[-1][4] - ry > 180: ry+=360
|
||||
while anim_data[-1][4] - ry < -180: ry-=360
|
||||
|
||||
while anim_data[-1][5] - rz > 180: rz+=360
|
||||
while anim_data[-1][5] - rz < -180: rz-=360
|
||||
|
||||
# Done importing motion data #
|
||||
anim_data.append( (lx, ly, lz, rx, ry, rz) )
|
||||
lineIdx += 1
|
||||
|
||||
# Assign children
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bvh_node_parent= bvh_node.parent
|
||||
if bvh_node_parent:
|
||||
bvh_node_parent.children.append(bvh_node)
|
||||
|
||||
# Now set the tip of each bvh_node
|
||||
for bvh_node in bvh_nodes.values():
|
||||
|
||||
if not bvh_node.rest_tail_world:
|
||||
if len(bvh_node.children)==0:
|
||||
# could just fail here, but rare BVH files have childless nodes
|
||||
bvh_node.rest_tail_world = Vector(bvh_node.rest_head_world)
|
||||
bvh_node.rest_tail_local = Vector(bvh_node.rest_head_local)
|
||||
elif len(bvh_node.children)==1:
|
||||
bvh_node.rest_tail_world= Vector(bvh_node.children[0].rest_head_world)
|
||||
bvh_node.rest_tail_local= Vector(bvh_node.children[0].rest_head_local)
|
||||
else:
|
||||
# allow this, see above
|
||||
#if not bvh_node.children:
|
||||
# raise 'error, bvh node has no end and no children. bad file'
|
||||
|
||||
# Removed temp for now
|
||||
rest_tail_world= Vector(0,0,0)
|
||||
rest_tail_local= Vector(0,0,0)
|
||||
for bvh_node_child in bvh_node.children:
|
||||
rest_tail_world += bvh_node_child.rest_head_world
|
||||
rest_tail_local += bvh_node_child.rest_head_local
|
||||
|
||||
bvh_node.rest_tail_world= rest_tail_world * (1.0/len(bvh_node.children))
|
||||
bvh_node.rest_tail_local= rest_tail_local * (1.0/len(bvh_node.children))
|
||||
|
||||
# Make sure tail isnt the same location as the head.
|
||||
if (bvh_node.rest_tail_local-bvh_node.rest_head_local).length <= 0.001*GLOBAL_SCALE:
|
||||
|
||||
bvh_node.rest_tail_local.y= bvh_node.rest_tail_local.y + GLOBAL_SCALE/10
|
||||
bvh_node.rest_tail_world.y= bvh_node.rest_tail_world.y + GLOBAL_SCALE/10
|
||||
|
||||
|
||||
|
||||
return bvh_nodes
|
||||
|
||||
|
||||
|
||||
def bvh_node_dict2objects(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False):
|
||||
|
||||
if IMPORT_START_FRAME<1:
|
||||
IMPORT_START_FRAME= 1
|
||||
|
||||
scn= context.scene
|
||||
scn.objects.selected = []
|
||||
|
||||
objects= []
|
||||
|
||||
def add_ob(name):
|
||||
ob = scn.objects.new('Empty')
|
||||
objects.append(ob)
|
||||
return ob
|
||||
|
||||
# Add objects
|
||||
for name, bvh_node in bvh_nodes.items():
|
||||
bvh_node.temp= add_ob(name)
|
||||
|
||||
# Parent the objects
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bvh_node.temp.makeParent([ bvh_node_child.temp for bvh_node_child in bvh_node.children ], 1, 0) # ojbs, noninverse, 1 = not fast.
|
||||
|
||||
# Offset
|
||||
for bvh_node in bvh_nodes.values():
|
||||
# Make relative to parents offset
|
||||
bvh_node.temp.loc= bvh_node.rest_head_local
|
||||
|
||||
# Add tail objects
|
||||
for name, bvh_node in bvh_nodes.items():
|
||||
if not bvh_node.children:
|
||||
ob_end= add_ob(name + '_end')
|
||||
bvh_node.temp.makeParent([ob_end], 1, 0) # ojbs, noninverse, 1 = not fast.
|
||||
ob_end.loc= bvh_node.rest_tail_local
|
||||
|
||||
|
||||
# Animate the data, the last used bvh_node will do since they all have the same number of frames
|
||||
for current_frame in range(len(bvh_node.anim_data)):
|
||||
Blender.Set('curframe', current_frame+IMPORT_START_FRAME)
|
||||
|
||||
for bvh_node in bvh_nodes.values():
|
||||
lx,ly,lz,rx,ry,rz= bvh_node.anim_data[current_frame]
|
||||
|
||||
rest_head_local= bvh_node.rest_head_local
|
||||
bvh_node.temp.loc= rest_head_local.x+lx, rest_head_local.y+ly, rest_head_local.z+lz
|
||||
|
||||
bvh_node.temp.rot= rx*DEG2RAD,ry*DEG2RAD,rz*DEG2RAD
|
||||
|
||||
bvh_node.temp.insertIpoKey(Blender.Object.IpoKeyTypes.LOCROT)
|
||||
|
||||
scn.update(1)
|
||||
return objects
|
||||
|
||||
|
||||
|
||||
def bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False):
|
||||
|
||||
if IMPORT_START_FRAME<1:
|
||||
IMPORT_START_FRAME= 1
|
||||
|
||||
|
||||
# Add the new armature,
|
||||
scn = context.scene
|
||||
#XXX scn.objects.selected = []
|
||||
for ob in scn.objects:
|
||||
ob.selected = False
|
||||
|
||||
|
||||
#XXX arm_data= bpy.data.armatures.new()
|
||||
#XXX arm_ob = scn.objects.new(arm_data)
|
||||
bpy.ops.object.armature_add()
|
||||
arm_ob= scn.objects[-1]
|
||||
arm_data= arm_ob.data
|
||||
|
||||
|
||||
|
||||
|
||||
#XXX scn.objects.context = [arm_ob]
|
||||
#XXX scn.objects.active = arm_ob
|
||||
arm_ob.selected= True
|
||||
scn.objects.active= arm_ob
|
||||
print(scn.objects.active)
|
||||
|
||||
|
||||
# Put us into editmode
|
||||
#XXX arm_data.makeEditable()
|
||||
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||
|
||||
|
||||
|
||||
# Get the average bone length for zero length bones, we may not use this.
|
||||
average_bone_length= 0.0
|
||||
nonzero_count= 0
|
||||
for bvh_node in bvh_nodes.values():
|
||||
l= (bvh_node.rest_head_local-bvh_node.rest_tail_local).length
|
||||
if l:
|
||||
average_bone_length+= l
|
||||
nonzero_count+=1
|
||||
|
||||
# Very rare cases all bones couldbe zero length???
|
||||
if not average_bone_length:
|
||||
average_bone_length = 0.1
|
||||
else:
|
||||
# Normal operation
|
||||
average_bone_length = average_bone_length/nonzero_count
|
||||
|
||||
|
||||
#XXX - sloppy operator code
|
||||
|
||||
bpy.ops.armature.delete()
|
||||
bpy.ops.armature.select_all_toggle()
|
||||
bpy.ops.armature.delete()
|
||||
|
||||
ZERO_AREA_BONES= []
|
||||
for name, bvh_node in bvh_nodes.items():
|
||||
# New editbone
|
||||
bpy.ops.armature.bone_primitive_add(name="Bone")
|
||||
|
||||
#XXX bone= bvh_node.temp= Blender.Armature.Editbone()
|
||||
bone= bvh_node.temp= arm_data.edit_bones[-1]
|
||||
|
||||
bone.name= name
|
||||
# arm_data.bones[name]= bone
|
||||
|
||||
bone.head= bvh_node.rest_head_world
|
||||
bone.tail= bvh_node.rest_tail_world
|
||||
|
||||
# ZERO AREA BONES.
|
||||
if (bone.head-bone.tail).length < 0.001:
|
||||
if bvh_node.parent:
|
||||
ofs= bvh_node.parent.rest_head_local- bvh_node.parent.rest_tail_local
|
||||
if ofs.length: # is our parent zero length also?? unlikely
|
||||
bone.tail= bone.tail+ofs
|
||||
else:
|
||||
bone.tail.y= bone.tail.y+average_bone_length
|
||||
else:
|
||||
bone.tail.y= bone.tail.y+average_bone_length
|
||||
|
||||
ZERO_AREA_BONES.append(bone.name)
|
||||
|
||||
|
||||
for bvh_node in bvh_nodes.values():
|
||||
if bvh_node.parent:
|
||||
# bvh_node.temp is the Editbone
|
||||
|
||||
# Set the bone parent
|
||||
bvh_node.temp.parent= bvh_node.parent.temp
|
||||
|
||||
# Set the connection state
|
||||
if not bvh_node.has_loc and\
|
||||
bvh_node.parent and\
|
||||
bvh_node.parent.temp.name not in ZERO_AREA_BONES and\
|
||||
bvh_node.parent.rest_tail_local == bvh_node.rest_head_local:
|
||||
bvh_node.temp.connected= True
|
||||
|
||||
# Replace the editbone with the editbone name,
|
||||
# to avoid memory errors accessing the editbone outside editmode
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bvh_node.temp= bvh_node.temp.name
|
||||
|
||||
#XXX arm_data.update()
|
||||
|
||||
# Now Apply the animation to the armature
|
||||
|
||||
# Get armature animation data
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
bpy.ops.object.mode_set(mode='POSE', toggle=False)
|
||||
|
||||
pose= arm_ob.pose
|
||||
pose_bones= pose.pose_channels
|
||||
|
||||
|
||||
if ROT_STYLE=='NATIVE':
|
||||
eul_order_lookup = {\
|
||||
(0,1,2):'XYZ',
|
||||
(0,2,1):'XZY',
|
||||
(1,0,2):'YXZ',
|
||||
(1,2,0):'YZX',
|
||||
(2,0,1):'ZXY',
|
||||
(2,1,0):'ZYZ'
|
||||
}
|
||||
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bone_name= bvh_node.temp # may not be the same name as the bvh_node, could have been shortened.
|
||||
pose_bone= pose_bones[bone_name]
|
||||
pose_bone.rotation_mode = eul_order_lookup[tuple(bvh_node.rot_order)]
|
||||
|
||||
elif ROT_STYLE=='XYZ':
|
||||
for pose_bone in pose_bones:
|
||||
pose_bone.rotation_mode = 'XYZ'
|
||||
else:
|
||||
# Quats default
|
||||
pass
|
||||
|
||||
|
||||
bpy.ops.pose.select_all_toggle() # set
|
||||
bpy.ops.anim.insert_keyframe_menu(type=-4) # XXX - -4 ???
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#for p in pose_bones:
|
||||
# print(p)
|
||||
|
||||
|
||||
#XXX action = Blender.Armature.NLA.NewAction("Action")
|
||||
#XXX action.setActive(arm_ob)
|
||||
|
||||
#bpy.ops.act.new()
|
||||
#action = bpy.data.actions[-1]
|
||||
|
||||
# arm_ob.animation_data.action = action
|
||||
action = arm_ob.animation_data.action
|
||||
|
||||
|
||||
|
||||
|
||||
#xformConstants= [ Blender.Object.Pose.LOC, Blender.Object.Pose.ROT ]
|
||||
|
||||
# Replace the bvh_node.temp (currently an editbone)
|
||||
# With a tuple (pose_bone, armature_bone, bone_rest_matrix, bone_rest_matrix_inv)
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bone_name= bvh_node.temp # may not be the same name as the bvh_node, could have been shortened.
|
||||
pose_bone= pose_bones[bone_name]
|
||||
rest_bone= arm_data.bones[bone_name]
|
||||
#XXX bone_rest_matrix = rest_bone.matrix['ARMATURESPACE'].rotationPart()
|
||||
bone_rest_matrix = rest_bone.matrix.rotationPart()
|
||||
|
||||
|
||||
bone_rest_matrix_inv= Matrix(bone_rest_matrix)
|
||||
bone_rest_matrix_inv.invert()
|
||||
|
||||
bone_rest_matrix_inv.resize4x4()
|
||||
bone_rest_matrix.resize4x4()
|
||||
bvh_node.temp= (pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv)
|
||||
|
||||
|
||||
# Make a dict for fast access without rebuilding a list all the time.
|
||||
'''
|
||||
xformConstants_dict={
|
||||
(True,True): [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT],\
|
||||
(False,True): [Blender.Object.Pose.ROT],\
|
||||
(True,False): [Blender.Object.Pose.LOC],\
|
||||
(False,False): [],\
|
||||
}
|
||||
'''
|
||||
|
||||
# KEYFRAME METHOD, SLOW, USE IPOS DIRECT
|
||||
|
||||
# Animate the data, the last used bvh_node will do since they all have the same number of frames
|
||||
for current_frame in range(len(bvh_node.anim_data)-1): # skip the first frame (rest frame)
|
||||
# print current_frame
|
||||
|
||||
#if current_frame==150: # debugging
|
||||
# break
|
||||
|
||||
# Dont neet to set the current frame
|
||||
for bvh_node in bvh_nodes.values():
|
||||
pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp
|
||||
lx,ly,lz,rx,ry,rz= bvh_node.anim_data[current_frame+1]
|
||||
|
||||
if bvh_node.has_rot:
|
||||
|
||||
if ROT_STYLE=='QUAT':
|
||||
# Set the rotation, not so simple
|
||||
bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).toMatrix()
|
||||
|
||||
bone_rotation_matrix.resize4x4()
|
||||
#XXX ORDER CHANGE???
|
||||
#pose_bone.rotation_quaternion= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat() # ORIGINAL
|
||||
# pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix).toQuat()
|
||||
# pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix).toQuat() # BAD
|
||||
# pose_bone.rotation_quaternion= bone_rotation_matrix.toQuat() # NOT GOOD
|
||||
# pose_bone.rotation_quaternion= bone_rotation_matrix.toQuat() # NOT GOOD
|
||||
|
||||
#pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix_inv * bone_rest_matrix).toQuat()
|
||||
#pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rest_matrix * bone_rotation_matrix).toQuat()
|
||||
#pose_bone.rotation_quaternion= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat()
|
||||
|
||||
#pose_bone.rotation_quaternion= ( bone_rest_matrix* bone_rest_matrix_inv * bone_rotation_matrix).toQuat()
|
||||
#pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix * bone_rest_matrix_inv).toQuat()
|
||||
#pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix ).toQuat()
|
||||
|
||||
pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix).toQuat()
|
||||
|
||||
else:
|
||||
bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).toMatrix()
|
||||
bone_rotation_matrix.resize4x4()
|
||||
|
||||
eul= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toEuler()
|
||||
|
||||
#pose_bone.rotation_euler = math.radians(rx), math.radians(ry), math.radians(rz)
|
||||
pose_bone.rotation_euler = eul
|
||||
|
||||
print("ROTATION" + str(Euler(math.radians(rx), math.radians(ry), math.radians(rz))))
|
||||
|
||||
if bvh_node.has_loc:
|
||||
# Set the Location, simple too
|
||||
|
||||
#XXX ORDER CHANGE
|
||||
# pose_bone.location= (TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local ) * bone_rest_matrix_inv).translationPart() # WHY * 10? - just how pose works
|
||||
# pose_bone.location= (bone_rest_matrix_inv * TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local )).translationPart()
|
||||
# pose_bone.location= lx, ly, lz
|
||||
pose_bone.location= Vector(lx, ly, lz) - bvh_node.rest_head_local
|
||||
|
||||
|
||||
#XXX # TODO- add in 2.5
|
||||
if 0:
|
||||
# Get the transform
|
||||
xformConstants= xformConstants_dict[bvh_node.has_loc, bvh_node.has_rot]
|
||||
|
||||
if xformConstants:
|
||||
# Insert the keyframe from the loc/quat
|
||||
pose_bone.insertKey(arm_ob, current_frame+IMPORT_START_FRAME, xformConstants, True )
|
||||
else:
|
||||
|
||||
if bvh_node.has_loc:
|
||||
pose_bone.keyframe_insert("location")
|
||||
if bvh_node.has_rot:
|
||||
if ROT_STYLE=='QUAT':
|
||||
pose_bone.keyframe_insert("rotation_quaternion")
|
||||
else:
|
||||
pose_bone.keyframe_insert("rotation_euler")
|
||||
|
||||
|
||||
|
||||
# bpy.ops.anim.insert_keyframe_menu(type=-4) # XXX - -4 ???
|
||||
bpy.ops.screen.frame_offset(delta=1)
|
||||
|
||||
# First time, set the IPO's to linear
|
||||
#XXX #TODO
|
||||
if 0:
|
||||
if current_frame==0:
|
||||
for ipo in action.getAllChannelIpos().values():
|
||||
if ipo:
|
||||
for cur in ipo:
|
||||
cur.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
|
||||
if IMPORT_LOOP:
|
||||
cur.extend = Blender.IpoCurve.ExtendTypes.CYCLIC
|
||||
|
||||
|
||||
else:
|
||||
for cu in action.fcurves:
|
||||
for bez in cu.keyframe_points:
|
||||
bez.interpolation = 'CONSTANT'
|
||||
|
||||
# END KEYFRAME METHOD
|
||||
|
||||
|
||||
"""
|
||||
# IPO KEYFRAME SETTING
|
||||
# Add in the IPOs by adding keyframes, AFAIK theres no way to add IPOs to an action so I do this :/
|
||||
for bvh_node in bvh_nodes.values():
|
||||
pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp
|
||||
|
||||
# Get the transform
|
||||
xformConstants= xformConstants_dict[bvh_node.has_loc, bvh_node.has_rot]
|
||||
if xformConstants:
|
||||
pose_bone.loc[:]= 0,0,0
|
||||
pose_bone.quat[:]= 0,0,1,0
|
||||
# Insert the keyframe from the loc/quat
|
||||
pose_bone.insertKey(arm_ob, IMPORT_START_FRAME, xformConstants)
|
||||
|
||||
|
||||
action_ipos= action.getAllChannelIpos()
|
||||
|
||||
|
||||
for bvh_node in bvh_nodes.values():
|
||||
has_loc= bvh_node.has_loc
|
||||
has_rot= bvh_node.has_rot
|
||||
|
||||
if not has_rot and not has_loc:
|
||||
# No animation data
|
||||
continue
|
||||
|
||||
ipo= action_ipos[bvh_node.temp[0].name] # posebones name as key
|
||||
|
||||
if has_loc:
|
||||
curve_xloc= ipo[Blender.Ipo.PO_LOCX]
|
||||
curve_yloc= ipo[Blender.Ipo.PO_LOCY]
|
||||
curve_zloc= ipo[Blender.Ipo.PO_LOCZ]
|
||||
|
||||
curve_xloc.interpolation= \
|
||||
curve_yloc.interpolation= \
|
||||
curve_zloc.interpolation= \
|
||||
Blender.IpoCurve.InterpTypes.LINEAR
|
||||
|
||||
|
||||
if has_rot:
|
||||
curve_wquat= ipo[Blender.Ipo.PO_QUATW]
|
||||
curve_xquat= ipo[Blender.Ipo.PO_QUATX]
|
||||
curve_yquat= ipo[Blender.Ipo.PO_QUATY]
|
||||
curve_zquat= ipo[Blender.Ipo.PO_QUATZ]
|
||||
|
||||
curve_wquat.interpolation= \
|
||||
curve_xquat.interpolation= \
|
||||
curve_yquat.interpolation= \
|
||||
curve_zquat.interpolation= \
|
||||
Blender.IpoCurve.InterpTypes.LINEAR
|
||||
|
||||
# Get the bone
|
||||
pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp
|
||||
|
||||
|
||||
def pose_rot(anim_data):
|
||||
bone_rotation_matrix= Euler(anim_data[3], anim_data[4], anim_data[5]).toMatrix()
|
||||
bone_rotation_matrix.resize4x4()
|
||||
return tuple((bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat()) # qw,qx,qy,qz
|
||||
|
||||
def pose_loc(anim_data):
|
||||
return tuple((TranslationMatrix(Vector(anim_data[0], anim_data[1], anim_data[2])) * bone_rest_matrix_inv).translationPart())
|
||||
|
||||
|
||||
last_frame= len(bvh_node.anim_data)+IMPORT_START_FRAME-1
|
||||
|
||||
if has_loc:
|
||||
pose_locations= [pose_loc(anim_key) for anim_key in bvh_node.anim_data]
|
||||
|
||||
# Add the start at the end, we know the start is just 0,0,0 anyway
|
||||
curve_xloc.append((last_frame, pose_locations[-1][0]))
|
||||
curve_yloc.append((last_frame, pose_locations[-1][1]))
|
||||
curve_zloc.append((last_frame, pose_locations[-1][2]))
|
||||
|
||||
if len(pose_locations) > 1:
|
||||
ox,oy,oz= pose_locations[0]
|
||||
x,y,z= pose_locations[1]
|
||||
|
||||
for i in range(1, len(pose_locations)-1): # from second frame to second last frame
|
||||
|
||||
nx,ny,nz= pose_locations[i+1]
|
||||
xset= yset= zset= True # we set all these by default
|
||||
if abs((ox+nx)/2 - x) < 0.00001: xset= False
|
||||
if abs((oy+ny)/2 - y) < 0.00001: yset= False
|
||||
if abs((oz+nz)/2 - z) < 0.00001: zset= False
|
||||
|
||||
if xset: curve_xloc.append((i+IMPORT_START_FRAME, x))
|
||||
if yset: curve_yloc.append((i+IMPORT_START_FRAME, y))
|
||||
if zset: curve_zloc.append((i+IMPORT_START_FRAME, z))
|
||||
|
||||
# Set the old and use the new
|
||||
ox,oy,oz= x,y,z
|
||||
x,y,z= nx,ny,nz
|
||||
|
||||
|
||||
if has_rot:
|
||||
pose_rotations= [pose_rot(anim_key) for anim_key in bvh_node.anim_data]
|
||||
|
||||
# Add the start at the end, we know the start is just 0,0,0 anyway
|
||||
curve_wquat.append((last_frame, pose_rotations[-1][0]))
|
||||
curve_xquat.append((last_frame, pose_rotations[-1][1]))
|
||||
curve_yquat.append((last_frame, pose_rotations[-1][2]))
|
||||
curve_zquat.append((last_frame, pose_rotations[-1][3]))
|
||||
|
||||
|
||||
if len(pose_rotations) > 1:
|
||||
ow,ox,oy,oz= pose_rotations[0]
|
||||
w,x,y,z= pose_rotations[1]
|
||||
|
||||
for i in range(1, len(pose_rotations)-1): # from second frame to second last frame
|
||||
|
||||
nw, nx,ny,nz= pose_rotations[i+1]
|
||||
wset= xset= yset= zset= True # we set all these by default
|
||||
if abs((ow+nw)/2 - w) < 0.00001: wset= False
|
||||
if abs((ox+nx)/2 - x) < 0.00001: xset= False
|
||||
if abs((oy+ny)/2 - y) < 0.00001: yset= False
|
||||
if abs((oz+nz)/2 - z) < 0.00001: zset= False
|
||||
|
||||
if wset: curve_wquat.append((i+IMPORT_START_FRAME, w))
|
||||
if xset: curve_xquat.append((i+IMPORT_START_FRAME, x))
|
||||
if yset: curve_yquat.append((i+IMPORT_START_FRAME, y))
|
||||
if zset: curve_zquat.append((i+IMPORT_START_FRAME, z))
|
||||
|
||||
# Set the old and use the new
|
||||
ow,ox,oy,oz= w,x,y,z
|
||||
w,x,y,z= nw,nx,ny,nz
|
||||
|
||||
# IPO KEYFRAME SETTING
|
||||
"""
|
||||
|
||||
# XXX NOT NEEDED NOW?
|
||||
# pose.update()
|
||||
return arm_ob
|
||||
|
||||
|
||||
#=============#
|
||||
# TESTING #
|
||||
#=============#
|
||||
|
||||
#('/metavr/mocap/bvh/boxer.bvh')
|
||||
#('/d/staggered_walk.bvh')
|
||||
#('/metavr/mocap/bvh/dg-306-g.bvh') # Incompleate EOF
|
||||
#('/metavr/mocap/bvh/wa8lk.bvh') # duplicate joint names, \r line endings.
|
||||
#('/metavr/mocap/bvh/walk4.bvh') # 0 channels
|
||||
|
||||
'''
|
||||
import os
|
||||
DIR = '/metavr/mocap/bvh/'
|
||||
for f in ('/d/staggered_walk.bvh',):
|
||||
#for f in os.listdir(DIR)[5:6]:
|
||||
#for f in os.listdir(DIR):
|
||||
if f.endswith('.bvh'):
|
||||
s = Blender.Scene.New(f)
|
||||
s.makeCurrent()
|
||||
#file= DIR + f
|
||||
file= f
|
||||
print f
|
||||
bvh_nodes= read_bvh(file, 1.0)
|
||||
bvh_node_dict2armature(bvh_nodes, 1)
|
||||
'''
|
||||
|
||||
def load_bvh_ui(context, file, PREF_UI= False):
|
||||
|
||||
#XXX if BPyMessages.Error_NoFile(file):
|
||||
#XXX return
|
||||
|
||||
#XXX Draw= Blender.Draw
|
||||
|
||||
IMPORT_SCALE = 0.1
|
||||
IMPORT_START_FRAME = 1
|
||||
IMPORT_AS_ARMATURE = 1
|
||||
IMPORT_AS_EMPTIES = 0
|
||||
IMPORT_LOOP = 0
|
||||
|
||||
# Get USER Options
|
||||
if PREF_UI:
|
||||
pup_block = [\
|
||||
('As Armature', IMPORT_AS_ARMATURE, 'Imports the BVH as an armature'),\
|
||||
('As Empties', IMPORT_AS_EMPTIES, 'Imports the BVH as empties'),\
|
||||
('Scale: ', IMPORT_SCALE, 0.001, 100.0, 'Scale the BVH, Use 0.01 when 1.0 is 1 metre'),\
|
||||
('Start Frame: ', IMPORT_START_FRAME, 1, 30000, 'Frame to start BVH motion'),\
|
||||
('Loop Animation', IMPORT_LOOP, 'Enable cyclic IPOs'),\
|
||||
]
|
||||
|
||||
#XXX if not Draw.PupBlock('BVH Import...', pup_block):
|
||||
#XXX return
|
||||
|
||||
# print('Attempting import BVH', file)
|
||||
|
||||
if not IMPORT_AS_ARMATURE and not IMPORT_AS_EMPTIES:
|
||||
raise('No import option selected')
|
||||
|
||||
#XXX Blender.Window.WaitCursor(1)
|
||||
# Get the BVH data and act on it.
|
||||
import time
|
||||
t1= time.time()
|
||||
print('\tparsing bvh...', end= "")
|
||||
bvh_nodes= read_bvh(context, file, IMPORT_SCALE)
|
||||
print('%.4f' % (time.time()-t1))
|
||||
t1= time.time()
|
||||
print('\timporting to blender...', end="")
|
||||
if IMPORT_AS_ARMATURE: bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME, IMPORT_LOOP)
|
||||
if IMPORT_AS_EMPTIES: bvh_node_dict2objects(context, bvh_nodes, IMPORT_START_FRAME, IMPORT_LOOP)
|
||||
|
||||
print('Done in %.4f\n' % (time.time()-t1))
|
||||
#XXX Blender.Window.WaitCursor(0)
|
||||
|
||||
def main():
|
||||
Blender.Window.FileSelector(load_bvh_ui, 'Import BVH', '*.bvh')
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class BvhImporter(bpy.types.Operator):
|
||||
'''Load a Wavefront OBJ File.'''
|
||||
bl_idname = "import_anim.bvh"
|
||||
bl_label = "Import BVH"
|
||||
|
||||
path = StringProperty(name="File Path", description="File path used for importing the OBJ file", maxlen= 1024, default= "")
|
||||
|
||||
def execute(self, context):
|
||||
# print("Selected: " + context.active_object.name)
|
||||
|
||||
read_bvh(context, self.path)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
|
||||
bpy.ops.add(BvhImporter)
|
||||
|
||||
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO(BvhImporter.bl_idname, text="Motion Capture (.bvh)...")
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func)
|
881
release/scripts/io/import_bvh.py
Normal file
881
release/scripts/io/import_bvh.py
Normal file
@ -0,0 +1,881 @@
|
||||
import math
|
||||
|
||||
# import Blender
|
||||
import bpy
|
||||
# import BPyMessages
|
||||
import Mathutils
|
||||
Vector= Mathutils.Vector
|
||||
Euler= Mathutils.Euler
|
||||
Matrix= Mathutils.Matrix
|
||||
RotationMatrix= Mathutils.RotationMatrix
|
||||
TranslationMatrix= Mathutils.TranslationMatrix
|
||||
|
||||
# NASTY GLOBAL
|
||||
ROT_STYLE = 'QUAT'
|
||||
|
||||
DEG2RAD = 0.017453292519943295
|
||||
|
||||
class bvh_node_class(object):
|
||||
__slots__=(\
|
||||
'name',# bvh joint name
|
||||
'parent',# bvh_node_class type or None for no parent
|
||||
'children',# a list of children of this type.
|
||||
'rest_head_world',# worldspace rest location for the head of this node
|
||||
'rest_head_local',# localspace rest location for the head of this node
|
||||
'rest_tail_world',# # worldspace rest location for the tail of this node
|
||||
'rest_tail_local',# # worldspace rest location for the tail of this node
|
||||
'channels',# list of 6 ints, -1 for an unused channel, otherwise an index for the BVH motion data lines, lock triple then rot triple
|
||||
'rot_order',# a triple of indicies as to the order rotation is applied. [0,1,2] is x/y/z - [None, None, None] if no rotation.
|
||||
'anim_data',# a list one tuple's one for each frame. (locx, locy, locz, rotx, roty, rotz)
|
||||
'has_loc',# Conveinience function, bool, same as (channels[0]!=-1 or channels[1]!=-1 channels[2]!=-1)
|
||||
'has_rot',# Conveinience function, bool, same as (channels[3]!=-1 or channels[4]!=-1 channels[5]!=-1)
|
||||
'temp')# use this for whatever you want
|
||||
|
||||
def __init__(self, name, rest_head_world, rest_head_local, parent, channels, rot_order):
|
||||
self.name= name
|
||||
self.rest_head_world= rest_head_world
|
||||
self.rest_head_local= rest_head_local
|
||||
self.rest_tail_world= None
|
||||
self.rest_tail_local= None
|
||||
self.parent= parent
|
||||
self.channels= channels
|
||||
self.rot_order= rot_order
|
||||
|
||||
# convenience functions
|
||||
self.has_loc= channels[0] != -1 or channels[1] != -1 or channels[2] != -1
|
||||
self.has_rot= channels[3] != -1 or channels[4] != -1 or channels[5] != -1
|
||||
|
||||
|
||||
self.children= []
|
||||
|
||||
# list of 6 length tuples: (lx,ly,lz, rx,ry,rz)
|
||||
# even if the channels arnt used they will just be zero
|
||||
#
|
||||
self.anim_data= [(0,0,0,0,0,0)]
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return 'BVH name:"%s", rest_loc:(%.3f,%.3f,%.3f), rest_tail:(%.3f,%.3f,%.3f)' %\
|
||||
(self.name,\
|
||||
self.rest_head_world.x, self.rest_head_world.y, self.rest_head_world.z,\
|
||||
self.rest_head_world.x, self.rest_head_world.y, self.rest_head_world.z)
|
||||
|
||||
|
||||
|
||||
# Change the order rotation is applied.
|
||||
MATRIX_IDENTITY_3x3 = Matrix([1,0,0],[0,1,0],[0,0,1])
|
||||
MATRIX_IDENTITY_4x4 = Matrix([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1])
|
||||
|
||||
def eulerRotate(x,y,z, rot_order):
|
||||
|
||||
# Clamp all values between 0 and 360, values outside this raise an error.
|
||||
mats=[RotationMatrix(math.radians(x%360),3,'x'), RotationMatrix(math.radians(y%360),3,'y'), RotationMatrix(math.radians(z%360),3,'z')]
|
||||
# print rot_order
|
||||
# Standard BVH multiplication order, apply the rotation in the order Z,X,Y
|
||||
|
||||
#XXX, order changes???
|
||||
#eul = (mats[rot_order[2]]*(mats[rot_order[1]]* (mats[rot_order[0]]* MATRIX_IDENTITY_3x3))).toEuler()
|
||||
eul = (MATRIX_IDENTITY_3x3*mats[rot_order[0]]*(mats[rot_order[1]]* (mats[rot_order[2]]))).toEuler()
|
||||
|
||||
eul = math.degrees(eul.x), math.degrees(eul.y), math.degrees(eul.z)
|
||||
|
||||
return eul
|
||||
|
||||
def read_bvh(context, file_path, GLOBAL_SCALE=1.0):
|
||||
# File loading stuff
|
||||
# Open the file for importing
|
||||
file = open(file_path, 'rU')
|
||||
|
||||
# Seperate into a list of lists, each line a list of words.
|
||||
file_lines = file.readlines()
|
||||
# Non standard carrage returns?
|
||||
if len(file_lines) == 1:
|
||||
file_lines = file_lines[0].split('\r')
|
||||
|
||||
# Split by whitespace.
|
||||
file_lines =[ll for ll in [ l.split() for l in file_lines] if ll]
|
||||
|
||||
|
||||
# Create Hirachy as empties
|
||||
|
||||
if file_lines[0][0].lower() == 'hierarchy':
|
||||
#print 'Importing the BVH Hierarchy for:', file_path
|
||||
pass
|
||||
else:
|
||||
raise 'ERROR: This is not a BVH file'
|
||||
|
||||
bvh_nodes= {None:None}
|
||||
bvh_nodes_serial = [None]
|
||||
|
||||
channelIndex = -1
|
||||
|
||||
|
||||
lineIdx = 0 # An index for the file.
|
||||
while lineIdx < len(file_lines) -1:
|
||||
#...
|
||||
if file_lines[lineIdx][0].lower() == 'root' or file_lines[lineIdx][0].lower() == 'joint':
|
||||
|
||||
# Join spaces into 1 word with underscores joining it.
|
||||
if len(file_lines[lineIdx]) > 2:
|
||||
file_lines[lineIdx][1] = '_'.join(file_lines[lineIdx][1:])
|
||||
file_lines[lineIdx] = file_lines[lineIdx][:2]
|
||||
|
||||
# MAY NEED TO SUPPORT MULTIPLE ROOT's HERE!!!, Still unsure weather multiple roots are possible.??
|
||||
|
||||
# Make sure the names are unique- Object names will match joint names exactly and both will be unique.
|
||||
name = file_lines[lineIdx][1]
|
||||
|
||||
#print '%snode: %s, parent: %s' % (len(bvh_nodes_serial) * ' ', name, bvh_nodes_serial[-1])
|
||||
|
||||
lineIdx += 2 # Incriment to the next line (Offset)
|
||||
rest_head_local = Vector( GLOBAL_SCALE*float(file_lines[lineIdx][1]), GLOBAL_SCALE*float(file_lines[lineIdx][2]), GLOBAL_SCALE*float(file_lines[lineIdx][3]) )
|
||||
lineIdx += 1 # Incriment to the next line (Channels)
|
||||
|
||||
# newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation]
|
||||
# newChannel references indecies to the motiondata,
|
||||
# if not assigned then -1 refers to the last value that will be added on loading at a value of zero, this is appended
|
||||
# We'll add a zero value onto the end of the MotionDATA so this is always refers to a value.
|
||||
my_channel = [-1, -1, -1, -1, -1, -1]
|
||||
my_rot_order= [None, None, None]
|
||||
rot_count= 0
|
||||
for channel in file_lines[lineIdx][2:]:
|
||||
channel= channel.lower()
|
||||
channelIndex += 1 # So the index points to the right channel
|
||||
if channel == 'xposition': my_channel[0] = channelIndex
|
||||
elif channel == 'yposition': my_channel[1] = channelIndex
|
||||
elif channel == 'zposition': my_channel[2] = channelIndex
|
||||
|
||||
elif channel == 'xrotation':
|
||||
my_channel[3] = channelIndex
|
||||
my_rot_order[rot_count]= 0
|
||||
rot_count+=1
|
||||
elif channel == 'yrotation':
|
||||
my_channel[4] = channelIndex
|
||||
my_rot_order[rot_count]= 1
|
||||
rot_count+=1
|
||||
elif channel == 'zrotation':
|
||||
my_channel[5] = channelIndex
|
||||
my_rot_order[rot_count]= 2
|
||||
rot_count+=1
|
||||
|
||||
channels = file_lines[lineIdx][2:]
|
||||
|
||||
my_parent= bvh_nodes_serial[-1] # account for none
|
||||
|
||||
|
||||
# Apply the parents offset accumletivly
|
||||
if my_parent==None:
|
||||
rest_head_world= Vector(rest_head_local)
|
||||
else:
|
||||
rest_head_world= my_parent.rest_head_world + rest_head_local
|
||||
|
||||
bvh_node= bvh_nodes[name]= bvh_node_class(name, rest_head_world, rest_head_local, my_parent, my_channel, my_rot_order)
|
||||
|
||||
# If we have another child then we can call ourselves a parent, else
|
||||
bvh_nodes_serial.append(bvh_node)
|
||||
|
||||
# Account for an end node
|
||||
if file_lines[lineIdx][0].lower() == 'end' and file_lines[lineIdx][1].lower() == 'site': # There is somtimes a name after 'End Site' but we will ignore it.
|
||||
lineIdx += 2 # Incriment to the next line (Offset)
|
||||
rest_tail = Vector( GLOBAL_SCALE*float(file_lines[lineIdx][1]), GLOBAL_SCALE*float(file_lines[lineIdx][2]), GLOBAL_SCALE*float(file_lines[lineIdx][3]) )
|
||||
|
||||
bvh_nodes_serial[-1].rest_tail_world= bvh_nodes_serial[-1].rest_head_world + rest_tail
|
||||
bvh_nodes_serial[-1].rest_tail_local= rest_tail
|
||||
|
||||
|
||||
# Just so we can remove the Parents in a uniform way- End end never has kids
|
||||
# so this is a placeholder
|
||||
bvh_nodes_serial.append(None)
|
||||
|
||||
if len(file_lines[lineIdx]) == 1 and file_lines[lineIdx][0] == '}': # == ['}']
|
||||
bvh_nodes_serial.pop() # Remove the last item
|
||||
|
||||
if len(file_lines[lineIdx]) == 1 and file_lines[lineIdx][0].lower() == 'motion':
|
||||
#print '\nImporting motion data'
|
||||
lineIdx += 3 # Set the cursor to the first frame
|
||||
break
|
||||
|
||||
lineIdx += 1
|
||||
|
||||
|
||||
# Remove the None value used for easy parent reference
|
||||
del bvh_nodes[None]
|
||||
# Dont use anymore
|
||||
del bvh_nodes_serial
|
||||
|
||||
bvh_nodes_list= bvh_nodes.values()
|
||||
|
||||
while lineIdx < len(file_lines):
|
||||
line= file_lines[lineIdx]
|
||||
for bvh_node in bvh_nodes_list:
|
||||
#for bvh_node in bvh_nodes_serial:
|
||||
lx= ly= lz= rx= ry= rz= 0.0
|
||||
channels= bvh_node.channels
|
||||
anim_data= bvh_node.anim_data
|
||||
if channels[0] != -1:
|
||||
lx= GLOBAL_SCALE * float( line[channels[0]] )
|
||||
|
||||
if channels[1] != -1:
|
||||
ly= GLOBAL_SCALE * float( line[channels[1]] )
|
||||
|
||||
if channels[2] != -1:
|
||||
lz= GLOBAL_SCALE * float( line[channels[2]] )
|
||||
|
||||
if channels[3] != -1 or channels[4] != -1 or channels[5] != -1:
|
||||
rx, ry, rz = float( line[channels[3]] ), float( line[channels[4]] ), float( line[channels[5]] )
|
||||
|
||||
if ROT_STYLE != 'NATIVE':
|
||||
rx, ry, rz = eulerRotate(rx, ry, rz, bvh_node.rot_order)
|
||||
|
||||
#x,y,z = x/10.0, y/10.0, z/10.0 # For IPO's 36 is 360d
|
||||
|
||||
# Make interpolation not cross between 180d, thjis fixes sub frame interpolation and time scaling.
|
||||
# Will go from (355d to 365d) rather then to (355d to 5d) - inbetween these 2 there will now be a correct interpolation.
|
||||
|
||||
while anim_data[-1][3] - rx > 180: rx+=360
|
||||
while anim_data[-1][3] - rx < -180: rx-=360
|
||||
|
||||
while anim_data[-1][4] - ry > 180: ry+=360
|
||||
while anim_data[-1][4] - ry < -180: ry-=360
|
||||
|
||||
while anim_data[-1][5] - rz > 180: rz+=360
|
||||
while anim_data[-1][5] - rz < -180: rz-=360
|
||||
|
||||
# Done importing motion data #
|
||||
anim_data.append( (lx, ly, lz, rx, ry, rz) )
|
||||
lineIdx += 1
|
||||
|
||||
# Assign children
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bvh_node_parent= bvh_node.parent
|
||||
if bvh_node_parent:
|
||||
bvh_node_parent.children.append(bvh_node)
|
||||
|
||||
# Now set the tip of each bvh_node
|
||||
for bvh_node in bvh_nodes.values():
|
||||
|
||||
if not bvh_node.rest_tail_world:
|
||||
if len(bvh_node.children)==0:
|
||||
# could just fail here, but rare BVH files have childless nodes
|
||||
bvh_node.rest_tail_world = Vector(bvh_node.rest_head_world)
|
||||
bvh_node.rest_tail_local = Vector(bvh_node.rest_head_local)
|
||||
elif len(bvh_node.children)==1:
|
||||
bvh_node.rest_tail_world= Vector(bvh_node.children[0].rest_head_world)
|
||||
bvh_node.rest_tail_local= Vector(bvh_node.children[0].rest_head_local)
|
||||
else:
|
||||
# allow this, see above
|
||||
#if not bvh_node.children:
|
||||
# raise 'error, bvh node has no end and no children. bad file'
|
||||
|
||||
# Removed temp for now
|
||||
rest_tail_world= Vector(0,0,0)
|
||||
rest_tail_local= Vector(0,0,0)
|
||||
for bvh_node_child in bvh_node.children:
|
||||
rest_tail_world += bvh_node_child.rest_head_world
|
||||
rest_tail_local += bvh_node_child.rest_head_local
|
||||
|
||||
bvh_node.rest_tail_world= rest_tail_world * (1.0/len(bvh_node.children))
|
||||
bvh_node.rest_tail_local= rest_tail_local * (1.0/len(bvh_node.children))
|
||||
|
||||
# Make sure tail isnt the same location as the head.
|
||||
if (bvh_node.rest_tail_local-bvh_node.rest_head_local).length <= 0.001*GLOBAL_SCALE:
|
||||
|
||||
bvh_node.rest_tail_local.y= bvh_node.rest_tail_local.y + GLOBAL_SCALE/10
|
||||
bvh_node.rest_tail_world.y= bvh_node.rest_tail_world.y + GLOBAL_SCALE/10
|
||||
|
||||
|
||||
|
||||
return bvh_nodes
|
||||
|
||||
|
||||
|
||||
def bvh_node_dict2objects(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False):
|
||||
|
||||
if IMPORT_START_FRAME<1:
|
||||
IMPORT_START_FRAME= 1
|
||||
|
||||
scn= context.scene
|
||||
scn.objects.selected = []
|
||||
|
||||
objects= []
|
||||
|
||||
def add_ob(name):
|
||||
ob = scn.objects.new('Empty')
|
||||
objects.append(ob)
|
||||
return ob
|
||||
|
||||
# Add objects
|
||||
for name, bvh_node in bvh_nodes.items():
|
||||
bvh_node.temp= add_ob(name)
|
||||
|
||||
# Parent the objects
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bvh_node.temp.makeParent([ bvh_node_child.temp for bvh_node_child in bvh_node.children ], 1, 0) # ojbs, noninverse, 1 = not fast.
|
||||
|
||||
# Offset
|
||||
for bvh_node in bvh_nodes.values():
|
||||
# Make relative to parents offset
|
||||
bvh_node.temp.loc= bvh_node.rest_head_local
|
||||
|
||||
# Add tail objects
|
||||
for name, bvh_node in bvh_nodes.items():
|
||||
if not bvh_node.children:
|
||||
ob_end= add_ob(name + '_end')
|
||||
bvh_node.temp.makeParent([ob_end], 1, 0) # ojbs, noninverse, 1 = not fast.
|
||||
ob_end.loc= bvh_node.rest_tail_local
|
||||
|
||||
|
||||
# Animate the data, the last used bvh_node will do since they all have the same number of frames
|
||||
for current_frame in range(len(bvh_node.anim_data)):
|
||||
Blender.Set('curframe', current_frame+IMPORT_START_FRAME)
|
||||
|
||||
for bvh_node in bvh_nodes.values():
|
||||
lx,ly,lz,rx,ry,rz= bvh_node.anim_data[current_frame]
|
||||
|
||||
rest_head_local= bvh_node.rest_head_local
|
||||
bvh_node.temp.loc= rest_head_local.x+lx, rest_head_local.y+ly, rest_head_local.z+lz
|
||||
|
||||
bvh_node.temp.rot= rx*DEG2RAD,ry*DEG2RAD,rz*DEG2RAD
|
||||
|
||||
bvh_node.temp.insertIpoKey(Blender.Object.IpoKeyTypes.LOCROT)
|
||||
|
||||
scn.update(1)
|
||||
return objects
|
||||
|
||||
|
||||
|
||||
def bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False):
|
||||
|
||||
if IMPORT_START_FRAME<1:
|
||||
IMPORT_START_FRAME= 1
|
||||
|
||||
|
||||
# Add the new armature,
|
||||
scn = context.scene
|
||||
#XXX scn.objects.selected = []
|
||||
for ob in scn.objects:
|
||||
ob.selected = False
|
||||
|
||||
|
||||
#XXX arm_data= bpy.data.armatures.new()
|
||||
#XXX arm_ob = scn.objects.new(arm_data)
|
||||
bpy.ops.object.armature_add()
|
||||
arm_ob= scn.objects[-1]
|
||||
arm_data= arm_ob.data
|
||||
|
||||
|
||||
|
||||
|
||||
#XXX scn.objects.context = [arm_ob]
|
||||
#XXX scn.objects.active = arm_ob
|
||||
arm_ob.selected= True
|
||||
scn.objects.active= arm_ob
|
||||
print(scn.objects.active)
|
||||
|
||||
|
||||
# Put us into editmode
|
||||
#XXX arm_data.makeEditable()
|
||||
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||
|
||||
|
||||
|
||||
# Get the average bone length for zero length bones, we may not use this.
|
||||
average_bone_length= 0.0
|
||||
nonzero_count= 0
|
||||
for bvh_node in bvh_nodes.values():
|
||||
l= (bvh_node.rest_head_local-bvh_node.rest_tail_local).length
|
||||
if l:
|
||||
average_bone_length+= l
|
||||
nonzero_count+=1
|
||||
|
||||
# Very rare cases all bones couldbe zero length???
|
||||
if not average_bone_length:
|
||||
average_bone_length = 0.1
|
||||
else:
|
||||
# Normal operation
|
||||
average_bone_length = average_bone_length/nonzero_count
|
||||
|
||||
|
||||
#XXX - sloppy operator code
|
||||
|
||||
bpy.ops.armature.delete()
|
||||
bpy.ops.armature.select_all_toggle()
|
||||
bpy.ops.armature.delete()
|
||||
|
||||
ZERO_AREA_BONES= []
|
||||
for name, bvh_node in bvh_nodes.items():
|
||||
# New editbone
|
||||
bpy.ops.armature.bone_primitive_add(name="Bone")
|
||||
|
||||
#XXX bone= bvh_node.temp= Blender.Armature.Editbone()
|
||||
bone= bvh_node.temp= arm_data.edit_bones[-1]
|
||||
|
||||
bone.name= name
|
||||
# arm_data.bones[name]= bone
|
||||
|
||||
bone.head= bvh_node.rest_head_world
|
||||
bone.tail= bvh_node.rest_tail_world
|
||||
|
||||
# ZERO AREA BONES.
|
||||
if (bone.head-bone.tail).length < 0.001:
|
||||
if bvh_node.parent:
|
||||
ofs= bvh_node.parent.rest_head_local- bvh_node.parent.rest_tail_local
|
||||
if ofs.length: # is our parent zero length also?? unlikely
|
||||
bone.tail= bone.tail+ofs
|
||||
else:
|
||||
bone.tail.y= bone.tail.y+average_bone_length
|
||||
else:
|
||||
bone.tail.y= bone.tail.y+average_bone_length
|
||||
|
||||
ZERO_AREA_BONES.append(bone.name)
|
||||
|
||||
|
||||
for bvh_node in bvh_nodes.values():
|
||||
if bvh_node.parent:
|
||||
# bvh_node.temp is the Editbone
|
||||
|
||||
# Set the bone parent
|
||||
bvh_node.temp.parent= bvh_node.parent.temp
|
||||
|
||||
# Set the connection state
|
||||
if not bvh_node.has_loc and\
|
||||
bvh_node.parent and\
|
||||
bvh_node.parent.temp.name not in ZERO_AREA_BONES and\
|
||||
bvh_node.parent.rest_tail_local == bvh_node.rest_head_local:
|
||||
bvh_node.temp.connected= True
|
||||
|
||||
# Replace the editbone with the editbone name,
|
||||
# to avoid memory errors accessing the editbone outside editmode
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bvh_node.temp= bvh_node.temp.name
|
||||
|
||||
#XXX arm_data.update()
|
||||
|
||||
# Now Apply the animation to the armature
|
||||
|
||||
# Get armature animation data
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
bpy.ops.object.mode_set(mode='POSE', toggle=False)
|
||||
|
||||
pose= arm_ob.pose
|
||||
pose_bones= pose.pose_channels
|
||||
|
||||
|
||||
if ROT_STYLE=='NATIVE':
|
||||
eul_order_lookup = {\
|
||||
(0,1,2):'XYZ',
|
||||
(0,2,1):'XZY',
|
||||
(1,0,2):'YXZ',
|
||||
(1,2,0):'YZX',
|
||||
(2,0,1):'ZXY',
|
||||
(2,1,0):'ZYZ'
|
||||
}
|
||||
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bone_name= bvh_node.temp # may not be the same name as the bvh_node, could have been shortened.
|
||||
pose_bone= pose_bones[bone_name]
|
||||
pose_bone.rotation_mode = eul_order_lookup[tuple(bvh_node.rot_order)]
|
||||
|
||||
elif ROT_STYLE=='XYZ':
|
||||
for pose_bone in pose_bones:
|
||||
pose_bone.rotation_mode = 'XYZ'
|
||||
else:
|
||||
# Quats default
|
||||
pass
|
||||
|
||||
|
||||
bpy.ops.pose.select_all_toggle() # set
|
||||
bpy.ops.anim.insert_keyframe_menu(type=-4) # XXX - -4 ???
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#for p in pose_bones:
|
||||
# print(p)
|
||||
|
||||
|
||||
#XXX action = Blender.Armature.NLA.NewAction("Action")
|
||||
#XXX action.setActive(arm_ob)
|
||||
|
||||
#bpy.ops.act.new()
|
||||
#action = bpy.data.actions[-1]
|
||||
|
||||
# arm_ob.animation_data.action = action
|
||||
action = arm_ob.animation_data.action
|
||||
|
||||
|
||||
|
||||
|
||||
#xformConstants= [ Blender.Object.Pose.LOC, Blender.Object.Pose.ROT ]
|
||||
|
||||
# Replace the bvh_node.temp (currently an editbone)
|
||||
# With a tuple (pose_bone, armature_bone, bone_rest_matrix, bone_rest_matrix_inv)
|
||||
for bvh_node in bvh_nodes.values():
|
||||
bone_name= bvh_node.temp # may not be the same name as the bvh_node, could have been shortened.
|
||||
pose_bone= pose_bones[bone_name]
|
||||
rest_bone= arm_data.bones[bone_name]
|
||||
#XXX bone_rest_matrix = rest_bone.matrix['ARMATURESPACE'].rotationPart()
|
||||
bone_rest_matrix = rest_bone.matrix.rotationPart()
|
||||
|
||||
|
||||
bone_rest_matrix_inv= Matrix(bone_rest_matrix)
|
||||
bone_rest_matrix_inv.invert()
|
||||
|
||||
bone_rest_matrix_inv.resize4x4()
|
||||
bone_rest_matrix.resize4x4()
|
||||
bvh_node.temp= (pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv)
|
||||
|
||||
|
||||
# Make a dict for fast access without rebuilding a list all the time.
|
||||
'''
|
||||
xformConstants_dict={
|
||||
(True,True): [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT],\
|
||||
(False,True): [Blender.Object.Pose.ROT],\
|
||||
(True,False): [Blender.Object.Pose.LOC],\
|
||||
(False,False): [],\
|
||||
}
|
||||
'''
|
||||
|
||||
# KEYFRAME METHOD, SLOW, USE IPOS DIRECT
|
||||
|
||||
# Animate the data, the last used bvh_node will do since they all have the same number of frames
|
||||
for current_frame in range(len(bvh_node.anim_data)-1): # skip the first frame (rest frame)
|
||||
# print current_frame
|
||||
|
||||
#if current_frame==150: # debugging
|
||||
# break
|
||||
|
||||
# Dont neet to set the current frame
|
||||
for bvh_node in bvh_nodes.values():
|
||||
pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp
|
||||
lx,ly,lz,rx,ry,rz= bvh_node.anim_data[current_frame+1]
|
||||
|
||||
if bvh_node.has_rot:
|
||||
|
||||
if ROT_STYLE=='QUAT':
|
||||
# Set the rotation, not so simple
|
||||
bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).toMatrix()
|
||||
|
||||
bone_rotation_matrix.resize4x4()
|
||||
#XXX ORDER CHANGE???
|
||||
#pose_bone.rotation_quaternion= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat() # ORIGINAL
|
||||
# pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix).toQuat()
|
||||
# pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix).toQuat() # BAD
|
||||
# pose_bone.rotation_quaternion= bone_rotation_matrix.toQuat() # NOT GOOD
|
||||
# pose_bone.rotation_quaternion= bone_rotation_matrix.toQuat() # NOT GOOD
|
||||
|
||||
#pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix_inv * bone_rest_matrix).toQuat()
|
||||
#pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rest_matrix * bone_rotation_matrix).toQuat()
|
||||
#pose_bone.rotation_quaternion= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat()
|
||||
|
||||
#pose_bone.rotation_quaternion= ( bone_rest_matrix* bone_rest_matrix_inv * bone_rotation_matrix).toQuat()
|
||||
#pose_bone.rotation_quaternion= (bone_rotation_matrix * bone_rest_matrix * bone_rest_matrix_inv).toQuat()
|
||||
#pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix ).toQuat()
|
||||
|
||||
pose_bone.rotation_quaternion= (bone_rest_matrix_inv * bone_rotation_matrix * bone_rest_matrix).toQuat()
|
||||
|
||||
else:
|
||||
bone_rotation_matrix= Euler(math.radians(rx), math.radians(ry), math.radians(rz)).toMatrix()
|
||||
bone_rotation_matrix.resize4x4()
|
||||
|
||||
eul= (bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toEuler()
|
||||
|
||||
#pose_bone.rotation_euler = math.radians(rx), math.radians(ry), math.radians(rz)
|
||||
pose_bone.rotation_euler = eul
|
||||
|
||||
print("ROTATION" + str(Euler(math.radians(rx), math.radians(ry), math.radians(rz))))
|
||||
|
||||
if bvh_node.has_loc:
|
||||
# Set the Location, simple too
|
||||
|
||||
#XXX ORDER CHANGE
|
||||
# pose_bone.location= (TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local ) * bone_rest_matrix_inv).translationPart() # WHY * 10? - just how pose works
|
||||
# pose_bone.location= (bone_rest_matrix_inv * TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local )).translationPart()
|
||||
# pose_bone.location= lx, ly, lz
|
||||
pose_bone.location= Vector(lx, ly, lz) - bvh_node.rest_head_local
|
||||
|
||||
|
||||
#XXX # TODO- add in 2.5
|
||||
if 0:
|
||||
# Get the transform
|
||||
xformConstants= xformConstants_dict[bvh_node.has_loc, bvh_node.has_rot]
|
||||
|
||||
if xformConstants:
|
||||
# Insert the keyframe from the loc/quat
|
||||
pose_bone.insertKey(arm_ob, current_frame+IMPORT_START_FRAME, xformConstants, True )
|
||||
else:
|
||||
|
||||
if bvh_node.has_loc:
|
||||
pose_bone.keyframe_insert("location")
|
||||
if bvh_node.has_rot:
|
||||
if ROT_STYLE=='QUAT':
|
||||
pose_bone.keyframe_insert("rotation_quaternion")
|
||||
else:
|
||||
pose_bone.keyframe_insert("rotation_euler")
|
||||
|
||||
|
||||
|
||||
# bpy.ops.anim.insert_keyframe_menu(type=-4) # XXX - -4 ???
|
||||
bpy.ops.screen.frame_offset(delta=1)
|
||||
|
||||
# First time, set the IPO's to linear
|
||||
#XXX #TODO
|
||||
if 0:
|
||||
if current_frame==0:
|
||||
for ipo in action.getAllChannelIpos().values():
|
||||
if ipo:
|
||||
for cur in ipo:
|
||||
cur.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
|
||||
if IMPORT_LOOP:
|
||||
cur.extend = Blender.IpoCurve.ExtendTypes.CYCLIC
|
||||
|
||||
|
||||
else:
|
||||
for cu in action.fcurves:
|
||||
for bez in cu.keyframe_points:
|
||||
bez.interpolation = 'CONSTANT'
|
||||
|
||||
# END KEYFRAME METHOD
|
||||
|
||||
|
||||
"""
|
||||
# IPO KEYFRAME SETTING
|
||||
# Add in the IPOs by adding keyframes, AFAIK theres no way to add IPOs to an action so I do this :/
|
||||
for bvh_node in bvh_nodes.values():
|
||||
pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp
|
||||
|
||||
# Get the transform
|
||||
xformConstants= xformConstants_dict[bvh_node.has_loc, bvh_node.has_rot]
|
||||
if xformConstants:
|
||||
pose_bone.loc[:]= 0,0,0
|
||||
pose_bone.quat[:]= 0,0,1,0
|
||||
# Insert the keyframe from the loc/quat
|
||||
pose_bone.insertKey(arm_ob, IMPORT_START_FRAME, xformConstants)
|
||||
|
||||
|
||||
action_ipos= action.getAllChannelIpos()
|
||||
|
||||
|
||||
for bvh_node in bvh_nodes.values():
|
||||
has_loc= bvh_node.has_loc
|
||||
has_rot= bvh_node.has_rot
|
||||
|
||||
if not has_rot and not has_loc:
|
||||
# No animation data
|
||||
continue
|
||||
|
||||
ipo= action_ipos[bvh_node.temp[0].name] # posebones name as key
|
||||
|
||||
if has_loc:
|
||||
curve_xloc= ipo[Blender.Ipo.PO_LOCX]
|
||||
curve_yloc= ipo[Blender.Ipo.PO_LOCY]
|
||||
curve_zloc= ipo[Blender.Ipo.PO_LOCZ]
|
||||
|
||||
curve_xloc.interpolation= \
|
||||
curve_yloc.interpolation= \
|
||||
curve_zloc.interpolation= \
|
||||
Blender.IpoCurve.InterpTypes.LINEAR
|
||||
|
||||
|
||||
if has_rot:
|
||||
curve_wquat= ipo[Blender.Ipo.PO_QUATW]
|
||||
curve_xquat= ipo[Blender.Ipo.PO_QUATX]
|
||||
curve_yquat= ipo[Blender.Ipo.PO_QUATY]
|
||||
curve_zquat= ipo[Blender.Ipo.PO_QUATZ]
|
||||
|
||||
curve_wquat.interpolation= \
|
||||
curve_xquat.interpolation= \
|
||||
curve_yquat.interpolation= \
|
||||
curve_zquat.interpolation= \
|
||||
Blender.IpoCurve.InterpTypes.LINEAR
|
||||
|
||||
# Get the bone
|
||||
pose_bone, bone, bone_rest_matrix, bone_rest_matrix_inv= bvh_node.temp
|
||||
|
||||
|
||||
def pose_rot(anim_data):
|
||||
bone_rotation_matrix= Euler(anim_data[3], anim_data[4], anim_data[5]).toMatrix()
|
||||
bone_rotation_matrix.resize4x4()
|
||||
return tuple((bone_rest_matrix * bone_rotation_matrix * bone_rest_matrix_inv).toQuat()) # qw,qx,qy,qz
|
||||
|
||||
def pose_loc(anim_data):
|
||||
return tuple((TranslationMatrix(Vector(anim_data[0], anim_data[1], anim_data[2])) * bone_rest_matrix_inv).translationPart())
|
||||
|
||||
|
||||
last_frame= len(bvh_node.anim_data)+IMPORT_START_FRAME-1
|
||||
|
||||
if has_loc:
|
||||
pose_locations= [pose_loc(anim_key) for anim_key in bvh_node.anim_data]
|
||||
|
||||
# Add the start at the end, we know the start is just 0,0,0 anyway
|
||||
curve_xloc.append((last_frame, pose_locations[-1][0]))
|
||||
curve_yloc.append((last_frame, pose_locations[-1][1]))
|
||||
curve_zloc.append((last_frame, pose_locations[-1][2]))
|
||||
|
||||
if len(pose_locations) > 1:
|
||||
ox,oy,oz= pose_locations[0]
|
||||
x,y,z= pose_locations[1]
|
||||
|
||||
for i in range(1, len(pose_locations)-1): # from second frame to second last frame
|
||||
|
||||
nx,ny,nz= pose_locations[i+1]
|
||||
xset= yset= zset= True # we set all these by default
|
||||
if abs((ox+nx)/2 - x) < 0.00001: xset= False
|
||||
if abs((oy+ny)/2 - y) < 0.00001: yset= False
|
||||
if abs((oz+nz)/2 - z) < 0.00001: zset= False
|
||||
|
||||
if xset: curve_xloc.append((i+IMPORT_START_FRAME, x))
|
||||
if yset: curve_yloc.append((i+IMPORT_START_FRAME, y))
|
||||
if zset: curve_zloc.append((i+IMPORT_START_FRAME, z))
|
||||
|
||||
# Set the old and use the new
|
||||
ox,oy,oz= x,y,z
|
||||
x,y,z= nx,ny,nz
|
||||
|
||||
|
||||
if has_rot:
|
||||
pose_rotations= [pose_rot(anim_key) for anim_key in bvh_node.anim_data]
|
||||
|
||||
# Add the start at the end, we know the start is just 0,0,0 anyway
|
||||
curve_wquat.append((last_frame, pose_rotations[-1][0]))
|
||||
curve_xquat.append((last_frame, pose_rotations[-1][1]))
|
||||
curve_yquat.append((last_frame, pose_rotations[-1][2]))
|
||||
curve_zquat.append((last_frame, pose_rotations[-1][3]))
|
||||
|
||||
|
||||
if len(pose_rotations) > 1:
|
||||
ow,ox,oy,oz= pose_rotations[0]
|
||||
w,x,y,z= pose_rotations[1]
|
||||
|
||||
for i in range(1, len(pose_rotations)-1): # from second frame to second last frame
|
||||
|
||||
nw, nx,ny,nz= pose_rotations[i+1]
|
||||
wset= xset= yset= zset= True # we set all these by default
|
||||
if abs((ow+nw)/2 - w) < 0.00001: wset= False
|
||||
if abs((ox+nx)/2 - x) < 0.00001: xset= False
|
||||
if abs((oy+ny)/2 - y) < 0.00001: yset= False
|
||||
if abs((oz+nz)/2 - z) < 0.00001: zset= False
|
||||
|
||||
if wset: curve_wquat.append((i+IMPORT_START_FRAME, w))
|
||||
if xset: curve_xquat.append((i+IMPORT_START_FRAME, x))
|
||||
if yset: curve_yquat.append((i+IMPORT_START_FRAME, y))
|
||||
if zset: curve_zquat.append((i+IMPORT_START_FRAME, z))
|
||||
|
||||
# Set the old and use the new
|
||||
ow,ox,oy,oz= w,x,y,z
|
||||
w,x,y,z= nw,nx,ny,nz
|
||||
|
||||
# IPO KEYFRAME SETTING
|
||||
"""
|
||||
|
||||
# XXX NOT NEEDED NOW?
|
||||
# pose.update()
|
||||
return arm_ob
|
||||
|
||||
|
||||
#=============#
|
||||
# TESTING #
|
||||
#=============#
|
||||
|
||||
#('/metavr/mocap/bvh/boxer.bvh')
|
||||
#('/d/staggered_walk.bvh')
|
||||
#('/metavr/mocap/bvh/dg-306-g.bvh') # Incompleate EOF
|
||||
#('/metavr/mocap/bvh/wa8lk.bvh') # duplicate joint names, \r line endings.
|
||||
#('/metavr/mocap/bvh/walk4.bvh') # 0 channels
|
||||
|
||||
'''
|
||||
import os
|
||||
DIR = '/metavr/mocap/bvh/'
|
||||
for f in ('/d/staggered_walk.bvh',):
|
||||
#for f in os.listdir(DIR)[5:6]:
|
||||
#for f in os.listdir(DIR):
|
||||
if f.endswith('.bvh'):
|
||||
s = Blender.Scene.New(f)
|
||||
s.makeCurrent()
|
||||
#file= DIR + f
|
||||
file= f
|
||||
print f
|
||||
bvh_nodes= read_bvh(file, 1.0)
|
||||
bvh_node_dict2armature(bvh_nodes, 1)
|
||||
'''
|
||||
|
||||
def load_bvh_ui(context, file, PREF_UI= False):
|
||||
|
||||
#XXX if BPyMessages.Error_NoFile(file):
|
||||
#XXX return
|
||||
|
||||
#XXX Draw= Blender.Draw
|
||||
|
||||
IMPORT_SCALE = 0.1
|
||||
IMPORT_START_FRAME = 1
|
||||
IMPORT_AS_ARMATURE = 1
|
||||
IMPORT_AS_EMPTIES = 0
|
||||
IMPORT_LOOP = 0
|
||||
|
||||
# Get USER Options
|
||||
if PREF_UI:
|
||||
pup_block = [\
|
||||
('As Armature', IMPORT_AS_ARMATURE, 'Imports the BVH as an armature'),\
|
||||
('As Empties', IMPORT_AS_EMPTIES, 'Imports the BVH as empties'),\
|
||||
('Scale: ', IMPORT_SCALE, 0.001, 100.0, 'Scale the BVH, Use 0.01 when 1.0 is 1 metre'),\
|
||||
('Start Frame: ', IMPORT_START_FRAME, 1, 30000, 'Frame to start BVH motion'),\
|
||||
('Loop Animation', IMPORT_LOOP, 'Enable cyclic IPOs'),\
|
||||
]
|
||||
|
||||
#XXX if not Draw.PupBlock('BVH Import...', pup_block):
|
||||
#XXX return
|
||||
|
||||
# print('Attempting import BVH', file)
|
||||
|
||||
if not IMPORT_AS_ARMATURE and not IMPORT_AS_EMPTIES:
|
||||
raise('No import option selected')
|
||||
|
||||
#XXX Blender.Window.WaitCursor(1)
|
||||
# Get the BVH data and act on it.
|
||||
import time
|
||||
t1= time.time()
|
||||
print('\tparsing bvh...', end= "")
|
||||
bvh_nodes= read_bvh(context, file, IMPORT_SCALE)
|
||||
print('%.4f' % (time.time()-t1))
|
||||
t1= time.time()
|
||||
print('\timporting to blender...', end="")
|
||||
if IMPORT_AS_ARMATURE: bvh_node_dict2armature(context, bvh_nodes, IMPORT_START_FRAME, IMPORT_LOOP)
|
||||
if IMPORT_AS_EMPTIES: bvh_node_dict2objects(context, bvh_nodes, IMPORT_START_FRAME, IMPORT_LOOP)
|
||||
|
||||
print('Done in %.4f\n' % (time.time()-t1))
|
||||
#XXX Blender.Window.WaitCursor(0)
|
||||
|
||||
def main():
|
||||
Blender.Window.FileSelector(load_bvh_ui, 'Import BVH', '*.bvh')
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class BvhImporter(bpy.types.Operator):
|
||||
'''Load a Wavefront OBJ File.'''
|
||||
bl_idname = "import.bvh"
|
||||
bl_label = "Import BVH"
|
||||
|
||||
path = StringProperty(name="File Path", description="File path used for importing the OBJ file", maxlen= 1024, default= "")
|
||||
|
||||
def execute(self, context):
|
||||
# print("Selected: " + context.active_object.name)
|
||||
|
||||
read_bvh(context, self.path)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
|
||||
bpy.ops.add(BvhImporter)
|
||||
|
||||
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("import.bvh", text="Motion Capture (.bvh)...")
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func)
|
@ -139,7 +139,7 @@ import os
|
||||
import time
|
||||
import struct
|
||||
|
||||
from import_obj import unpack_face_list, load_image
|
||||
from import_scene_obj import unpack_face_list, load_image
|
||||
|
||||
import bpy
|
||||
import Mathutils
|
||||
@ -1143,7 +1143,7 @@ from bpy.props import *
|
||||
|
||||
class IMPORT_OT_autodesk_3ds(bpy.types.Operator):
|
||||
'''Import from 3DS file format (.3ds)'''
|
||||
bl_idname = "import.autodesk_3ds"
|
||||
bl_idname = "import_scene.autodesk_3ds"
|
||||
bl_label = 'Import 3DS'
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
@ -1167,7 +1167,7 @@ class IMPORT_OT_autodesk_3ds(bpy.types.Operator):
|
||||
bpy.ops.add(IMPORT_OT_autodesk_3ds)
|
||||
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("import.autodesk_3ds", text="3D Studio (.3ds)...")
|
||||
menu_func = lambda self, context: self.layout.itemO(IMPORT_OT_autodesk_3ds.bl_idname, text="3D Studio (.3ds)...")
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func)
|
||||
|
||||
# NOTES:
|
@ -1574,7 +1574,7 @@ from bpy.props import *
|
||||
|
||||
class IMPORT_OT_obj(bpy.types.Operator):
|
||||
'''Load a Wavefront OBJ File.'''
|
||||
bl_idname = "import.obj"
|
||||
bl_idname = "import_scene.obj"
|
||||
bl_label = "Import OBJ"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
@ -1626,7 +1626,7 @@ bpy.ops.add(IMPORT_OT_obj)
|
||||
|
||||
|
||||
import dynamic_menu
|
||||
menu_func = lambda self, context: self.layout.itemO("import.obj", text="Wavefront (.obj)...")
|
||||
menu_func = lambda self, context: self.layout.itemO(IMPORT_OT_obj.bl_idname, text="Wavefront (.obj)...")
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func)
|
||||
|
||||
|
@ -46,7 +46,7 @@ def addPointCache(job, ob, point_cache, default_path):
|
||||
if name == "":
|
||||
name = "".join(["%02X" % ord(c) for c in ob.name])
|
||||
|
||||
cache_path = bpy.sys.expandpath(point_cache.filepath) if point_cache.external else default_path
|
||||
cache_path = bpy.utils.expandpath(point_cache.filepath) if point_cache.external else default_path
|
||||
|
||||
index = "%02i" % point_cache.index
|
||||
|
||||
@ -111,14 +111,14 @@ def clientSendJob(conn, scene, anim = False):
|
||||
# LIBRARIES
|
||||
###########################
|
||||
for lib in bpy.data.libraries:
|
||||
job.addFile(bpy.sys.expandpath(lib_path))
|
||||
job.addFile(bpy.utils.expandpath(lib_path))
|
||||
|
||||
###########################
|
||||
# IMAGES
|
||||
###########################
|
||||
for image in bpy.data.images:
|
||||
if image.source == "FILE" and not image.packed_file:
|
||||
job.addFile(bpy.sys.expandpath(image.filename))
|
||||
job.addFile(bpy.utils.expandpath(image.filename))
|
||||
|
||||
###########################
|
||||
# FLUID + POINT CACHE
|
||||
@ -129,7 +129,7 @@ def clientSendJob(conn, scene, anim = False):
|
||||
for object in bpy.data.objects:
|
||||
for modifier in object.modifiers:
|
||||
if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN":
|
||||
addFluidFiles(job, bpy.sys.expandpath(modifier.settings.path))
|
||||
addFluidFiles(job, bpy.utils.expandpath(modifier.settings.path))
|
||||
elif modifier.type == "CLOTH":
|
||||
addPointCache(job, object, modifier.point_cache, default_path)
|
||||
elif modifier.type == "SOFT_BODY":
|
||||
@ -253,3 +253,15 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
|
||||
|
||||
conn.close()
|
||||
|
||||
def compatible(module):
|
||||
exec("import " + module)
|
||||
module = eval(module)
|
||||
for member in dir(module):
|
||||
subclass = getattr(module, member)
|
||||
try: subclass.COMPAT_ENGINES.add('NET_RENDER')
|
||||
except: pass
|
||||
del module
|
||||
|
||||
compatible("properties_render")
|
||||
compatible("properties_world")
|
||||
compatible("properties_material")
|
||||
|
72
release/scripts/modules/bpy_ext/Mesh.py
Normal file
72
release/scripts/modules/bpy_ext/Mesh.py
Normal file
@ -0,0 +1,72 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
def ord_ind(i1,i2):
|
||||
if i1<i2: return i1,i2
|
||||
return i2,i1
|
||||
|
||||
def edge_key(ed):
|
||||
v1, v2 = tuple(ed.verts)
|
||||
return ord_ind(v1, v2)
|
||||
|
||||
def face_edge_keys(face):
|
||||
verts = tuple(face.verts)
|
||||
if len(verts)==3:
|
||||
return ord_ind(verts[0], verts[1]), ord_ind(verts[1], verts[2]), ord_ind(verts[2], verts[0])
|
||||
|
||||
return ord_ind(verts[0], verts[1]), ord_ind(verts[1], verts[2]), ord_ind(verts[2], verts[3]), ord_ind(verts[3], verts[0])
|
||||
|
||||
def mesh_edge_keys(mesh):
|
||||
return [edge_key for face in mesh.faces for edge_key in face.edge_keys()]
|
||||
|
||||
def mesh_edge_face_count_dict(mesh, face_edge_keys=None):
|
||||
|
||||
# Optional speedup
|
||||
if face_edge_keys==None:
|
||||
face_edge_keys = [face.edge_keys() for face in face_list]
|
||||
|
||||
face_edge_count = {}
|
||||
for face_keys in face_edge_keys:
|
||||
for key in face_keys:
|
||||
try:
|
||||
face_edge_count[key] += 1
|
||||
except:
|
||||
face_edge_count[key] = 1
|
||||
|
||||
|
||||
return face_edge_count
|
||||
|
||||
def mesh_edge_face_count(mesh, face_edge_keys=None):
|
||||
edge_face_count_dict = mesh.edge_face_count_dict(face_edge_keys)
|
||||
return [edge_face_count_dict.get(ed.key(), 0) for ed in mesh.edges]
|
||||
|
||||
import bpy
|
||||
|
||||
# * Edge *
|
||||
class_obj = bpy.types.MeshEdge
|
||||
class_obj.key = edge_key
|
||||
|
||||
# * Face *
|
||||
class_obj = bpy.types.MeshFace
|
||||
class_obj.edge_keys = face_edge_keys
|
||||
|
||||
# * Mesh *
|
||||
class_obj = bpy.types.Mesh
|
||||
class_obj.edge_keys = mesh_edge_keys
|
||||
class_obj.edge_face_count = mesh_edge_face_count
|
||||
class_obj.edge_face_count_dict = mesh_edge_face_count_dict
|
@ -19,4 +19,4 @@
|
||||
import bpy
|
||||
class_obj = bpy.types.Object
|
||||
|
||||
class_obj.getChildren = lambda ob: [child for child in bpy.data.objects if child.parent == ob]
|
||||
class_obj.getChildren = lambda self: [child for child in bpy.data.objects if child.parent == self]
|
||||
|
@ -17,3 +17,4 @@
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy_ext.Object
|
||||
import bpy_ext.Mesh
|
||||
|
@ -127,6 +127,12 @@ class bpy_ops_submodule_op(object):
|
||||
'''
|
||||
|
||||
__keys__ = ('module', 'func')
|
||||
|
||||
|
||||
def _get_doc(self):
|
||||
return op_as_string(self.idname())
|
||||
|
||||
__doc__ = property(_get_doc)
|
||||
|
||||
def __init__(self, module, func):
|
||||
self.module = module
|
||||
@ -186,365 +192,3 @@ class bpy_ops_submodule_op(object):
|
||||
|
||||
import bpy
|
||||
bpy.ops = bpy_ops()
|
||||
|
||||
# TODO, C macro's cant define settings :|
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
|
||||
class MESH_OT_delete_edgeloop(bpy.types.Operator):
|
||||
'''Export a single object as a stanford PLY with normals,
|
||||
colours and texture coordinates.'''
|
||||
bl_idname = "mesh.delete_edgeloop"
|
||||
bl_label = "Delete Edge Loop"
|
||||
|
||||
def execute(self, context):
|
||||
bpy.ops.tfm.edge_slide(value=1.0)
|
||||
bpy.ops.mesh.select_more()
|
||||
bpy.ops.mesh.remove_doubles()
|
||||
return ('FINISHED',)
|
||||
|
||||
rna_path_prop = StringProperty(name="Context Attributes",
|
||||
description="rna context string", maxlen=1024, default="")
|
||||
|
||||
rna_reverse_prop = BoolProperty(name="Reverse",
|
||||
description="Cycle backwards", default=False)
|
||||
|
||||
|
||||
class NullPathMember:
|
||||
pass
|
||||
|
||||
|
||||
def context_path_validate(context, path):
|
||||
import sys
|
||||
try:
|
||||
value = eval("context.%s" % path)
|
||||
except AttributeError:
|
||||
if "'NoneType'" in str(sys.exc_info()[1]):
|
||||
# One of the items in the rna path is None, just ignore this
|
||||
value = NullPathMember
|
||||
else:
|
||||
# We have a real error in the rna path, dont ignore that
|
||||
raise
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def execute_context_assign(self, context):
|
||||
if context_path_validate(context, self.path) == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
exec("context.%s=self.value" % self.path)
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_context_set_boolean(bpy.types.Operator):
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_boolean"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = BoolProperty(name="Value",
|
||||
description="Assignment value", default=True)
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_set_int(bpy.types.Operator): # same as enum
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_int"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = IntProperty(name="Value", description="Assign value", default=0)
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_set_float(bpy.types.Operator): # same as enum
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_int"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = FloatProperty(name="Value",
|
||||
description="Assignment value", default=0.0)
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_set_string(bpy.types.Operator): # same as enum
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_string"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = StringProperty(name="Value",
|
||||
description="Assign value", maxlen=1024, default="")
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_set_enum(bpy.types.Operator):
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_enum"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = StringProperty(name="Value",
|
||||
description="Assignment value (as a string)",
|
||||
maxlen=1024, default="")
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_toggle(bpy.types.Operator):
|
||||
'''Toggle a context value.'''
|
||||
bl_idname = "wm.context_toggle"
|
||||
bl_label = "Context Toggle"
|
||||
path = rna_path_prop
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
if context_path_validate(context, self.path) == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
exec("context.%s=not (context.%s)" % (self.path, self.path))
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_context_toggle_enum(bpy.types.Operator):
|
||||
'''Toggle a context value.'''
|
||||
bl_idname = "wm.context_toggle_enum"
|
||||
bl_label = "Context Toggle Values"
|
||||
|
||||
path = rna_path_prop
|
||||
value_1 = StringProperty(name="Value", \
|
||||
description="Toggle enum", maxlen=1024, default="")
|
||||
|
||||
value_2 = StringProperty(name="Value", \
|
||||
description="Toggle enum", maxlen=1024, default="")
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
if context_path_validate(context, self.path) == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
exec("context.%s = ['%s', '%s'][context.%s!='%s']" % \
|
||||
(self.path, self.value_1, self.value_2, self.path, self.value_2))
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_context_cycle_int(bpy.types.Operator):
|
||||
'''Set a context value. Useful for cycling active material,
|
||||
vertex keys, groups' etc.'''
|
||||
bl_idname = "wm.context_cycle_int"
|
||||
bl_label = "Context Int Cycle"
|
||||
path = rna_path_prop
|
||||
reverse = rna_reverse_prop
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
value = context_path_validate(context, self.path)
|
||||
if value == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
self.value = value
|
||||
if self.reverse:
|
||||
self.value -= 1
|
||||
else:
|
||||
self.value += 1
|
||||
execute_context_assign(self, context)
|
||||
|
||||
if self.value != eval("context.%s" % self.path):
|
||||
# relies on rna clamping int's out of the range
|
||||
if self.reverse:
|
||||
self.value = (1 << 32)
|
||||
else:
|
||||
self.value = - (1 << 32)
|
||||
execute_context_assign(self, context)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_context_cycle_enum(bpy.types.Operator):
|
||||
'''Toggle a context value.'''
|
||||
bl_idname = "wm.context_cycle_enum"
|
||||
bl_label = "Context Enum Cycle"
|
||||
|
||||
path = rna_path_prop
|
||||
reverse = rna_reverse_prop
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
value = context_path_validate(context, self.path)
|
||||
if value == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
orig_value = value
|
||||
|
||||
# Have to get rna enum values
|
||||
rna_struct_str, rna_prop_str = self.path.rsplit('.', 1)
|
||||
i = rna_prop_str.find('[')
|
||||
|
||||
# just incse we get "context.foo.bar[0]"
|
||||
if i != -1:
|
||||
rna_prop_str = rna_prop_str[0:i]
|
||||
|
||||
rna_struct = eval("context.%s.rna_type" % rna_struct_str)
|
||||
|
||||
rna_prop = rna_struct.properties[rna_prop_str]
|
||||
|
||||
if type(rna_prop) != bpy.types.EnumProperty:
|
||||
raise Exception("expected an enum property")
|
||||
|
||||
enums = rna_struct.properties[rna_prop_str].items.keys()
|
||||
orig_index = enums.index(orig_value)
|
||||
|
||||
# Have the info we need, advance to the next item
|
||||
if self.reverse:
|
||||
if orig_index == 0:
|
||||
advance_enum = enums[-1]
|
||||
else:
|
||||
advance_enum = enums[orig_index-1]
|
||||
else:
|
||||
if orig_index == len(enums) - 1:
|
||||
advance_enum = enums[0]
|
||||
else:
|
||||
advance_enum = enums[orig_index + 1]
|
||||
|
||||
# set the new value
|
||||
exec("context.%s=advance_enum" % self.path)
|
||||
return ('FINISHED',)
|
||||
|
||||
doc_id = StringProperty(name="Doc ID",
|
||||
description="ID for the documentation", maxlen=1024, default="")
|
||||
|
||||
doc_new = StringProperty(name="Doc New",
|
||||
description="", maxlen=1024, default="")
|
||||
|
||||
|
||||
class WM_OT_doc_view(bpy.types.Operator):
|
||||
'''Load online reference docs'''
|
||||
bl_idname = "wm.doc_view"
|
||||
bl_label = "View Documentation"
|
||||
|
||||
doc_id = doc_id
|
||||
_prefix = 'http://www.blender.org/documentation/250PythonDoc'
|
||||
|
||||
def _nested_class_string(self, class_string):
|
||||
ls = []
|
||||
class_obj = getattr(bpy.types, class_string, None).bl_rna
|
||||
while class_obj:
|
||||
ls.insert(0, class_obj)
|
||||
class_obj = class_obj.nested
|
||||
return '.'.join([class_obj.identifier for class_obj in ls])
|
||||
|
||||
def execute(self, context):
|
||||
id_split = self.doc_id.split('.')
|
||||
if len(id_split) == 1: # rna, class
|
||||
url = '%s/bpy.types.%s-class.html' % (self._prefix, id_split[0])
|
||||
elif len(id_split) == 2: # rna, class.prop
|
||||
class_name, class_prop = id_split
|
||||
|
||||
# It so happens that epydoc nests these
|
||||
class_name_full = self._nested_class_string(class_name)
|
||||
|
||||
if hasattr(bpy.types, class_name.upper() + '_OT_' + class_prop):
|
||||
url = '%s/bpy.ops.%s-module.html#%s' % \
|
||||
(self._prefix, class_name_full, class_prop)
|
||||
else:
|
||||
url = '%s/bpy.types.%s-class.html#%s' % \
|
||||
(self._prefix, class_name_full, class_prop)
|
||||
|
||||
else:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
import webbrowser
|
||||
webbrowser.open(url)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_doc_edit(bpy.types.Operator):
|
||||
'''Load online reference docs'''
|
||||
bl_idname = "wm.doc_edit"
|
||||
bl_label = "Edit Documentation"
|
||||
|
||||
doc_id = doc_id
|
||||
doc_new = doc_new
|
||||
|
||||
_url = "http://www.mindrones.com/blender/svn/xmlrpc.php"
|
||||
|
||||
def _send_xmlrpc(self, data_dict):
|
||||
print("sending data:", data_dict)
|
||||
|
||||
import xmlrpc.client
|
||||
user = 'blenderuser'
|
||||
pwd = 'blender>user'
|
||||
|
||||
docblog = xmlrpc.client.ServerProxy(self._url)
|
||||
docblog.metaWeblog.newPost(1, user, pwd, data_dict, 1)
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
class_name, class_prop = self.doc_id.split('.')
|
||||
|
||||
if not self.doc_new:
|
||||
return 'OPERATOR_CANCELLED'
|
||||
|
||||
# check if this is an operator
|
||||
op_name = class_name.upper() + '_OT_' + class_prop
|
||||
op_class = getattr(bpy.types, op_name, None)
|
||||
|
||||
# Upload this to the web server
|
||||
upload = {}
|
||||
|
||||
if op_class:
|
||||
rna = op_class.bl_rna
|
||||
doc_orig = rna.description
|
||||
if doc_orig == self.doc_new:
|
||||
return 'OPERATOR_CANCELLED'
|
||||
|
||||
print("op - old:'%s' -> new:'%s'" % (doc_orig, self.doc_new))
|
||||
upload["title"] = 'OPERATOR %s:%s' % (self.doc_id, doc_orig)
|
||||
upload["description"] = self.doc_new
|
||||
|
||||
self._send_xmlrpc(upload)
|
||||
|
||||
else:
|
||||
rna = getattr(bpy.types, class_name).bl_rna
|
||||
doc_orig = rna.properties[class_prop].description
|
||||
if doc_orig == self.doc_new:
|
||||
return 'OPERATOR_CANCELLED'
|
||||
|
||||
print("rna - old:'%s' -> new:'%s'" % (doc_orig, self.doc_new))
|
||||
upload["title"] = 'RNA %s:%s' % s(self.doc_id, doc_orig)
|
||||
|
||||
upload["description"] = self.doc_new
|
||||
|
||||
self._send_xmlrpc(upload)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.invoke_props_popup(self, event)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
|
||||
bpy.ops.add(MESH_OT_delete_edgeloop)
|
||||
|
||||
bpy.ops.add(WM_OT_context_set_boolean)
|
||||
bpy.ops.add(WM_OT_context_set_int)
|
||||
bpy.ops.add(WM_OT_context_set_float)
|
||||
bpy.ops.add(WM_OT_context_set_string)
|
||||
bpy.ops.add(WM_OT_context_set_enum)
|
||||
bpy.ops.add(WM_OT_context_toggle)
|
||||
bpy.ops.add(WM_OT_context_toggle_enum)
|
||||
bpy.ops.add(WM_OT_context_cycle_enum)
|
||||
bpy.ops.add(WM_OT_context_cycle_int)
|
||||
|
||||
bpy.ops.add(WM_OT_doc_view)
|
||||
bpy.ops.add(WM_OT_doc_edit)
|
||||
|
@ -26,5 +26,5 @@ def expandpath(path):
|
||||
return path
|
||||
|
||||
import types
|
||||
bpy.sys = types.ModuleType("bpy.sys")
|
||||
bpy.sys.expandpath = expandpath
|
||||
bpy.utils = types.ModuleType("bpy.utils")
|
||||
bpy.utils.expandpath = expandpath
|
@ -16,10 +16,11 @@
|
||||
"""This module provides intellisense features such as:
|
||||
|
||||
* autocompletion
|
||||
* calltips (not yet implemented)
|
||||
* calltips
|
||||
|
||||
It unifies all completion plugins and only loads them on demand.
|
||||
"""
|
||||
|
||||
# TODO: file complete if startswith quotes
|
||||
import os
|
||||
import re
|
||||
@ -63,6 +64,9 @@ def complete(line, cursor, namespace, private=True):
|
||||
:type private: bool
|
||||
:returns: list of completions, word
|
||||
:rtype: list, str
|
||||
|
||||
>>> complete('re.sr', 5, {'re': re})
|
||||
(['re.sre_compile', 're.sre_parse'], 're.sr')
|
||||
"""
|
||||
re_unquoted_word = RE_UNQUOTED_WORD.search(line[:cursor])
|
||||
if re_unquoted_word:
|
||||
@ -99,14 +103,28 @@ def expand(line, cursor, namespace, private=True):
|
||||
current expanded line, updated cursor position and scrollback
|
||||
|
||||
:rtype: str, int, str
|
||||
|
||||
>>> expand('os.path.isdir(', 14, {'os': os})[-1]
|
||||
'isdir(s)\\nReturn true if the pathname refers to an existing directory.'
|
||||
>>> expand('abs(', 4, {})[-1]
|
||||
'abs(number) -> number\\nReturn the absolute value of the argument.'
|
||||
"""
|
||||
matches, word = complete(line, cursor, namespace, private)
|
||||
if line[:cursor].strip().endswith('('):
|
||||
import complete_calltip
|
||||
matches, word, scrollback = complete_calltip.complete(line,
|
||||
cursor, namespace)
|
||||
no_calltip = False
|
||||
else:
|
||||
matches, word = complete(line, cursor, namespace, private)
|
||||
if len(matches) == 1:
|
||||
scrollback = ''
|
||||
else:
|
||||
scrollback = ' '.join([m.split('.')[-1] for m in matches])
|
||||
no_calltip = True
|
||||
prefix = os.path.commonprefix(matches)[len(word):]
|
||||
if prefix:
|
||||
line = line[:cursor] + prefix + line[cursor:]
|
||||
cursor += len(prefix)
|
||||
if len(matches) == 1:
|
||||
scrollback = ''
|
||||
else:
|
||||
scrollback = ' '.join([m.split('.')[-1] for m in matches])
|
||||
if no_calltip and prefix.endswith('('):
|
||||
return expand(line, cursor, namespace, private)
|
||||
return line, cursor, scrollback
|
||||
|
@ -74,7 +74,7 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg):
|
||||
from bpy.props import *
|
||||
|
||||
|
||||
class AddTorusPrimitive(bpy.types.Operator):
|
||||
class AddTorus(bpy.types.Operator):
|
||||
'''Add a torus mesh.'''
|
||||
bl_idname = "mesh.primitive_torus_add"
|
||||
bl_label = "Add Torus"
|
||||
@ -117,7 +117,7 @@ class AddTorusPrimitive(bpy.types.Operator):
|
||||
ob_new = bpy.data.add_object('MESH', "Torus")
|
||||
ob_new.data = mesh
|
||||
scene.add_object(ob_new)
|
||||
scene.active_object = ob_new
|
||||
scene.objects.active = ob_new
|
||||
ob_new.selected = True
|
||||
|
||||
ob_new.location = tuple(context.scene.cursor_location)
|
||||
@ -125,12 +125,12 @@ class AddTorusPrimitive(bpy.types.Operator):
|
||||
return ('FINISHED',)
|
||||
|
||||
# Register the operator
|
||||
bpy.ops.add(AddTorusPrimitive)
|
||||
bpy.ops.add(AddTorus)
|
||||
|
||||
# Add to a menu
|
||||
import dynamic_menu
|
||||
|
||||
menu_func = (lambda self, context: self.layout.itemO("mesh.primitive_torus_add",
|
||||
menu_func = (lambda self, context: self.layout.itemO(AddTorus.bl_idname,
|
||||
text="Torus", icon='ICON_MESH_DONUT'))
|
||||
|
||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_mesh_add, menu_func)
|
225
release/scripts/op/console_python.py
Normal file
225
release/scripts/op/console_python.py
Normal file
@ -0,0 +1,225 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
import sys
|
||||
import bpy
|
||||
|
||||
language_id = 'python'
|
||||
|
||||
def add_scrollback(text, text_type):
|
||||
for l in text.split('\n'):
|
||||
bpy.ops.console.scrollback_append(text=l.replace('\t', ' '),
|
||||
type=text_type)
|
||||
|
||||
def get_console(console_id):
|
||||
'''
|
||||
helper function for console operators
|
||||
currently each text datablock gets its own
|
||||
console - bpython_code.InteractiveConsole()
|
||||
...which is stored in this function.
|
||||
|
||||
console_id can be any hashable type
|
||||
'''
|
||||
from code import InteractiveConsole
|
||||
|
||||
try:
|
||||
consoles = get_console.consoles
|
||||
except:
|
||||
consoles = get_console.consoles = {}
|
||||
|
||||
# clear all dead consoles, use text names as IDs
|
||||
# TODO, find a way to clear IDs
|
||||
'''
|
||||
for console_id in list(consoles.keys()):
|
||||
if console_id not in bpy.data.texts:
|
||||
del consoles[id]
|
||||
'''
|
||||
|
||||
try:
|
||||
console, stdout, stderr = consoles[console_id]
|
||||
except:
|
||||
namespace = {'__builtins__': __builtins__, 'bpy': bpy}
|
||||
console = InteractiveConsole(namespace)
|
||||
|
||||
import io
|
||||
stdout = io.StringIO()
|
||||
stderr = io.StringIO()
|
||||
|
||||
consoles[console_id] = console, stdout, stderr
|
||||
|
||||
return console, stdout, stderr
|
||||
|
||||
|
||||
class PyConsoleExec(bpy.types.Operator):
|
||||
'''Execute the current console line as a python expression.'''
|
||||
bl_idname = "console.execute_" + language_id
|
||||
bl_label = "Console Execute"
|
||||
bl_register = False
|
||||
|
||||
# Both prompts must be the same length
|
||||
PROMPT = '>>> '
|
||||
PROMPT_MULTI = '... '
|
||||
|
||||
# is this working???
|
||||
'''
|
||||
def poll(self, context):
|
||||
return (context.space_data.type == 'PYTHON')
|
||||
'''
|
||||
# its not :|
|
||||
|
||||
def execute(self, context):
|
||||
sc = context.space_data
|
||||
|
||||
try:
|
||||
line = sc.history[-1].line
|
||||
except:
|
||||
return ('CANCELLED',)
|
||||
|
||||
if sc.console_type != 'PYTHON':
|
||||
return ('CANCELLED',)
|
||||
|
||||
console, stdout, stderr = get_console(hash(context.region))
|
||||
|
||||
# Hack, useful but must add some other way to access
|
||||
#if "C" not in console.locals:
|
||||
console.locals["C"] = context
|
||||
|
||||
# redirect output
|
||||
sys.stdout = stdout
|
||||
sys.stderr = stderr
|
||||
|
||||
# run the console
|
||||
if not line.strip():
|
||||
line_exec = '\n' # executes a multiline statement
|
||||
else:
|
||||
line_exec = line
|
||||
|
||||
is_multiline = console.push(line_exec)
|
||||
|
||||
stdout.seek(0)
|
||||
stderr.seek(0)
|
||||
|
||||
output = stdout.read()
|
||||
output_err = stderr.read()
|
||||
|
||||
# cleanup
|
||||
sys.stdout = sys.__stdout__
|
||||
sys.stderr = sys.__stderr__
|
||||
sys.last_traceback = None
|
||||
|
||||
# So we can reuse, clear all data
|
||||
stdout.truncate(0)
|
||||
stderr.truncate(0)
|
||||
|
||||
bpy.ops.console.scrollback_append(text=sc.prompt + line, type='INPUT')
|
||||
|
||||
if is_multiline:
|
||||
sc.prompt = self.PROMPT_MULTI
|
||||
else:
|
||||
sc.prompt = self.PROMPT
|
||||
|
||||
# insert a new blank line
|
||||
bpy.ops.console.history_append(text="", current_character=0,
|
||||
remove_duplicates=True)
|
||||
|
||||
# Insert the output into the editor
|
||||
# not quite correct because the order might have changed,
|
||||
# but ok 99% of the time.
|
||||
if output:
|
||||
add_scrollback(output, 'OUTPUT')
|
||||
if output_err:
|
||||
add_scrollback(output_err, 'ERROR')
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class PyConsoleAutocomplete(bpy.types.Operator):
|
||||
'''Evaluate the namespace up until the cursor and give a list of
|
||||
options or complete the name if there is only one.'''
|
||||
bl_idname = "console.autocomplete_" + language_id
|
||||
bl_label = "Python Console Autocomplete"
|
||||
bl_register = False
|
||||
|
||||
def poll(self, context):
|
||||
return context.space_data.console_type == 'PYTHON'
|
||||
|
||||
def execute(self, context):
|
||||
from console import intellisense
|
||||
|
||||
sc = context.space_data
|
||||
|
||||
console = get_console(hash(context.region))[0]
|
||||
|
||||
current_line = sc.history[-1]
|
||||
line = current_line.line
|
||||
|
||||
if not console:
|
||||
return ('CANCELLED',)
|
||||
|
||||
if sc.console_type != 'PYTHON':
|
||||
return ('CANCELLED',)
|
||||
|
||||
# This function isnt aware of the text editor or being an operator
|
||||
# just does the autocomp then copy its results back
|
||||
current_line.line, current_line.current_character, scrollback = \
|
||||
intellisense.expand(
|
||||
line=current_line.line,
|
||||
cursor=current_line.current_character,
|
||||
namespace=console.locals,
|
||||
private='-d' in sys.argv)
|
||||
|
||||
# Now we need to copy back the line from blender back into the
|
||||
# text editor. This will change when we dont use the text editor
|
||||
# anymore
|
||||
if scrollback:
|
||||
add_scrollback(scrollback, 'INFO')
|
||||
|
||||
context.area.tag_redraw()
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class PyConsoleBanner(bpy.types.Operator):
|
||||
bl_idname = "console.banner_" + language_id
|
||||
|
||||
def execute(self, context):
|
||||
sc = context.space_data
|
||||
version_string = sys.version.strip().replace('\n', ' ')
|
||||
|
||||
add_scrollback(" * Python Interactive Console %s *" % version_string, 'OUTPUT')
|
||||
add_scrollback("Command History: Up/Down Arrow", 'OUTPUT')
|
||||
add_scrollback("Cursor: Left/Right Home/End", 'OUTPUT')
|
||||
add_scrollback("Remove: Backspace/Delete", 'OUTPUT')
|
||||
add_scrollback("Execute: Enter", 'OUTPUT')
|
||||
add_scrollback("Autocomplete: Ctrl+Space", 'OUTPUT')
|
||||
add_scrollback("Ctrl +/- Wheel: Zoom", 'OUTPUT')
|
||||
add_scrollback("Builtin Modules: bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.context, Mathutils, Geometry, BGL", 'OUTPUT')
|
||||
add_scrollback("", 'OUTPUT')
|
||||
add_scrollback("", 'OUTPUT')
|
||||
sc.prompt = PyConsoleExec.PROMPT
|
||||
|
||||
# Add context into the namespace for quick access
|
||||
console = get_console(hash(context.region))[0]
|
||||
console.locals["C"] = bpy.context
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
bpy.ops.add(PyConsoleExec)
|
||||
bpy.ops.add(PyConsoleAutocomplete)
|
||||
bpy.ops.add(PyConsoleBanner)
|
102
release/scripts/op/console_shell.py
Normal file
102
release/scripts/op/console_shell.py
Normal file
@ -0,0 +1,102 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
import sys
|
||||
import bpy
|
||||
|
||||
language_id = 'shell'
|
||||
|
||||
def add_scrollback(text, text_type):
|
||||
for l in text.split('\n'):
|
||||
bpy.ops.console.scrollback_append(text=l.replace('\t', ' '),
|
||||
type=text_type)
|
||||
|
||||
|
||||
def shell_run(text):
|
||||
import os
|
||||
add_scrollback(os.popen(text).read(), 'OUTPUT')
|
||||
|
||||
class ShellConsoleExec(bpy.types.Operator):
|
||||
'''Execute the current console line as a python expression.'''
|
||||
bl_idname = "console.execute_" + language_id
|
||||
bl_label = "Console Execute"
|
||||
bl_register = False
|
||||
|
||||
# Both prompts must be the same length
|
||||
PROMPT = '$ '
|
||||
|
||||
# is this working???
|
||||
'''
|
||||
def poll(self, context):
|
||||
return (context.space_data.type == 'PYTHON')
|
||||
'''
|
||||
# its not :|
|
||||
|
||||
def execute(self, context):
|
||||
sc = context.space_data
|
||||
|
||||
try:
|
||||
line = sc.history[-1].line
|
||||
except:
|
||||
return ('CANCELLED',)
|
||||
|
||||
bpy.ops.console.scrollback_append(text=sc.prompt + line, type='INPUT')
|
||||
|
||||
shell_run(line)
|
||||
|
||||
# insert a new blank line
|
||||
bpy.ops.console.history_append(text="", current_character=0,
|
||||
remove_duplicates=True)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class ShellConsoleAutocomplete(bpy.types.Operator):
|
||||
'''Evaluate the namespace up until the cursor and give a list of
|
||||
options or complete the name if there is only one.'''
|
||||
bl_idname = "console.autocomplete_" + language_id
|
||||
bl_label = "Python Console Autocomplete"
|
||||
bl_register = False
|
||||
|
||||
def poll(self, context):
|
||||
return context.space_data.console_type == 'PYTHON'
|
||||
|
||||
def execute(self, context):
|
||||
from console import intellisense
|
||||
|
||||
sc = context.space_data
|
||||
|
||||
# TODO
|
||||
return ('CANCELLED',)
|
||||
|
||||
|
||||
class ShellConsoleBanner(bpy.types.Operator):
|
||||
bl_idname = "console.banner_" + language_id
|
||||
|
||||
def execute(self, context):
|
||||
sc = context.space_data
|
||||
|
||||
shell_run("bash --version")
|
||||
sc.prompt = ShellConsoleExec.PROMPT
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
bpy.ops.add(ShellConsoleExec)
|
||||
bpy.ops.add(ShellConsoleAutocomplete)
|
||||
bpy.ops.add(ShellConsoleBanner)
|
71
release/scripts/op/mesh.py
Normal file
71
release/scripts/op/mesh.py
Normal file
@ -0,0 +1,71 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
|
||||
def main(context):
|
||||
ob = context.active_object
|
||||
bpy.ops.mesh.selection_type(type='FACE')
|
||||
is_editmode = (ob.mode=='EDIT')
|
||||
if is_editmode:
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
mesh = ob.data
|
||||
|
||||
face_list = [face for face in mesh.faces]
|
||||
face_edge_keys = [face.edge_keys() for face in face_list]
|
||||
|
||||
edge_face_count = mesh.edge_face_count_dict(face_edge_keys)
|
||||
|
||||
def test_interior(index):
|
||||
for key in face_edge_keys[index]:
|
||||
if edge_face_count[key] < 3:
|
||||
return False
|
||||
return True
|
||||
|
||||
for index, face in enumerate(face_list):
|
||||
if(test_interior(index)):
|
||||
face.selected = True
|
||||
else:
|
||||
face.selected = False
|
||||
|
||||
if is_editmode:
|
||||
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||
|
||||
class MeshSelectInteriorFaces(bpy.types.Operator):
|
||||
'''Select faces where all edges have more then 2 face users.'''
|
||||
|
||||
bl_idname = "mesh.faces_select_interior"
|
||||
bl_label = "Select Interior Faces"
|
||||
bl_register = True
|
||||
bl_undo = True
|
||||
|
||||
def poll(self, context):
|
||||
ob = context.active_object
|
||||
return (ob and ob.type == 'MESH')
|
||||
|
||||
def execute(self, context):
|
||||
main(context)
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
# Register the operator
|
||||
bpy.ops.add(MeshSelectInteriorFaces)
|
||||
|
||||
if __name__ == "__main__":
|
||||
bpy.ops.mesh.faces_select_interior()
|
@ -222,22 +222,6 @@ class edgeLoop(object):
|
||||
|
||||
# Returns face edges.
|
||||
# face must have edge data.
|
||||
|
||||
# Utility funcs for 2.5, make into a module??
|
||||
def ord_ind(i1,i2):
|
||||
if i1<i2: return i1,i2
|
||||
return i2,i1
|
||||
|
||||
def edge_key(ed):
|
||||
v1,v2 = tuple(ed.verts)
|
||||
return ord_ind(v1, v2)
|
||||
|
||||
def face_edge_keys(f):
|
||||
verts = tuple(f.verts)
|
||||
if len(verts)==3:
|
||||
return ord_ind(verts[0], verts[1]), ord_ind(verts[1], verts[2]), ord_ind(verts[2], verts[0])
|
||||
|
||||
return ord_ind(verts[0], verts[1]), ord_ind(verts[1], verts[2]), ord_ind(verts[2], verts[3]), ord_ind(verts[3], verts[0])
|
||||
|
||||
def mesh_faces_extend(me, faces, mat_idx = 0):
|
||||
orig_facetot = len(me.faces)
|
||||
@ -272,15 +256,15 @@ def getSelectedEdges(context, me, ob):
|
||||
if MESH_MODE == 'FACE':
|
||||
context.scene.tool_settings.mesh_selection_mode = 'EDGE'
|
||||
# value is [edge, face_sel_user_in]
|
||||
edge_dict= dict((edge_key(ed), [ed, 0]) for ed in me.edges)
|
||||
edge_dict= dict((ed.key(), [ed, 0]) for ed in me.edges)
|
||||
|
||||
for f in me.faces:
|
||||
if f.sel:
|
||||
for edkey in face_edge_keys(f):
|
||||
if f.selected:
|
||||
for edkey in f.edge_keys():
|
||||
edge_dict[edkey][1] += 1
|
||||
|
||||
context.scene.tool_settings.mesh_selection_mode = MESH_MODE
|
||||
return [ ed_data[0] for ed_data in edge_dict.itervalues() if ed_data[1] == 1 ]
|
||||
return [ ed_data[0] for ed_data in edge_dict.values() if ed_data[1] == 1 ]
|
||||
|
||||
|
||||
|
||||
@ -296,7 +280,7 @@ def getVertLoops(selEdges, me):
|
||||
vert_used = [False] * tot
|
||||
|
||||
for ed in selEdges:
|
||||
i1, i2 = edge_key(ed)
|
||||
i1, i2 = ed.key()
|
||||
vert_siblings[i1].append(i2)
|
||||
vert_siblings[i2].append(i1)
|
||||
|
1146
release/scripts/op/uvcalc_smart_project.py
Normal file
1146
release/scripts/op/uvcalc_smart_project.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,3 @@
|
||||
# bl_author = ["Campbell Barton aka ideasman42", "Keith Boshoff aka Wahooney"]
|
||||
# bl_url = ["www.blender.org", "blenderartists.org", "www.python.org"]
|
||||
# bl_version = "0.2"
|
||||
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# Script copyright (C) Campbell J Barton
|
||||
@ -25,6 +21,8 @@
|
||||
|
||||
# History
|
||||
#
|
||||
# Originally written by Campbell Barton aka ideasman42
|
||||
#
|
||||
# 2009-11-01: * 2.5 port by Keith "Wahooney" Boshoff
|
||||
# * Replaced old method with my own, speed is similar (about 0.001 sec on Suzanne)
|
||||
# but results are far more accurate
|
||||
@ -38,19 +36,20 @@ import time
|
||||
from Mathutils import Vector
|
||||
from bpy.props import *
|
||||
|
||||
def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, dirt_only, sel_only):
|
||||
def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, dirt_only):
|
||||
## Window.WaitCursor(1)
|
||||
|
||||
#BPyMesh.meshCalcNormals(me)
|
||||
|
||||
vert_tone= [0.0] * len(me.verts)
|
||||
vert_tone_count= [0] * len(me.verts)
|
||||
vert_tone = [0.0] * len(me.verts)
|
||||
|
||||
min_tone =180.0
|
||||
max_tone =0.0
|
||||
|
||||
# create lookup table for each vertex's connected vertices (via edges)
|
||||
con = [[] for i in range(len(me.verts))]
|
||||
con = []
|
||||
|
||||
min_tone=180.0
|
||||
max_tone=0.0
|
||||
con = [[] for i in range(len(me.verts))]
|
||||
|
||||
# add connected verts
|
||||
for e in me.edges:
|
||||
@ -73,64 +72,56 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
|
||||
ang = math.acos(no.dot(vec))
|
||||
|
||||
# enforce min/max
|
||||
ang = max(clamp_dirt, ang)
|
||||
|
||||
vert_tone[v.index] = max(clamp_clean, min(clamp_dirt, ang))
|
||||
if not dirt_only:
|
||||
ang = min(clamp_clean, ang)
|
||||
|
||||
# average vert_tone_list into vert_tonef
|
||||
# for i, tones in enumerate(vert_tone):
|
||||
# if vert_tone_count[i]:
|
||||
# vert_tone[i] = vert_tone[i] / vert_tone_count[i]
|
||||
|
||||
# Below we use edges to blur along so the edges need counting, not the faces
|
||||
vert_tone_count= [0] * len(me.verts)
|
||||
for ed in me.edges:
|
||||
vert_tone_count[ed.verts[0]] += 1
|
||||
vert_tone_count[ed.verts[1]] += 1
|
||||
|
||||
|
||||
# Blur tone
|
||||
blur = blur_strength
|
||||
blur_inv = 1.0 - blur_strength
|
||||
vert_tone[v.index] = ang
|
||||
|
||||
# blur tones
|
||||
for i in range(blur_iterations):
|
||||
|
||||
# backup the original tones
|
||||
orig_vert_tone= list(vert_tone)
|
||||
orig_vert_tone = list(vert_tone)
|
||||
|
||||
for ed in me.edges:
|
||||
# use connected verts look up for blurring
|
||||
for j, c in enumerate(con):
|
||||
for v in c:
|
||||
vert_tone[j] += blur_strength * orig_vert_tone[v]
|
||||
|
||||
i1 = ed.verts[0]
|
||||
i2 = ed.verts[1]
|
||||
vert_tone[j] /= len(c) * blur_strength + 1
|
||||
|
||||
val1 = (orig_vert_tone[i2]*blur) + (orig_vert_tone[i1]*blur_inv)
|
||||
val2 = (orig_vert_tone[i1]*blur) + (orig_vert_tone[i2]*blur_inv)
|
||||
min_tone = min(vert_tone)
|
||||
max_tone = max(vert_tone)
|
||||
|
||||
# Apply the ton divided by the number of faces connected
|
||||
vert_tone[i1] += val1 / max(vert_tone_count[i1], 1)
|
||||
vert_tone[i2] += val2 / max(vert_tone_count[i2], 1)
|
||||
# debug information
|
||||
# print(min_tone * 2 * math.pi)
|
||||
# print(max_tone * 2 * math.pi)
|
||||
# print(clamp_clean)
|
||||
# print(clamp_dirt)
|
||||
|
||||
tone_range = max_tone-min_tone
|
||||
|
||||
min_tone= min(vert_tone)
|
||||
max_tone= max(vert_tone)
|
||||
|
||||
print(min_tone)
|
||||
print(max_tone)
|
||||
print(clamp_clean)
|
||||
print(clamp_dirt)
|
||||
|
||||
tone_range= max_tone-min_tone
|
||||
if max_tone==min_tone:
|
||||
if not tone_range:
|
||||
return
|
||||
|
||||
for lay in me.vertex_colors:
|
||||
if lay.active:
|
||||
active_col_layer = lay.data
|
||||
active_col_layer = None
|
||||
|
||||
if len(me.vertex_colors):
|
||||
for lay in me.vertex_colors:
|
||||
if lay.active:
|
||||
active_col_layer = lay.data
|
||||
else:
|
||||
bpy.ops.mesh.vertex_color_add()
|
||||
me.vertex_colors[0].active = True
|
||||
active_col_layer = me.vertex_colors[0].data
|
||||
|
||||
if not active_col_layer:
|
||||
return('CANCELLED', )
|
||||
return("CANCELLED", )
|
||||
|
||||
for i, f in enumerate(me.faces):
|
||||
if not sel_only or f.sel:
|
||||
if not me.use_paint_mask or f.selected:
|
||||
|
||||
f_col = active_col_layer[i]
|
||||
|
||||
f_col = [f_col.color1, f_col.color2, f_col.color3, f_col.color4]
|
||||
@ -140,49 +131,47 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
|
||||
tone = vert_tone[me.verts[v].index]
|
||||
tone = (tone-min_tone)/tone_range
|
||||
|
||||
if dirt_only:
|
||||
tone = min(tone, 0.5)
|
||||
tone *= 2
|
||||
|
||||
col[0] = tone*col[0]
|
||||
col[1] = tone*col[1]
|
||||
col[2] = tone*col[2]
|
||||
|
||||
## Window.WaitCursor(0)
|
||||
|
||||
|
||||
class VertexPaintDirt(bpy.types.Operator):
|
||||
'''This script uses the concavity of vertices to shade the mesh, and optionaly blur the shading to remove artifacts from spesific edges.'''
|
||||
|
||||
bl_idname = "mesh.vertex_paint_dirt"
|
||||
bl_label = "Dirty Vertex Colors"
|
||||
bl_register = True
|
||||
bl_undo = True
|
||||
|
||||
blur_strength = FloatProperty(name="Blur Strength", description="Blur strength per iteration", default=1.0, min=0.01, max=1.0)
|
||||
blur_iterations = IntProperty(name="Blur Iterations", description="Number times to blur the colors. (higher blurs more)", default=1, min=0, max=40)
|
||||
clean_angle = FloatProperty(name="Highlight Angle", description="Less then 90 limits the angle used in the tonal range", default=0.0, min=0.0, max=180.0)
|
||||
dirt_angle = FloatProperty(name="Dirt Angle", description="Less then 90 limits the angle used in the tonal range", default=180.0, min=0.0, max=180.0)
|
||||
dirt_only = BoolProperty(name="Dirt Only", description="Dont calculate cleans for convex areas", default=False)
|
||||
sel_faces_only = BoolProperty(name="Selected Faces Only", description="Only apply to UV/Face selected faces (mix vpain/uvface select)", default=False)
|
||||
blur_strength = FloatProperty(name = "Blur Strength", description = "Blur strength per iteration", default = 1.0, min = 0.01, max = 1.0)
|
||||
blur_iterations = IntProperty(name = "Blur Iterations", description = "Number times to blur the colors. (higher blurs more)", default = 1, min = 0, max = 40)
|
||||
clean_angle = FloatProperty(name = "Highlight Angle", description = "Less then 90 limits the angle used in the tonal range", default = 180.0, min = 0.0, max = 180.0)
|
||||
dirt_angle = FloatProperty(name = "Dirt Angle", description = "Less then 90 limits the angle used in the tonal range", default = 0.0, min = 0.0, max = 180.0)
|
||||
dirt_only = BoolProperty(name= "Dirt Only", description = "Dont calculate cleans for convex areas", default = False)
|
||||
|
||||
def execute(self, context):
|
||||
sce= context.scene
|
||||
ob= context.object
|
||||
sce = context.scene
|
||||
ob = context.object
|
||||
|
||||
if not ob or ob.type != 'MESH':
|
||||
print('Error, no active mesh object, aborting.')
|
||||
print(ob)
|
||||
print(ob.type)
|
||||
return('CANCELLED',)
|
||||
|
||||
me = ob.data
|
||||
|
||||
t = time.time()
|
||||
|
||||
applyVertexDirt(me, self.blur_iterations, self.blur_strength, math.radians(self.dirt_angle), math.radians(self.clean_angle), self.dirt_only, self.sel_faces_only)
|
||||
applyVertexDirt(me, self.blur_iterations, self.blur_strength, math.radians(self.dirt_angle), math.radians(self.clean_angle), self.dirt_only)
|
||||
|
||||
print('done in %.6f' % (time.time()-t))
|
||||
print('Dirt calculated in %.6f' % (time.time()-t))
|
||||
|
||||
return('FINISHED',)
|
||||
|
||||
|
||||
bpy.ops.add(VertexPaintDirt)
|
||||
|
||||
if __name__ == "__main__":
|
378
release/scripts/op/wm.py
Normal file
378
release/scripts/op/wm.py
Normal file
@ -0,0 +1,378 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8-80 compliant>
|
||||
|
||||
import bpy
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class MESH_OT_delete_edgeloop(bpy.types.Operator):
|
||||
'''Export a single object as a stanford PLY with normals,
|
||||
colours and texture coordinates.'''
|
||||
bl_idname = "mesh.delete_edgeloop"
|
||||
bl_label = "Delete Edge Loop"
|
||||
|
||||
def execute(self, context):
|
||||
bpy.ops.tfm.edge_slide(value=1.0)
|
||||
bpy.ops.mesh.select_more()
|
||||
bpy.ops.mesh.remove_doubles()
|
||||
return ('FINISHED',)
|
||||
|
||||
rna_path_prop = StringProperty(name="Context Attributes",
|
||||
description="rna context string", maxlen=1024, default="")
|
||||
|
||||
rna_reverse_prop = BoolProperty(name="Reverse",
|
||||
description="Cycle backwards", default=False)
|
||||
|
||||
class NullPathMember:
|
||||
pass
|
||||
|
||||
|
||||
def context_path_validate(context, path):
|
||||
import sys
|
||||
try:
|
||||
value = eval("context.%s" % path)
|
||||
except AttributeError:
|
||||
if "'NoneType'" in str(sys.exc_info()[1]):
|
||||
# One of the items in the rna path is None, just ignore this
|
||||
value = NullPathMember
|
||||
else:
|
||||
# We have a real error in the rna path, dont ignore that
|
||||
raise
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def execute_context_assign(self, context):
|
||||
if context_path_validate(context, self.path) == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
exec("context.%s=self.value" % self.path)
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_context_set_boolean(bpy.types.Operator):
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_boolean"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = BoolProperty(name="Value",
|
||||
description="Assignment value", default=True)
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_set_int(bpy.types.Operator): # same as enum
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_int"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = IntProperty(name="Value", description="Assign value", default=0)
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_set_float(bpy.types.Operator): # same as enum
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_int"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = FloatProperty(name="Value",
|
||||
description="Assignment value", default=0.0)
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_set_string(bpy.types.Operator): # same as enum
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_string"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = StringProperty(name="Value",
|
||||
description="Assign value", maxlen=1024, default="")
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_set_enum(bpy.types.Operator):
|
||||
'''Set a context value.'''
|
||||
bl_idname = "wm.context_set_enum"
|
||||
bl_label = "Context Set"
|
||||
|
||||
path = rna_path_prop
|
||||
value = StringProperty(name="Value",
|
||||
description="Assignment value (as a string)",
|
||||
maxlen=1024, default="")
|
||||
|
||||
execute = execute_context_assign
|
||||
|
||||
|
||||
class WM_OT_context_toggle(bpy.types.Operator):
|
||||
'''Toggle a context value.'''
|
||||
bl_idname = "wm.context_toggle"
|
||||
bl_label = "Context Toggle"
|
||||
path = rna_path_prop
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
if context_path_validate(context, self.path) == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
exec("context.%s=not (context.%s)" % (self.path, self.path))
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_context_toggle_enum(bpy.types.Operator):
|
||||
'''Toggle a context value.'''
|
||||
bl_idname = "wm.context_toggle_enum"
|
||||
bl_label = "Context Toggle Values"
|
||||
|
||||
path = rna_path_prop
|
||||
value_1 = StringProperty(name="Value", \
|
||||
description="Toggle enum", maxlen=1024, default="")
|
||||
|
||||
value_2 = StringProperty(name="Value", \
|
||||
description="Toggle enum", maxlen=1024, default="")
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
if context_path_validate(context, self.path) == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
exec("context.%s = ['%s', '%s'][context.%s!='%s']" % \
|
||||
(self.path, self.value_1, self.value_2, self.path, self.value_2))
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_context_cycle_int(bpy.types.Operator):
|
||||
'''Set a context value. Useful for cycling active material,
|
||||
vertex keys, groups' etc.'''
|
||||
bl_idname = "wm.context_cycle_int"
|
||||
bl_label = "Context Int Cycle"
|
||||
path = rna_path_prop
|
||||
reverse = rna_reverse_prop
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
value = context_path_validate(context, self.path)
|
||||
if value == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
self.value = value
|
||||
if self.reverse:
|
||||
self.value -= 1
|
||||
else:
|
||||
self.value += 1
|
||||
execute_context_assign(self, context)
|
||||
|
||||
if self.value != eval("context.%s" % self.path):
|
||||
# relies on rna clamping int's out of the range
|
||||
if self.reverse:
|
||||
self.value = (1 << 32)
|
||||
else:
|
||||
self.value = - (1 << 32)
|
||||
execute_context_assign(self, context)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_context_cycle_enum(bpy.types.Operator):
|
||||
'''Toggle a context value.'''
|
||||
bl_idname = "wm.context_cycle_enum"
|
||||
bl_label = "Context Enum Cycle"
|
||||
|
||||
path = rna_path_prop
|
||||
reverse = rna_reverse_prop
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
value = context_path_validate(context, self.path)
|
||||
if value == NullPathMember:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
orig_value = value
|
||||
|
||||
# Have to get rna enum values
|
||||
rna_struct_str, rna_prop_str = self.path.rsplit('.', 1)
|
||||
i = rna_prop_str.find('[')
|
||||
|
||||
# just incse we get "context.foo.bar[0]"
|
||||
if i != -1:
|
||||
rna_prop_str = rna_prop_str[0:i]
|
||||
|
||||
rna_struct = eval("context.%s.rna_type" % rna_struct_str)
|
||||
|
||||
rna_prop = rna_struct.properties[rna_prop_str]
|
||||
|
||||
if type(rna_prop) != bpy.types.EnumProperty:
|
||||
raise Exception("expected an enum property")
|
||||
|
||||
enums = rna_struct.properties[rna_prop_str].items.keys()
|
||||
orig_index = enums.index(orig_value)
|
||||
|
||||
# Have the info we need, advance to the next item
|
||||
if self.reverse:
|
||||
if orig_index == 0:
|
||||
advance_enum = enums[-1]
|
||||
else:
|
||||
advance_enum = enums[orig_index-1]
|
||||
else:
|
||||
if orig_index == len(enums) - 1:
|
||||
advance_enum = enums[0]
|
||||
else:
|
||||
advance_enum = enums[orig_index + 1]
|
||||
|
||||
# set the new value
|
||||
exec("context.%s=advance_enum" % self.path)
|
||||
return ('FINISHED',)
|
||||
|
||||
doc_id = StringProperty(name="Doc ID",
|
||||
description="ID for the documentation", maxlen=1024, default="")
|
||||
|
||||
doc_new = StringProperty(name="Doc New",
|
||||
description="", maxlen=1024, default="")
|
||||
|
||||
|
||||
class WM_OT_doc_view(bpy.types.Operator):
|
||||
'''Load online reference docs'''
|
||||
bl_idname = "wm.doc_view"
|
||||
bl_label = "View Documentation"
|
||||
|
||||
doc_id = doc_id
|
||||
_prefix = 'http://www.blender.org/documentation/250PythonDoc'
|
||||
|
||||
def _nested_class_string(self, class_string):
|
||||
ls = []
|
||||
class_obj = getattr(bpy.types, class_string, None).bl_rna
|
||||
while class_obj:
|
||||
ls.insert(0, class_obj)
|
||||
class_obj = class_obj.nested
|
||||
return '.'.join([class_obj.identifier for class_obj in ls])
|
||||
|
||||
def execute(self, context):
|
||||
id_split = self.doc_id.split('.')
|
||||
if len(id_split) == 1: # rna, class
|
||||
url = '%s/bpy.types.%s-class.html' % (self._prefix, id_split[0])
|
||||
elif len(id_split) == 2: # rna, class.prop
|
||||
class_name, class_prop = id_split
|
||||
|
||||
if hasattr(bpy.types, class_name.upper() + '_OT_' + class_prop):
|
||||
url = '%s/bpy.ops.%s-module.html#%s' % \
|
||||
(self._prefix, class_name, class_prop)
|
||||
else:
|
||||
# It so happens that epydoc nests these
|
||||
class_name_full = self._nested_class_string(class_name)
|
||||
url = '%s/bpy.types.%s-class.html#%s' % \
|
||||
(self._prefix, class_name_full, class_prop)
|
||||
|
||||
else:
|
||||
return ('PASS_THROUGH',)
|
||||
|
||||
import webbrowser
|
||||
webbrowser.open(url)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class WM_OT_doc_edit(bpy.types.Operator):
|
||||
'''Load online reference docs'''
|
||||
bl_idname = "wm.doc_edit"
|
||||
bl_label = "Edit Documentation"
|
||||
|
||||
doc_id = doc_id
|
||||
doc_new = doc_new
|
||||
|
||||
_url = "http://www.mindrones.com/blender/svn/xmlrpc.php"
|
||||
|
||||
def _send_xmlrpc(self, data_dict):
|
||||
print("sending data:", data_dict)
|
||||
|
||||
import xmlrpc.client
|
||||
user = 'blenderuser'
|
||||
pwd = 'blender>user'
|
||||
|
||||
docblog = xmlrpc.client.ServerProxy(self._url)
|
||||
docblog.metaWeblog.newPost(1, user, pwd, data_dict, 1)
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
class_name, class_prop = self.doc_id.split('.')
|
||||
|
||||
if not self.doc_new:
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
# check if this is an operator
|
||||
op_name = class_name.upper() + '_OT_' + class_prop
|
||||
op_class = getattr(bpy.types, op_name, None)
|
||||
|
||||
# Upload this to the web server
|
||||
upload = {}
|
||||
|
||||
if op_class:
|
||||
rna = op_class.bl_rna
|
||||
doc_orig = rna.description
|
||||
if doc_orig == self.doc_new:
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
print("op - old:'%s' -> new:'%s'" % (doc_orig, self.doc_new))
|
||||
upload["title"] = 'OPERATOR %s:%s' % (self.doc_id, doc_orig)
|
||||
upload["description"] = self.doc_new
|
||||
|
||||
self._send_xmlrpc(upload)
|
||||
|
||||
else:
|
||||
rna = getattr(bpy.types, class_name).bl_rna
|
||||
doc_orig = rna.properties[class_prop].description
|
||||
if doc_orig == self.doc_new:
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
print("rna - old:'%s' -> new:'%s'" % (doc_orig, self.doc_new))
|
||||
upload["title"] = 'RNA %s:%s' % (self.doc_id, doc_orig)
|
||||
|
||||
upload["description"] = self.doc_new
|
||||
|
||||
self._send_xmlrpc(upload)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.invoke_props_popup(self, event)
|
||||
return ('RUNNING_MODAL',)
|
||||
|
||||
|
||||
bpy.ops.add(MESH_OT_delete_edgeloop)
|
||||
|
||||
bpy.ops.add(WM_OT_context_set_boolean)
|
||||
bpy.ops.add(WM_OT_context_set_int)
|
||||
bpy.ops.add(WM_OT_context_set_float)
|
||||
bpy.ops.add(WM_OT_context_set_string)
|
||||
bpy.ops.add(WM_OT_context_set_enum)
|
||||
bpy.ops.add(WM_OT_context_toggle)
|
||||
bpy.ops.add(WM_OT_context_toggle_enum)
|
||||
bpy.ops.add(WM_OT_context_cycle_enum)
|
||||
bpy.ops.add(WM_OT_context_cycle_int)
|
||||
|
||||
bpy.ops.add(WM_OT_doc_view)
|
||||
bpy.ops.add(WM_OT_doc_edit)
|
@ -19,6 +19,7 @@
|
||||
import bpy
|
||||
|
||||
def write_some_data(context, path, use_some_setting):
|
||||
print("running write_some_data...")
|
||||
pass
|
||||
|
||||
from bpy.props import *
|
||||
@ -33,16 +34,18 @@ class ExportSomeData(bpy.types.Operator):
|
||||
|
||||
# TODO, add better example props
|
||||
path = StringProperty(name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= "")
|
||||
use_some_setting = BoolProperty(name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True)
|
||||
use_setting = BoolProperty(name="Example Boolean", description="Example Tooltip", default= True)
|
||||
|
||||
def poll(self, context):
|
||||
return context.active_object != None
|
||||
|
||||
def execute(self, context):
|
||||
if not self.is_property_set("path"):
|
||||
raise Exception("filename not set")
|
||||
|
||||
write(self.path, context, use_setting, SOME_SETTING = self.use_some_setting)
|
||||
# # Bug, currently isnt working
|
||||
#if not self.is_property_set("path"):
|
||||
# raise Exception("filename not set")
|
||||
|
||||
write_some_data(self.path, context, self.use_setting)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
@ -53,11 +56,11 @@ class ExportSomeData(bpy.types.Operator):
|
||||
# File selector
|
||||
wm.add_fileselect(self) # will run self.execute()
|
||||
return ('RUNNING_MODAL',)
|
||||
else if 0:
|
||||
elif 0:
|
||||
# Redo popup
|
||||
wm.invoke_props_popup(self, event) #
|
||||
return ('RUNNING_MODAL',)
|
||||
else if 0:
|
||||
elif 0:
|
||||
return self.execute(context)
|
||||
|
||||
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
@ -179,20 +179,22 @@ class DATA_PT_shape_keys(DataButtonsPanel):
|
||||
sub.alignment = 'RIGHT'
|
||||
|
||||
subrow = sub.row(align=True)
|
||||
subrow.active = enable_edit_value
|
||||
subrow1 = subrow.row(align=True)
|
||||
subrow1.active = enable_edit_value
|
||||
if ob.shape_key_lock:
|
||||
subrow.itemR(ob, "shape_key_lock", icon='ICON_PINNED', text="")
|
||||
subrow1.itemR(ob, "shape_key_lock", icon='ICON_PINNED', text="")
|
||||
else:
|
||||
subrow.itemR(ob, "shape_key_lock", icon='ICON_UNPINNED', text="")
|
||||
subrow1.itemR(ob, "shape_key_lock", icon='ICON_UNPINNED', text="")
|
||||
if kb.mute:
|
||||
subrow.itemR(kb, "mute", icon='ICON_MUTE_IPO_ON', text="")
|
||||
subrow1.itemR(kb, "mute", icon='ICON_MUTE_IPO_ON', text="")
|
||||
else:
|
||||
subrow.itemR(kb, "mute", icon='ICON_MUTE_IPO_OFF', text="")
|
||||
subrow1.itemR(kb, "mute", icon='ICON_MUTE_IPO_OFF', text="")
|
||||
subrow.itemR(ob, "shape_key_edit_mode", text="")
|
||||
|
||||
subrow = sub.row(align=True)
|
||||
subrow.itemO("object.shape_key_mirror", icon='ICON_ARROW_LEFTRIGHT', text="")
|
||||
subrow.itemO("object.shape_key_clear", icon='ICON_X', text="")
|
||||
|
||||
sub.itemO("object.shape_key_mirror", icon='ICON_MOD_MIRROR', text="")
|
||||
|
||||
sub.itemR(ob, "shape_key_edit_mode", text="")
|
||||
|
||||
|
||||
row = layout.row()
|
||||
row.itemR(kb, "name")
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
@ -88,7 +88,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
|
||||
col = split.column()
|
||||
col.itemR(con, "chain_length")
|
||||
col.itemR(con, "targetless")
|
||||
|
||||
|
||||
def CHILD_OF(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
@ -129,7 +129,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
|
||||
row.itemR(con, "target_z")
|
||||
|
||||
self.space_template(layout, con)
|
||||
|
||||
|
||||
def IK(self, context, layout, con):
|
||||
if context.object.pose.ik_solver == "ITASC":
|
||||
layout.itemR(con, "ik_type")
|
||||
@ -168,7 +168,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
|
||||
sub = col.column()
|
||||
sub.active = con.rotation
|
||||
sub.itemR(con, "orient_weight", text="Rotation", slider=True)
|
||||
|
||||
|
||||
def IK_COPY_POSE(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
self.ik_template(layout, con)
|
||||
@ -212,7 +212,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
|
||||
row = layout.row()
|
||||
row.itemR(con, "weight", text="Weight", slider=True)
|
||||
row.itemR(con, "distance", text="Distance", slider=True)
|
||||
|
||||
|
||||
def FOLLOW_PATH(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
@ -310,7 +310,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
|
||||
row = layout.row()
|
||||
row.itemL(text="Convert:")
|
||||
row.itemR(con, "owner_space", text="")
|
||||
|
||||
|
||||
def LIMIT_SCALE(self, context, layout, con):
|
||||
split = layout.split()
|
||||
|
||||
@ -351,7 +351,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
|
||||
row = layout.row()
|
||||
row.itemL(text="Convert:")
|
||||
row.itemR(con, "owner_space", text="")
|
||||
|
||||
|
||||
def COPY_ROTATION(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
@ -378,7 +378,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
|
||||
layout.itemR(con, "offset")
|
||||
|
||||
self.space_template(layout, con)
|
||||
|
||||
|
||||
def COPY_LOCATION(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
@ -438,7 +438,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="Convert:")
|
||||
row.itemR(con, "owner_space", text="")
|
||||
row.itemR(con, "target_space", text="")
|
||||
|
||||
def LOCKED_TRACK(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
@ -597,17 +597,17 @@ class ConstraintButtonsPanel(bpy.types.Panel):
|
||||
|
||||
def SPLINE_IK(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
|
||||
col = layout.column()
|
||||
col.itemL(text="Spline Fitting:")
|
||||
col.itemR(con, "chain_length")
|
||||
col.itemR(con, "even_divisions")
|
||||
#col.itemR(con, "affect_root") # XXX: this is not that useful yet
|
||||
|
||||
|
||||
col = layout.column()
|
||||
col.itemL(text="Chain Scaling:")
|
||||
col.itemR(con, "keep_max_length")
|
||||
col.itemR(con, "radius_to_thickness")
|
||||
col.itemR(con, "xz_scaling_mode")
|
||||
|
||||
|
||||
class OBJECT_PT_constraints(ConstraintButtonsPanel):
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
@ -930,63 +930,64 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
psys = context.particle_system
|
||||
part = psys.settings
|
||||
|
||||
layout.itemL(text="Nothing here yet.")
|
||||
# layout.itemL(text="Nothing here yet.")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemL(text="Vertex Group")
|
||||
#row.itemL(text="Negate")
|
||||
row = layout.row()
|
||||
row.itemL(text="Vertex Group")
|
||||
row.itemL(text="Negate")
|
||||
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_density")
|
||||
#row.itemR(psys, "vertex_group_density_negate", text="")
|
||||
row = layout.row()
|
||||
row.item_pointerR(psys, "vertex_group_density", ob, "vertex_groups", text="Density")
|
||||
row.itemR(psys, "vertex_group_density_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_velocity")
|
||||
#row.itemR(psys, "vertex_group_velocity_negate", text="")
|
||||
row = layout.row()
|
||||
row.item_pointerR(psys, "vertex_group_velocity", ob, "vertex_groups", text="Velocity")
|
||||
row.itemR(psys, "vertex_group_velocity_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_length")
|
||||
#row.itemR(psys, "vertex_group_length_negate", text="")
|
||||
row = layout.row()
|
||||
row.item_pointerR(psys, "vertex_group_length", ob, "vertex_groups", text="Length")
|
||||
row.itemR(psys, "vertex_group_length_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_clump")
|
||||
#row.itemR(psys, "vertex_group_clump_negate", text="")
|
||||
row = layout.row()
|
||||
row.item_pointerR(psys, "vertex_group_clump", ob, "vertex_groups", text="Clump")
|
||||
row.itemR(psys, "vertex_group_clump_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_kink")
|
||||
#row.itemR(psys, "vertex_group_kink_negate", text="")
|
||||
row = layout.row()
|
||||
row.item_pointerR(psys, "vertex_group_kink", ob, "vertex_groups", text="Kink")
|
||||
row.itemR(psys, "vertex_group_kink_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_roughness1")
|
||||
#row.itemR(psys, "vertex_group_roughness1_negate", text="")
|
||||
row = layout.row()
|
||||
row.item_pointerR(psys, "vertex_group_roughness1", ob, "vertex_groups", text="Roughness 1")
|
||||
row.itemR(psys, "vertex_group_roughness1_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_roughness2")
|
||||
#row.itemR(psys, "vertex_group_roughness2_negate", text="")
|
||||
row = layout.row()
|
||||
row.item_pointerR(psys, "vertex_group_roughness2", ob, "vertex_groups", text="Roughness 2")
|
||||
row.itemR(psys, "vertex_group_roughness2_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_roughness_end")
|
||||
#row.itemR(psys, "vertex_group_roughness_end_negate", text="")
|
||||
row = layout.row()
|
||||
row.item_pointerR(psys, "vertex_group_roughness_end", ob, "vertex_groups", text="Roughness End")
|
||||
row.itemR(psys, "vertex_group_roughness_end_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_size")
|
||||
#row.itemR(psys, "vertex_group_size_negate", text="")
|
||||
row = layout.row()
|
||||
row.item_pointerR(psys, "vertex_group_size", ob, "vertex_groups", text="Size")
|
||||
row.itemR(psys, "vertex_group_size_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_tangent")
|
||||
#row.itemR(psys, "vertex_group_tangent_negate", text="")
|
||||
row = layout.row()
|
||||
row.item_pointerR(psys, "vertex_group_tangent", ob, "vertex_groups", text="Tangent")
|
||||
row.itemR(psys, "vertex_group_tangent_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_rotation")
|
||||
#row.itemR(psys, "vertex_group_rotation_negate", text="")
|
||||
row = layout.row()
|
||||
row.item_pointerR(psys, "vertex_group_rotation", ob, "vertex_groups", text="Rotation")
|
||||
row.itemR(psys, "vertex_group_rotation_negate", text="")
|
||||
|
||||
#row = layout.row()
|
||||
#row.itemR(psys, "vertex_group_field")
|
||||
#row.itemR(psys, "vertex_group_field_negate", text="")
|
||||
row = layout.row()
|
||||
row.item_pointerR(psys, "vertex_group_field", ob, "vertex_groups", text="Field")
|
||||
row.itemR(psys, "vertex_group_field_negate", text="")
|
||||
|
||||
bpy.types.register(PARTICLE_PT_particles)
|
||||
bpy.types.register(PARTICLE_PT_hair_dynamics)
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
@ -73,8 +73,9 @@ class PHYSICS_PT_softbody(PhysicButtonsPanel):
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Object:")
|
||||
col.itemR(softbody, "mass")
|
||||
col.itemR(softbody, "friction")
|
||||
col.itemR(softbody, "mass")
|
||||
col.item_pointerR(softbody, "mass_vertex_group", ob, "vertex_groups", text="Mass:")
|
||||
|
||||
col = split.column()
|
||||
col.itemL(text="Simulation:")
|
||||
@ -167,6 +168,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel):
|
||||
col.itemR(softbody, "plastic")
|
||||
col.itemR(softbody, "bending")
|
||||
col.itemR(softbody, "spring_length", text="Length")
|
||||
col.item_pointerR(softbody, "spring_vertex_group", ob, "vertex_groups", text="Springs:")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(softbody, "stiff_quads")
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
@ -19,6 +19,7 @@
|
||||
# <pep8 compliant>
|
||||
import sys
|
||||
import bpy
|
||||
from bpy.props import *
|
||||
|
||||
|
||||
class CONSOLE_HT_header(bpy.types.Header):
|
||||
@ -68,6 +69,7 @@ class CONSOLE_MT_console(bpy.types.Menu):
|
||||
layout.itemO("console.clear")
|
||||
layout.itemO("console.copy")
|
||||
layout.itemO("console.paste")
|
||||
layout.itemM("CONSOLE_MT_language")
|
||||
|
||||
|
||||
class CONSOLE_MT_report(bpy.types.Menu):
|
||||
@ -81,6 +83,24 @@ class CONSOLE_MT_report(bpy.types.Menu):
|
||||
layout.itemO("console.report_delete")
|
||||
layout.itemO("console.report_copy")
|
||||
|
||||
class CONSOLE_MT_language(bpy.types.Menu):
|
||||
bl_label = "Languages..."
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.column()
|
||||
|
||||
mod = bpy.ops.console
|
||||
languages = []
|
||||
for opname in dir(mod):
|
||||
# execute_python, execute_shell etc.
|
||||
if opname.startswith("execute_"):
|
||||
languages.append(opname.split('_', 1)[-1])
|
||||
|
||||
languages.sort()
|
||||
|
||||
for language in languages:
|
||||
layout.item_stringO("console.language", "language", language, text=language[0].upper() + language[1:])
|
||||
|
||||
def add_scrollback(text, text_type):
|
||||
for l in text.split('\n'):
|
||||
@ -88,125 +108,26 @@ def add_scrollback(text, text_type):
|
||||
type=text_type)
|
||||
|
||||
|
||||
def get_console(console_id):
|
||||
'''
|
||||
helper function for console operators
|
||||
currently each text datablock gets its own
|
||||
console - bpython_code.InteractiveConsole()
|
||||
...which is stored in this function.
|
||||
|
||||
console_id can be any hashable type
|
||||
'''
|
||||
from code import InteractiveConsole
|
||||
|
||||
try:
|
||||
consoles = get_console.consoles
|
||||
except:
|
||||
consoles = get_console.consoles = {}
|
||||
|
||||
# clear all dead consoles, use text names as IDs
|
||||
# TODO, find a way to clear IDs
|
||||
'''
|
||||
for console_id in list(consoles.keys()):
|
||||
if console_id not in bpy.data.texts:
|
||||
del consoles[id]
|
||||
'''
|
||||
|
||||
try:
|
||||
console, stdout, stderr = consoles[console_id]
|
||||
except:
|
||||
namespace = {'__builtins__': __builtins__, 'bpy': bpy}
|
||||
console = InteractiveConsole(namespace)
|
||||
|
||||
import io
|
||||
stdout = io.StringIO()
|
||||
stderr = io.StringIO()
|
||||
|
||||
consoles[console_id] = console, stdout, stderr
|
||||
|
||||
return console, stdout, stderr
|
||||
|
||||
|
||||
class CONSOLE_OT_exec(bpy.types.Operator):
|
||||
class ConsoleExec(bpy.types.Operator):
|
||||
'''Execute the current console line as a python expression.'''
|
||||
bl_idname = "console.execute"
|
||||
bl_label = "Console Execute"
|
||||
bl_register = False
|
||||
|
||||
# Both prompts must be the same length
|
||||
PROMPT = '>>> '
|
||||
PROMPT_MULTI = '... '
|
||||
|
||||
# is this working???
|
||||
'''
|
||||
def poll(self, context):
|
||||
return (context.space_data.type == 'PYTHON')
|
||||
'''
|
||||
# its not :|
|
||||
|
||||
def execute(self, context):
|
||||
sc = context.space_data
|
||||
|
||||
try:
|
||||
line = sc.history[-1].line
|
||||
except:
|
||||
return ('CANCELLED',)
|
||||
execute = getattr(bpy.ops.console, "execute_" + sc.language, None)
|
||||
|
||||
if sc.console_type != 'PYTHON':
|
||||
return ('CANCELLED',)
|
||||
|
||||
console, stdout, stderr = get_console(hash(context.region))
|
||||
|
||||
# redirect output
|
||||
sys.stdout = stdout
|
||||
sys.stderr = stderr
|
||||
|
||||
# run the console
|
||||
if not line.strip():
|
||||
line_exec = '\n' # executes a multiline statement
|
||||
if execute:
|
||||
execute()
|
||||
else:
|
||||
line_exec = line
|
||||
|
||||
is_multiline = console.push(line_exec)
|
||||
|
||||
stdout.seek(0)
|
||||
stderr.seek(0)
|
||||
|
||||
output = stdout.read()
|
||||
output_err = stderr.read()
|
||||
|
||||
# cleanup
|
||||
sys.stdout = sys.__stdout__
|
||||
sys.stderr = sys.__stderr__
|
||||
sys.last_traceback = None
|
||||
|
||||
# So we can reuse, clear all data
|
||||
stdout.truncate(0)
|
||||
stderr.truncate(0)
|
||||
|
||||
bpy.ops.console.scrollback_append(text=sc.prompt + line, type='INPUT')
|
||||
|
||||
if is_multiline:
|
||||
sc.prompt = self.PROMPT_MULTI
|
||||
else:
|
||||
sc.prompt = self.PROMPT
|
||||
|
||||
# insert a new blank line
|
||||
bpy.ops.console.history_append(text="", current_character=0,
|
||||
remove_duplicates=True)
|
||||
|
||||
# Insert the output into the editor
|
||||
# not quite correct because the order might have changed,
|
||||
# but ok 99% of the time.
|
||||
if output:
|
||||
add_scrollback(output, 'OUTPUT')
|
||||
if output_err:
|
||||
add_scrollback(output_err, 'ERROR')
|
||||
print("Error: bpy.ops.console.execute_" + sc.language + " - not found")
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
class CONSOLE_OT_autocomplete(bpy.types.Operator):
|
||||
class ConsoleAutocomplete(bpy.types.Operator):
|
||||
'''Evaluate the namespace up until the cursor and give a list of
|
||||
options or complete the name if there is only one.'''
|
||||
bl_idname = "console.autocomplete"
|
||||
@ -214,40 +135,58 @@ class CONSOLE_OT_autocomplete(bpy.types.Operator):
|
||||
bl_register = False
|
||||
|
||||
def poll(self, context):
|
||||
return context.space_data.console_type == 'PYTHON'
|
||||
return context.space_data.console_type != 'REPORT'
|
||||
|
||||
def execute(self, context):
|
||||
from console import intellisense
|
||||
|
||||
sc = context.space_data
|
||||
|
||||
console = get_console(hash(context.region))[0]
|
||||
autocomplete = getattr(bpy.ops.console, "autocomplete_" + sc.language, None)
|
||||
|
||||
current_line = sc.history[-1]
|
||||
line = current_line.line
|
||||
if autocomplete:
|
||||
autocomplete()
|
||||
else:
|
||||
print("Error: bpy.ops.console.autocomplete_" + sc.language + " - not found")
|
||||
|
||||
if not console:
|
||||
return ('CANCELLED',)
|
||||
return ('FINISHED',)
|
||||
|
||||
if sc.console_type != 'PYTHON':
|
||||
return ('CANCELLED',)
|
||||
|
||||
# This function isnt aware of the text editor or being an operator
|
||||
# just does the autocomp then copy its results back
|
||||
current_line.line, current_line.current_character, scrollback = \
|
||||
intellisense.expand(
|
||||
line=current_line.line,
|
||||
cursor=current_line.current_character,
|
||||
namespace=console.locals,
|
||||
private='-d' in sys.argv)
|
||||
class ConsoleBanner(bpy.types.Operator):
|
||||
bl_idname = "console.banner"
|
||||
|
||||
# Now we need to copy back the line from blender back into the
|
||||
# text editor. This will change when we dont use the text editor
|
||||
# anymore
|
||||
if scrollback:
|
||||
add_scrollback(scrollback, 'INFO')
|
||||
def execute(self, context):
|
||||
sc = context.space_data
|
||||
|
||||
# default to python
|
||||
if not sc.language:
|
||||
sc.language = 'python'
|
||||
|
||||
context.area.tag_redraw()
|
||||
banner = getattr(bpy.ops.console, "banner_" + sc.language, None)
|
||||
|
||||
if banner:
|
||||
banner()
|
||||
else:
|
||||
print("Error: bpy.ops.console.banner_" + sc.language + " - not found")
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
|
||||
|
||||
class ConsoleLanguage(bpy.types.Operator):
|
||||
'''Set the current language for this console'''
|
||||
bl_idname = "console.language"
|
||||
language = StringProperty(name="Language", maxlen= 32, default= "")
|
||||
|
||||
def execute(self, context):
|
||||
sc = context.space_data
|
||||
|
||||
# defailt to python
|
||||
sc.language = self.language
|
||||
|
||||
bpy.ops.console.banner()
|
||||
|
||||
# insert a new blank line
|
||||
bpy.ops.console.history_append(text="", current_character=0,
|
||||
remove_duplicates=True)
|
||||
|
||||
return ('FINISHED',)
|
||||
|
||||
@ -255,6 +194,12 @@ class CONSOLE_OT_autocomplete(bpy.types.Operator):
|
||||
bpy.types.register(CONSOLE_HT_header)
|
||||
bpy.types.register(CONSOLE_MT_console)
|
||||
bpy.types.register(CONSOLE_MT_report)
|
||||
bpy.types.register(CONSOLE_MT_language)
|
||||
|
||||
bpy.ops.add(CONSOLE_OT_exec)
|
||||
bpy.ops.add(CONSOLE_OT_autocomplete)
|
||||
# Stubs that call the language operators
|
||||
bpy.ops.add(ConsoleExec)
|
||||
bpy.ops.add(ConsoleAutocomplete)
|
||||
bpy.ops.add(ConsoleBanner)
|
||||
|
||||
# Set the language and call the banner
|
||||
bpy.ops.add(ConsoleLanguage)
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
@ -208,7 +208,7 @@ class IMAGE_MT_uvs(bpy.types.Menu):
|
||||
|
||||
layout.itemS()
|
||||
|
||||
layout.itemR(settings, "proportional_editing")
|
||||
layout.item_menu_enumR(settings, "proportional_editing")
|
||||
layout.item_menu_enumR(settings, "proportional_editing_falloff")
|
||||
|
||||
layout.itemS()
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
@ -187,7 +187,9 @@ class INFO_MT_add(bpy.types.Menu):
|
||||
layout.itemO("object.text_add", text="Text", icon='ICON_OUTLINER_OB_FONT')
|
||||
|
||||
layout.itemS()
|
||||
|
||||
|
||||
layout.operator_context = "INVOKE_SCREEN"
|
||||
|
||||
layout.itemO("object.armature_add", text="Armature", icon='ICON_OUTLINER_OB_ARMATURE')
|
||||
layout.item_enumO("object.add", "type", 'LATTICE', icon='ICON_OUTLINER_OB_LATTICE')
|
||||
layout.item_enumO("object.add", "type", 'EMPTY', icon='ICON_OUTLINER_OB_EMPTY')
|
||||
@ -195,6 +197,9 @@ class INFO_MT_add(bpy.types.Menu):
|
||||
layout.itemS()
|
||||
|
||||
layout.item_enumO("object.add", "type", 'CAMERA', icon='ICON_OUTLINER_OB_CAMERA')
|
||||
|
||||
layout.operator_context = "EXEC_SCREEN"
|
||||
|
||||
layout.item_menu_enumO("object.lamp_add", "type", 'LAMP', text="Lamp", icon='ICON_OUTLINER_OB_LAMP')
|
||||
|
||||
layout.itemS()
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
@ -118,7 +118,7 @@ class SEQUENCER_MT_view(bpy.types.Menu):
|
||||
if st.display_mode == 'IMAGE':
|
||||
layout.itemR(st, "draw_safe_margin")
|
||||
if st.display_mode == 'WAVEFORM':
|
||||
layout.itemR(st, "seperate_color_preview")
|
||||
layout.itemR(st, "separate_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, "");
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
@ -342,6 +342,722 @@ class USERPREF_PT_system(bpy.types.Panel):
|
||||
sub1.itemR(system, "memory_cache_limit")
|
||||
|
||||
|
||||
class USERPREF_PT_theme(bpy.types.Panel):
|
||||
bl_space_type = 'USER_PREFERENCES'
|
||||
bl_label = "Themes"
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_show_header = False
|
||||
|
||||
def poll(self, context):
|
||||
userpref = context.user_preferences
|
||||
|
||||
return (userpref.active_section == 'THEMES')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
theme = context.user_preferences.themes[0]
|
||||
|
||||
|
||||
split = layout.split(percentage=0.33)
|
||||
split.itemR(theme, "active_theme", text="")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
split = layout.split()
|
||||
|
||||
if theme.active_theme == 'VIEW_3D':
|
||||
v3d = theme.view_3d
|
||||
|
||||
col = split.column()
|
||||
col.itemR(v3d, "back")
|
||||
col.itemR(v3d, "title")
|
||||
col.itemR(v3d, "text")
|
||||
col.itemR(v3d, "text_hi")
|
||||
col.itemR(v3d, "header")
|
||||
col.itemR(v3d, "header_text")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(v3d, "header_text_hi")
|
||||
col.itemR(v3d, "grid")
|
||||
col.itemR(v3d, "panel", slider=True)
|
||||
col.itemR(v3d, "wire")
|
||||
col.itemR(v3d, "lamp", slider=True)
|
||||
|
||||
col = split.column()
|
||||
col.itemR(v3d, "current_frame")
|
||||
col.itemR(v3d, "editmesh_active", slider=True)
|
||||
col.itemR(v3d, "object_selected")
|
||||
col.itemR(v3d, "object_active")
|
||||
col.itemR(v3d, "object_grouped")
|
||||
col.itemR(v3d, "object_grouped_active")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(v3d, "transform")
|
||||
col.itemR(v3d, "vertex")
|
||||
col.itemR(v3d, "face", slider=True)
|
||||
col.itemR(v3d, "normal")
|
||||
col.itemR(v3d, "bone_solid")
|
||||
col.itemR(v3d, "bone_pose")
|
||||
|
||||
# col.itemR(v3d, "edge") Doesn't seem to work
|
||||
elif theme.active_theme == 'USER_INTERFACE':
|
||||
|
||||
ui = theme.user_interface.wcol_regular
|
||||
|
||||
layout.itemL(text="Regular:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
layout.itemS()
|
||||
|
||||
ui = theme.user_interface.wcol_tool
|
||||
layout.itemL(text="Tool:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_radio
|
||||
layout.itemL(text="Radio Buttons:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_text
|
||||
layout.itemL(text="Text:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_option
|
||||
layout.itemL(text="Option:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_toggle
|
||||
layout.itemL(text="Toggle:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_num
|
||||
layout.itemL(text="Number Field:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_numslider
|
||||
layout.itemL(text="Value Slider:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_box
|
||||
layout.itemL(text="Box:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_menu
|
||||
layout.itemL(text="Menu:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_pulldown
|
||||
layout.itemL(text="Pulldown:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_menu_back
|
||||
layout.itemL(text="Menu Back:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_menu_item
|
||||
layout.itemL(text="Menu Item:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_scroll
|
||||
layout.itemL(text="Scroll Bar:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_list_item
|
||||
layout.itemL(text="List Item:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "outline")
|
||||
sub1.itemR(ui, "item", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner", slider=True)
|
||||
sub1.itemR(ui, "inner_sel", slider=True)
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "text")
|
||||
sub1.itemR(ui, "text_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "shaded")
|
||||
sub2 = sub1.column(align=True)
|
||||
sub2.active = ui.shaded
|
||||
sub2.itemR(ui, "shadetop")
|
||||
sub2.itemR(ui, "shadedown")
|
||||
|
||||
ui = theme.user_interface.wcol_state
|
||||
layout.itemL(text="State:")
|
||||
|
||||
sub = layout.row()
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner_anim")
|
||||
sub1.itemR(ui, "inner_anim_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner_driven")
|
||||
sub1.itemR(ui, "inner_driven_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "inner_key")
|
||||
sub1.itemR(ui, "inner_key_sel")
|
||||
sub1 = sub.column()
|
||||
sub1.itemR(ui, "blend")
|
||||
|
||||
ui = theme.user_interface
|
||||
layout.itemS()
|
||||
|
||||
sub = layout.row()
|
||||
sub.itemR(ui, "icon_file")
|
||||
|
||||
layout.itemS()
|
||||
layout.itemS()
|
||||
|
||||
|
||||
elif theme.active_theme == 'GRAPH_EDITOR':
|
||||
graph = theme.graph_editor
|
||||
|
||||
col = split.column()
|
||||
col.itemR(graph, "back")
|
||||
col.itemR(graph, "title")
|
||||
col.itemR(graph, "text")
|
||||
col.itemR(graph, "text_hi")
|
||||
col.itemR(graph, "header")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(graph, "header_text")
|
||||
col.itemR(graph, "header_text_hi")
|
||||
col.itemR(graph, "grid")
|
||||
col.itemR(graph, "panel")
|
||||
col.itemR(graph, "window_sliders")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(graph, "channels_region")
|
||||
col.itemR(graph, "vertex")
|
||||
col.itemR(graph, "current_frame")
|
||||
col.itemR(graph, "handle_vertex")
|
||||
col.itemR(graph, "handle_vertex_select")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(graph, "handle_vertex_size")
|
||||
col.itemR(graph, "channel_group")
|
||||
col.itemR(graph, "active_channels_group")
|
||||
col.itemR(graph, "dopesheet_channel")
|
||||
col.itemR(graph, "dopesheet_subchannel")
|
||||
|
||||
|
||||
elif theme.active_theme == 'FILE_BROWSER':
|
||||
file = theme.file_browser
|
||||
|
||||
col = split.column()
|
||||
col.itemR(file, "back")
|
||||
col.itemR(file, "title")
|
||||
col.itemR(file, "text")
|
||||
col.itemR(file, "text_hi")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(file, "header")
|
||||
col.itemR(file, "header_text")
|
||||
col.itemR(file, "header_text_hi")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(file, "selected_file")
|
||||
col.itemR(file, "tiles")
|
||||
col.itemR(file, "scrollbar")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(file, "scroll_handle")
|
||||
col.itemR(file, "active_file")
|
||||
col.itemR(file, "active_file_text")
|
||||
|
||||
elif theme.active_theme == 'NLA_EDITOR':
|
||||
nla = theme.nla_editor
|
||||
|
||||
col = split.column()
|
||||
col.itemR(nla, "back")
|
||||
col.itemR(nla, "title")
|
||||
col.itemR(nla, "text")
|
||||
col.itemR(nla, "text_hi")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(nla, "header")
|
||||
col.itemR(nla, "header_text")
|
||||
col.itemR(nla, "header_text_hi")
|
||||
col.itemR(nla, "grid")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(nla, "view_sliders")
|
||||
col.itemR(nla, "bars")
|
||||
col.itemR(nla, "bars_selected")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(nla, "strips")
|
||||
col.itemR(nla, "strips_selected")
|
||||
col.itemR(nla, "current_frame")
|
||||
|
||||
elif theme.active_theme == 'DOPESHEET_EDITOR':
|
||||
dope = theme.dopesheet_editor
|
||||
|
||||
col = split.column()
|
||||
col.itemR(dope, "back")
|
||||
col.itemR(dope, "title")
|
||||
col.itemR(dope, "text")
|
||||
col.itemR(dope, "text_hi")
|
||||
col.itemR(dope, "header")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(dope, "header_text")
|
||||
col.itemR(dope, "header_text_hi")
|
||||
col.itemR(dope, "grid")
|
||||
col.itemR(dope, "value_sliders")
|
||||
col.itemR(dope, "view_sliders")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(dope, "channels")
|
||||
col.itemR(dope, "channels_selected")
|
||||
col.itemR(dope, "channel_group")
|
||||
col.itemR(dope, "active_channels_group")
|
||||
col.itemR(dope, "long_key")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(dope, "long_key_selected")
|
||||
col.itemR(dope, "current_frame")
|
||||
col.itemR(dope, "dopesheet_channel")
|
||||
col.itemR(dope, "dopesheet_subchannel")
|
||||
|
||||
elif theme.active_theme == 'IMAGE_EDITOR':
|
||||
image = theme.image_editor
|
||||
|
||||
col = split.column()
|
||||
col.itemR(image, "back")
|
||||
col.itemR(image, "title")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(image, "text")
|
||||
col.itemR(image, "text_hi")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(image, "header")
|
||||
col.itemR(image, "header_text")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(image, "header_text_hi")
|
||||
col.itemR(image, "editmesh_active", slider=True)
|
||||
|
||||
elif theme.active_theme == 'SEQUENCE_EDITOR':
|
||||
seq = theme.sequence_editor
|
||||
|
||||
col = split.column()
|
||||
col.itemR(seq, "back")
|
||||
col.itemR(seq, "title")
|
||||
col.itemR(seq, "text")
|
||||
col.itemR(seq, "text_hi")
|
||||
col.itemR(seq, "header")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(seq, "header_text")
|
||||
col.itemR(seq, "header_text_hi")
|
||||
col.itemR(seq, "grid")
|
||||
col.itemR(seq, "window_sliders")
|
||||
col.itemR(seq, "movie_strip")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(seq, "image_strip")
|
||||
col.itemR(seq, "scene_strip")
|
||||
col.itemR(seq, "audio_strip")
|
||||
col.itemR(seq, "effect_strip")
|
||||
col.itemR(seq, "plugin_strip")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(seq, "transition_strip")
|
||||
col.itemR(seq, "meta_strip")
|
||||
col.itemR(seq, "current_frame")
|
||||
col.itemR(seq, "keyframe")
|
||||
col.itemR(seq, "draw_action")
|
||||
|
||||
elif theme.active_theme == 'PROPERTIES':
|
||||
prop = theme.properties
|
||||
|
||||
col = split.column()
|
||||
col.itemR(prop, "back")
|
||||
col.itemR(prop, "title")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(prop, "text")
|
||||
col.itemR(prop, "text_hi")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(prop, "header")
|
||||
col.itemR(prop, "header_text")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(prop, "header_text_hi")
|
||||
col.itemR(prop, "panel")
|
||||
|
||||
elif theme.active_theme == 'TEXT_EDITOR':
|
||||
text = theme.text_editor
|
||||
|
||||
col = split.column()
|
||||
col.itemR(text, "back")
|
||||
col.itemR(text, "title")
|
||||
col.itemR(text, "text")
|
||||
col.itemR(text, "text_hi")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(text, "header")
|
||||
col.itemR(text, "header_text")
|
||||
col.itemR(text, "header_text_hi")
|
||||
col.itemR(text, "line_numbers_background")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(text, "scroll_bar")
|
||||
col.itemR(text, "selected_text")
|
||||
col.itemR(text, "cursor")
|
||||
col.itemR(text, "syntax_builtin")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(text, "syntax_special")
|
||||
col.itemR(text, "syntax_comment")
|
||||
col.itemR(text, "syntax_string")
|
||||
col.itemR(text, "syntax_numbers")
|
||||
|
||||
elif theme.active_theme == 'TIMELINE':
|
||||
time = theme.timeline
|
||||
|
||||
col = split.column()
|
||||
col.itemR(time, "back")
|
||||
col.itemR(time, "title")
|
||||
col.itemR(time, "text")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(time, "text_hi")
|
||||
col.itemR(time, "header")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(time, "header_text")
|
||||
col.itemR(time, "header_text_hi")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(time, "grid")
|
||||
col.itemR(time, "current_frame")
|
||||
|
||||
elif theme.active_theme == 'NODE_EDITOR':
|
||||
node = theme.node_editor
|
||||
|
||||
col = split.column()
|
||||
col.itemR(node, "back")
|
||||
col.itemR(node, "title")
|
||||
col.itemR(node, "text")
|
||||
col.itemR(node, "text_hi")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(node, "header")
|
||||
col.itemR(node, "header_text")
|
||||
col.itemR(node, "header_text_hi")
|
||||
col.itemR(node, "wires")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(node, "wire_select")
|
||||
col.itemR(node, "selected_text")
|
||||
col.itemR(node, "node_backdrop")
|
||||
col.itemR(node, "in_out_node")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(node, "converter_node")
|
||||
col.itemR(node, "operator_node")
|
||||
col.itemR(node, "group_node")
|
||||
|
||||
elif theme.active_theme == 'LOGIC_EDITOR':
|
||||
logic = theme.logic_editor
|
||||
|
||||
col = split.column()
|
||||
col.itemR(logic, "back")
|
||||
col.itemR(logic, "title")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(logic, "text")
|
||||
col.itemR(logic, "text_hi")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(logic, "header")
|
||||
col.itemR(logic, "header_text")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(logic, "header_text_hi")
|
||||
col.itemR(logic, "panel")
|
||||
|
||||
elif theme.active_theme == 'OUTLINER':
|
||||
out = theme.outliner
|
||||
|
||||
col = split.column()
|
||||
col.itemR(out, "back")
|
||||
col.itemR(out, "title")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(out, "text")
|
||||
col.itemR(out, "text_hi")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(out, "header")
|
||||
col.itemR(out, "header_text")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(out, "header_text_hi")
|
||||
|
||||
elif theme.active_theme == 'INFO':
|
||||
info = theme.info
|
||||
|
||||
col = split.column()
|
||||
col.itemR(info, "back")
|
||||
col.itemR(info, "title")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(info, "text")
|
||||
col.itemR(info, "text_hi")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(info, "header")
|
||||
col.itemR(info, "header_text")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(info, "header_text_hi")
|
||||
|
||||
elif theme.active_theme == 'USER_PREFERENCES':
|
||||
prefs = theme.user_preferences
|
||||
|
||||
col = split.column()
|
||||
col.itemR(prefs, "back")
|
||||
col.itemR(prefs, "title")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(prefs, "text")
|
||||
col.itemR(prefs, "text_hi")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(prefs, "header")
|
||||
col.itemR(prefs, "header_text")
|
||||
|
||||
col = split.column()
|
||||
col.itemR(prefs, "header_text_hi")
|
||||
|
||||
|
||||
class USERPREF_PT_file(bpy.types.Panel):
|
||||
bl_space_type = 'USER_PREFERENCES'
|
||||
bl_label = "Files"
|
||||
@ -515,9 +1231,9 @@ class USERPREF_PT_input(bpy.types.Panel):
|
||||
itemrow = row.row()
|
||||
itemrow.enabled = km.user_defined
|
||||
if kmi.active:
|
||||
itemrow.itemR(kmi, "active", text="", icon="ICON_CHECKBOX_HLT")
|
||||
itemrow.itemR(kmi, "active", text="", icon="ICON_CHECKBOX_HLT")
|
||||
else:
|
||||
itemrow.itemR(kmi, "active", text="", icon="ICON_CHECKBOX_DEHLT")
|
||||
itemrow.itemR(kmi, "active", text="", icon="ICON_CHECKBOX_DEHLT")
|
||||
|
||||
itemcol = itemrow.column()
|
||||
itemcol.active = kmi.active
|
||||
@ -585,6 +1301,7 @@ bpy.types.register(USERPREF_HT_header)
|
||||
bpy.types.register(USERPREF_MT_view)
|
||||
bpy.types.register(USERPREF_PT_tabs)
|
||||
bpy.types.register(USERPREF_PT_interface)
|
||||
bpy.types.register(USERPREF_PT_theme)
|
||||
bpy.types.register(USERPREF_PT_edit)
|
||||
bpy.types.register(USERPREF_PT_system)
|
||||
bpy.types.register(USERPREF_PT_file)
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
@ -90,6 +90,22 @@ class VIEW3D_MT_snap(bpy.types.Menu):
|
||||
layout.itemO("view3d.snap_cursor_to_grid", text="Cursor to Grid")
|
||||
layout.itemO("view3d.snap_cursor_to_active", text="Cursor to Active")
|
||||
|
||||
class VIEW3D_MT_uv_map(dynamic_menu.DynMenu):
|
||||
bl_label = "UV Mapping"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.itemO("uv.unwrap")
|
||||
layout.itemO("uv.cube_project")
|
||||
layout.itemO("uv.cylinder_project")
|
||||
layout.itemO("uv.sphere_project")
|
||||
layout.itemO("uv.project_from_view")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
layout.itemO("uv.reset")
|
||||
|
||||
# ********** View menus **********
|
||||
|
||||
|
||||
@ -175,11 +191,41 @@ class VIEW3D_MT_view_align(bpy.types.Menu):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.itemM("VIEW3D_MT_view_align_selected")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
layout.item_booleanO("view3d.view_all", "center", True, text="Center Cursor and View All")
|
||||
layout.itemO("view3d.camera_to_view", text="Align Active Camera to View")
|
||||
layout.itemO("view3d.view_center")
|
||||
|
||||
|
||||
class VIEW3D_MT_view_align_selected(bpy.types.Menu):
|
||||
bl_label = "Align View to Selected"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
props = layout.itemO("view3d.viewnumpad", properties=True, text="Top")
|
||||
props.align_active = True
|
||||
props.type = 'TOP'
|
||||
props = layout.itemO("view3d.viewnumpad", properties=True, text="Bottom")
|
||||
props.align_active = True
|
||||
props.type = 'BOTTOM'
|
||||
props = layout.itemO("view3d.viewnumpad", properties=True, text="Front")
|
||||
props.align_active = True
|
||||
props.type = 'FRONT'
|
||||
props = layout.itemO("view3d.viewnumpad", properties=True, text="Back")
|
||||
props.align_active = True
|
||||
props.type = 'BACK'
|
||||
props = layout.itemO("view3d.viewnumpad", properties=True, text="Right")
|
||||
props.align_active = True
|
||||
props.type = 'RIGHT'
|
||||
props = layout.itemO("view3d.viewnumpad", properties=True, text="Left")
|
||||
props.align_active = True
|
||||
props.type = 'LEFT'
|
||||
|
||||
|
||||
class VIEW3D_MT_view_cameras(bpy.types.Menu):
|
||||
bl_label = "Cameras"
|
||||
|
||||
@ -209,9 +255,9 @@ class VIEW3D_MT_select_object(bpy.types.Menu):
|
||||
layout.itemO("object.select_mirror", text="Mirror")
|
||||
layout.itemO("object.select_by_layer", text="Select All by Layer")
|
||||
layout.item_menu_enumO("object.select_by_type", "type", "", text="Select All by Type...")
|
||||
|
||||
|
||||
layout.itemS()
|
||||
|
||||
|
||||
layout.item_menu_enumO("object.select_grouped", "type", text="Grouped")
|
||||
layout.item_menu_enumO("object.select_linked", "type", text="Linked")
|
||||
layout.itemO("object.select_pattern", text="Select Pattern...")
|
||||
@ -286,6 +332,8 @@ class VIEW3D_MT_select_edit_mesh(bpy.types.Menu):
|
||||
layout.itemO("mesh.select_random", text="Random...")
|
||||
layout.itemO("mesh.edges_select_sharp", text="Sharp Edges")
|
||||
layout.itemO("mesh.faces_select_linked_flat", text="Linked Flat Faces")
|
||||
layout.itemO("mesh.faces_select_interior", text="Interior Faces")
|
||||
layout.itemO("mesh.select_axis", text="Side of Active")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
@ -407,7 +455,7 @@ class VIEW3D_MT_select_edit_armature(bpy.types.Menu):
|
||||
layout = self.layout
|
||||
|
||||
layout.itemO("view3d.select_border")
|
||||
|
||||
|
||||
|
||||
layout.itemS()
|
||||
|
||||
@ -463,8 +511,10 @@ class VIEW3D_MT_object(bpy.types.Menu):
|
||||
layout.item_booleanO("object.duplicate", "linked", True, text="Duplicate Linked")
|
||||
layout.itemO("object.delete", text="Delete...")
|
||||
layout.itemO("object.proxy_make", text="Make Proxy...")
|
||||
layout.itemM("VIEW3D_MT_make_links", text="Make Links...")
|
||||
layout.item_menu_enumO("object.make_local", "type", text="Make Local...")
|
||||
layout.itemM("VIEW3D_MT_make_single_user")
|
||||
layout.itemM("VIEW3D_MT_make_links")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
@ -588,6 +638,18 @@ class VIEW3D_MT_make_single_user(bpy.types.Menu):
|
||||
props = layout.itemO("object.make_single_user", properties=True, text="Animation")
|
||||
props.animation = True
|
||||
|
||||
|
||||
class VIEW3D_MT_make_links(bpy.types.Menu):
|
||||
bl_label = "Make Links"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.item_menu_enumO("object.make_links_scene", "type", text="Objects to Scene...")
|
||||
|
||||
layout.items_enumO("object.make_links_data", property="type") # inline
|
||||
|
||||
|
||||
# ********** Vertex paint menu **********
|
||||
|
||||
|
||||
@ -831,7 +893,7 @@ class VIEW3D_MT_edit_mesh(bpy.types.Menu):
|
||||
|
||||
layout.itemS()
|
||||
|
||||
layout.itemO("uv.mapping_menu", text="UV Unwrap...")
|
||||
layout.itemM("VIEW3D_MT_uv_map", text="UV Unwrap...")
|
||||
|
||||
layout.itemS()
|
||||
|
||||
@ -1307,6 +1369,33 @@ class VIEW3D_PT_3dview_properties(bpy.types.Panel):
|
||||
|
||||
layout.column().itemR(scene, "cursor_location", text="3D Cursor:")
|
||||
|
||||
class VIEW3D_PT_3dview_item(bpy.types.Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_label = "Item"
|
||||
|
||||
def poll(self, context):
|
||||
return (context.active_object or context.bone or context.edit_bone)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="", icon='ICON_OBJECT_DATA')
|
||||
row.itemR(ob, "name", text="")
|
||||
|
||||
if ((context.active_bone or context.active_pchan) and ob.type == 'ARMATURE' and (ob.mode == 'EDIT' or ob.mode == 'POSE')):
|
||||
bone = context.active_bone
|
||||
if not bone:
|
||||
pchan = context.active_pchan
|
||||
if pchan:
|
||||
bone = pchan.bone
|
||||
|
||||
row = layout.row()
|
||||
row.itemL(text="", icon='ICON_BONE_DATA')
|
||||
row.itemR(bone, "name", text="")
|
||||
|
||||
class VIEW3D_PT_3dview_display(bpy.types.Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
@ -1358,8 +1447,8 @@ class VIEW3D_PT_3dview_meshdisplay(bpy.types.Panel):
|
||||
bl_label = "Mesh Display"
|
||||
|
||||
def poll(self, context):
|
||||
editmesh = context.mode == 'EDIT_MESH'
|
||||
return (editmesh)
|
||||
# The active object check is needed because of localmode
|
||||
return (context.active_object and (context.mode == 'EDIT_MESH'))
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -1562,6 +1651,7 @@ bpy.types.register(VIEW3D_HT_header) # Header
|
||||
bpy.types.register(VIEW3D_MT_view) #View Menus
|
||||
bpy.types.register(VIEW3D_MT_view_navigation)
|
||||
bpy.types.register(VIEW3D_MT_view_align)
|
||||
bpy.types.register(VIEW3D_MT_view_align_selected)
|
||||
bpy.types.register(VIEW3D_MT_view_cameras)
|
||||
|
||||
bpy.types.register(VIEW3D_MT_select_object) # Select Menus
|
||||
@ -1584,6 +1674,7 @@ bpy.types.register(VIEW3D_MT_object_group)
|
||||
bpy.types.register(VIEW3D_MT_object_constraints)
|
||||
bpy.types.register(VIEW3D_MT_object_showhide)
|
||||
bpy.types.register(VIEW3D_MT_make_single_user)
|
||||
bpy.types.register(VIEW3D_MT_make_links)
|
||||
|
||||
|
||||
bpy.types.register(VIEW3D_MT_sculpt) # Sculpt Menu
|
||||
@ -1603,6 +1694,7 @@ bpy.types.register(VIEW3D_MT_pose_constraints)
|
||||
bpy.types.register(VIEW3D_MT_pose_showhide)
|
||||
|
||||
bpy.types.register(VIEW3D_MT_snap) # Edit Menus
|
||||
bpy.types.register(VIEW3D_MT_uv_map) # Edit Menus
|
||||
|
||||
bpy.types.register(VIEW3D_MT_edit_mesh)
|
||||
bpy.types.register(VIEW3D_MT_edit_mesh_specials) # Only as a menu for keybindings
|
||||
@ -1631,7 +1723,8 @@ bpy.types.register(VIEW3D_MT_edit_armature)
|
||||
bpy.types.register(VIEW3D_MT_edit_armature_parent)
|
||||
bpy.types.register(VIEW3D_MT_edit_armature_roll)
|
||||
|
||||
bpy.types.register(VIEW3D_PT_3dview_properties) # Panels
|
||||
bpy.types.register(VIEW3D_PT_3dview_item) # Panels
|
||||
bpy.types.register(VIEW3D_PT_3dview_properties)
|
||||
bpy.types.register(VIEW3D_PT_3dview_display)
|
||||
bpy.types.register(VIEW3D_PT_3dview_meshdisplay)
|
||||
bpy.types.register(VIEW3D_PT_3dview_curvedisplay)
|
||||
|
@ -4,12 +4,12 @@
|
||||
# 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.
|
||||
@ -101,6 +101,7 @@ class VIEW3D_PT_tools_meshedit(View3DPanel):
|
||||
col.itemO("mesh.screw")
|
||||
col.itemO("mesh.merge")
|
||||
col.itemO("mesh.rip_move")
|
||||
col.itemO("mesh.flip_normals")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.itemL(text="Shading:")
|
||||
@ -109,7 +110,8 @@ class VIEW3D_PT_tools_meshedit(View3DPanel):
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.itemL(text="UV Mapping:")
|
||||
col.itemO("uv.mapping_menu", text="Unwrap")
|
||||
col.item_stringO("wm.call_menu", "name", "VIEW3D_MT_uv_map", text="Unwrap")
|
||||
|
||||
col.itemO("mesh.uvs_rotate")
|
||||
col.itemO("mesh.uvs_mirror")
|
||||
|
||||
@ -133,10 +135,12 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mesh = context.active_object.data
|
||||
ob = context.active_object
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.itemR(mesh, "use_mirror_x")
|
||||
if ob:
|
||||
mesh = context.active_object.data
|
||||
col = layout.column(align=True)
|
||||
col.itemR(mesh, "use_mirror_x")
|
||||
|
||||
# ********** default tools for editmode_curve ****************
|
||||
|
||||
@ -521,7 +525,7 @@ class VIEW3D_PT_tools_brush(PaintPanel):
|
||||
col.row().itemR(brush, "direction", expand=True)
|
||||
|
||||
if brush.sculpt_tool == 'LAYER':
|
||||
col.itemR(brush, "persistent")
|
||||
col.itemR(brush, "use_persistent")
|
||||
col.itemO("sculpt.set_persistent_base")
|
||||
|
||||
# Texture Paint Mode #
|
||||
@ -826,6 +830,8 @@ class VIEW3D_PT_tools_particlemode(View3DPanel):
|
||||
|
||||
layout.itemR(pe, "type", text="")
|
||||
|
||||
ptcache = None
|
||||
|
||||
if pe.type == 'PARTICLES':
|
||||
if ob.particle_systems:
|
||||
if len(ob.particle_systems) > 1:
|
||||
|
@ -78,8 +78,6 @@ endif
|
||||
|
||||
GRPLIB = $(OCGDIR)/creator/$(DEBUG_DIR)libcreator.a
|
||||
GRPLIB += $(OCGDIR)/blender/windowmanager/$(DEBUG_DIR)libwindowmanager.a
|
||||
GRPLIB += $(NAN_BSP)/lib/$(DEBUG_DIR)libbsp.a
|
||||
GRPLIB += $(NAN_BOOLOP)/lib/$(DEBUG_DIR)libboolop.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
|
||||
@ -118,6 +116,9 @@ COMLIB += $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_sdl.a
|
||||
COMLIB += $(NAN_SAMPLERATE)/lib/$(DEBUG_DIR)libsamplerate.a
|
||||
COMLIB += $(NAN_LZO)/lib/$(DEBUG_DIR)libminilzo.a
|
||||
COMLIB += $(NAN_LZMA)/lib/$(DEBUG_DIR)liblzma.a
|
||||
COMLIB += $(NAN_BSP)/lib/$(DEBUG_DIR)libbsp.a
|
||||
COMLIB += $(NAN_BOOLOP)/lib/$(DEBUG_DIR)libboolop.a
|
||||
COMLIB += $(NAN_DECIMATION)/lib/$(DEBUG_DIR)libdecimation.a
|
||||
|
||||
ifeq ($(WITH_FFMPEG),true)
|
||||
COMLIB += $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_ffmpeg.a
|
||||
@ -233,7 +234,6 @@ endif
|
||||
|
||||
# note: space_api.a in begin of editors, screen.a in end
|
||||
PULIB = $(NAN_MOTO)/lib/libmoto.a
|
||||
PULIB += $(NAN_DECIMATION)/lib/$(DEBUG_DIR)libdecimation.a
|
||||
PULIB += $(OCGDIR)/blender/readblenfile/$(DEBUG_DIR)libreadblenfile.a
|
||||
PULIB += $(OCGDIR)/blender/ed_space/$(DEBUG_DIR)libed_space.a
|
||||
PULIB += $(OCGDIR)/blender/ed_sound/$(DEBUG_DIR)libed_sound.a
|
||||
|
@ -44,7 +44,7 @@ void copy_defgroups (struct ListBase *lb1, struct ListBase *lb2);
|
||||
struct bDeformGroup *copy_defgroup (struct bDeformGroup *ingroup);
|
||||
struct bDeformGroup *get_named_vertexgroup (Object *ob, char *name);
|
||||
int get_defgroup_num (struct Object *ob, struct bDeformGroup *dg);
|
||||
int get_named_vertexgroup_num (Object *ob, char *name);
|
||||
int get_named_vertexgroup_num (Object *ob, const char *name);
|
||||
void unique_vertexgroup_name (struct bDeformGroup *dg, struct Object *ob);
|
||||
|
||||
float deformvert_get_weight(const struct MDeformVert *dvert, int group_num);
|
||||
|
@ -1689,7 +1689,9 @@ static void splineik_init_tree_from_pchan(Object *ob, bPoseChannel *pchan_tip)
|
||||
/* setup new empty array for the points list */
|
||||
if (ikData->points)
|
||||
MEM_freeN(ikData->points);
|
||||
ikData->numpoints= (ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT)? ikData->chainlen : ikData->chainlen+1;
|
||||
// NOTE: just do chainlen+1 always for now, since we may get crashes otherwise
|
||||
//ikData->numpoints= (ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT)? ikData->chainlen : ikData->chainlen+1;
|
||||
ikData->numpoints= ikData->chainlen+1;
|
||||
ikData->points= MEM_callocN(sizeof(float)*ikData->numpoints, "Spline IK Binding");
|
||||
|
||||
/* perform binding of the joints to parametric positions along the curve based
|
||||
@ -1804,106 +1806,128 @@ static void splineik_init_tree(Scene *scene, Object *ob, float ctime)
|
||||
static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *ob, bPoseChannel *pchan, int index, float ctime)
|
||||
{
|
||||
bSplineIKConstraint *ikData= tree->ikData;
|
||||
float dirX[3]={1,0,0}, dirZ[3]={0,0,1};
|
||||
float axis1[3], axis2[3], tmpVec[3];
|
||||
float poseHead[3], poseTail[3], poseMat[4][4];
|
||||
float splineVec[3], scaleFac;
|
||||
float rad, radius=1.0f;
|
||||
float vec[4], dir[3];
|
||||
|
||||
/* step 1: get xyz positions for the endpoints of the bone
|
||||
* assume that they can be calculated on the path so that these calls will never fail
|
||||
*/
|
||||
/* tail */
|
||||
/* firstly, calculate the bone matrix the standard way, since this is needed for roll control */
|
||||
where_is_pose_bone(scene, ob, pchan, ctime);
|
||||
|
||||
VECCOPY(poseHead, pchan->pose_head);
|
||||
VECCOPY(poseTail, pchan->pose_tail);
|
||||
|
||||
/* step 1a: get xyz positions for the tail endpoint of the bone */
|
||||
if ( where_on_path(ikData->tar, tree->points[index], vec, dir, NULL, &rad) ) {
|
||||
/* convert the position to pose-space, then store it */
|
||||
Mat4MulVecfl(ob->imat, vec);
|
||||
VECCOPY(pchan->pose_tail, vec);
|
||||
VECCOPY(poseTail, vec);
|
||||
|
||||
/* set the new radius */
|
||||
radius= rad;
|
||||
}
|
||||
/* head
|
||||
* - check that this isn't the last bone that is subject to restrictions
|
||||
* i.e. if no-root option is enabled, the root should be calculated in the standard way
|
||||
*/
|
||||
if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT)==0 || (index+1 < ikData->chainlen))
|
||||
{
|
||||
/* the head location of this bone is driven by the spline */
|
||||
if ( where_on_path(ikData->tar, tree->points[index+1], vec, dir, NULL, &rad) ) {
|
||||
/* store the position, and convert it to pose space */
|
||||
Mat4MulVecfl(ob->imat, vec);
|
||||
VECCOPY(pchan->pose_head, vec);
|
||||
|
||||
/* set the new radius (it should be the average value) */
|
||||
radius = (radius+rad) / 2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// FIXME: this option isn't really useful yet...
|
||||
// maybe we are more interested in the head deltas that arise from this instead?
|
||||
/* use the standard calculations for this */
|
||||
where_is_pose_bone(scene, ob, pchan, ctime);
|
||||
|
||||
/* step 1b: get xyz positions for the head endpoint of the bone */
|
||||
/* firstly, calculate the position that the path suggests */
|
||||
if ( where_on_path(ikData->tar, tree->points[index+1], vec, dir, NULL, &rad) ) {
|
||||
/* store the position, and convert it to pose space */
|
||||
Mat4MulVecfl(ob->imat, vec);
|
||||
VECCOPY(poseHead, vec);
|
||||
|
||||
/* hack: assume for now that the pose_tail vector is still valid from the previous step,
|
||||
* and set that again now so that the chain doesn't get broken
|
||||
*/
|
||||
VECCOPY(pchan->pose_tail, vec);
|
||||
/* set the new radius (it should be the average value) */
|
||||
radius = (radius+rad) / 2;
|
||||
}
|
||||
if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) && (pchan == tree->root))
|
||||
{
|
||||
// this is the root bone, and it can be controlled however we like...
|
||||
// TODO: how do we calculate the offset of the root, if we don't even know the binding?
|
||||
VECCOPY(poseHead, pchan->pose_head);
|
||||
}
|
||||
|
||||
|
||||
/* step 2a: determine the implied transform from these endpoints
|
||||
/* step 2: determine the implied transform from these endpoints
|
||||
* - splineVec: the vector direction that the spline applies on the bone
|
||||
* - scaleFac: the factor that the bone length is scaled by to get the desired amount
|
||||
*/
|
||||
VecSubf(splineVec, pchan->pose_tail, pchan->pose_head);
|
||||
scaleFac= VecLength(splineVec) / pchan->bone->length; // TODO: this will need to be modified by blending factor
|
||||
VecSubf(splineVec, poseTail, poseHead);
|
||||
scaleFac= VecLength(splineVec) / pchan->bone->length;
|
||||
|
||||
/* step 2b: the spline vector now becomes the y-axis of the bone
|
||||
* - we need to normalise the splineVec first, so that it's just a unit direction vector
|
||||
/* step 3: compute the shortest rotation needed to map from the bone rotation to the current axis
|
||||
* - this uses the same method as is used for the Damped Track Constraint (see the code there for details)
|
||||
*/
|
||||
Mat4One(pchan->pose_mat);
|
||||
|
||||
Normalize(splineVec);
|
||||
VECCOPY(pchan->pose_mat[1], splineVec);
|
||||
|
||||
|
||||
/* step 3a: determine two vectors which will both be at right angles to the bone vector
|
||||
* based on the "Gram Schmidt process" for finding a set of Orthonormal Vectors, described at
|
||||
* http://ltcconline.net/greenl/courses/203/Vectors/orthonormalBases.htm
|
||||
* and normalise them to make sure they will behave nicely (as unit vectors)
|
||||
*/
|
||||
/* x-axis = dirX - projection(dirX onto splineVec) */
|
||||
Projf(axis1, dirX, splineVec); /* project dirX onto splineVec */
|
||||
VecSubf(pchan->pose_mat[0], dirX, axis1);
|
||||
|
||||
Normalize(pchan->pose_mat[0]);
|
||||
|
||||
/* z-axis = dirZ - projection(dirZ onto splineVec) - projection(dirZ onto dirX) */
|
||||
Projf(axis1, dirZ, splineVec); /* project dirZ onto Y-Axis */
|
||||
Projf(axis2, dirZ, pchan->pose_mat[0]); /* project dirZ onto X-Axis */
|
||||
|
||||
VecSubf(tmpVec, dirZ, axis1); /* dirZ - proj(dirZ->YAxis) */
|
||||
VecSubf(pchan->pose_mat[2], tmpVec, axis2); /* (dirZ - proj(dirZ->YAxis)) - proj(dirZ->XAxis) */
|
||||
|
||||
Normalize(pchan->pose_mat[2]);
|
||||
|
||||
/* step 3b: rotate these axes for roll control and also to minimise flipping rotations */
|
||||
// NOTE: for controlling flipping rotations, we could look to the curve for guidance...
|
||||
// TODO: code me!
|
||||
|
||||
{
|
||||
float dmat[3][3], rmat[3][3], tmat[3][3];
|
||||
float raxis[3], rangle;
|
||||
|
||||
/* compute the raw rotation matrix from the bone's current matrix by extracting only the
|
||||
* orientation-relevant axes, and normalising them
|
||||
*/
|
||||
VECCOPY(rmat[0], pchan->pose_mat[0]);
|
||||
VECCOPY(rmat[1], pchan->pose_mat[1]);
|
||||
VECCOPY(rmat[2], pchan->pose_mat[2]);
|
||||
Mat3Ortho(rmat);
|
||||
|
||||
/* also, normalise the orientation imposed by the bone, now that we've extracted the scale factor */
|
||||
Normalize(splineVec);
|
||||
|
||||
/* calculate smallest axis-angle rotation necessary for getting from the
|
||||
* current orientation of the bone, to the spline-imposed direction
|
||||
*/
|
||||
Crossf(raxis, rmat[1], splineVec);
|
||||
|
||||
rangle= Inpf(rmat[1], splineVec);
|
||||
rangle= acos( MAX2(-1.0f, MIN2(1.0f, rangle)) );
|
||||
|
||||
/* construct rotation matrix from the axis-angle rotation found above
|
||||
* - this call takes care to make sure that the axis provided is a unit vector first
|
||||
*/
|
||||
AxisAngleToMat3(raxis, rangle, dmat);
|
||||
|
||||
/* combine these rotations so that the y-axis of the bone is now aligned as the spline dictates,
|
||||
* while still maintaining roll control from the existing bone animation
|
||||
*/
|
||||
Mat3MulMat3(tmat, dmat, rmat); // m1, m3, m2
|
||||
Mat3Ortho(tmat); /* attempt to reduce shearing, though I doubt this'll really help too much now... */
|
||||
Mat4CpyMat3(poseMat, tmat);
|
||||
}
|
||||
|
||||
/* step 4: set the scaling factors for the axes */
|
||||
// TODO: include a no-scale option?
|
||||
{
|
||||
/* only multiply the y-axis by the scaling factor to get nice volume-preservation */
|
||||
VecMulf(pchan->pose_mat[1], scaleFac);
|
||||
VecMulf(poseMat[1], scaleFac);
|
||||
|
||||
/* set the scaling factors of the x and z axes from the average radius of the curve? */
|
||||
if (ikData->flag & CONSTRAINT_SPLINEIK_RAD2FAT) {
|
||||
VecMulf(pchan->pose_mat[0], radius);
|
||||
VecMulf(pchan->pose_mat[2], radius);
|
||||
/* set the scaling factors of the x and z axes from... */
|
||||
switch (ikData->xzScaleMode) {
|
||||
case CONSTRAINT_SPLINEIK_XZS_RADIUS:
|
||||
{
|
||||
/* radius of curve */
|
||||
VecMulf(poseMat[0], radius);
|
||||
VecMulf(poseMat[2], radius);
|
||||
}
|
||||
break;
|
||||
case CONSTRAINT_SPLINEIK_XZS_ORIGINAL:
|
||||
{
|
||||
/* original scales get used */
|
||||
float scale;
|
||||
|
||||
/* x-axis scale */
|
||||
scale= VecLength(pchan->pose_mat[0]);
|
||||
VecMulf(poseMat[0], scale);
|
||||
/* z-axis scale */
|
||||
scale= VecLength(pchan->pose_mat[2]);
|
||||
VecMulf(poseMat[2], scale);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* step 5: set the location of the bone in the matrix */
|
||||
VECCOPY(pchan->pose_mat[3], pchan->pose_head);
|
||||
VECCOPY(poseMat[3], pchan->pose_head);
|
||||
|
||||
/* finally, store the new transform */
|
||||
Mat4CpyMat4(pchan->pose_mat, poseMat);
|
||||
VECCOPY(pchan->pose_head, poseHead);
|
||||
VECCOPY(pchan->pose_tail, poseTail);
|
||||
|
||||
/* done! */
|
||||
pchan->flag |= POSE_DONE;
|
||||
|
@ -537,7 +537,7 @@ static int read_undosave(bContext *C, UndoElem *uel)
|
||||
int success=0, fileflags;
|
||||
|
||||
/* This is needed so undoing/redoing doesnt crash with threaded previews going */
|
||||
WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C));
|
||||
WM_jobs_stop_all(CTX_wm_manager(C));
|
||||
|
||||
strcpy(scestr, G.sce); /* temporal store */
|
||||
fileflags= G.fileflags;
|
||||
|
@ -526,8 +526,8 @@ DerivedMesh *NewBooleanDerivedMesh_intern(
|
||||
CSG_FreeVertexDescriptor(&vd_o);
|
||||
CSG_FreeFaceDescriptor(&fd_o);
|
||||
}
|
||||
// else
|
||||
// XXX error("Unknown internal error in boolean");
|
||||
else
|
||||
printf("Unknown internal error in boolean");
|
||||
|
||||
CSG_FreeBooleanOperation(bool_op);
|
||||
|
||||
|
@ -145,6 +145,7 @@ Curve *add_curve(char *name, int type)
|
||||
cu->fsize= 1.0;
|
||||
cu->ulheight = 0.05;
|
||||
cu->texflag= CU_AUTOSPACE;
|
||||
cu->twist_mode= CU_TWIST_MINIMUM; // XXX: this one seems to be the best one in most cases, at least for curve deform...
|
||||
|
||||
cu->bb= unit_boundbox();
|
||||
|
||||
@ -2906,7 +2907,7 @@ void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3])
|
||||
|
||||
float (*curve_getKeyVertexCos(Curve *cu, ListBase *lb, float *key))[3]
|
||||
{
|
||||
int i, numVerts;
|
||||
int i, numVerts = count_curveverts(lb);
|
||||
float *co, (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "cu_vcos");
|
||||
Nurb *nu;
|
||||
|
||||
|
@ -110,7 +110,7 @@ bDeformGroup *get_named_vertexgroup (Object *ob, char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int get_named_vertexgroup_num (Object *ob, char *name)
|
||||
int get_named_vertexgroup_num (Object *ob, const char *name)
|
||||
{
|
||||
/* Return the location of the named deform group within the list of
|
||||
* deform groups. This function is a combination of get_defgroup_num and
|
||||
|
@ -82,7 +82,7 @@
|
||||
#include "BKE_anim.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_bmesh.h"
|
||||
// XXX #include "BKE_booleanops.h"
|
||||
#include "BKE_booleanops.h"
|
||||
#include "BKE_cloth.h"
|
||||
#include "BKE_collision.h"
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
@ -113,18 +113,12 @@
|
||||
#include "BKE_shrinkwrap.h"
|
||||
#include "BKE_simple_deform.h"
|
||||
|
||||
//XXX #include "LOD_DependKludge.h"
|
||||
#include "LOD_decimation.h"
|
||||
|
||||
// XXX
|
||||
static struct DerivedMesh *NewBooleanDerivedMesh() {return NULL;}
|
||||
|
||||
#include "CCGSubSurf.h"
|
||||
|
||||
#include "RE_shader_ext.h"
|
||||
|
||||
//XXX #include "BIF_meshlaplacian.h"
|
||||
|
||||
/* Utility */
|
||||
|
||||
static int is_last_displist(Object *ob)
|
||||
@ -3577,10 +3571,11 @@ static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
|
||||
{
|
||||
int i;
|
||||
int texmapping = dmd->texmapping;
|
||||
float mapob_imat[4][4];
|
||||
|
||||
if(texmapping == MOD_DISP_MAP_OBJECT) {
|
||||
if(dmd->map_object)
|
||||
Mat4Invert(dmd->map_object->imat, dmd->map_object->obmat);
|
||||
Mat4Invert(mapob_imat, dmd->map_object->obmat);
|
||||
else /* if there is no map object, default to local */
|
||||
texmapping = MOD_DISP_MAP_LOCAL;
|
||||
}
|
||||
@ -3651,7 +3646,7 @@ static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
|
||||
case MOD_DISP_MAP_OBJECT:
|
||||
VECCOPY(*texco, *co);
|
||||
Mat4MulVecfl(ob->obmat, *texco);
|
||||
Mat4MulVecfl(dmd->map_object->imat, *texco);
|
||||
Mat4MulVecfl(mapob_imat, *texco);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -4137,11 +4132,11 @@ static DerivedMesh *decimateModifier_applyModifier(
|
||||
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||
int useRenderParams, int isFinalCalc)
|
||||
{
|
||||
// DecimateModifierData *dmd = (DecimateModifierData*) md;
|
||||
DecimateModifierData *dmd = (DecimateModifierData*) md;
|
||||
DerivedMesh *dm = derivedData, *result = NULL;
|
||||
MVert *mvert;
|
||||
MFace *mface;
|
||||
// LOD_Decimation_Info lod;
|
||||
LOD_Decimation_Info lod;
|
||||
int totvert, totface;
|
||||
int a, numTris;
|
||||
|
||||
@ -4163,8 +4158,6 @@ static DerivedMesh *decimateModifier_applyModifier(
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// XXX
|
||||
#if 0
|
||||
lod.vertex_buffer= MEM_mallocN(3*sizeof(float)*totvert, "vertices");
|
||||
lod.vertex_normal_buffer= MEM_mallocN(3*sizeof(float)*totvert, "normals");
|
||||
lod.triangle_index_buffer= MEM_mallocN(3*sizeof(int)*numTris, "trias");
|
||||
@ -4249,10 +4242,6 @@ static DerivedMesh *decimateModifier_applyModifier(
|
||||
MEM_freeN(lod.vertex_buffer);
|
||||
MEM_freeN(lod.vertex_normal_buffer);
|
||||
MEM_freeN(lod.triangle_index_buffer);
|
||||
#else
|
||||
modifier_setError(md, "Modifier not working yet in 2.5.");
|
||||
goto exit;
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return result;
|
||||
@ -6389,12 +6378,6 @@ static CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData
|
||||
|
||||
dataMask |= (1 << CD_MDEFORMVERT);
|
||||
|
||||
/* particles only need this if they are after a non deform modifier, and
|
||||
* the modifier stack will only create them in that case. */
|
||||
// dataMask |= CD_MASK_ORIGSPACE;
|
||||
|
||||
// dataMask |= CD_MASK_ORCO;
|
||||
|
||||
return dataMask;
|
||||
}
|
||||
|
||||
@ -7865,17 +7848,17 @@ static void meshdeformModifier_do(
|
||||
float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
|
||||
Mesh *me= ob->data;
|
||||
Mesh *me= (mmd->object)? mmd->object->data: NULL;
|
||||
EditMesh *em = (me)? BKE_mesh_get_editmesh(me): NULL;
|
||||
DerivedMesh *tmpdm, *cagedm;
|
||||
MDeformVert *dvert = NULL;
|
||||
MDeformWeight *dw;
|
||||
EditMesh *em = BKE_mesh_get_editmesh(me);
|
||||
MVert *cagemvert;
|
||||
float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
|
||||
float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3];
|
||||
int a, b, totvert, totcagevert, defgrp_index;
|
||||
|
||||
if(!mmd->object || (!mmd->bindcos && !mmd->needbind))
|
||||
if(!mmd->object || (!mmd->bindcos && !mmd->bindfunc))
|
||||
return;
|
||||
|
||||
/* get cage derivedmesh */
|
||||
@ -7913,7 +7896,7 @@ static void meshdeformModifier_do(
|
||||
/* progress bar redraw can make this recursive .. */
|
||||
if(!recursive) {
|
||||
recursive = 1;
|
||||
//XXX harmonic_coordinates_bind(mmd, vertexCos, numVerts, cagemat);
|
||||
mmd->bindfunc(md->scene, mmd, (float*)vertexCos, numVerts, cagemat);
|
||||
recursive = 0;
|
||||
}
|
||||
}
|
||||
|
@ -2276,7 +2276,7 @@ static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float c
|
||||
/* Object *ob= ctx->sim.ob; */
|
||||
ParticleSystem *psys= ctx->sim.psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
ParticleEditSettings *pset = &scene->toolsettings->particle;
|
||||
/* ParticleEditSettings *pset = &scene->toolsettings->particle; */
|
||||
int totparent=0, between=0;
|
||||
int steps = (int)pow(2.0, (double)part->draw_step);
|
||||
int totchild = psys->totchild;
|
||||
@ -3334,6 +3334,8 @@ void object_remove_particle_system(Scene *scene, Object *ob)
|
||||
|
||||
if(ob->particlesystem.first)
|
||||
((ParticleSystem *) ob->particlesystem.first)->flag |= PSYS_CURRENT;
|
||||
else
|
||||
ob->mode &= ~OB_MODE_PARTICLE_EDIT;
|
||||
|
||||
DAG_scene_sort(scene);
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
|
@ -1156,7 +1156,7 @@ static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * na
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* generate a seperate proxy directory for each preview size */
|
||||
/* generate a separate proxy directory for each preview size */
|
||||
|
||||
if (seq->type == SEQ_IMAGE) {
|
||||
StripElem * se = give_stripelem(seq, cfra);
|
||||
@ -1285,7 +1285,7 @@ static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int re
|
||||
IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
|
||||
}
|
||||
|
||||
/* quality is fixed, otherwise one has to generate seperate
|
||||
/* quality is fixed, otherwise one has to generate separate
|
||||
directories for every quality...
|
||||
|
||||
depth = 32 is intentionally left in, otherwise ALPHA channels
|
||||
|
@ -92,12 +92,13 @@ static int (*SB_localInterruptCallBack)(void) = NULL;
|
||||
|
||||
/* ********** soft body engine ******* */
|
||||
|
||||
typedef enum {SB_EDGE=1,SB_BEND=2,SB_STIFFQUAD=3} type_spring;
|
||||
|
||||
typedef struct BodySpring {
|
||||
int v1, v2;
|
||||
float len, strength, cf,load;
|
||||
float len,cf,load;
|
||||
float ext_force[3]; /* edges colliding and sailing */
|
||||
short order;
|
||||
type_spring springtype;
|
||||
short flag;
|
||||
} BodySpring;
|
||||
|
||||
@ -613,13 +614,11 @@ static void add_mesh_quad_diag_springs(Object *ob)
|
||||
if(mface->v4) {
|
||||
bs->v1= mface->v1;
|
||||
bs->v2= mface->v3;
|
||||
bs->strength= s_shear;
|
||||
bs->order =2;
|
||||
bs->springtype =SB_STIFFQUAD;
|
||||
bs++;
|
||||
bs->v1= mface->v2;
|
||||
bs->v2= mface->v4;
|
||||
bs->strength= s_shear;
|
||||
bs->order =2;
|
||||
bs->springtype =SB_STIFFQUAD;
|
||||
bs++;
|
||||
|
||||
}
|
||||
@ -670,8 +669,7 @@ static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int ad
|
||||
if (addsprings){
|
||||
bs3->v1= v0;
|
||||
bs3->v2= bs2->v1;
|
||||
bs3->strength= stiffness;
|
||||
bs3->order=2;
|
||||
bs3->springtype =SB_BEND;
|
||||
bs3++;
|
||||
}
|
||||
}
|
||||
@ -680,8 +678,7 @@ static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int ad
|
||||
if (addsprings){
|
||||
bs3->v1= v0;
|
||||
bs3->v2= bs2->v2;
|
||||
bs3->strength= stiffness;
|
||||
bs3->order=2;
|
||||
bs3->springtype =SB_BEND;
|
||||
bs3++;
|
||||
}
|
||||
|
||||
@ -785,7 +782,7 @@ static void calculate_collision_balls(Object *ob)
|
||||
/* first estimation based on attached */
|
||||
for(b=bp->nofsprings;b>0;b--){
|
||||
bs = sb->bspring + bp->springs[b-1];
|
||||
if (bs->order == 1){
|
||||
if (bs->springtype == SB_EDGE){
|
||||
akku += bs->len;
|
||||
akku_count++,
|
||||
min = MIN2(bs->len,min);
|
||||
@ -1529,7 +1526,7 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
|
||||
feedback[0]=feedback[1]=feedback[2]=0.0f;
|
||||
bs->flag &= ~BSF_INTERSECT;
|
||||
|
||||
if (bs->order ==1){
|
||||
if (bs->springtype == SB_EDGE){
|
||||
/* +++ springs colliding */
|
||||
if (ob->softflag & OB_SB_EDGECOLL){
|
||||
if ( sb_detect_edge_collisionCached (sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos,
|
||||
@ -2074,10 +2071,24 @@ static void sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float fo
|
||||
forcefactor = iks/bs->len;
|
||||
else
|
||||
forcefactor = iks;
|
||||
kw = (bp1->springweight+bp2->springweight)/2.0f;
|
||||
kw = kw * kw;
|
||||
kw = kw * kw;
|
||||
forcefactor *= bs->strength * kw;
|
||||
kw = (bp1->springweight+bp2->springweight)/2.0f;
|
||||
kw = kw * kw;
|
||||
kw = kw * kw;
|
||||
switch (bs->springtype){
|
||||
case SB_EDGE:
|
||||
forcefactor *= kw;
|
||||
break;
|
||||
case SB_BEND:
|
||||
forcefactor *=sb->secondspring*kw;
|
||||
break;
|
||||
case SB_STIFFQUAD:
|
||||
forcefactor *=sb->shearstiff*sb->shearstiff* kw;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Vec3PlusStVec(bp1->force,(bs->len - distance)*forcefactor,dir);
|
||||
|
||||
/* do bp1 <--> bp2 viscous */
|
||||
@ -3275,8 +3286,7 @@ static void mesh_to_softbody(Scene *scene, Object *ob)
|
||||
for(a=me->totedge; a>0; a--, medge++, bs++) {
|
||||
bs->v1= medge->v1;
|
||||
bs->v2= medge->v2;
|
||||
bs->strength= 1.0;
|
||||
bs->order=1;
|
||||
bs->springtype=SB_EDGE;
|
||||
}
|
||||
|
||||
|
||||
@ -3354,44 +3364,39 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff,Object *
|
||||
if(w) {
|
||||
bs->v1 = bpc;
|
||||
bs->v2 = bpc-dw;
|
||||
bs->strength= 1.0;
|
||||
bs->order=1;
|
||||
bs->springtype=SB_EDGE;
|
||||
bs->len= globallen((bp-dw)->vec, bp->vec,ob);
|
||||
bs++;
|
||||
}
|
||||
if(v) {
|
||||
bs->v1 = bpc;
|
||||
bs->v2 = bpc-dv;
|
||||
bs->strength= 1.0;
|
||||
bs->order=1;
|
||||
bs->springtype=SB_EDGE;
|
||||
bs->len= globallen((bp-dv)->vec, bp->vec,ob);
|
||||
bs++;
|
||||
}
|
||||
if(u) {
|
||||
bs->v1 = bpuc;
|
||||
bs->v2 = bpc;
|
||||
bs->strength= 1.0;
|
||||
bs->order=1;
|
||||
bs->springtype=SB_EDGE;
|
||||
bs->len= globallen((bpu)->vec, bp->vec,ob);
|
||||
bs++;
|
||||
}
|
||||
|
||||
if (dostiff) {
|
||||
|
||||
if(w){
|
||||
if(w){
|
||||
if( v && u ) {
|
||||
bs->v1 = bpc;
|
||||
bs->v2 = bpc-dw-dv-1;
|
||||
bs->strength= 1.0;
|
||||
bs->order=2;
|
||||
bs->springtype=SB_BEND;
|
||||
bs->len= globallen((bp-dw-dv-1)->vec, bp->vec,ob);
|
||||
bs++;
|
||||
}
|
||||
if( (v < lt->pntsv-1) && (u) ) {
|
||||
bs->v1 = bpc;
|
||||
bs->v2 = bpc-dw+dv-1;
|
||||
bs->strength= 1.0;
|
||||
bs->order=2;
|
||||
bs->springtype=SB_BEND;
|
||||
bs->len= globallen((bp-dw+dv-1)->vec, bp->vec,ob);
|
||||
bs++;
|
||||
}
|
||||
@ -3401,16 +3406,14 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff,Object *
|
||||
if( v && u ) {
|
||||
bs->v1 = bpc;
|
||||
bs->v2 = bpc+dw-dv-1;
|
||||
bs->strength= 1.0;
|
||||
bs->order=2;
|
||||
bs->springtype=SB_BEND;
|
||||
bs->len= globallen((bp+dw-dv-1)->vec, bp->vec,ob);
|
||||
bs++;
|
||||
}
|
||||
if( (v < lt->pntsv-1) && (u) ) {
|
||||
bs->v1 = bpc;
|
||||
bs->v2 = bpc+dw+dv-1;
|
||||
bs->strength= 1.0;
|
||||
bs->order=2;
|
||||
bs->springtype=SB_BEND;
|
||||
bs->len= globallen((bp+dw+dv-1)->vec, bp->vec,ob);
|
||||
bs++;
|
||||
}
|
||||
@ -3520,22 +3523,19 @@ static void curve_surf_to_softbody(Scene *scene, Object *ob)
|
||||
if(a>0) {
|
||||
bs->v1= curindex-1;
|
||||
bs->v2= curindex;
|
||||
bs->strength= 1.0;
|
||||
bs->order=1;
|
||||
bs->springtype=SB_EDGE;
|
||||
bs->len= globallen( (bezt-1)->vec[2], bezt->vec[0], ob );
|
||||
bs++;
|
||||
}
|
||||
bs->v1= curindex;
|
||||
bs->v2= curindex+1;
|
||||
bs->strength= 1.0;
|
||||
bs->order=1;
|
||||
bs->springtype=SB_EDGE;
|
||||
bs->len= globallen( bezt->vec[0], bezt->vec[1], ob );
|
||||
bs++;
|
||||
|
||||
|
||||
bs->v1= curindex+1;
|
||||
bs->v2= curindex+2;
|
||||
bs->strength= 1.0;
|
||||
bs->order=1;
|
||||
bs->springtype=SB_EDGE;
|
||||
bs->len= globallen( bezt->vec[1], bezt->vec[2], ob );
|
||||
bs++;
|
||||
}
|
||||
@ -3551,8 +3551,7 @@ static void curve_surf_to_softbody(Scene *scene, Object *ob)
|
||||
if(totspring && a>0) {
|
||||
bs->v1= curindex-1;
|
||||
bs->v2= curindex;
|
||||
bs->strength= 1.0;
|
||||
bs->order=1;
|
||||
bs->springtype=SB_EDGE;
|
||||
bs->len= globallen( (bpnt-1)->vec, bpnt->vec , ob );
|
||||
bs++;
|
||||
}
|
||||
@ -3769,7 +3768,15 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
|
||||
{
|
||||
/* the simulator */
|
||||
float forcetime;
|
||||
double sct,sst=PIL_check_seconds_timer();
|
||||
double sct,sst;
|
||||
|
||||
|
||||
sst=PIL_check_seconds_timer();
|
||||
/* Integration back in time is possible in theory, but pretty useless here.
|
||||
So we refuse to do so. Since we do not know anything about 'outside' canges
|
||||
especially colliders we refuse to go more than 10 frames.
|
||||
*/
|
||||
if(dtime < 0 || dtime > 10.5f) return;
|
||||
|
||||
ccd_update_deflector_hash(scene, ob, sb->scratch->colliderhash);
|
||||
|
||||
@ -3784,8 +3791,8 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
|
||||
/* special case of 2nd order Runge-Kutta type AKA Heun */
|
||||
int mid_flags=0;
|
||||
float err = 0;
|
||||
float forcetimemax = 1.0f;
|
||||
float forcetimemin = 0.001f;
|
||||
float forcetimemax = 1.0f; /* set defaults guess we shall do one frame */
|
||||
float forcetimemin = 0.01f; /* set defaults guess 1/100 is tight enough */
|
||||
float timedone =0.0; /* how far did we get without violating error condition */
|
||||
/* loops = counter for emergency brake
|
||||
* we don't want to lock up the system if physics fail
|
||||
@ -3793,13 +3800,12 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
|
||||
int loops =0 ;
|
||||
|
||||
SoftHeunTol = sb->rklimit; /* humm .. this should be calculated from sb parameters and sizes */
|
||||
if (sb->minloops > 0) forcetimemax = 1.0f / sb->minloops;
|
||||
|
||||
if (sb->maxloops > 0) forcetimemin = 1.0f / sb->maxloops;
|
||||
/* adjust loop limits */
|
||||
if (sb->minloops > 0) forcetimemax = dtime / sb->minloops;
|
||||
if (sb->maxloops > 0) forcetimemin = dtime / sb->maxloops;
|
||||
|
||||
if(sb->solver_ID>0) mid_flags |= MID_PRESERVE;
|
||||
|
||||
//forcetime = dtime; /* hope for integrating in one step */
|
||||
forcetime =forcetimemax; /* hope for integrating in one step */
|
||||
while ( (ABS(timedone) < ABS(dtime)) && (loops < 2000) )
|
||||
{
|
||||
@ -3853,7 +3859,7 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
|
||||
loops++;
|
||||
if(sb->solverflags & SBSO_MONITOR ){
|
||||
sct=PIL_check_seconds_timer();
|
||||
if (sct-sst > 0.5f) printf("%3.0f%% \r",100.0f*timedone);
|
||||
if (sct-sst > 0.5f) printf("%3.0f%% \r",100.0f*timedone/dtime);
|
||||
}
|
||||
/* ask for user break */
|
||||
if (SB_localInterruptCallBack && SB_localInterruptCallBack()) break;
|
||||
@ -4022,11 +4028,11 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
|
||||
/* checking time: */
|
||||
dtime = framedelta*timescale;
|
||||
|
||||
/* do simulation */
|
||||
softbody_step(scene, ob, sb, dtime);
|
||||
|
||||
softbody_to_object(ob, vertexCos, numVerts, 0);
|
||||
|
||||
/* do simulation */
|
||||
cache->simframe= framenr;
|
||||
cache->flag |= PTCACHE_SIMULATION_VALID;
|
||||
|
||||
|
@ -1125,7 +1125,7 @@ PointDensity *BKE_add_pointdensity(void)
|
||||
pd->totpoints = 0;
|
||||
pd->coba = add_colorband(1);
|
||||
pd->object = NULL;
|
||||
pd->psys = NULL;
|
||||
pd->psys = 0;
|
||||
return pd;
|
||||
}
|
||||
|
||||
|
@ -2882,10 +2882,8 @@ static void lib_link_texture(FileData *fd, Main *main)
|
||||
tex->ima= newlibadr_us(fd, tex->id.lib, tex->ima);
|
||||
tex->ipo= newlibadr_us(fd, tex->id.lib, tex->ipo);
|
||||
if(tex->env) tex->env->object= newlibadr(fd, tex->id.lib, tex->env->object);
|
||||
if(tex->pd) {
|
||||
if(tex->pd)
|
||||
tex->pd->object= newlibadr(fd, tex->id.lib, tex->pd->object);
|
||||
tex->pd->psys= newlibadr(fd, tex->id.lib, tex->pd->psys);
|
||||
}
|
||||
if(tex->vd) tex->vd->object= newlibadr(fd, tex->id.lib, tex->vd->object);
|
||||
|
||||
if(tex->nodetree)
|
||||
|
@ -1293,7 +1293,7 @@ static int animchannels_borderselect_exec(bContext *C, wmOperator *op)
|
||||
bAnimContext ac;
|
||||
rcti rect;
|
||||
short selectmode=0;
|
||||
int event;
|
||||
int gesture_mode;
|
||||
|
||||
/* get editor data */
|
||||
if (ANIM_animdata_get_context(C, &ac) == 0)
|
||||
@ -1305,8 +1305,8 @@ static int animchannels_borderselect_exec(bContext *C, wmOperator *op)
|
||||
rect.xmax= RNA_int_get(op->ptr, "xmax");
|
||||
rect.ymax= RNA_int_get(op->ptr, "ymax");
|
||||
|
||||
event= RNA_int_get(op->ptr, "event_type");
|
||||
if (event == LEFTMOUSE) // FIXME... hardcoded
|
||||
gesture_mode= RNA_int_get(op->ptr, "gesture_mode");
|
||||
if (gesture_mode == GESTURE_MODAL_SELECT)
|
||||
selectmode = ACHANNEL_SETFLAG_ADD;
|
||||
else
|
||||
selectmode = ACHANNEL_SETFLAG_CLEAR;
|
||||
@ -1338,11 +1338,7 @@ void ANIM_OT_channels_select_border(wmOperatorType *ot)
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
/* rna */
|
||||
RNA_def_int(ot->srna, "event_type", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX);
|
||||
RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX);
|
||||
RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX);
|
||||
RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX);
|
||||
RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
|
||||
WM_operator_properties_gesture_border(ot, FALSE);
|
||||
}
|
||||
|
||||
/* ******************** Mouse-Click Operator *********************** */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user