Merged changes in the trunk up to revision 25613.
This commit is contained in:
@@ -47,18 +47,21 @@ if MACOSX_ARCHITECTURE == 'ppc':
|
|||||||
# CC = 'gcc-3.3'
|
# CC = 'gcc-3.3'
|
||||||
# CXX = 'g++-3.3'
|
# CXX = 'g++-3.3'
|
||||||
MAC_MIN_VERS = '10.4'
|
MAC_MIN_VERS = '10.4'
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = '10.4'
|
||||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
||||||
LCGDIR = '#../lib/darwin-8.0.0-powerpc'
|
LCGDIR = '#../lib/darwin-8.0.0-powerpc'
|
||||||
CC = 'gcc-4.0'
|
CC = 'gcc-4.0'
|
||||||
CXX = 'g++-4.0'
|
CXX = 'g++-4.0'
|
||||||
elif MACOSX_ARCHITECTURE == 'i386':
|
elif MACOSX_ARCHITECTURE == 'i386':
|
||||||
MAC_MIN_VERS = '10.4'
|
MAC_MIN_VERS = '10.4'
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = '10.4'
|
||||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
||||||
LCGDIR = '#../lib/darwin-8.x.i386'
|
LCGDIR = '#../lib/darwin-8.x.i386'
|
||||||
CC = 'gcc-4.0'
|
CC = 'gcc-4.0'
|
||||||
CXX = 'g++-4.0'
|
CXX = 'g++-4.0'
|
||||||
else :
|
else :
|
||||||
MAC_MIN_VERS = '10.5'
|
MAC_MIN_VERS = '10.5'
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = '10.5'
|
||||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
|
MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
|
||||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||||
CC = 'gcc-4.2'
|
CC = 'gcc-4.2'
|
||||||
|
|||||||
@@ -793,7 +793,7 @@ btSoftBody* btSoftBodyHelpers::CreateEllipsoid(btSoftBodyWorldInfo& worldInfo,c
|
|||||||
//
|
//
|
||||||
btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo,const btScalar* vertices,
|
btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo,const btScalar* vertices,
|
||||||
const int* triangles,
|
const int* triangles,
|
||||||
int ntriangles)
|
int ntriangles, bool randomizeConstraints)
|
||||||
{
|
{
|
||||||
int maxidx=0;
|
int maxidx=0;
|
||||||
int i,j,ni;
|
int i,j,ni;
|
||||||
@@ -828,14 +828,16 @@ btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo
|
|||||||
#undef IDX
|
#undef IDX
|
||||||
psb->appendFace(idx[0],idx[1],idx[2]);
|
psb->appendFace(idx[0],idx[1],idx[2]);
|
||||||
}
|
}
|
||||||
// don't randomize now, let's give a chance to the application to set face data
|
if (randomizeConstraints)
|
||||||
//psb->randomizeConstraints();
|
{
|
||||||
|
psb->randomizeConstraints();
|
||||||
|
}
|
||||||
return(psb);
|
return(psb);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBodyWorldInfo& worldInfo, const btVector3* vertices,
|
btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBodyWorldInfo& worldInfo, const btVector3* vertices,
|
||||||
int nvertices)
|
int nvertices, bool randomizeConstraints)
|
||||||
{
|
{
|
||||||
HullDesc hdsc(QF_TRIANGLES,nvertices,vertices);
|
HullDesc hdsc(QF_TRIANGLES,nvertices,vertices);
|
||||||
HullResult hres;
|
HullResult hres;
|
||||||
@@ -855,6 +857,9 @@ btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBodyWorldInfo& worldI
|
|||||||
psb->appendFace(idx[0],idx[1],idx[2]);
|
psb->appendFace(idx[0],idx[1],idx[2]);
|
||||||
}
|
}
|
||||||
hlib.ReleaseResult(hres);
|
hlib.ReleaseResult(hres);
|
||||||
psb->randomizeConstraints();
|
if (randomizeConstraints)
|
||||||
|
{
|
||||||
|
psb->randomizeConstraints();
|
||||||
|
}
|
||||||
return(psb);
|
return(psb);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,11 +109,13 @@ struct btSoftBodyHelpers
|
|||||||
static btSoftBody* CreateFromTriMesh( btSoftBodyWorldInfo& worldInfo,
|
static btSoftBody* CreateFromTriMesh( btSoftBodyWorldInfo& worldInfo,
|
||||||
const btScalar* vertices,
|
const btScalar* vertices,
|
||||||
const int* triangles,
|
const int* triangles,
|
||||||
int ntriangles);
|
int ntriangles,
|
||||||
|
bool randomizeConstraints = true);
|
||||||
/* Create from convex-hull */
|
/* Create from convex-hull */
|
||||||
static btSoftBody* CreateFromConvexHull( btSoftBodyWorldInfo& worldInfo,
|
static btSoftBody* CreateFromConvexHull( btSoftBodyWorldInfo& worldInfo,
|
||||||
const btVector3* vertices,
|
const btVector3* vertices,
|
||||||
int nvertices);
|
int nvertices,
|
||||||
|
bool randomizeConstraints = true);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //SOFT_BODY_HELPERS_H
|
#endif //SOFT_BODY_HELPERS_H
|
||||||
|
|||||||
@@ -40,11 +40,6 @@ IF(WITH_OPENAL)
|
|||||||
SET(INC ${INC} OpenAL ${OPENAL_INCLUDE_DIR})
|
SET(INC ${INC} OpenAL ${OPENAL_INCLUDE_DIR})
|
||||||
FILE(GLOB OPENALSRC OpenAL/*.cpp)
|
FILE(GLOB OPENALSRC OpenAL/*.cpp)
|
||||||
ADD_DEFINITIONS(-DWITH_OPENAL)
|
ADD_DEFINITIONS(-DWITH_OPENAL)
|
||||||
|
|
||||||
STRING(REGEX MATCH ".*ramework.*" FRAMEWORK ${OPENAL_INCLUDE_DIR})
|
|
||||||
IF(FRAMEWORK)
|
|
||||||
ADD_DEFINITIONS(-DAPPLE_FRAMEWORK_FIX)
|
|
||||||
ENDIF(FRAMEWORK)
|
|
||||||
ENDIF(WITH_OPENAL)
|
ENDIF(WITH_OPENAL)
|
||||||
|
|
||||||
IF(WITH_JACK)
|
IF(WITH_JACK)
|
||||||
@@ -59,6 +54,12 @@ IF(WITH_SNDFILE)
|
|||||||
ADD_DEFINITIONS(-DWITH_SNDFILE)
|
ADD_DEFINITIONS(-DWITH_SNDFILE)
|
||||||
ENDIF(WITH_SNDFILE)
|
ENDIF(WITH_SNDFILE)
|
||||||
|
|
||||||
SET(SRC ${SRC} ${FFMPEGSRC} ${SNDFILESRC} ${SDLSRC} ${OPENALSRC} ${JACKSRC})
|
IF(WITH_FFTW3)
|
||||||
|
SET(INC ${INC} fftw ${FFTW3_INC})
|
||||||
|
FILE(GLOB FFTW3SRC fftw/*.cpp)
|
||||||
|
ADD_DEFINITIONS(-DWITH_FFTW3)
|
||||||
|
ENDIF(WITH_FFTW3)
|
||||||
|
|
||||||
|
SET(SRC ${SRC} ${FFMPEGSRC} ${SNDFILESRC} ${FFTW3SRC} ${SDLSRC} ${OPENALSRC} ${JACKSRC})
|
||||||
|
|
||||||
BLENDERLIB(bf_audaspace "${SRC}" "${INC}")
|
BLENDERLIB(bf_audaspace "${SRC}" "${INC}")
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* The loop count.
|
* The loop count.
|
||||||
*/
|
*/
|
||||||
float m_loop;
|
int m_loop;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
|||||||
45
intern/audaspace/FX/AUD_RectifyFactory.cpp
Normal file
45
intern/audaspace/FX/AUD_RectifyFactory.cpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_RectifyFactory.h"
|
||||||
|
#include "AUD_RectifyReader.h"
|
||||||
|
|
||||||
|
AUD_RectifyFactory::AUD_RectifyFactory(AUD_IFactory* factory) :
|
||||||
|
AUD_EffectFactory(factory) {}
|
||||||
|
|
||||||
|
AUD_RectifyFactory::AUD_RectifyFactory() :
|
||||||
|
AUD_EffectFactory(0) {}
|
||||||
|
|
||||||
|
AUD_IReader* AUD_RectifyFactory::createReader()
|
||||||
|
{
|
||||||
|
AUD_IReader* reader = getReader();
|
||||||
|
|
||||||
|
if(reader != 0)
|
||||||
|
{
|
||||||
|
reader = new AUD_RectifyReader(reader); AUD_NEW("reader")
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
51
intern/audaspace/FX/AUD_RectifyFactory.h
Normal file
51
intern/audaspace/FX/AUD_RectifyFactory.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_RECTIFYFACTORY
|
||||||
|
#define AUD_RECTIFYFACTORY
|
||||||
|
|
||||||
|
#include "AUD_EffectFactory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This factory rectifies another factory.
|
||||||
|
*/
|
||||||
|
class AUD_RectifyFactory : public AUD_EffectFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new rectify factory.
|
||||||
|
* \param factory The input factory.
|
||||||
|
*/
|
||||||
|
AUD_RectifyFactory(AUD_IFactory* factory = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new rectify factory.
|
||||||
|
*/
|
||||||
|
AUD_RectifyFactory();
|
||||||
|
|
||||||
|
virtual AUD_IReader* createReader();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_RECTIFYFACTORY
|
||||||
82
intern/audaspace/FX/AUD_RectifyReader.cpp
Normal file
82
intern/audaspace/FX/AUD_RectifyReader.cpp
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_RectifyReader.h"
|
||||||
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
AUD_RectifyReader::AUD_RectifyReader(AUD_IReader* reader) :
|
||||||
|
AUD_EffectReader(reader)
|
||||||
|
{
|
||||||
|
int bigendian = 1;
|
||||||
|
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
|
||||||
|
|
||||||
|
switch(m_reader->getSpecs().format)
|
||||||
|
{
|
||||||
|
case AUD_FORMAT_S16:
|
||||||
|
m_rectify = AUD_rectify<int16_t>;
|
||||||
|
break;
|
||||||
|
case AUD_FORMAT_S32:
|
||||||
|
m_rectify = AUD_rectify<int32_t>;
|
||||||
|
break;
|
||||||
|
case AUD_FORMAT_FLOAT32:
|
||||||
|
m_rectify = AUD_rectify<float>;
|
||||||
|
break;
|
||||||
|
case AUD_FORMAT_FLOAT64:
|
||||||
|
m_rectify = AUD_rectify<double>;
|
||||||
|
break;
|
||||||
|
case AUD_FORMAT_U8:
|
||||||
|
m_rectify = AUD_rectify_u8;
|
||||||
|
break;
|
||||||
|
case AUD_FORMAT_S24:
|
||||||
|
m_rectify = bigendian ? AUD_rectify_s24_be : AUD_rectify_s24_le;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
delete m_reader;
|
||||||
|
AUD_THROW(AUD_ERROR_READER);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_RectifyReader::~AUD_RectifyReader()
|
||||||
|
{
|
||||||
|
delete m_buffer; AUD_DELETE("buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_RectifyReader::read(int & length, sample_t* & buffer)
|
||||||
|
{
|
||||||
|
sample_t* buf;
|
||||||
|
AUD_Specs specs = m_reader->getSpecs();
|
||||||
|
|
||||||
|
m_reader->read(length, buf);
|
||||||
|
if(m_buffer->getSize() < length*AUD_SAMPLE_SIZE(specs))
|
||||||
|
m_buffer->resize(length*AUD_SAMPLE_SIZE(specs));
|
||||||
|
|
||||||
|
buffer = m_buffer->getBuffer();
|
||||||
|
|
||||||
|
m_rectify(buffer, buf, length * specs.channels);
|
||||||
|
}
|
||||||
65
intern/audaspace/FX/AUD_RectifyReader.h
Normal file
65
intern/audaspace/FX/AUD_RectifyReader.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_RECTIFYREADER
|
||||||
|
#define AUD_RECTIFYREADER
|
||||||
|
|
||||||
|
#include "AUD_EffectReader.h"
|
||||||
|
#include "AUD_ConverterFunctions.h"
|
||||||
|
class AUD_Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class reads another reader and rectifies it.
|
||||||
|
*/
|
||||||
|
class AUD_RectifyReader : public AUD_EffectReader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The playback buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rectifying function.
|
||||||
|
*/
|
||||||
|
AUD_rectify_f m_rectify;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new rectify reader.
|
||||||
|
* \param reader The reader to read from.
|
||||||
|
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||||
|
*/
|
||||||
|
AUD_RectifyReader(AUD_IReader* reader);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the reader.
|
||||||
|
*/
|
||||||
|
virtual ~AUD_RectifyReader();
|
||||||
|
|
||||||
|
virtual void read(int & length, sample_t* & buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_RECTIFYREADER
|
||||||
@@ -56,6 +56,10 @@ ifeq ($(WITH_SNDFILE),true)
|
|||||||
DIRS += sndfile
|
DIRS += sndfile
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(WITH_FFTW3),true)
|
||||||
|
DIRS += fftw
|
||||||
|
endif
|
||||||
|
|
||||||
include nan_subdirs.mk
|
include nan_subdirs.mk
|
||||||
|
|
||||||
install: $(ALL_OR_DEBUG)
|
install: $(ALL_OR_DEBUG)
|
||||||
@@ -80,6 +84,10 @@ ifeq ($(WITH_SNDFILE),true)
|
|||||||
@../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_sndfile.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
|
@../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_sndfile.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(WITH_FFTW3),true)
|
||||||
|
@../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_fftw.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(OS),darwin)
|
ifeq ($(OS),darwin)
|
||||||
ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaudaspace.a
|
ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaudaspace.a
|
||||||
ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_src.a
|
ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_src.a
|
||||||
@@ -102,5 +110,9 @@ ifeq ($(WITH_SNDFILE),true)
|
|||||||
ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_sndfile.a
|
ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_sndfile.a
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(WITH_FFTW3),true)
|
||||||
|
ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_fftw.a
|
||||||
|
endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
@../tools/cpifdiff.sh intern/*.h $(NAN_AUDASPACE)/include/
|
@../tools/cpifdiff.sh intern/*.h $(NAN_AUDASPACE)/include/
|
||||||
|
|||||||
@@ -31,4 +31,9 @@ if env['WITH_BF_SNDFILE']:
|
|||||||
incs += ' sndfile ' + env['BF_SNDFILE_INC']
|
incs += ' sndfile ' + env['BF_SNDFILE_INC']
|
||||||
defs.append('WITH_SNDFILE')
|
defs.append('WITH_SNDFILE')
|
||||||
|
|
||||||
|
if env['WITH_BF_FFTW3']:
|
||||||
|
sources += env.Glob('fftw/*.cpp')
|
||||||
|
incs += ' fftw ' + env['BF_FFTW3_INC']
|
||||||
|
defs.append('WITH_FFTW3')
|
||||||
|
|
||||||
env.BlenderLib ('bf_audaspace', sources, Split(incs), defs, libtype=['intern','player'], priority = [25,215] )
|
env.BlenderLib ('bf_audaspace', sources, Split(incs), defs, libtype=['intern','player'], priority = [25,215] )
|
||||||
|
|||||||
79
intern/audaspace/fftw/AUD_BandPassFactory.cpp
Normal file
79
intern/audaspace/fftw/AUD_BandPassFactory.cpp
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_BandPassFactory.h"
|
||||||
|
#include "AUD_BandPassReader.h"
|
||||||
|
|
||||||
|
AUD_BandPassFactory::AUD_BandPassFactory(AUD_IFactory* factory, float low,
|
||||||
|
float high) :
|
||||||
|
AUD_EffectFactory(factory),
|
||||||
|
m_low(low),
|
||||||
|
m_high(high) {}
|
||||||
|
|
||||||
|
AUD_BandPassFactory::AUD_BandPassFactory(float low, float high) :
|
||||||
|
AUD_EffectFactory(0),
|
||||||
|
m_low(low),
|
||||||
|
m_high(high) {}
|
||||||
|
|
||||||
|
float AUD_BandPassFactory::getLow()
|
||||||
|
{
|
||||||
|
return m_low;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AUD_BandPassFactory::getHigh()
|
||||||
|
{
|
||||||
|
return m_high;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_BandPassFactory::setLow(float low)
|
||||||
|
{
|
||||||
|
m_low = low;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_BandPassFactory::setHigh(float high)
|
||||||
|
{
|
||||||
|
m_high = high;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_IReader* AUD_BandPassFactory::createReader()
|
||||||
|
{
|
||||||
|
AUD_IReader* reader = getReader();
|
||||||
|
|
||||||
|
if(reader != 0)
|
||||||
|
{
|
||||||
|
if(reader->getSpecs().format == AUD_FORMAT_FLOAT32)
|
||||||
|
{
|
||||||
|
reader = new AUD_BandPassReader(reader, m_low, m_high);
|
||||||
|
AUD_NEW("reader")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete reader; AUD_DELETE("reader")
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
88
intern/audaspace/fftw/AUD_BandPassFactory.h
Normal file
88
intern/audaspace/fftw/AUD_BandPassFactory.h
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_BANDPASSFACTORY
|
||||||
|
#define AUD_BANDPASSFACTORY
|
||||||
|
|
||||||
|
#include "AUD_EffectFactory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This factory creates a band pass filter for a sound wave.
|
||||||
|
*/
|
||||||
|
class AUD_BandPassFactory : public AUD_EffectFactory
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The lowest frequency to be passed.
|
||||||
|
*/
|
||||||
|
float m_low;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The highest frequency to be passed.
|
||||||
|
*/
|
||||||
|
float m_high;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new band pass factory.
|
||||||
|
* \param factory The input factory.
|
||||||
|
* \param low The lowest passed frequency.
|
||||||
|
* \param high The highest passed frequency.
|
||||||
|
*/
|
||||||
|
AUD_BandPassFactory(AUD_IFactory* factory, float low, float high);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new band pass factory.
|
||||||
|
* \param low The lowest passed frequency.
|
||||||
|
* \param high The highest passed frequency.
|
||||||
|
*/
|
||||||
|
AUD_BandPassFactory(float low, float high);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the lowest passed frequency.
|
||||||
|
*/
|
||||||
|
float getLow();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the highest passed frequency.
|
||||||
|
*/
|
||||||
|
float getHigh();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the lowest passed frequency.
|
||||||
|
* \param low The lowest passed frequency.
|
||||||
|
*/
|
||||||
|
void setLow(float low);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the highest passed frequency.
|
||||||
|
* \param high The highest passed frequency.
|
||||||
|
*/
|
||||||
|
void setHigh(float hight);
|
||||||
|
|
||||||
|
virtual AUD_IReader* createReader();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_BANDPASSFACTORY
|
||||||
126
intern/audaspace/fftw/AUD_BandPassReader.cpp
Normal file
126
intern/audaspace/fftw/AUD_BandPassReader.cpp
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AUD_BandPassReader.h"
|
||||||
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
AUD_BandPassReader::AUD_BandPassReader(AUD_IReader* reader, float low,
|
||||||
|
float high) :
|
||||||
|
AUD_EffectReader(reader), m_low(low), m_high(high)
|
||||||
|
{
|
||||||
|
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
m_in = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
m_out = new AUD_Buffer(); AUD_NEW("buffer")
|
||||||
|
m_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_BandPassReader::~AUD_BandPassReader()
|
||||||
|
{
|
||||||
|
if(m_length != 0)
|
||||||
|
{
|
||||||
|
fftw_destroy_plan(m_forward);
|
||||||
|
fftw_destroy_plan(m_backward);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_buffer; AUD_DELETE("buffer")
|
||||||
|
delete m_in; AUD_DELETE("buffer")
|
||||||
|
delete m_out; AUD_DELETE("buffer")
|
||||||
|
}
|
||||||
|
|
||||||
|
AUD_ReaderType AUD_BandPassReader::getType()
|
||||||
|
{
|
||||||
|
return m_reader->getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_BandPassReader::read(int & length, sample_t* & buffer)
|
||||||
|
{
|
||||||
|
AUD_Specs specs = m_reader->getSpecs();
|
||||||
|
|
||||||
|
m_reader->read(length, buffer);
|
||||||
|
|
||||||
|
if(length > 0)
|
||||||
|
{
|
||||||
|
if(length * AUD_SAMPLE_SIZE(specs) > m_buffer->getSize())
|
||||||
|
m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
|
||||||
|
|
||||||
|
if(length != m_length)
|
||||||
|
{
|
||||||
|
if(m_length != 0)
|
||||||
|
{
|
||||||
|
fftw_destroy_plan(m_forward);
|
||||||
|
fftw_destroy_plan(m_backward);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_length = length;
|
||||||
|
printf("WINDOW: %d\n", m_length);
|
||||||
|
|
||||||
|
if(m_length * sizeof(double) > m_in->getSize())
|
||||||
|
{
|
||||||
|
m_in->resize(m_length * sizeof(double));
|
||||||
|
m_out->resize((m_length / 2 + 1) * sizeof(fftw_complex));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_forward = fftw_plan_dft_r2c_1d(m_length,
|
||||||
|
(double*)m_in->getBuffer(),
|
||||||
|
(fftw_complex*)m_out->getBuffer(),
|
||||||
|
FFTW_ESTIMATE);
|
||||||
|
m_backward = fftw_plan_dft_c2r_1d(m_length,
|
||||||
|
(fftw_complex*)m_out->getBuffer(),
|
||||||
|
(double*)m_in->getBuffer(),
|
||||||
|
FFTW_ESTIMATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
float* source = (float*) buffer;
|
||||||
|
double* target = (double*) m_in->getBuffer();
|
||||||
|
float* target2 = (float*) m_buffer->getBuffer();
|
||||||
|
fftw_complex* complex = (fftw_complex*) m_out->getBuffer();
|
||||||
|
float frequency;
|
||||||
|
|
||||||
|
for(int channel = 0; channel < specs.channels; channel++)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < m_length; i++)
|
||||||
|
target[i] = source[i * specs.channels + channel];
|
||||||
|
|
||||||
|
fftw_execute(m_forward);
|
||||||
|
|
||||||
|
for(int i = 0; i < m_length / 2 + 1; i++)
|
||||||
|
{
|
||||||
|
frequency = i * specs.rate / (m_length / 2.0 + 1.0);
|
||||||
|
if((frequency < m_low) || (frequency > m_high))
|
||||||
|
complex[i][0] = complex[i][1] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fftw_execute(m_backward);
|
||||||
|
|
||||||
|
for(int i = 0; i < m_length; i++)
|
||||||
|
target2[i * specs.channels + channel] = target[i] / m_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = m_buffer->getBuffer();
|
||||||
|
}
|
||||||
99
intern/audaspace/fftw/AUD_BandPassReader.h
Normal file
99
intern/audaspace/fftw/AUD_BandPassReader.h
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* Copyright 2009 Jörg Hermann Müller
|
||||||
|
*
|
||||||
|
* This file is part of AudaSpace.
|
||||||
|
*
|
||||||
|
* AudaSpace is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* AudaSpace 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* ***** END LGPL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_BANDPASSREADER
|
||||||
|
#define AUD_BANDPASSREADER
|
||||||
|
|
||||||
|
#include <fftw3.h>
|
||||||
|
|
||||||
|
#include "AUD_EffectReader.h"
|
||||||
|
class AUD_Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class only passes a specific frequency band of another reader.
|
||||||
|
*/
|
||||||
|
class AUD_BandPassReader : public AUD_EffectReader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The playback buffer.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The input buffer for fourier transformations.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_in;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The output buffer for fourier transformations.
|
||||||
|
*/
|
||||||
|
AUD_Buffer *m_out;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The lowest passed frequency.
|
||||||
|
*/
|
||||||
|
float m_low;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The highest passed frequency.
|
||||||
|
*/
|
||||||
|
float m_high;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fftw plan for forward transformation.
|
||||||
|
*/
|
||||||
|
fftw_plan m_forward;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fftw plan for backward transformation.
|
||||||
|
*/
|
||||||
|
fftw_plan m_backward;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The length of the plans.
|
||||||
|
*/
|
||||||
|
int m_length;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new band pass reader.
|
||||||
|
* \param reader The reader to read from.
|
||||||
|
* \param low The lowest passed frequency.
|
||||||
|
* \param high The highest passed frequency.
|
||||||
|
* \exception AUD_Exception Thrown if the reader specified is NULL.
|
||||||
|
*/
|
||||||
|
AUD_BandPassReader(AUD_IReader* reader, float low, float high);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the reader.
|
||||||
|
*/
|
||||||
|
virtual ~AUD_BandPassReader();
|
||||||
|
|
||||||
|
virtual AUD_ReaderType getType();
|
||||||
|
virtual void read(int & length, sample_t* & buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUD_BANDPASSREADER
|
||||||
42
intern/audaspace/fftw/Makefile
Normal file
42
intern/audaspace/fftw/Makefile
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# The Original Code is: all of this file.
|
||||||
|
#
|
||||||
|
# Contributor(s): none yet.
|
||||||
|
#
|
||||||
|
# ***** END GPL LICENSE BLOCK *****
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
LIBNAME = aud_fftw
|
||||||
|
DIR = $(OCGDIR)/intern/audaspace
|
||||||
|
|
||||||
|
include nan_compile.mk
|
||||||
|
|
||||||
|
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
|
||||||
|
|
||||||
|
CPPFLAGS += -I../intern
|
||||||
|
CPPFLAGS += -I../FX
|
||||||
|
CPPFLAGS += -I..
|
||||||
|
CPPFLAGS += -I.
|
||||||
|
CPPFLAGS += -I$(BF_FFTW3)/include
|
||||||
@@ -81,7 +81,7 @@ void AUD_BufferReader::read(int & length, sample_t* & buffer)
|
|||||||
|
|
||||||
buffer = m_buffer.get()->getBuffer()+m_position*sample_size;
|
buffer = m_buffer.get()->getBuffer()+m_position*sample_size;
|
||||||
|
|
||||||
// in case the end of the buffer is reach
|
// in case the end of the buffer is reached
|
||||||
if(m_buffer.get()->getSize() < (m_position+length)*sample_size)
|
if(m_buffer.get()->getSize() < (m_position+length)*sample_size)
|
||||||
length = m_buffer.get()->getSize()/sample_size-m_position;
|
length = m_buffer.get()->getSize()/sample_size-m_position;
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "AUD_LimiterFactory.h"
|
#include "AUD_LimiterFactory.h"
|
||||||
#include "AUD_PingPongFactory.h"
|
#include "AUD_PingPongFactory.h"
|
||||||
#include "AUD_LoopFactory.h"
|
#include "AUD_LoopFactory.h"
|
||||||
|
#include "AUD_RectifyFactory.h"
|
||||||
#include "AUD_ReadDevice.h"
|
#include "AUD_ReadDevice.h"
|
||||||
#include "AUD_SourceCaps.h"
|
#include "AUD_SourceCaps.h"
|
||||||
#include "AUD_IReader.h"
|
#include "AUD_IReader.h"
|
||||||
@@ -285,6 +286,20 @@ int AUD_stopLoop(AUD_Handle* handle)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AUD_Sound* AUD_rectifySound(AUD_Sound* sound)
|
||||||
|
{
|
||||||
|
assert(sound);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new AUD_RectifyFactory(sound);
|
||||||
|
}
|
||||||
|
catch(AUD_Exception)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AUD_unload(AUD_Sound* sound)
|
void AUD_unload(AUD_Sound* sound)
|
||||||
{
|
{
|
||||||
assert(sound);
|
assert(sound);
|
||||||
|
|||||||
@@ -149,6 +149,13 @@ extern AUD_Sound* AUD_loopSound(AUD_Sound* sound);
|
|||||||
*/
|
*/
|
||||||
extern int AUD_stopLoop(AUD_Handle* handle);
|
extern int AUD_stopLoop(AUD_Handle* handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rectifies a sound.
|
||||||
|
* \param sound The sound to rectify.
|
||||||
|
* \return A handle of the rectified sound.
|
||||||
|
*/
|
||||||
|
extern AUD_Sound* AUD_rectifySound(AUD_Sound* sound);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unloads a sound of any type.
|
* Unloads a sound of any type.
|
||||||
* \param sound The handle of the sound.
|
* \param sound The handle of the sound.
|
||||||
|
|||||||
@@ -500,3 +500,43 @@ void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AUD_rectify_u8(sample_t* target, sample_t* source, int count)
|
||||||
|
{
|
||||||
|
for(int i=0; i<count; i++)
|
||||||
|
target[i] = source[i] < 0x80 ? 0x0100 - source[i] : source[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_rectify_s24_le(sample_t* target, sample_t* source, int count)
|
||||||
|
{
|
||||||
|
count *= 3;
|
||||||
|
int value;
|
||||||
|
|
||||||
|
for(int i=0; i<count; i+=3)
|
||||||
|
{
|
||||||
|
value = source[i+2] << 16 | source[i+1] << 8 | source[i];
|
||||||
|
value |= (((value & 0x800000) >> 23) * 255) << 24;
|
||||||
|
if(value < 0)
|
||||||
|
value = -value;
|
||||||
|
target[i+2] = value >> 16;
|
||||||
|
target[i+1] = value >> 8;
|
||||||
|
target[i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_rectify_s24_be(sample_t* target, sample_t* source, int count)
|
||||||
|
{
|
||||||
|
count *= 3;
|
||||||
|
int value;
|
||||||
|
|
||||||
|
for(int i=0; i < count; i+=3)
|
||||||
|
{
|
||||||
|
value = source[i] << 16 | source[i+1] << 8 | source[i+2];
|
||||||
|
value |= (((value & 0x800000) >> 23) * 255) << 24;
|
||||||
|
if(value < 0)
|
||||||
|
value = -value;
|
||||||
|
target[i] = value >> 16;
|
||||||
|
target[i+1] = value >> 8;
|
||||||
|
target[i+2] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ typedef void (*AUD_convert_f)(sample_t* target, sample_t* source, int length);
|
|||||||
typedef void (*AUD_volume_adjust_f)(sample_t* target, sample_t* source,
|
typedef void (*AUD_volume_adjust_f)(sample_t* target, sample_t* source,
|
||||||
int count, float volume);
|
int count, float volume);
|
||||||
|
|
||||||
|
typedef void (*AUD_rectify_f)(sample_t* target, sample_t* source, int count);
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void AUD_convert_copy(sample_t* target, sample_t* source, int length)
|
void AUD_convert_copy(sample_t* target, sample_t* source, int length)
|
||||||
{
|
{
|
||||||
@@ -153,4 +155,19 @@ void AUD_volume_adjust_s24_le(sample_t* target, sample_t* source,
|
|||||||
void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
|
void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
|
||||||
int count, float volume);
|
int count, float volume);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void AUD_rectify(sample_t* target, sample_t* source, int count)
|
||||||
|
{
|
||||||
|
T* t = (T*)target;
|
||||||
|
T* s = (T*)source;
|
||||||
|
for(int i=0; i < count; i++)
|
||||||
|
t[i] = s[i] < 0 ? -s[i] : s[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void AUD_rectify_u8(sample_t* target, sample_t* source, int count);
|
||||||
|
|
||||||
|
void AUD_rectify_s24_le(sample_t* target, sample_t* source, int count);
|
||||||
|
|
||||||
|
void AUD_rectify_s24_be(sample_t* target, sample_t* source, int count);
|
||||||
|
|
||||||
#endif //AUD_CONVERTERFUNCTIONS
|
#endif //AUD_CONVERTERFUNCTIONS
|
||||||
|
|||||||
@@ -59,9 +59,10 @@ endif
|
|||||||
ifeq ($(WITH_SNDFILE),true)
|
ifeq ($(WITH_SNDFILE),true)
|
||||||
CPPFLAGS += -DWITH_SNDFILE
|
CPPFLAGS += -DWITH_SNDFILE
|
||||||
CPPFLAGS += -I../sndfile
|
CPPFLAGS += -I../sndfile
|
||||||
|
CPPFLAGS += -I$(NAN_SNDFILE)/include
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CPPFLAGS += -I$(LCGDIR)/samplerate/include/
|
CPPFLAGS += -I$(NAN_SAMPLERATE)/include/
|
||||||
CPPFLAGS += -I../ffmpeg
|
CPPFLAGS += -I../ffmpeg
|
||||||
CPPFLAGS += -I../FX
|
CPPFLAGS += -I../FX
|
||||||
CPPFLAGS += -I../SDL
|
CPPFLAGS += -I../SDL
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="2"
|
Optimization="2"
|
||||||
InlineFunctionExpansion="2"
|
InlineFunctionExpansion="2"
|
||||||
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include"
|
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include;..\..\..\..\..\lib\windows\fftw3\include"
|
||||||
PreprocessorDefinitions="WIN32,NDEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
|
PreprocessorDefinitions="WIN32,NDEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include"
|
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include;..\..\..\..\..\lib\windows\fftw3\include"
|
||||||
PreprocessorDefinitions="WIN32,_DEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
|
PreprocessorDefinitions="WIN32,_DEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
@@ -193,7 +193,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
InlineFunctionExpansion="2"
|
InlineFunctionExpansion="2"
|
||||||
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include"
|
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include;..\..\..\..\..\lib\windows\fftw3\include"
|
||||||
PreprocessorDefinitions="WIN32,NDEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
|
PreprocessorDefinitions="WIN32,NDEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="2"
|
RuntimeLibrary="2"
|
||||||
@@ -267,7 +267,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include"
|
AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include;..\..\..\..\..\lib\windows\fftw3\include"
|
||||||
PreprocessorDefinitions="WIN32,_DEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
|
PreprocessorDefinitions="WIN32,_DEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -629,6 +629,22 @@
|
|||||||
RelativePath="..\..\FX\AUD_PitchReader.h"
|
RelativePath="..\..\FX\AUD_PitchReader.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_RectifyFactory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_RectifyFactory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_RectifyReader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\FX\AUD_RectifyReader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\FX\AUD_ReverseFactory.cpp"
|
RelativePath="..\..\FX\AUD_ReverseFactory.cpp"
|
||||||
>
|
>
|
||||||
@@ -762,6 +778,26 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="fftw"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\fftw\AUD_BandPassFactory.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\fftw\AUD_BandPassFactory.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\fftw\AUD_BandPassReader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\fftw\AUD_BandPassReader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Files>
|
</Files>
|
||||||
<Globals>
|
<Globals>
|
||||||
</Globals>
|
</Globals>
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ include nan_compile.mk
|
|||||||
|
|
||||||
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
|
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
|
||||||
|
|
||||||
|
CPPFLAGS += -I$(NAN_SNDFILE)/include
|
||||||
CPPFLAGS += -I../intern
|
CPPFLAGS += -I../intern
|
||||||
CPPFLAGS += -I..
|
CPPFLAGS += -I..
|
||||||
CPPFLAGS += -I.
|
CPPFLAGS += -I.
|
||||||
|
|||||||
@@ -283,8 +283,12 @@ sgstrf (superlu_options_t *options, SuperMatrix *A,
|
|||||||
* -------------------------------------- */
|
* -------------------------------------- */
|
||||||
/* Determine the union of the row structure of the snode */
|
/* Determine the union of the row structure of the snode */
|
||||||
if ( (*info = ssnode_dfs(jcol, kcol, asub, xa_begin, xa_end,
|
if ( (*info = ssnode_dfs(jcol, kcol, asub, xa_begin, xa_end,
|
||||||
xprune, marker, &Glu)) != 0 )
|
xprune, marker, &Glu)) != 0 ) {
|
||||||
|
if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r);
|
||||||
|
SUPERLU_FREE (iperm_c);
|
||||||
|
SUPERLU_FREE (relax_end);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nextu = xusub[jcol];
|
nextu = xusub[jcol];
|
||||||
nextlu = xlusup[jcol];
|
nextlu = xlusup[jcol];
|
||||||
@@ -293,8 +297,12 @@ sgstrf (superlu_options_t *options, SuperMatrix *A,
|
|||||||
new_next = nextlu + (xlsub[fsupc+1]-xlsub[fsupc])*(kcol-jcol+1);
|
new_next = nextlu + (xlsub[fsupc+1]-xlsub[fsupc])*(kcol-jcol+1);
|
||||||
nzlumax = Glu.nzlumax;
|
nzlumax = Glu.nzlumax;
|
||||||
while ( new_next > nzlumax ) {
|
while ( new_next > nzlumax ) {
|
||||||
if ( (*info = sLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, &Glu)) )
|
if ( (*info = sLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, &Glu)) ) {
|
||||||
return;
|
if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r);
|
||||||
|
SUPERLU_FREE (iperm_c);
|
||||||
|
SUPERLU_FREE (relax_end);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (icol = jcol; icol<= kcol; icol++) {
|
for (icol = jcol; icol<= kcol; icol++) {
|
||||||
@@ -350,17 +358,31 @@ sgstrf (superlu_options_t *options, SuperMatrix *A,
|
|||||||
|
|
||||||
if ((*info = scolumn_dfs(m, jj, perm_r, &nseg, &panel_lsub[k],
|
if ((*info = scolumn_dfs(m, jj, perm_r, &nseg, &panel_lsub[k],
|
||||||
segrep, &repfnz[k], xprune, marker,
|
segrep, &repfnz[k], xprune, marker,
|
||||||
parent, xplore, &Glu)) != 0) return;
|
parent, xplore, &Glu)) != 0) {
|
||||||
|
if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r);
|
||||||
|
SUPERLU_FREE (iperm_c);
|
||||||
|
SUPERLU_FREE (relax_end);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Numeric updates */
|
/* Numeric updates */
|
||||||
if ((*info = scolumn_bmod(jj, (nseg - nseg1), &dense[k],
|
if ((*info = scolumn_bmod(jj, (nseg - nseg1), &dense[k],
|
||||||
tempv, &segrep[nseg1], &repfnz[k],
|
tempv, &segrep[nseg1], &repfnz[k],
|
||||||
jcol, &Glu, stat)) != 0) return;
|
jcol, &Glu, stat)) != 0) {
|
||||||
|
if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r);
|
||||||
|
SUPERLU_FREE (iperm_c);
|
||||||
|
SUPERLU_FREE (relax_end);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy the U-segments to ucol[*] */
|
/* Copy the U-segments to ucol[*] */
|
||||||
if ((*info = scopy_to_ucol(jj, nseg, segrep, &repfnz[k],
|
if ((*info = scopy_to_ucol(jj, nseg, segrep, &repfnz[k],
|
||||||
perm_r, &dense[k], &Glu)) != 0)
|
perm_r, &dense[k], &Glu)) != 0) {
|
||||||
return;
|
if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r);
|
||||||
|
SUPERLU_FREE (iperm_c);
|
||||||
|
SUPERLU_FREE (relax_end);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( (*info = spivotL(jj, diag_pivot_thresh, &usepr, perm_r,
|
if ( (*info = spivotL(jj, diag_pivot_thresh, &usepr, perm_r,
|
||||||
iperm_r, iperm_c, &pivrow, &Glu, stat)) )
|
iperm_r, iperm_c, &pivrow, &Glu, stat)) )
|
||||||
@@ -429,5 +451,4 @@ sgstrf (superlu_options_t *options, SuperMatrix *A,
|
|||||||
if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r);
|
if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r);
|
||||||
SUPERLU_FREE (iperm_c);
|
SUPERLU_FREE (iperm_c);
|
||||||
SUPERLU_FREE (relax_end);
|
SUPERLU_FREE (relax_end);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -415,6 +415,10 @@
|
|||||||
RelativePath="..\..\..\source\blender\editors\interface\interface_layout.c"
|
RelativePath="..\..\..\source\blender\editors\interface\interface_layout.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\source\blender\editors\interface\interface_ops.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\source\blender\editors\interface\interface_panel.c"
|
RelativePath="..\..\..\source\blender\editors\interface\interface_panel.c"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1126,23 +1126,21 @@ class Export3DS(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
save_3ds(self.properties.path, context)
|
save_3ds(self.properties.path, context)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
def poll(self, context): # Poll isnt working yet
|
def poll(self, context): # Poll isnt working yet
|
||||||
return context.active_object != None
|
return context.active_object != None
|
||||||
|
|
||||||
bpy.ops.add(Export3DS)
|
bpy.types.register(Export3DS)
|
||||||
|
|
||||||
# Add to a menu
|
# Add to a menu
|
||||||
import dynamic_menu
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
def menu_func(self, context):
|
||||||
default_path = bpy.data.filename.replace(".blend", ".3ds")
|
default_path = bpy.data.filename.replace(".blend", ".3ds")
|
||||||
self.layout.operator(Export3DS.bl_idname, text="Autodesk 3DS...").path = default_path
|
self.layout.operator(Export3DS.bl_idname, text="Autodesk 3DS...").path = default_path
|
||||||
|
|
||||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||||
|
|||||||
@@ -651,8 +651,8 @@ def write(filename, batch_objects = None, \
|
|||||||
}''' % (curtime))
|
}''' % (curtime))
|
||||||
|
|
||||||
file.write('\nCreationTime: "%.4i-%.2i-%.2i %.2i:%.2i:%.2i:000"' % curtime)
|
file.write('\nCreationTime: "%.4i-%.2i-%.2i %.2i:%.2i:%.2i:000"' % curtime)
|
||||||
file.write('\nCreator: "Blender3D version 2.5"')
|
file.write('\nCreator: "Blender3D version %s"' % bpy.version_string)
|
||||||
# file.write('\nCreator: "Blender3D version %.2f"' % Blender.Get('version'))
|
|
||||||
|
|
||||||
pose_items = [] # list of (fbxName, matrix) to write pose data for, easier to collect allong the way
|
pose_items = [] # list of (fbxName, matrix) to write pose data for, easier to collect allong the way
|
||||||
|
|
||||||
@@ -3361,7 +3361,7 @@ class ExportFBX(bpy.types.Operator):
|
|||||||
# to the class instance from the operator settings before calling.
|
# to the class instance from the operator settings before calling.
|
||||||
|
|
||||||
|
|
||||||
path = StringProperty(name="File Path", description="File path used for exporting the FBX file", maxlen= 1024, default= "")
|
path = StringProperty(name="File Path", description="File path used for exporting the FBX file", maxlen= 1024, default="")
|
||||||
|
|
||||||
EXP_OBS_SELECTED = BoolProperty(name="Selected Objects", description="Export selected objects on visible layers", default=True)
|
EXP_OBS_SELECTED = BoolProperty(name="Selected Objects", description="Export selected objects on visible layers", default=True)
|
||||||
# EXP_OBS_SCENE = BoolProperty(name="Scene Objects", description="Export all objects in this scene", default=True)
|
# EXP_OBS_SCENE = BoolProperty(name="Scene Objects", description="Export all objects in this scene", default=True)
|
||||||
@@ -3387,7 +3387,7 @@ class ExportFBX(bpy.types.Operator):
|
|||||||
BATCH_ENABLE = BoolProperty(name="Enable Batch", description="Automate exporting multiple scenes or groups to files", default=False)
|
BATCH_ENABLE = BoolProperty(name="Enable Batch", description="Automate exporting multiple scenes or groups to files", default=False)
|
||||||
BATCH_GROUP = BoolProperty(name="Group > File", description="Export each group as an FBX file, if false, export each scene as an FBX file", default=False)
|
BATCH_GROUP = BoolProperty(name="Group > File", description="Export each group as an FBX file, if false, export each scene as an FBX file", default=False)
|
||||||
BATCH_OWN_DIR = BoolProperty(name="Own Dir", description="Create a dir for each exported file", default=True)
|
BATCH_OWN_DIR = BoolProperty(name="Own Dir", description="Create a dir for each exported file", default=True)
|
||||||
BATCH_FILE_PREFIX = StringProperty(name="Prefix", description="Prefix each file with this name", maxlen= 1024, default="")
|
BATCH_FILE_PREFIX = StringProperty(name="Prefix", description="Prefix each file with this name", maxlen=1024, default="")
|
||||||
|
|
||||||
|
|
||||||
def poll(self, context):
|
def poll(self, context):
|
||||||
@@ -3426,15 +3426,15 @@ class ExportFBX(bpy.types.Operator):
|
|||||||
self.properties.BATCH_FILE_PREFIX,
|
self.properties.BATCH_FILE_PREFIX,
|
||||||
self.properties.BATCH_OWN_DIR)
|
self.properties.BATCH_OWN_DIR)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
bpy.ops.add(ExportFBX)
|
bpy.types.register(ExportFBX)
|
||||||
|
|
||||||
# if __name__ == "__main__":
|
# if __name__ == "__main__":
|
||||||
# bpy.ops.EXPORT_OT_ply(filename="/tmp/test.ply")
|
# bpy.ops.EXPORT_OT_ply(filename="/tmp/test.ply")
|
||||||
@@ -3462,13 +3462,8 @@ bpy.ops.add(ExportFBX)
|
|||||||
# SMALL or COSMETICAL
|
# SMALL or COSMETICAL
|
||||||
# - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version')
|
# - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version')
|
||||||
|
|
||||||
|
|
||||||
# Add to a menu
|
|
||||||
import dynamic_menu
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
def menu_func(self, context):
|
||||||
default_path = bpy.data.filename.replace(".blend", ".fbx")
|
default_path = bpy.data.filename.replace(".blend", ".fbx")
|
||||||
self.layout.operator(ExportFBX.bl_idname, text="Autodesk FBX...").path = default_path
|
self.layout.operator(ExportFBX.bl_idname, text="Autodesk FBX...").path = default_path
|
||||||
|
|
||||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
menu_item = bpy.types.INFO_MT_file_export.append(menu_func)
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ def write(filename, sce, ob, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS):
|
|||||||
|
|
||||||
numverts = len(me.verts)
|
numverts = len(me.verts)
|
||||||
|
|
||||||
numframes = PREF_ENDFRAME-PREF_STARTFRAME + 1
|
numframes = PREF_ENDFRAME - PREF_STARTFRAME + 1
|
||||||
PREF_FPS = float(PREF_FPS)
|
PREF_FPS = float(PREF_FPS)
|
||||||
f = open(filename, 'wb') #no Errors yet:Safe to create file
|
f = open(filename, 'wb') #no Errors yet:Safe to create file
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ def write(filename, sce, ob, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS):
|
|||||||
f.write(pack(">2i", numframes, numverts))
|
f.write(pack(">2i", numframes, numverts))
|
||||||
|
|
||||||
# Write the frame times (should we use the time IPO??)
|
# Write the frame times (should we use the time IPO??)
|
||||||
f.write( pack(">%df" % (numframes), *[frame / PREF_FPS for frame in range(numframes)]) ) # seconds
|
f.write(pack(">%df" % (numframes), *[frame / PREF_FPS for frame in range(numframes)])) # seconds
|
||||||
|
|
||||||
#rest frame needed to keep frames in sync
|
#rest frame needed to keep frames in sync
|
||||||
"""
|
"""
|
||||||
@@ -159,8 +159,8 @@ class ExportMDD(bpy.types.Operator):
|
|||||||
|
|
||||||
# List of operator properties, the attributes will be assigned
|
# List of operator properties, the attributes will be assigned
|
||||||
# to the class instance from the operator settings before calling.
|
# 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= "")
|
path = StringProperty(name="File Path", description="File path used for exporting the MDD file", maxlen=1024)
|
||||||
fps = IntProperty(name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default= 25)
|
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)
|
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)
|
end_frame = IntProperty(name="End Frame", description="End frame for baking", min=minframe, max=maxframe, default=250)
|
||||||
|
|
||||||
@@ -173,24 +173,21 @@ class ExportMDD(bpy.types.Operator):
|
|||||||
raise Exception("filename not set")
|
raise Exception("filename not set")
|
||||||
write(self.properties.path, context.scene, context.active_object,
|
write(self.properties.path, context.scene, context.active_object,
|
||||||
self.properties.start_frame, self.properties.end_frame, self.properties.fps)
|
self.properties.start_frame, self.properties.end_frame, self.properties.fps)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
bpy.ops.add(ExportMDD)
|
bpy.types.register(ExportMDD)
|
||||||
|
|
||||||
# Add to a menu
|
|
||||||
import dynamic_menu
|
|
||||||
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
def menu_func(self, context):
|
||||||
default_path = bpy.data.filename.replace(".blend", ".mdd")
|
default_path = bpy.data.filename.replace(".blend", ".mdd")
|
||||||
self.layout.operator(ExportMDD.bl_idname, text="Vertex Keyframe Animation (.mdd)...").path = default_path
|
self.layout.operator(ExportMDD.bl_idname, text="Vertex Keyframe Animation (.mdd)...").path = default_path
|
||||||
|
|
||||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
bpy.ops.export.mdd(path="/tmp/test.mdd")
|
bpy.ops.export.mdd(path="/tmp/test.mdd")
|
||||||
|
|||||||
@@ -40,29 +40,6 @@ All objects that can be represented as a mesh (mesh, curve, metaball, surface, t
|
|||||||
will be exported as mesh data.
|
will be exported as mesh data.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
# OBJ Export v1.1 by Campbell Barton (AKA Ideasman)
|
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
# ***** 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 LICENCE BLOCK *****
|
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# import math and other in functions that use them for the sake of fast Blender startup
|
# import math and other in functions that use them for the sake of fast Blender startup
|
||||||
# import math
|
# import math
|
||||||
import os
|
import os
|
||||||
@@ -384,8 +361,7 @@ def write(filename, objects, scene,
|
|||||||
file = open(filename, "w")
|
file = open(filename, "w")
|
||||||
|
|
||||||
# Write Header
|
# Write Header
|
||||||
version = "2.5"
|
file.write('# Blender3D v%s OBJ File: %s\n' % (bpy.version_string, bpy.data.filename.split('/')[-1].split('\\')[-1] ))
|
||||||
file.write('# Blender3D v%s OBJ File: %s\n' % (version, bpy.data.filename.split('/')[-1].split('\\')[-1] ))
|
|
||||||
file.write('# www.blender3d.org\n')
|
file.write('# www.blender3d.org\n')
|
||||||
|
|
||||||
# Tell the obj file what material file to use.
|
# Tell the obj file what material file to use.
|
||||||
@@ -444,7 +420,7 @@ def write(filename, objects, scene,
|
|||||||
me = ob.create_mesh(EXPORT_APPLY_MODIFIERS, 'PREVIEW')
|
me = ob.create_mesh(EXPORT_APPLY_MODIFIERS, 'PREVIEW')
|
||||||
|
|
||||||
if EXPORT_ROTX90:
|
if EXPORT_ROTX90:
|
||||||
me.transform(ob_mat * mat_xrot90)
|
me.transform(mat_xrot90 * ob_mat)
|
||||||
else:
|
else:
|
||||||
me.transform(ob_mat)
|
me.transform(ob_mat)
|
||||||
|
|
||||||
@@ -980,26 +956,20 @@ class ExportOBJ(bpy.types.Operator):
|
|||||||
EXPORT_SEL_ONLY=self.properties.use_selection,
|
EXPORT_SEL_ONLY=self.properties.use_selection,
|
||||||
EXPORT_ALL_SCENES=self.properties.use_all_scenes)
|
EXPORT_ALL_SCENES=self.properties.use_all_scenes)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
bpy.types.register(ExportOBJ)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bpy.ops.add(ExportOBJ)
|
|
||||||
|
|
||||||
import dynamic_menu
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
def menu_func(self, context):
|
||||||
default_path = bpy.data.filename.replace(".blend", ".obj")
|
default_path = bpy.data.filename.replace(".blend", ".obj")
|
||||||
self.layout.operator(ExportOBJ.bl_idname, text="Wavefront (.obj)...").path = default_path
|
self.layout.operator(ExportOBJ.bl_idname, text="Wavefront (.obj)...").path = default_path
|
||||||
|
|
||||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
menu_item = bpy.types.INFO_MT_file_export.append(menu_func)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
bpy.ops.EXPORT_OT_obj(filename="/tmp/test.obj")
|
bpy.ops.EXPORT_OT_obj(filename="/tmp/test.obj")
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ def write(filename, scene, ob, \
|
|||||||
normal_key = rvec3d(normal)
|
normal_key = rvec3d(normal)
|
||||||
|
|
||||||
if faceUV:
|
if faceUV:
|
||||||
uvcoord = uv[j][0], 1.0-uv[j][1]
|
uvcoord = uv[j][0], 1.0 - uv[j][1]
|
||||||
uvcoord_key = rvec2d(uvcoord)
|
uvcoord_key = rvec2d(uvcoord)
|
||||||
elif vertexUV:
|
elif vertexUV:
|
||||||
uvcoord = v.uvco[0], 1.0 - v.uvco[1]
|
uvcoord = v.uvco[0], 1.0 - v.uvco[1]
|
||||||
@@ -205,8 +205,7 @@ def write(filename, scene, ob, \
|
|||||||
|
|
||||||
file.write('ply\n')
|
file.write('ply\n')
|
||||||
file.write('format ascii 1.0\n')
|
file.write('format ascii 1.0\n')
|
||||||
version = "2.5" # Blender.Get('version')
|
file.write('comment Created by Blender3D %s - www.blender.org, source file: %s\n' % (bpy.version_string, bpy.data.filename.split('/')[-1].split('\\')[-1]))
|
||||||
file.write('comment Created by Blender3D %s - www.blender.org, source file: %s\n' % (version, bpy.data.filename.split('/')[-1].split('\\')[-1]))
|
|
||||||
|
|
||||||
file.write('element vertex %d\n' % len(ply_verts))
|
file.write('element vertex %d\n' % len(ply_verts))
|
||||||
|
|
||||||
@@ -246,7 +245,7 @@ def write(filename, scene, ob, \
|
|||||||
file.write('\n')
|
file.write('\n')
|
||||||
|
|
||||||
for pf in ply_faces:
|
for pf in ply_faces:
|
||||||
if len(pf)==3:
|
if len(pf) == 3:
|
||||||
file.write('3 %d %d %d\n' % tuple(pf))
|
file.write('3 %d %d %d\n' % tuple(pf))
|
||||||
else:
|
else:
|
||||||
file.write('4 %d %d %d %d\n' % tuple(pf))
|
file.write('4 %d %d %d %d\n' % tuple(pf))
|
||||||
@@ -297,12 +296,12 @@ class ExportPLY(bpy.types.Operator):
|
|||||||
EXPORT_COLORS=self.properties.use_colors,
|
EXPORT_COLORS=self.properties.use_colors,
|
||||||
)
|
)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
@@ -316,16 +315,15 @@ class ExportPLY(bpy.types.Operator):
|
|||||||
row.prop(props, "use_colors")
|
row.prop(props, "use_colors")
|
||||||
|
|
||||||
|
|
||||||
bpy.ops.add(ExportPLY)
|
bpy.types.register(ExportPLY)
|
||||||
|
|
||||||
import dynamic_menu
|
|
||||||
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
def menu_func(self, context):
|
||||||
default_path = bpy.data.filename.replace(".blend", ".ply")
|
default_path = bpy.data.filename.replace(".blend", ".ply")
|
||||||
self.layout.operator(ExportPLY.bl_idname, text="Stanford (.ply)...").path = default_path
|
self.layout.operator(ExportPLY.bl_idname, text="Stanford (.ply)...").path = default_path
|
||||||
|
|
||||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
bpy.ops.export.ply(path="/tmp/test.ply")
|
bpy.ops.export.ply(path="/tmp/test.ply")
|
||||||
|
|
||||||
|
|||||||
@@ -1233,22 +1233,21 @@ class ExportX3D(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
x3d_export(self.properties.path, context, self.properties.apply_modifiers, self.properties.triangulate, self.properties.compress)
|
x3d_export(self.properties.path, context, self.properties.apply_modifiers, self.properties.triangulate, self.properties.compress)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
bpy.ops.add(ExportX3D)
|
bpy.types.register(ExportX3D)
|
||||||
|
|
||||||
import dynamic_menu
|
|
||||||
|
|
||||||
def menu_func(self, context):
|
def menu_func(self, context):
|
||||||
default_path = bpy.data.filename.replace(".blend", ".x3d")
|
default_path = bpy.data.filename.replace(".blend", ".x3d")
|
||||||
self.layout.operator(ExportX3D.bl_idname, text="X3D Extensible 3D (.x3d)...").path = default_path
|
self.layout.operator(ExportX3D.bl_idname, text="X3D Extensible 3D (.x3d)...").path = default_path
|
||||||
|
|
||||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||||
|
|
||||||
# NOTES
|
# NOTES
|
||||||
# - blender version is hardcoded
|
# - blender version is hardcoded
|
||||||
|
|||||||
@@ -887,17 +887,15 @@ class BvhImporter(bpy.types.Operator):
|
|||||||
|
|
||||||
read_bvh(context, self.properties.path)
|
read_bvh(context, self.properties.path)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
bpy.ops.add(BvhImporter)
|
bpy.types.register(BvhImporter)
|
||||||
|
|
||||||
|
|
||||||
import dynamic_menu
|
|
||||||
menu_func = lambda self, context: self.layout.operator(BvhImporter.bl_idname, text="Motion Capture (.bvh)...")
|
menu_func = lambda self, context: self.layout.operator(BvhImporter.bl_idname, text="Motion Capture (.bvh)...")
|
||||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func)
|
bpy.types.INFO_MT_file_import.append(menu_func)
|
||||||
|
|||||||
@@ -1151,7 +1151,7 @@ class IMPORT_OT_autodesk_3ds(bpy.types.Operator):
|
|||||||
# List of operator properties, the attributes will be assigned
|
# List of operator properties, the attributes will be assigned
|
||||||
# to the class instance from the operator settings before calling.
|
# to the class instance from the operator settings before calling.
|
||||||
|
|
||||||
path = StringProperty(name="File Path", description="File path used for importing the 3DS file", maxlen= 1024, default= ""),
|
path = StringProperty(name="File Path", description="File path used for importing the 3DS file", maxlen= 1024, default= "")
|
||||||
|
|
||||||
# size_constraint = FloatProperty(name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0),
|
# size_constraint = FloatProperty(name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0),
|
||||||
# search_images = BoolProperty(name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True),
|
# search_images = BoolProperty(name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True),
|
||||||
@@ -1159,19 +1159,18 @@ class IMPORT_OT_autodesk_3ds(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
load_3ds(self.properties.path, context, 0.0, False, False)
|
load_3ds(self.properties.path, context, 0.0, False, False)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
bpy.ops.add(IMPORT_OT_autodesk_3ds)
|
bpy.types.register(IMPORT_OT_autodesk_3ds)
|
||||||
|
|
||||||
import dynamic_menu
|
|
||||||
menu_func = lambda self, context: self.layout.operator(IMPORT_OT_autodesk_3ds.bl_idname, text="3D Studio (.3ds)...")
|
menu_func = lambda self, context: self.layout.operator(IMPORT_OT_autodesk_3ds.bl_idname, text="3D Studio (.3ds)...")
|
||||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func)
|
bpy.types.INFO_MT_file_import.append(menu_func)
|
||||||
|
|
||||||
# NOTES:
|
# NOTES:
|
||||||
# why add 1 extra vertex? and remove it when done?
|
# why add 1 extra vertex? and remove it when done? - "Answer - eekadoodle - would need to re-order UV's without this since face order isnt always what we give blender, BMesh will solve :D"
|
||||||
# disabled scaling to size, this requires exposing bb (easy) and understanding how it works (needs some time)
|
# disabled scaling to size, this requires exposing bb (easy) and understanding how it works (needs some time)
|
||||||
|
|||||||
@@ -1616,20 +1616,19 @@ class IMPORT_OT_obj(bpy.types.Operator):
|
|||||||
self.properties.IMAGE_SEARCH,
|
self.properties.IMAGE_SEARCH,
|
||||||
self.properties.POLYGROUPS)
|
self.properties.POLYGROUPS)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
bpy.ops.add(IMPORT_OT_obj)
|
bpy.types.register(IMPORT_OT_obj)
|
||||||
|
|
||||||
|
|
||||||
import dynamic_menu
|
|
||||||
menu_func = lambda self, context: self.layout.operator(IMPORT_OT_obj.bl_idname, text="Wavefront (.obj)...")
|
menu_func = lambda self, context: self.layout.operator(IMPORT_OT_obj.bl_idname, text="Wavefront (.obj)...")
|
||||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func)
|
menu_item = bpy.types.INFO_MT_file_import.append(menu_func)
|
||||||
|
|
||||||
|
|
||||||
# NOTES (all line numbers refer to 2.4x import_obj.py, not this file)
|
# NOTES (all line numbers refer to 2.4x import_obj.py, not this file)
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# 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
|
# modify it under the terms of the GNU General Public License
|
||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
@@ -22,129 +22,129 @@ from netrender.utils import *
|
|||||||
import netrender.model
|
import netrender.model
|
||||||
|
|
||||||
class RatingRule:
|
class RatingRule:
|
||||||
def rate(self, job):
|
def rate(self, job):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
class ExclusionRule:
|
class ExclusionRule:
|
||||||
def test(self, job):
|
def test(self, job):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class PriorityRule:
|
class PriorityRule:
|
||||||
def test(self, job):
|
def test(self, job):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class Balancer:
|
class Balancer:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.rules = []
|
self.rules = []
|
||||||
self.priorities = []
|
self.priorities = []
|
||||||
self.exceptions = []
|
self.exceptions = []
|
||||||
|
|
||||||
def addRule(self, rule):
|
def addRule(self, rule):
|
||||||
self.rules.append(rule)
|
self.rules.append(rule)
|
||||||
|
|
||||||
def addPriority(self, priority):
|
def addPriority(self, priority):
|
||||||
self.priorities.append(priority)
|
self.priorities.append(priority)
|
||||||
|
|
||||||
def addException(self, exception):
|
def addException(self, exception):
|
||||||
self.exceptions.append(exception)
|
self.exceptions.append(exception)
|
||||||
|
|
||||||
def applyRules(self, job):
|
def applyRules(self, job):
|
||||||
return sum((rule.rate(job) for rule in self.rules))
|
return sum((rule.rate(job) for rule in self.rules))
|
||||||
|
|
||||||
def applyPriorities(self, job):
|
def applyPriorities(self, job):
|
||||||
for priority in self.priorities:
|
for priority in self.priorities:
|
||||||
if priority.test(job):
|
if priority.test(job):
|
||||||
return True # priorities are first
|
return True # priorities are first
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def applyExceptions(self, job):
|
def applyExceptions(self, job):
|
||||||
for exception in self.exceptions:
|
for exception in self.exceptions:
|
||||||
if exception.test(job):
|
if exception.test(job):
|
||||||
return True # exceptions are last
|
return True # exceptions are last
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def sortKey(self, job):
|
def sortKey(self, job):
|
||||||
return (1 if self.applyExceptions(job) else 0, # exceptions after
|
return (1 if self.applyExceptions(job) else 0, # exceptions after
|
||||||
0 if self.applyPriorities(job) else 1, # priorities first
|
0 if self.applyPriorities(job) else 1, # priorities first
|
||||||
self.applyRules(job))
|
self.applyRules(job))
|
||||||
|
|
||||||
def balance(self, jobs):
|
def balance(self, jobs):
|
||||||
if jobs:
|
if jobs:
|
||||||
# use inline copy to make sure the list is still accessible while sorting
|
# use inline copy to make sure the list is still accessible while sorting
|
||||||
jobs[:] = sorted(jobs, key=self.sortKey)
|
jobs[:] = sorted(jobs, key=self.sortKey)
|
||||||
return jobs[0]
|
return jobs[0]
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# ==========================
|
# ==========================
|
||||||
|
|
||||||
class RatingUsage(RatingRule):
|
class RatingUsage(RatingRule):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Usage rating"
|
return "Usage rating"
|
||||||
|
|
||||||
def rate(self, job):
|
def rate(self, job):
|
||||||
# less usage is better
|
# less usage is better
|
||||||
return job.usage / job.priority
|
return job.usage / job.priority
|
||||||
|
|
||||||
class RatingUsageByCategory(RatingRule):
|
class RatingUsageByCategory(RatingRule):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Usage per category rating"
|
return "Usage per category rating"
|
||||||
|
|
||||||
def __init__(self, get_jobs):
|
|
||||||
self.getJobs = get_jobs
|
|
||||||
def rate(self, job):
|
|
||||||
total_category_usage = sum([j.usage for j in self.getJobs() if j.category == job.category])
|
|
||||||
maximum_priority = max([j.priority for j in self.getJobs() if j.category == job.category])
|
|
||||||
|
|
||||||
# less usage is better
|
|
||||||
return total_category_usage / maximum_priority
|
|
||||||
|
|
||||||
class NewJobPriority(PriorityRule):
|
|
||||||
def str_limit(self):
|
|
||||||
return "less than %i frame%s done" % (self.limit, "s" if self.limit > 1 else "")
|
|
||||||
|
|
||||||
def __str__(self):
|
def __init__(self, get_jobs):
|
||||||
return "Priority to new jobs"
|
self.getJobs = get_jobs
|
||||||
|
def rate(self, job):
|
||||||
def __init__(self, limit = 1):
|
total_category_usage = sum([j.usage for j in self.getJobs() if j.category == job.category])
|
||||||
self.limit = limit
|
maximum_priority = max([j.priority for j in self.getJobs() if j.category == job.category])
|
||||||
|
|
||||||
def test(self, job):
|
# less usage is better
|
||||||
return job.countFrames(status = DONE) < self.limit
|
return total_category_usage / maximum_priority
|
||||||
|
|
||||||
|
class NewJobPriority(PriorityRule):
|
||||||
|
def str_limit(self):
|
||||||
|
return "less than %i frame%s done" % (self.limit, "s" if self.limit > 1 else "")
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "Priority to new jobs"
|
||||||
|
|
||||||
|
def __init__(self, limit = 1):
|
||||||
|
self.limit = limit
|
||||||
|
|
||||||
|
def test(self, job):
|
||||||
|
return job.countFrames(status = DONE) < self.limit
|
||||||
|
|
||||||
class MinimumTimeBetweenDispatchPriority(PriorityRule):
|
class MinimumTimeBetweenDispatchPriority(PriorityRule):
|
||||||
def str_limit(self):
|
def str_limit(self):
|
||||||
return "more than %i minute%s since last" % (self.limit, "s" if self.limit > 1 else "")
|
return "more than %i minute%s since last" % (self.limit, "s" if self.limit > 1 else "")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Priority to jobs that haven't been dispatched recently"
|
return "Priority to jobs that haven't been dispatched recently"
|
||||||
|
|
||||||
def __init__(self, limit = 10):
|
def __init__(self, limit = 10):
|
||||||
self.limit = limit
|
self.limit = limit
|
||||||
|
|
||||||
def test(self, job):
|
def test(self, job):
|
||||||
return job.countFrames(status = DISPATCHED) == 0 and (time.time() - job.last_dispatched) / 60 > self.limit
|
return job.countFrames(status = DISPATCHED) == 0 and (time.time() - job.last_dispatched) / 60 > self.limit
|
||||||
|
|
||||||
class ExcludeQueuedEmptyJob(ExclusionRule):
|
class ExcludeQueuedEmptyJob(ExclusionRule):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Exclude queued and empty jobs"
|
return "Exclude queued and empty jobs"
|
||||||
|
|
||||||
def test(self, job):
|
|
||||||
return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0
|
|
||||||
|
|
||||||
class ExcludeSlavesLimit(ExclusionRule):
|
|
||||||
def str_limit(self):
|
|
||||||
return "more than %.0f%% of all slaves" % (self.limit * 100)
|
|
||||||
|
|
||||||
def __str__(self):
|
def test(self, job):
|
||||||
return "Exclude jobs that would use too many slaves"
|
return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0
|
||||||
|
|
||||||
def __init__(self, count_jobs, count_slaves, limit = 0.75):
|
class ExcludeSlavesLimit(ExclusionRule):
|
||||||
self.count_jobs = count_jobs
|
def str_limit(self):
|
||||||
self.count_slaves = count_slaves
|
return "more than %.0f%% of all slaves" % (self.limit * 100)
|
||||||
self.limit = limit
|
|
||||||
|
def __str__(self):
|
||||||
def test(self, job):
|
return "Exclude jobs that would use too many slaves"
|
||||||
return not ( self.count_jobs() == 1 or self.count_slaves() <= 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit )
|
|
||||||
|
def __init__(self, count_jobs, count_slaves, limit = 0.75):
|
||||||
|
self.count_jobs = count_jobs
|
||||||
|
self.count_slaves = count_slaves
|
||||||
|
self.limit = limit
|
||||||
|
|
||||||
|
def test(self, job):
|
||||||
|
return not ( self.count_jobs() == 1 or self.count_slaves() <= 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit )
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
@@ -28,253 +28,253 @@ import netrender.master as master
|
|||||||
from netrender.utils import *
|
from netrender.utils import *
|
||||||
|
|
||||||
def addFluidFiles(job, path):
|
def addFluidFiles(job, path):
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
pattern = re.compile("fluidsurface_(final|preview)_([0-9]+)\.(bobj|bvel)\.gz")
|
pattern = re.compile("fluidsurface_(final|preview)_([0-9]+)\.(bobj|bvel)\.gz")
|
||||||
|
|
||||||
for fluid_file in sorted(os.listdir(path)):
|
for fluid_file in sorted(os.listdir(path)):
|
||||||
match = pattern.match(fluid_file)
|
match = pattern.match(fluid_file)
|
||||||
|
|
||||||
if match:
|
if match:
|
||||||
# fluid frames starts at 0, which explains the +1
|
# fluid frames starts at 0, which explains the +1
|
||||||
# This is stupid
|
# This is stupid
|
||||||
current_frame = int(match.groups()[1]) + 1
|
current_frame = int(match.groups()[1]) + 1
|
||||||
job.addFile(path + fluid_file, current_frame, current_frame)
|
job.addFile(path + fluid_file, current_frame, current_frame)
|
||||||
|
|
||||||
def addPointCache(job, ob, point_cache, default_path):
|
def addPointCache(job, ob, point_cache, default_path):
|
||||||
if not point_cache.disk_cache:
|
if not point_cache.disk_cache:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
name = point_cache.name
|
name = point_cache.name
|
||||||
if name == "":
|
if name == "":
|
||||||
name = "".join(["%02X" % ord(c) for c in ob.name])
|
name = "".join(["%02X" % ord(c) for c in ob.name])
|
||||||
|
|
||||||
cache_path = bpy.utils.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
|
index = "%02i" % point_cache.index
|
||||||
|
|
||||||
if os.path.exists(cache_path):
|
if os.path.exists(cache_path):
|
||||||
pattern = re.compile(name + "_([0-9]+)_" + index + "\.bphys")
|
pattern = re.compile(name + "_([0-9]+)_" + index + "\.bphys")
|
||||||
|
|
||||||
cache_files = []
|
cache_files = []
|
||||||
|
|
||||||
|
for cache_file in sorted(os.listdir(cache_path)):
|
||||||
|
match = pattern.match(cache_file)
|
||||||
|
|
||||||
|
if match:
|
||||||
|
cache_frame = int(match.groups()[0])
|
||||||
|
cache_files.append((cache_frame, cache_file))
|
||||||
|
|
||||||
|
cache_files.sort()
|
||||||
|
|
||||||
|
if len(cache_files) == 1:
|
||||||
|
cache_frame, cache_file = cache_files[0]
|
||||||
|
job.addFile(cache_path + cache_file, cache_frame, cache_frame)
|
||||||
|
else:
|
||||||
|
for i in range(len(cache_files)):
|
||||||
|
current_item = cache_files[i]
|
||||||
|
next_item = cache_files[i+1] if i + 1 < len(cache_files) else None
|
||||||
|
previous_item = cache_files[i - 1] if i > 0 else None
|
||||||
|
|
||||||
|
current_frame, current_file = current_item
|
||||||
|
|
||||||
|
if not next_item and not previous_item:
|
||||||
|
job.addFile(cache_path + current_file, current_frame, current_frame)
|
||||||
|
elif next_item and not previous_item:
|
||||||
|
next_frame = next_item[0]
|
||||||
|
job.addFile(cache_path + current_file, current_frame, next_frame - 1)
|
||||||
|
elif not next_item and previous_item:
|
||||||
|
previous_frame = previous_item[0]
|
||||||
|
job.addFile(cache_path + current_file, previous_frame + 1, current_frame)
|
||||||
|
else:
|
||||||
|
next_frame = next_item[0]
|
||||||
|
previous_frame = previous_item[0]
|
||||||
|
job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1)
|
||||||
|
|
||||||
for cache_file in sorted(os.listdir(cache_path)):
|
|
||||||
match = pattern.match(cache_file)
|
|
||||||
|
|
||||||
if match:
|
|
||||||
cache_frame = int(match.groups()[0])
|
|
||||||
cache_files.append((cache_frame, cache_file))
|
|
||||||
|
|
||||||
cache_files.sort()
|
|
||||||
|
|
||||||
if len(cache_files) == 1:
|
|
||||||
cache_frame, cache_file = cache_files[0]
|
|
||||||
job.addFile(cache_path + cache_file, cache_frame, cache_frame)
|
|
||||||
else:
|
|
||||||
for i in range(len(cache_files)):
|
|
||||||
current_item = cache_files[i]
|
|
||||||
next_item = cache_files[i+1] if i + 1 < len(cache_files) else None
|
|
||||||
previous_item = cache_files[i - 1] if i > 0 else None
|
|
||||||
|
|
||||||
current_frame, current_file = current_item
|
|
||||||
|
|
||||||
if not next_item and not previous_item:
|
|
||||||
job.addFile(cache_path + current_file, current_frame, current_frame)
|
|
||||||
elif next_item and not previous_item:
|
|
||||||
next_frame = next_item[0]
|
|
||||||
job.addFile(cache_path + current_file, current_frame, next_frame - 1)
|
|
||||||
elif not next_item and previous_item:
|
|
||||||
previous_frame = previous_item[0]
|
|
||||||
job.addFile(cache_path + current_file, previous_frame + 1, current_frame)
|
|
||||||
else:
|
|
||||||
next_frame = next_item[0]
|
|
||||||
previous_frame = previous_item[0]
|
|
||||||
job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1)
|
|
||||||
|
|
||||||
def clientSendJob(conn, scene, anim = False):
|
def clientSendJob(conn, scene, anim = False):
|
||||||
netsettings = scene.network_render
|
netsettings = scene.network_render
|
||||||
job = netrender.model.RenderJob()
|
job = netrender.model.RenderJob()
|
||||||
|
|
||||||
if anim:
|
|
||||||
for f in range(scene.start_frame, scene.end_frame + 1):
|
|
||||||
job.addFrame(f)
|
|
||||||
else:
|
|
||||||
job.addFrame(scene.current_frame)
|
|
||||||
|
|
||||||
filename = bpy.data.filename
|
|
||||||
job.addFile(filename)
|
|
||||||
|
|
||||||
job_name = netsettings.job_name
|
|
||||||
path, name = os.path.split(filename)
|
|
||||||
if job_name == "[default]":
|
|
||||||
job_name = name
|
|
||||||
|
|
||||||
###########################
|
|
||||||
# LIBRARIES
|
|
||||||
###########################
|
|
||||||
for lib in bpy.data.libraries:
|
|
||||||
job.addFile(bpy.utils.expandpath(lib.filename))
|
|
||||||
|
|
||||||
###########################
|
|
||||||
# IMAGES
|
|
||||||
###########################
|
|
||||||
for image in bpy.data.images:
|
|
||||||
if image.source == "FILE" and not image.packed_file:
|
|
||||||
job.addFile(bpy.utils.expandpath(image.filename))
|
|
||||||
|
|
||||||
###########################
|
|
||||||
# FLUID + POINT CACHE
|
|
||||||
###########################
|
|
||||||
root, ext = os.path.splitext(name)
|
|
||||||
default_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that
|
|
||||||
|
|
||||||
for object in bpy.data.objects:
|
if anim:
|
||||||
for modifier in object.modifiers:
|
for f in range(scene.start_frame, scene.end_frame + 1):
|
||||||
if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN":
|
job.addFrame(f)
|
||||||
addFluidFiles(job, bpy.utils.expandpath(modifier.settings.path))
|
else:
|
||||||
elif modifier.type == "CLOTH":
|
job.addFrame(scene.current_frame)
|
||||||
addPointCache(job, object, modifier.point_cache, default_path)
|
|
||||||
elif modifier.type == "SOFT_BODY":
|
|
||||||
addPointCache(job, object, modifier.point_cache, default_path)
|
|
||||||
elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN":
|
|
||||||
addPointCache(job, object, modifier.domain_settings.point_cache_low, default_path)
|
|
||||||
if modifier.domain_settings.highres:
|
|
||||||
addPointCache(job, object, modifier.domain_settings.point_cache_high, default_path)
|
|
||||||
|
|
||||||
# particles modifier are stupid and don't contain data
|
filename = bpy.data.filename
|
||||||
# we have to go through the object property
|
job.addFile(filename)
|
||||||
for psys in object.particle_systems:
|
|
||||||
addPointCache(job, object, psys.point_cache, default_path)
|
job_name = netsettings.job_name
|
||||||
|
path, name = os.path.split(filename)
|
||||||
#print(job.files)
|
if job_name == "[default]":
|
||||||
|
job_name = name
|
||||||
job.name = job_name
|
|
||||||
job.category = netsettings.job_category
|
###########################
|
||||||
|
# LIBRARIES
|
||||||
for slave in netrender.blacklist:
|
###########################
|
||||||
job.blacklist.append(slave.id)
|
for lib in bpy.data.libraries:
|
||||||
|
job.addFile(bpy.utils.expandpath(lib.filename))
|
||||||
job.chunks = netsettings.chunks
|
|
||||||
job.priority = netsettings.priority
|
###########################
|
||||||
|
# IMAGES
|
||||||
# try to send path first
|
###########################
|
||||||
conn.request("POST", "/job", repr(job.serialize()))
|
for image in bpy.data.images:
|
||||||
response = conn.getresponse()
|
if image.source == "FILE" and not image.packed_file:
|
||||||
|
job.addFile(bpy.utils.expandpath(image.filename))
|
||||||
job_id = response.getheader("job-id")
|
|
||||||
|
###########################
|
||||||
# if not ACCEPTED (but not processed), send files
|
# FLUID + POINT CACHE
|
||||||
if response.status == http.client.ACCEPTED:
|
###########################
|
||||||
for rfile in job.files:
|
root, ext = os.path.splitext(name)
|
||||||
f = open(rfile.filepath, "rb")
|
default_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that
|
||||||
conn.request("PUT", fileURL(job_id, rfile.index), f)
|
|
||||||
f.close()
|
for object in bpy.data.objects:
|
||||||
response = conn.getresponse()
|
for modifier in object.modifiers:
|
||||||
|
if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN":
|
||||||
# server will reply with ACCEPTED until all files are found
|
addFluidFiles(job, bpy.utils.expandpath(modifier.settings.path))
|
||||||
|
elif modifier.type == "CLOTH":
|
||||||
return job_id
|
addPointCache(job, object, modifier.point_cache, default_path)
|
||||||
|
elif modifier.type == "SOFT_BODY":
|
||||||
|
addPointCache(job, object, modifier.point_cache, default_path)
|
||||||
|
elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN":
|
||||||
|
addPointCache(job, object, modifier.domain_settings.point_cache_low, default_path)
|
||||||
|
if modifier.domain_settings.highres:
|
||||||
|
addPointCache(job, object, modifier.domain_settings.point_cache_high, default_path)
|
||||||
|
|
||||||
|
# particles modifier are stupid and don't contain data
|
||||||
|
# we have to go through the object property
|
||||||
|
for psys in object.particle_systems:
|
||||||
|
addPointCache(job, object, psys.point_cache, default_path)
|
||||||
|
|
||||||
|
#print(job.files)
|
||||||
|
|
||||||
|
job.name = job_name
|
||||||
|
job.category = netsettings.job_category
|
||||||
|
|
||||||
|
for slave in netrender.blacklist:
|
||||||
|
job.blacklist.append(slave.id)
|
||||||
|
|
||||||
|
job.chunks = netsettings.chunks
|
||||||
|
job.priority = netsettings.priority
|
||||||
|
|
||||||
|
# try to send path first
|
||||||
|
conn.request("POST", "/job", repr(job.serialize()))
|
||||||
|
response = conn.getresponse()
|
||||||
|
|
||||||
|
job_id = response.getheader("job-id")
|
||||||
|
|
||||||
|
# if not ACCEPTED (but not processed), send files
|
||||||
|
if response.status == http.client.ACCEPTED:
|
||||||
|
for rfile in job.files:
|
||||||
|
f = open(rfile.filepath, "rb")
|
||||||
|
conn.request("PUT", fileURL(job_id, rfile.index), f)
|
||||||
|
f.close()
|
||||||
|
response = conn.getresponse()
|
||||||
|
|
||||||
|
# server will reply with ACCEPTED until all files are found
|
||||||
|
|
||||||
|
return job_id
|
||||||
|
|
||||||
def requestResult(conn, job_id, frame):
|
def requestResult(conn, job_id, frame):
|
||||||
conn.request("GET", renderURL(job_id, frame))
|
conn.request("GET", renderURL(job_id, frame))
|
||||||
|
|
||||||
@rnaType
|
@rnaType
|
||||||
class NetworkRenderEngine(bpy.types.RenderEngine):
|
class NetworkRenderEngine(bpy.types.RenderEngine):
|
||||||
bl_idname = 'NET_RENDER'
|
bl_idname = 'NET_RENDER'
|
||||||
bl_label = "Network Render"
|
bl_label = "Network Render"
|
||||||
def render(self, scene):
|
def render(self, scene):
|
||||||
if scene.network_render.mode == "RENDER_CLIENT":
|
if scene.network_render.mode == "RENDER_CLIENT":
|
||||||
self.render_client(scene)
|
self.render_client(scene)
|
||||||
elif scene.network_render.mode == "RENDER_SLAVE":
|
elif scene.network_render.mode == "RENDER_SLAVE":
|
||||||
self.render_slave(scene)
|
self.render_slave(scene)
|
||||||
elif scene.network_render.mode == "RENDER_MASTER":
|
elif scene.network_render.mode == "RENDER_MASTER":
|
||||||
self.render_master(scene)
|
self.render_master(scene)
|
||||||
else:
|
else:
|
||||||
print("UNKNOWN OPERATION MODE")
|
print("UNKNOWN OPERATION MODE")
|
||||||
|
|
||||||
def render_master(self, scene):
|
def render_master(self, scene):
|
||||||
netsettings = scene.network_render
|
netsettings = scene.network_render
|
||||||
|
|
||||||
address = "" if netsettings.server_address == "[default]" else netsettings.server_address
|
address = "" if netsettings.server_address == "[default]" else netsettings.server_address
|
||||||
|
|
||||||
master.runMaster((address, netsettings.server_port), netsettings.server_broadcast, netsettings.path, self.update_stats, self.test_break)
|
master.runMaster((address, netsettings.server_port), netsettings.server_broadcast, netsettings.path, self.update_stats, self.test_break)
|
||||||
|
|
||||||
|
|
||||||
def render_slave(self, scene):
|
def render_slave(self, scene):
|
||||||
slave.render_slave(self, scene.network_render)
|
slave.render_slave(self, scene.network_render)
|
||||||
|
|
||||||
def render_client(self, scene):
|
def render_client(self, scene):
|
||||||
netsettings = scene.network_render
|
netsettings = scene.network_render
|
||||||
self.update_stats("", "Network render client initiation")
|
self.update_stats("", "Network render client initiation")
|
||||||
|
|
||||||
|
|
||||||
conn = clientConnection(netsettings.server_address, netsettings.server_port)
|
conn = clientConnection(netsettings.server_address, netsettings.server_port)
|
||||||
|
|
||||||
if conn:
|
if conn:
|
||||||
# Sending file
|
# Sending file
|
||||||
|
|
||||||
self.update_stats("", "Network render exporting")
|
self.update_stats("", "Network render exporting")
|
||||||
|
|
||||||
new_job = False
|
new_job = False
|
||||||
|
|
||||||
job_id = netsettings.job_id
|
job_id = netsettings.job_id
|
||||||
|
|
||||||
# reading back result
|
# reading back result
|
||||||
|
|
||||||
self.update_stats("", "Network render waiting for results")
|
self.update_stats("", "Network render waiting for results")
|
||||||
|
|
||||||
requestResult(conn, job_id, scene.current_frame)
|
requestResult(conn, job_id, scene.current_frame)
|
||||||
response = conn.getresponse()
|
response = conn.getresponse()
|
||||||
|
|
||||||
if response.status == http.client.NO_CONTENT:
|
if response.status == http.client.NO_CONTENT:
|
||||||
new_job = True
|
new_job = True
|
||||||
netsettings.job_id = clientSendJob(conn, scene)
|
netsettings.job_id = clientSendJob(conn, scene)
|
||||||
job_id = netsettings.job_id
|
job_id = netsettings.job_id
|
||||||
|
|
||||||
requestResult(conn, job_id, scene.current_frame)
|
requestResult(conn, job_id, scene.current_frame)
|
||||||
response = conn.getresponse()
|
response = conn.getresponse()
|
||||||
|
|
||||||
while response.status == http.client.ACCEPTED and not self.test_break():
|
while response.status == http.client.ACCEPTED and not self.test_break():
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
requestResult(conn, job_id, scene.current_frame)
|
requestResult(conn, job_id, scene.current_frame)
|
||||||
response = conn.getresponse()
|
response = conn.getresponse()
|
||||||
|
|
||||||
# cancel new jobs (animate on network) on break
|
# cancel new jobs (animate on network) on break
|
||||||
if self.test_break() and new_job:
|
if self.test_break() and new_job:
|
||||||
conn.request("POST", cancelURL(job_id))
|
conn.request("POST", cancelURL(job_id))
|
||||||
response = conn.getresponse()
|
response = conn.getresponse()
|
||||||
print( response.status, response.reason )
|
print( response.status, response.reason )
|
||||||
netsettings.job_id = 0
|
netsettings.job_id = 0
|
||||||
|
|
||||||
if response.status != http.client.OK:
|
if response.status != http.client.OK:
|
||||||
conn.close()
|
conn.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
r = scene.render_data
|
r = scene.render_data
|
||||||
x= int(r.resolution_x*r.resolution_percentage*0.01)
|
x= int(r.resolution_x*r.resolution_percentage*0.01)
|
||||||
y= int(r.resolution_y*r.resolution_percentage*0.01)
|
y= int(r.resolution_y*r.resolution_percentage*0.01)
|
||||||
|
|
||||||
f = open(netsettings.path + "output.exr", "wb")
|
f = open(netsettings.path + "output.exr", "wb")
|
||||||
buf = response.read(1024)
|
buf = response.read(1024)
|
||||||
|
|
||||||
while buf:
|
while buf:
|
||||||
f.write(buf)
|
f.write(buf)
|
||||||
buf = response.read(1024)
|
buf = response.read(1024)
|
||||||
|
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
result = self.begin_result(0, 0, x, y)
|
result = self.begin_result(0, 0, x, y)
|
||||||
result.load_from_file(netsettings.path + "output.exr", 0, 0)
|
result.load_from_file(netsettings.path + "output.exr", 0, 0)
|
||||||
self.end_result(result)
|
self.end_result(result)
|
||||||
|
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
def compatible(module):
|
def compatible(module):
|
||||||
module = __import__(module)
|
module = __import__(module)
|
||||||
for subclass in module.__dict__.values():
|
for subclass in module.__dict__.values():
|
||||||
try: subclass.COMPAT_ENGINES.add('NET_RENDER')
|
try: subclass.COMPAT_ENGINES.add('NET_RENDER')
|
||||||
except: pass
|
except: pass
|
||||||
del module
|
del module
|
||||||
|
|
||||||
compatible("properties_render")
|
compatible("properties_render")
|
||||||
compatible("properties_world")
|
compatible("properties_world")
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,12 +4,12 @@
|
|||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
@@ -24,226 +24,226 @@ from netrender.utils import *
|
|||||||
src_folder = os.path.split(__file__)[0]
|
src_folder = os.path.split(__file__)[0]
|
||||||
|
|
||||||
def get(handler):
|
def get(handler):
|
||||||
def output(text):
|
def output(text):
|
||||||
handler.wfile.write(bytes(text, encoding='utf8'))
|
handler.wfile.write(bytes(text, encoding='utf8'))
|
||||||
|
|
||||||
def head(title):
|
def head(title):
|
||||||
output("<html><head>")
|
output("<html><head>")
|
||||||
output("<script src='/html/netrender.js' type='text/javascript'></script>")
|
output("<script src='/html/netrender.js' type='text/javascript'></script>")
|
||||||
# output("<script src='/html/json2.js' type='text/javascript'></script>")
|
# output("<script src='/html/json2.js' type='text/javascript'></script>")
|
||||||
output("<title>")
|
output("<title>")
|
||||||
output(title)
|
output(title)
|
||||||
output("</title></head><body>")
|
output("</title></head><body>")
|
||||||
output("<link rel='stylesheet' href='/html/netrender.css' type='text/css'>")
|
output("<link rel='stylesheet' href='/html/netrender.css' type='text/css'>")
|
||||||
|
|
||||||
|
|
||||||
def link(text, url):
|
|
||||||
return "<a href='%s'>%s</a>" % (url, text)
|
|
||||||
|
|
||||||
def startTable(border=1, class_style = None, caption = None):
|
|
||||||
output("<table border='%i'" % border)
|
|
||||||
|
|
||||||
if class_style:
|
|
||||||
output(" class='%s'" % class_style)
|
|
||||||
|
|
||||||
output(">")
|
|
||||||
|
|
||||||
if caption:
|
|
||||||
output("<caption>%s</caption>" % caption)
|
|
||||||
|
|
||||||
def headerTable(*headers):
|
|
||||||
output("<thead><tr>")
|
|
||||||
|
|
||||||
for c in headers:
|
|
||||||
output("<td>" + c + "</td>")
|
|
||||||
|
|
||||||
output("</tr></thead>")
|
|
||||||
|
|
||||||
def rowTable(*data, id = None, class_style = None, extra = None):
|
|
||||||
output("<tr")
|
|
||||||
|
|
||||||
if id:
|
|
||||||
output(" id='%s'" % id)
|
|
||||||
|
|
||||||
if class_style:
|
|
||||||
output(" class='%s'" % class_style)
|
|
||||||
|
|
||||||
if extra:
|
def link(text, url):
|
||||||
output(" %s" % extra)
|
return "<a href='%s'>%s</a>" % (url, text)
|
||||||
|
|
||||||
output(">")
|
def startTable(border=1, class_style = None, caption = None):
|
||||||
|
output("<table border='%i'" % border)
|
||||||
for c in data:
|
|
||||||
output("<td>" + str(c) + "</td>")
|
|
||||||
|
|
||||||
output("</tr>")
|
|
||||||
|
|
||||||
def endTable():
|
|
||||||
output("</table>")
|
|
||||||
|
|
||||||
if handler.path == "/html/netrender.js":
|
|
||||||
f = open(os.path.join(src_folder, "netrender.js"), 'rb')
|
|
||||||
|
|
||||||
handler.send_head(content = "text/javascript")
|
|
||||||
shutil.copyfileobj(f, handler.wfile)
|
|
||||||
|
|
||||||
f.close()
|
|
||||||
elif handler.path == "/html/netrender.css":
|
|
||||||
f = open(os.path.join(src_folder, "netrender.css"), 'rb')
|
|
||||||
|
|
||||||
handler.send_head(content = "text/css")
|
|
||||||
shutil.copyfileobj(f, handler.wfile)
|
|
||||||
|
|
||||||
f.close()
|
|
||||||
elif handler.path == "/html" or handler.path == "/":
|
|
||||||
handler.send_head(content = "text/html")
|
|
||||||
head("NetRender")
|
|
||||||
|
|
||||||
output("<h2>Master</h2>")
|
|
||||||
|
|
||||||
output("""<button title="remove all jobs" onclick="request('/clear', null);">CLEAR JOB LIST</button>""")
|
|
||||||
|
|
||||||
startTable(caption = "Rules", class_style = "rules")
|
if class_style:
|
||||||
|
output(" class='%s'" % class_style)
|
||||||
|
|
||||||
headerTable("type", "description", "limit")
|
output(">")
|
||||||
|
|
||||||
for rule in handler.server.balancer.rules:
|
if caption:
|
||||||
rowTable("rating", rule, rule.str_limit() if hasattr(rule, "limit") else " ")
|
output("<caption>%s</caption>" % caption)
|
||||||
|
|
||||||
for rule in handler.server.balancer.priorities:
|
def headerTable(*headers):
|
||||||
rowTable("priority", rule, rule.str_limit() if hasattr(rule, "limit") else " ")
|
output("<thead><tr>")
|
||||||
|
|
||||||
for rule in handler.server.balancer.exceptions:
|
|
||||||
rowTable("exception", rule, rule.str_limit() if hasattr(rule, "limit") else " ")
|
|
||||||
|
|
||||||
endTable()
|
for c in headers:
|
||||||
|
output("<td>" + c + "</td>")
|
||||||
|
|
||||||
output("<h2>Slaves</h2>")
|
output("</tr></thead>")
|
||||||
|
|
||||||
startTable()
|
|
||||||
headerTable("name", "address", "last seen", "stats", "job")
|
|
||||||
|
|
||||||
for slave in handler.server.slaves:
|
|
||||||
rowTable(slave.name, slave.address[0], time.ctime(slave.last_seen), slave.stats, link(slave.job.name, "/html/job" + slave.job.id) if slave.job else "None")
|
|
||||||
|
|
||||||
endTable()
|
|
||||||
|
|
||||||
output("<h2>Jobs</h2>")
|
|
||||||
|
|
||||||
startTable()
|
|
||||||
headerTable(
|
|
||||||
" ",
|
|
||||||
"id",
|
|
||||||
"name",
|
|
||||||
"category",
|
|
||||||
"chunks",
|
|
||||||
"priority",
|
|
||||||
"usage",
|
|
||||||
"wait",
|
|
||||||
"status",
|
|
||||||
"length",
|
|
||||||
"done",
|
|
||||||
"dispatched",
|
|
||||||
"error",
|
|
||||||
"first",
|
|
||||||
"exception"
|
|
||||||
)
|
|
||||||
|
|
||||||
handler.server.balance()
|
def rowTable(*data, id = None, class_style = None, extra = None):
|
||||||
|
output("<tr")
|
||||||
for job in handler.server.jobs:
|
|
||||||
results = job.framesStatus()
|
|
||||||
rowTable(
|
|
||||||
"""<button title="cancel job" onclick="request('/cancel_%s', null);">X</button>""" % job.id +
|
|
||||||
"""<button title="reset all frames" onclick="request('/resetall_%s_0', null);">R</button>""" % job.id,
|
|
||||||
job.id,
|
|
||||||
link(job.name, "/html/job" + job.id),
|
|
||||||
job.category if job.category else "<i>None</i>",
|
|
||||||
str(job.chunks) +
|
|
||||||
"""<button title="increase priority" onclick="request('/edit_%s', "{'chunks': %i}");">+</button>""" % (job.id, job.chunks + 1) +
|
|
||||||
"""<button title="decrease priority" onclick="request('/edit_%s', "{'chunks': %i}");" %s>-</button>""" % (job.id, job.chunks - 1, "disabled=True" if job.chunks == 1 else ""),
|
|
||||||
str(job.priority) +
|
|
||||||
"""<button title="increase chunks size" onclick="request('/edit_%s', "{'priority': %i}");">+</button>""" % (job.id, job.priority + 1) +
|
|
||||||
"""<button title="decrease chunks size" onclick="request('/edit_%s', "{'priority': %i}");" %s>-</button>""" % (job.id, job.priority - 1, "disabled=True" if job.priority == 1 else ""),
|
|
||||||
"%0.1f%%" % (job.usage * 100),
|
|
||||||
"%is" % int(time.time() - job.last_dispatched),
|
|
||||||
job.statusText(),
|
|
||||||
len(job),
|
|
||||||
results[DONE],
|
|
||||||
results[DISPATCHED],
|
|
||||||
str(results[ERROR]) +
|
|
||||||
"""<button title="reset error frames" onclick="request('/reset_%s_0', null);" %s>R</button>""" % (job.id, "disabled=True" if not results[ERROR] else ""),
|
|
||||||
handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job)
|
|
||||||
)
|
|
||||||
|
|
||||||
endTable()
|
|
||||||
|
|
||||||
output("</body></html>")
|
|
||||||
|
|
||||||
elif handler.path.startswith("/html/job"):
|
|
||||||
handler.send_head(content = "text/html")
|
|
||||||
job_id = handler.path[9:]
|
|
||||||
|
|
||||||
head("NetRender")
|
|
||||||
|
|
||||||
job = handler.server.getJobID(job_id)
|
|
||||||
|
|
||||||
if job:
|
|
||||||
output("<h2>Files</h2>")
|
|
||||||
|
|
||||||
startTable()
|
|
||||||
headerTable("path")
|
|
||||||
|
|
||||||
tot_cache = 0
|
|
||||||
tot_fluid = 0
|
|
||||||
|
|
||||||
for file in job.files:
|
|
||||||
if file.filepath.endswith(".bphys"):
|
|
||||||
tot_cache += 1
|
|
||||||
elif file.filepath.endswith(".bobj.gz") or file.filepath.endswith(".bvel.gz"):
|
|
||||||
tot_fluid += 1
|
|
||||||
else:
|
|
||||||
rowTable(file.filepath)
|
|
||||||
|
|
||||||
if tot_cache > 0:
|
if id:
|
||||||
rowTable("%i physic cache files" % tot_cache, class_style = "toggle", extra = "onclick='toggleDisplay(".cache", "none", "table-row")'")
|
output(" id='%s'" % id)
|
||||||
for file in job.files:
|
|
||||||
if file.filepath.endswith(".bphys"):
|
|
||||||
rowTable(os.path.split(file.filepath)[1], class_style = "cache")
|
|
||||||
|
|
||||||
if tot_fluid > 0:
|
|
||||||
rowTable("%i fluid bake files" % tot_fluid, class_style = "toggle", extra = "onclick='toggleDisplay(".fluid", "none", "table-row")'")
|
|
||||||
for file in job.files:
|
|
||||||
if file.filepath.endswith(".bobj.gz") or file.filepath.endswith(".bvel.gz"):
|
|
||||||
rowTable(os.path.split(file.filepath)[1], class_style = "fluid")
|
|
||||||
|
|
||||||
endTable()
|
if class_style:
|
||||||
|
output(" class='%s'" % class_style)
|
||||||
output("<h2>Blacklist</h2>")
|
|
||||||
|
|
||||||
if job.blacklist:
|
|
||||||
startTable()
|
|
||||||
headerTable("name", "address")
|
|
||||||
|
|
||||||
for slave_id in job.blacklist:
|
|
||||||
slave = handler.server.slaves_map[slave_id]
|
|
||||||
rowTable(slave.name, slave.address[0])
|
|
||||||
|
|
||||||
endTable()
|
|
||||||
else:
|
|
||||||
output("<i>Empty</i>")
|
|
||||||
|
|
||||||
output("<h2>Frames</h2>")
|
if extra:
|
||||||
|
output(" %s" % extra)
|
||||||
startTable()
|
|
||||||
headerTable("no", "status", "render time", "slave", "log", "result")
|
output(">")
|
||||||
|
|
||||||
for frame in job.frames:
|
for c in data:
|
||||||
rowTable(frame.number, frame.statusText(), "%.1fs" % frame.time, frame.slave.name if frame.slave else " ", link("view log", logURL(job_id, frame.number)) if frame.log_path else " ", link("view result", renderURL(job_id, frame.number)) if frame.status == DONE else " ")
|
output("<td>" + str(c) + "</td>")
|
||||||
|
|
||||||
endTable()
|
output("</tr>")
|
||||||
else:
|
|
||||||
output("no such job")
|
def endTable():
|
||||||
|
output("</table>")
|
||||||
output("</body></html>")
|
|
||||||
|
if handler.path == "/html/netrender.js":
|
||||||
|
f = open(os.path.join(src_folder, "netrender.js"), 'rb')
|
||||||
|
|
||||||
|
handler.send_head(content = "text/javascript")
|
||||||
|
shutil.copyfileobj(f, handler.wfile)
|
||||||
|
|
||||||
|
f.close()
|
||||||
|
elif handler.path == "/html/netrender.css":
|
||||||
|
f = open(os.path.join(src_folder, "netrender.css"), 'rb')
|
||||||
|
|
||||||
|
handler.send_head(content = "text/css")
|
||||||
|
shutil.copyfileobj(f, handler.wfile)
|
||||||
|
|
||||||
|
f.close()
|
||||||
|
elif handler.path == "/html" or handler.path == "/":
|
||||||
|
handler.send_head(content = "text/html")
|
||||||
|
head("NetRender")
|
||||||
|
|
||||||
|
output("<h2>Master</h2>")
|
||||||
|
|
||||||
|
output("""<button title="remove all jobs" onclick="request('/clear', null);">CLEAR JOB LIST</button>""")
|
||||||
|
|
||||||
|
startTable(caption = "Rules", class_style = "rules")
|
||||||
|
|
||||||
|
headerTable("type", "description", "limit")
|
||||||
|
|
||||||
|
for rule in handler.server.balancer.rules:
|
||||||
|
rowTable("rating", rule, rule.str_limit() if hasattr(rule, "limit") else " ")
|
||||||
|
|
||||||
|
for rule in handler.server.balancer.priorities:
|
||||||
|
rowTable("priority", rule, rule.str_limit() if hasattr(rule, "limit") else " ")
|
||||||
|
|
||||||
|
for rule in handler.server.balancer.exceptions:
|
||||||
|
rowTable("exception", rule, rule.str_limit() if hasattr(rule, "limit") else " ")
|
||||||
|
|
||||||
|
endTable()
|
||||||
|
|
||||||
|
output("<h2>Slaves</h2>")
|
||||||
|
|
||||||
|
startTable()
|
||||||
|
headerTable("name", "address", "last seen", "stats", "job")
|
||||||
|
|
||||||
|
for slave in handler.server.slaves:
|
||||||
|
rowTable(slave.name, slave.address[0], time.ctime(slave.last_seen), slave.stats, link(slave.job.name, "/html/job" + slave.job.id) if slave.job else "None")
|
||||||
|
|
||||||
|
endTable()
|
||||||
|
|
||||||
|
output("<h2>Jobs</h2>")
|
||||||
|
|
||||||
|
startTable()
|
||||||
|
headerTable(
|
||||||
|
" ",
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"category",
|
||||||
|
"chunks",
|
||||||
|
"priority",
|
||||||
|
"usage",
|
||||||
|
"wait",
|
||||||
|
"status",
|
||||||
|
"length",
|
||||||
|
"done",
|
||||||
|
"dispatched",
|
||||||
|
"error",
|
||||||
|
"first",
|
||||||
|
"exception"
|
||||||
|
)
|
||||||
|
|
||||||
|
handler.server.balance()
|
||||||
|
|
||||||
|
for job in handler.server.jobs:
|
||||||
|
results = job.framesStatus()
|
||||||
|
rowTable(
|
||||||
|
"""<button title="cancel job" onclick="request('/cancel_%s', null);">X</button>""" % job.id +
|
||||||
|
"""<button title="reset all frames" onclick="request('/resetall_%s_0', null);">R</button>""" % job.id,
|
||||||
|
job.id,
|
||||||
|
link(job.name, "/html/job" + job.id),
|
||||||
|
job.category if job.category else "<i>None</i>",
|
||||||
|
str(job.chunks) +
|
||||||
|
"""<button title="increase priority" onclick="request('/edit_%s', "{'chunks': %i}");">+</button>""" % (job.id, job.chunks + 1) +
|
||||||
|
"""<button title="decrease priority" onclick="request('/edit_%s', "{'chunks': %i}");" %s>-</button>""" % (job.id, job.chunks - 1, "disabled=True" if job.chunks == 1 else ""),
|
||||||
|
str(job.priority) +
|
||||||
|
"""<button title="increase chunks size" onclick="request('/edit_%s', "{'priority': %i}");">+</button>""" % (job.id, job.priority + 1) +
|
||||||
|
"""<button title="decrease chunks size" onclick="request('/edit_%s', "{'priority': %i}");" %s>-</button>""" % (job.id, job.priority - 1, "disabled=True" if job.priority == 1 else ""),
|
||||||
|
"%0.1f%%" % (job.usage * 100),
|
||||||
|
"%is" % int(time.time() - job.last_dispatched),
|
||||||
|
job.statusText(),
|
||||||
|
len(job),
|
||||||
|
results[DONE],
|
||||||
|
results[DISPATCHED],
|
||||||
|
str(results[ERROR]) +
|
||||||
|
"""<button title="reset error frames" onclick="request('/reset_%s_0', null);" %s>R</button>""" % (job.id, "disabled=True" if not results[ERROR] else ""),
|
||||||
|
handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job)
|
||||||
|
)
|
||||||
|
|
||||||
|
endTable()
|
||||||
|
|
||||||
|
output("</body></html>")
|
||||||
|
|
||||||
|
elif handler.path.startswith("/html/job"):
|
||||||
|
handler.send_head(content = "text/html")
|
||||||
|
job_id = handler.path[9:]
|
||||||
|
|
||||||
|
head("NetRender")
|
||||||
|
|
||||||
|
job = handler.server.getJobID(job_id)
|
||||||
|
|
||||||
|
if job:
|
||||||
|
output("<h2>Files</h2>")
|
||||||
|
|
||||||
|
startTable()
|
||||||
|
headerTable("path")
|
||||||
|
|
||||||
|
tot_cache = 0
|
||||||
|
tot_fluid = 0
|
||||||
|
|
||||||
|
for file in job.files:
|
||||||
|
if file.filepath.endswith(".bphys"):
|
||||||
|
tot_cache += 1
|
||||||
|
elif file.filepath.endswith(".bobj.gz") or file.filepath.endswith(".bvel.gz"):
|
||||||
|
tot_fluid += 1
|
||||||
|
else:
|
||||||
|
rowTable(file.filepath)
|
||||||
|
|
||||||
|
if tot_cache > 0:
|
||||||
|
rowTable("%i physic cache files" % tot_cache, class_style = "toggle", extra = "onclick='toggleDisplay(".cache", "none", "table-row")'")
|
||||||
|
for file in job.files:
|
||||||
|
if file.filepath.endswith(".bphys"):
|
||||||
|
rowTable(os.path.split(file.filepath)[1], class_style = "cache")
|
||||||
|
|
||||||
|
if tot_fluid > 0:
|
||||||
|
rowTable("%i fluid bake files" % tot_fluid, class_style = "toggle", extra = "onclick='toggleDisplay(".fluid", "none", "table-row")'")
|
||||||
|
for file in job.files:
|
||||||
|
if file.filepath.endswith(".bobj.gz") or file.filepath.endswith(".bvel.gz"):
|
||||||
|
rowTable(os.path.split(file.filepath)[1], class_style = "fluid")
|
||||||
|
|
||||||
|
endTable()
|
||||||
|
|
||||||
|
output("<h2>Blacklist</h2>")
|
||||||
|
|
||||||
|
if job.blacklist:
|
||||||
|
startTable()
|
||||||
|
headerTable("name", "address")
|
||||||
|
|
||||||
|
for slave_id in job.blacklist:
|
||||||
|
slave = handler.server.slaves_map[slave_id]
|
||||||
|
rowTable(slave.name, slave.address[0])
|
||||||
|
|
||||||
|
endTable()
|
||||||
|
else:
|
||||||
|
output("<i>Empty</i>")
|
||||||
|
|
||||||
|
output("<h2>Frames</h2>")
|
||||||
|
|
||||||
|
startTable()
|
||||||
|
headerTable("no", "status", "render time", "slave", "log", "result")
|
||||||
|
|
||||||
|
for frame in job.frames:
|
||||||
|
rowTable(frame.number, frame.statusText(), "%.1fs" % frame.time, frame.slave.name if frame.slave else " ", link("view log", logURL(job_id, frame.number)) if frame.log_path else " ", link("view result", renderURL(job_id, frame.number)) if frame.status == DONE else " ")
|
||||||
|
|
||||||
|
endTable()
|
||||||
|
else:
|
||||||
|
output("no such job")
|
||||||
|
|
||||||
|
output("</body></html>")
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
@@ -23,256 +23,256 @@ import subprocess, shutil, time, hashlib
|
|||||||
from netrender.utils import *
|
from netrender.utils import *
|
||||||
|
|
||||||
class LogFile:
|
class LogFile:
|
||||||
def __init__(self, job_id = 0, slave_id = 0, frames = []):
|
def __init__(self, job_id = 0, slave_id = 0, frames = []):
|
||||||
self.job_id = job_id
|
self.job_id = job_id
|
||||||
self.slave_id = slave_id
|
self.slave_id = slave_id
|
||||||
self.frames = frames
|
self.frames = frames
|
||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
return {
|
return {
|
||||||
"job_id": self.job_id,
|
"job_id": self.job_id,
|
||||||
"slave_id": self.slave_id,
|
"slave_id": self.slave_id,
|
||||||
"frames": self.frames
|
"frames": self.frames
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def materialize(data):
|
def materialize(data):
|
||||||
if not data:
|
if not data:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
logfile = LogFile()
|
logfile = LogFile()
|
||||||
logfile.job_id = data["job_id"]
|
logfile.job_id = data["job_id"]
|
||||||
logfile.slave_id = data["slave_id"]
|
logfile.slave_id = data["slave_id"]
|
||||||
logfile.frames = data["frames"]
|
logfile.frames = data["frames"]
|
||||||
|
|
||||||
return logfile
|
return logfile
|
||||||
|
|
||||||
class RenderSlave:
|
class RenderSlave:
|
||||||
_slave_map = {}
|
_slave_map = {}
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.id = ""
|
|
||||||
self.name = ""
|
|
||||||
self.address = ("",0)
|
|
||||||
self.stats = ""
|
|
||||||
self.total_done = 0
|
|
||||||
self.total_error = 0
|
|
||||||
self.last_seen = 0.0
|
|
||||||
|
|
||||||
def serialize(self):
|
|
||||||
return {
|
|
||||||
"id": self.id,
|
|
||||||
"name": self.name,
|
|
||||||
"address": self.address,
|
|
||||||
"stats": self.stats,
|
|
||||||
"total_done": self.total_done,
|
|
||||||
"total_error": self.total_error,
|
|
||||||
"last_seen": self.last_seen
|
|
||||||
}
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def materialize(data, cache = True):
|
|
||||||
if not data:
|
|
||||||
return None
|
|
||||||
|
|
||||||
slave_id = data["id"]
|
|
||||||
|
|
||||||
if cache and slave_id in RenderSlave._slave_map:
|
def __init__(self):
|
||||||
return RenderSlave._slave_map[slave_id]
|
self.id = ""
|
||||||
|
self.name = ""
|
||||||
|
self.address = ("",0)
|
||||||
|
self.stats = ""
|
||||||
|
self.total_done = 0
|
||||||
|
self.total_error = 0
|
||||||
|
self.last_seen = 0.0
|
||||||
|
|
||||||
slave = RenderSlave()
|
def serialize(self):
|
||||||
slave.id = slave_id
|
return {
|
||||||
slave.name = data["name"]
|
"id": self.id,
|
||||||
slave.address = data["address"]
|
"name": self.name,
|
||||||
slave.stats = data["stats"]
|
"address": self.address,
|
||||||
slave.total_done = data["total_done"]
|
"stats": self.stats,
|
||||||
slave.total_error = data["total_error"]
|
"total_done": self.total_done,
|
||||||
slave.last_seen = data["last_seen"]
|
"total_error": self.total_error,
|
||||||
|
"last_seen": self.last_seen
|
||||||
|
}
|
||||||
|
|
||||||
if cache:
|
@staticmethod
|
||||||
RenderSlave._slave_map[slave_id] = slave
|
def materialize(data, cache = True):
|
||||||
|
if not data:
|
||||||
return slave
|
return None
|
||||||
|
|
||||||
|
slave_id = data["id"]
|
||||||
|
|
||||||
|
if cache and slave_id in RenderSlave._slave_map:
|
||||||
|
return RenderSlave._slave_map[slave_id]
|
||||||
|
|
||||||
|
slave = RenderSlave()
|
||||||
|
slave.id = slave_id
|
||||||
|
slave.name = data["name"]
|
||||||
|
slave.address = data["address"]
|
||||||
|
slave.stats = data["stats"]
|
||||||
|
slave.total_done = data["total_done"]
|
||||||
|
slave.total_error = data["total_error"]
|
||||||
|
slave.last_seen = data["last_seen"]
|
||||||
|
|
||||||
|
if cache:
|
||||||
|
RenderSlave._slave_map[slave_id] = slave
|
||||||
|
|
||||||
|
return slave
|
||||||
|
|
||||||
JOB_BLENDER = 1
|
JOB_BLENDER = 1
|
||||||
JOB_PROCESS = 2
|
JOB_PROCESS = 2
|
||||||
|
|
||||||
JOB_TYPES = {
|
JOB_TYPES = {
|
||||||
JOB_BLENDER: "Blender",
|
JOB_BLENDER: "Blender",
|
||||||
JOB_PROCESS: "Process"
|
JOB_PROCESS: "Process"
|
||||||
}
|
}
|
||||||
|
|
||||||
class RenderFile:
|
class RenderFile:
|
||||||
def __init__(self, filepath = "", index = 0, start = -1, end = -1):
|
def __init__(self, filepath = "", index = 0, start = -1, end = -1):
|
||||||
self.filepath = filepath
|
self.filepath = filepath
|
||||||
self.index = index
|
self.index = index
|
||||||
self.start = start
|
self.start = start
|
||||||
self.end = end
|
self.end = end
|
||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
return {
|
return {
|
||||||
"filepath": self.filepath,
|
"filepath": self.filepath,
|
||||||
"index": self.index,
|
"index": self.index,
|
||||||
"start": self.start,
|
"start": self.start,
|
||||||
"end": self.end
|
"end": self.end
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def materialize(data):
|
def materialize(data):
|
||||||
if not data:
|
if not data:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
rfile = RenderFile(data["filepath"], data["index"], data["start"], data["end"])
|
|
||||||
|
|
||||||
return rfile
|
rfile = RenderFile(data["filepath"], data["index"], data["start"], data["end"])
|
||||||
|
|
||||||
|
return rfile
|
||||||
|
|
||||||
class RenderJob:
|
class RenderJob:
|
||||||
def __init__(self, job_info = None):
|
def __init__(self, job_info = None):
|
||||||
self.id = ""
|
self.id = ""
|
||||||
self.type = JOB_BLENDER
|
self.type = JOB_BLENDER
|
||||||
self.name = ""
|
self.name = ""
|
||||||
self.category = "None"
|
self.category = "None"
|
||||||
self.status = JOB_WAITING
|
self.status = JOB_WAITING
|
||||||
self.files = []
|
self.files = []
|
||||||
self.chunks = 0
|
self.chunks = 0
|
||||||
self.priority = 0
|
self.priority = 0
|
||||||
self.blacklist = []
|
self.blacklist = []
|
||||||
|
|
||||||
self.usage = 0.0
|
self.usage = 0.0
|
||||||
self.last_dispatched = 0.0
|
self.last_dispatched = 0.0
|
||||||
self.frames = []
|
self.frames = []
|
||||||
|
|
||||||
if job_info:
|
|
||||||
self.type = job_info.type
|
|
||||||
self.name = job_info.name
|
|
||||||
self.category = job_info.category
|
|
||||||
self.status = job_info.status
|
|
||||||
self.files = job_info.files
|
|
||||||
self.chunks = job_info.chunks
|
|
||||||
self.priority = job_info.priority
|
|
||||||
self.blacklist = job_info.blacklist
|
|
||||||
|
|
||||||
def addFile(self, file_path, start=-1, end=-1):
|
|
||||||
self.files.append(RenderFile(file_path, len(self.files), start, end))
|
|
||||||
|
|
||||||
def addFrame(self, frame_number, command = ""):
|
|
||||||
frame = RenderFrame(frame_number, command)
|
|
||||||
self.frames.append(frame)
|
|
||||||
return frame
|
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self.frames)
|
|
||||||
|
|
||||||
def countFrames(self, status=QUEUED):
|
|
||||||
total = 0
|
|
||||||
for f in self.frames:
|
|
||||||
if f.status == status:
|
|
||||||
total += 1
|
|
||||||
|
|
||||||
return total
|
|
||||||
|
|
||||||
def countSlaves(self):
|
|
||||||
return len(set((frame.slave for frame in self.frames if frame.status == DISPATCHED)))
|
|
||||||
|
|
||||||
def statusText(self):
|
|
||||||
return JOB_STATUS_TEXT[self.status]
|
|
||||||
|
|
||||||
def framesStatus(self):
|
|
||||||
results = {
|
|
||||||
QUEUED: 0,
|
|
||||||
DISPATCHED: 0,
|
|
||||||
DONE: 0,
|
|
||||||
ERROR: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
for frame in self.frames:
|
|
||||||
results[frame.status] += 1
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
||||||
def __contains__(self, frame_number):
|
|
||||||
for f in self.frames:
|
|
||||||
if f.number == frame_number:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def __getitem__(self, frame_number):
|
|
||||||
for f in self.frames:
|
|
||||||
if f.number == frame_number:
|
|
||||||
return f
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def serialize(self, frames = None):
|
|
||||||
min_frame = min((f.number for f in frames)) if frames else -1
|
|
||||||
max_frame = max((f.number for f in frames)) if frames else -1
|
|
||||||
return {
|
|
||||||
"id": self.id,
|
|
||||||
"type": self.type,
|
|
||||||
"name": self.name,
|
|
||||||
"category": self.category,
|
|
||||||
"status": self.status,
|
|
||||||
"files": [f.serialize() for f in self.files if f.start == -1 or not frames or (f.start <= max_frame and f.end >= min_frame)],
|
|
||||||
"frames": [f.serialize() for f in self.frames if not frames or f in frames],
|
|
||||||
"chunks": self.chunks,
|
|
||||||
"priority": self.priority,
|
|
||||||
"usage": self.usage,
|
|
||||||
"blacklist": self.blacklist,
|
|
||||||
"last_dispatched": self.last_dispatched
|
|
||||||
}
|
|
||||||
|
|
||||||
@staticmethod
|
if job_info:
|
||||||
def materialize(data):
|
self.type = job_info.type
|
||||||
if not data:
|
self.name = job_info.name
|
||||||
return None
|
self.category = job_info.category
|
||||||
|
self.status = job_info.status
|
||||||
job = RenderJob()
|
self.files = job_info.files
|
||||||
job.id = data["id"]
|
self.chunks = job_info.chunks
|
||||||
job.type = data["type"]
|
self.priority = job_info.priority
|
||||||
job.name = data["name"]
|
self.blacklist = job_info.blacklist
|
||||||
job.category = data["category"]
|
|
||||||
job.status = data["status"]
|
|
||||||
job.files = [RenderFile.materialize(f) for f in data["files"]]
|
|
||||||
job.frames = [RenderFrame.materialize(f) for f in data["frames"]]
|
|
||||||
job.chunks = data["chunks"]
|
|
||||||
job.priority = data["priority"]
|
|
||||||
job.usage = data["usage"]
|
|
||||||
job.blacklist = data["blacklist"]
|
|
||||||
job.last_dispatched = data["last_dispatched"]
|
|
||||||
|
|
||||||
return job
|
def addFile(self, file_path, start=-1, end=-1):
|
||||||
|
self.files.append(RenderFile(file_path, len(self.files), start, end))
|
||||||
|
|
||||||
|
def addFrame(self, frame_number, command = ""):
|
||||||
|
frame = RenderFrame(frame_number, command)
|
||||||
|
self.frames.append(frame)
|
||||||
|
return frame
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.frames)
|
||||||
|
|
||||||
|
def countFrames(self, status=QUEUED):
|
||||||
|
total = 0
|
||||||
|
for f in self.frames:
|
||||||
|
if f.status == status:
|
||||||
|
total += 1
|
||||||
|
|
||||||
|
return total
|
||||||
|
|
||||||
|
def countSlaves(self):
|
||||||
|
return len(set((frame.slave for frame in self.frames if frame.status == DISPATCHED)))
|
||||||
|
|
||||||
|
def statusText(self):
|
||||||
|
return JOB_STATUS_TEXT[self.status]
|
||||||
|
|
||||||
|
def framesStatus(self):
|
||||||
|
results = {
|
||||||
|
QUEUED: 0,
|
||||||
|
DISPATCHED: 0,
|
||||||
|
DONE: 0,
|
||||||
|
ERROR: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for frame in self.frames:
|
||||||
|
results[frame.status] += 1
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
def __contains__(self, frame_number):
|
||||||
|
for f in self.frames:
|
||||||
|
if f.number == frame_number:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __getitem__(self, frame_number):
|
||||||
|
for f in self.frames:
|
||||||
|
if f.number == frame_number:
|
||||||
|
return f
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def serialize(self, frames = None):
|
||||||
|
min_frame = min((f.number for f in frames)) if frames else -1
|
||||||
|
max_frame = max((f.number for f in frames)) if frames else -1
|
||||||
|
return {
|
||||||
|
"id": self.id,
|
||||||
|
"type": self.type,
|
||||||
|
"name": self.name,
|
||||||
|
"category": self.category,
|
||||||
|
"status": self.status,
|
||||||
|
"files": [f.serialize() for f in self.files if f.start == -1 or not frames or (f.start <= max_frame and f.end >= min_frame)],
|
||||||
|
"frames": [f.serialize() for f in self.frames if not frames or f in frames],
|
||||||
|
"chunks": self.chunks,
|
||||||
|
"priority": self.priority,
|
||||||
|
"usage": self.usage,
|
||||||
|
"blacklist": self.blacklist,
|
||||||
|
"last_dispatched": self.last_dispatched
|
||||||
|
}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def materialize(data):
|
||||||
|
if not data:
|
||||||
|
return None
|
||||||
|
|
||||||
|
job = RenderJob()
|
||||||
|
job.id = data["id"]
|
||||||
|
job.type = data["type"]
|
||||||
|
job.name = data["name"]
|
||||||
|
job.category = data["category"]
|
||||||
|
job.status = data["status"]
|
||||||
|
job.files = [RenderFile.materialize(f) for f in data["files"]]
|
||||||
|
job.frames = [RenderFrame.materialize(f) for f in data["frames"]]
|
||||||
|
job.chunks = data["chunks"]
|
||||||
|
job.priority = data["priority"]
|
||||||
|
job.usage = data["usage"]
|
||||||
|
job.blacklist = data["blacklist"]
|
||||||
|
job.last_dispatched = data["last_dispatched"]
|
||||||
|
|
||||||
|
return job
|
||||||
|
|
||||||
class RenderFrame:
|
class RenderFrame:
|
||||||
def __init__(self, number = 0, command = ""):
|
def __init__(self, number = 0, command = ""):
|
||||||
self.number = number
|
self.number = number
|
||||||
self.time = 0
|
self.time = 0
|
||||||
self.status = QUEUED
|
self.status = QUEUED
|
||||||
self.slave = None
|
self.slave = None
|
||||||
self.command = command
|
self.command = command
|
||||||
|
|
||||||
def statusText(self):
|
def statusText(self):
|
||||||
return FRAME_STATUS_TEXT[self.status]
|
return FRAME_STATUS_TEXT[self.status]
|
||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
return {
|
return {
|
||||||
"number": self.number,
|
"number": self.number,
|
||||||
"time": self.time,
|
"time": self.time,
|
||||||
"status": self.status,
|
"status": self.status,
|
||||||
"slave": None if not self.slave else self.slave.serialize(),
|
"slave": None if not self.slave else self.slave.serialize(),
|
||||||
"command": self.command
|
"command": self.command
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def materialize(data):
|
|
||||||
if not data:
|
|
||||||
return None
|
|
||||||
|
|
||||||
frame = RenderFrame()
|
|
||||||
frame.number = data["number"]
|
|
||||||
frame.time = data["time"]
|
|
||||||
frame.status = data["status"]
|
|
||||||
frame.slave = RenderSlave.materialize(data["slave"])
|
|
||||||
frame.command = data["command"]
|
|
||||||
|
|
||||||
return frame
|
@staticmethod
|
||||||
|
def materialize(data):
|
||||||
|
if not data:
|
||||||
|
return None
|
||||||
|
|
||||||
|
frame = RenderFrame()
|
||||||
|
frame.number = data["number"]
|
||||||
|
frame.time = data["time"]
|
||||||
|
frame.status = data["status"]
|
||||||
|
frame.slave = RenderSlave.materialize(data["slave"])
|
||||||
|
frame.command = data["command"]
|
||||||
|
|
||||||
|
return frame
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
@@ -26,413 +26,416 @@ from netrender.utils import *
|
|||||||
import netrender.client as client
|
import netrender.client as client
|
||||||
import netrender.model
|
import netrender.model
|
||||||
|
|
||||||
@rnaOperator
|
@rnaType
|
||||||
class RENDER_OT_netslave_bake(bpy.types.Operator):
|
class RENDER_OT_netslave_bake(bpy.types.Operator):
|
||||||
'''NEED DESCRIPTION'''
|
'''NEED DESCRIPTION'''
|
||||||
bl_idname = "render.netslavebake"
|
bl_idname = "render.netslavebake"
|
||||||
bl_label = "Bake all in file"
|
bl_label = "Bake all in file"
|
||||||
|
|
||||||
def poll(self, context):
|
def poll(self, context):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
netsettings = scene.network_render
|
netsettings = scene.network_render
|
||||||
|
|
||||||
filename = bpy.data.filename
|
filename = bpy.data.filename
|
||||||
path, name = os.path.split(filename)
|
path, name = os.path.split(filename)
|
||||||
root, ext = os.path.splitext(name)
|
root, ext = os.path.splitext(name)
|
||||||
default_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that
|
default_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that
|
||||||
relative_path = os.sep + os.sep + "blendcache_" + root + os.sep
|
relative_path = os.sep + os.sep + "blendcache_" + root + os.sep
|
||||||
|
|
||||||
# Force all point cache next to the blend file
|
# Force all point cache next to the blend file
|
||||||
for object in bpy.data.objects:
|
for object in bpy.data.objects:
|
||||||
for modifier in object.modifiers:
|
for modifier in object.modifiers:
|
||||||
if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN":
|
if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN":
|
||||||
modifier.settings.path = relative_path
|
modifier.settings.path = relative_path
|
||||||
bpy.ops.fluid.bake({"active_object": object, "scene": scene})
|
bpy.ops.fluid.bake({"active_object": object, "scene": scene})
|
||||||
elif modifier.type == "CLOTH":
|
elif modifier.type == "CLOTH":
|
||||||
modifier.point_cache.step = 1
|
modifier.point_cache.step = 1
|
||||||
modifier.point_cache.disk_cache = True
|
modifier.point_cache.disk_cache = True
|
||||||
modifier.point_cache.external = False
|
modifier.point_cache.external = False
|
||||||
elif modifier.type == "SOFT_BODY":
|
elif modifier.type == "SOFT_BODY":
|
||||||
modifier.point_cache.step = 1
|
modifier.point_cache.step = 1
|
||||||
modifier.point_cache.disk_cache = True
|
modifier.point_cache.disk_cache = True
|
||||||
modifier.point_cache.external = False
|
modifier.point_cache.external = False
|
||||||
elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN":
|
elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN":
|
||||||
modifier.domain_settings.point_cache_low.step = 1
|
modifier.domain_settings.point_cache_low.step = 1
|
||||||
modifier.domain_settings.point_cache_low.disk_cache = True
|
modifier.domain_settings.point_cache_low.disk_cache = True
|
||||||
modifier.domain_settings.point_cache_low.external = False
|
modifier.domain_settings.point_cache_low.external = False
|
||||||
modifier.domain_settings.point_cache_high.step = 1
|
modifier.domain_settings.point_cache_high.step = 1
|
||||||
modifier.domain_settings.point_cache_high.disk_cache = True
|
modifier.domain_settings.point_cache_high.disk_cache = True
|
||||||
modifier.domain_settings.point_cache_high.external = False
|
modifier.domain_settings.point_cache_high.external = False
|
||||||
|
|
||||||
# particles modifier are stupid and don't contain data
|
# particles modifier are stupid and don't contain data
|
||||||
# we have to go through the object property
|
# we have to go through the object property
|
||||||
for psys in object.particle_systems:
|
for psys in object.particle_systems:
|
||||||
psys.point_cache.step = 1
|
psys.point_cache.step = 1
|
||||||
psys.point_cache.disk_cache = True
|
psys.point_cache.disk_cache = True
|
||||||
psys.point_cache.external = False
|
psys.point_cache.external = False
|
||||||
psys.point_cache.filepath = relative_path
|
psys.point_cache.filepath = relative_path
|
||||||
|
|
||||||
bpy.ops.ptcache.bake_all()
|
bpy.ops.ptcache.bake_all()
|
||||||
|
|
||||||
#bpy.ops.wm.save_mainfile(path = path + os.sep + root + "_baked.blend")
|
#bpy.ops.wm.save_mainfile(path = path + os.sep + root + "_baked.blend")
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
return self.execute(context)
|
return self.execute(context)
|
||||||
|
|
||||||
@rnaOperator
|
@rnaType
|
||||||
class RENDER_OT_netclientanim(bpy.types.Operator):
|
class RENDER_OT_netclientanim(bpy.types.Operator):
|
||||||
'''Start rendering an animation on network'''
|
'''Start rendering an animation on network'''
|
||||||
bl_idname = "render.netclientanim"
|
bl_idname = "render.netclientanim"
|
||||||
bl_label = "Animation on network"
|
bl_label = "Animation on network"
|
||||||
|
|
||||||
def poll(self, context):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
scene = context.scene
|
|
||||||
netsettings = scene.network_render
|
|
||||||
|
|
||||||
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
|
||||||
|
|
||||||
if conn:
|
def poll(self, context):
|
||||||
# Sending file
|
return True
|
||||||
scene.network_render.job_id = client.clientSendJob(conn, scene, True)
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
bpy.ops.screen.render('INVOKE_AREA', animation=True)
|
|
||||||
|
|
||||||
return ('FINISHED',)
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
return self.execute(context)
|
|
||||||
|
|
||||||
@rnaOperator
|
def execute(self, context):
|
||||||
|
scene = context.scene
|
||||||
|
netsettings = scene.network_render
|
||||||
|
|
||||||
|
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
||||||
|
|
||||||
|
if conn:
|
||||||
|
# Sending file
|
||||||
|
scene.network_render.job_id = client.clientSendJob(conn, scene, True)
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
bpy.ops.screen.render('INVOKE_AREA', animation=True)
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
return self.execute(context)
|
||||||
|
|
||||||
|
@rnaType
|
||||||
class RENDER_OT_netclientsend(bpy.types.Operator):
|
class RENDER_OT_netclientsend(bpy.types.Operator):
|
||||||
'''Send Render Job to the Network'''
|
'''Send Render Job to the Network'''
|
||||||
bl_idname = "render.netclientsend"
|
bl_idname = "render.netclientsend"
|
||||||
bl_label = "Send job"
|
bl_label = "Send job"
|
||||||
|
|
||||||
def poll(self, context):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
scene = context.scene
|
|
||||||
netsettings = scene.network_render
|
|
||||||
|
|
||||||
try:
|
|
||||||
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
|
||||||
|
|
||||||
if conn:
|
def poll(self, context):
|
||||||
# Sending file
|
return True
|
||||||
scene.network_render.job_id = client.clientSendJob(conn, scene, True)
|
|
||||||
conn.close()
|
|
||||||
self.report('INFO', "Job sent to master")
|
|
||||||
except Exception as err:
|
|
||||||
self.report('ERROR', str(err))
|
|
||||||
|
|
||||||
|
|
||||||
return ('FINISHED',)
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
return self.execute(context)
|
|
||||||
|
|
||||||
@rnaOperator
|
def execute(self, context):
|
||||||
|
scene = context.scene
|
||||||
|
netsettings = scene.network_render
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
||||||
|
|
||||||
|
if conn:
|
||||||
|
# Sending file
|
||||||
|
scene.network_render.job_id = client.clientSendJob(conn, scene, True)
|
||||||
|
conn.close()
|
||||||
|
self.report('INFO', "Job sent to master")
|
||||||
|
except Exception as err:
|
||||||
|
self.report('ERROR', str(err))
|
||||||
|
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
return self.execute(context)
|
||||||
|
|
||||||
|
@rnaType
|
||||||
class RENDER_OT_netclientstatus(bpy.types.Operator):
|
class RENDER_OT_netclientstatus(bpy.types.Operator):
|
||||||
'''Refresh the status of the current jobs'''
|
'''Refresh the status of the current jobs'''
|
||||||
bl_idname = "render.netclientstatus"
|
bl_idname = "render.netclientstatus"
|
||||||
bl_label = "Client Status"
|
bl_label = "Client Status"
|
||||||
|
|
||||||
def poll(self, context):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
netsettings = context.scene.network_render
|
|
||||||
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
|
||||||
|
|
||||||
if conn:
|
def poll(self, context):
|
||||||
conn.request("GET", "/status")
|
return True
|
||||||
|
|
||||||
response = conn.getresponse()
|
|
||||||
print( response.status, response.reason )
|
|
||||||
|
|
||||||
jobs = (netrender.model.RenderJob.materialize(j) for j in eval(str(response.read(), encoding='utf8')))
|
|
||||||
|
|
||||||
while(len(netsettings.jobs) > 0):
|
|
||||||
netsettings.jobs.remove(0)
|
|
||||||
|
|
||||||
netrender.jobs = []
|
|
||||||
|
|
||||||
for j in jobs:
|
|
||||||
netrender.jobs.append(j)
|
|
||||||
netsettings.jobs.add()
|
|
||||||
job = netsettings.jobs[-1]
|
|
||||||
|
|
||||||
j.results = j.framesStatus() # cache frame status
|
|
||||||
|
|
||||||
job.name = j.name
|
|
||||||
|
|
||||||
return ('FINISHED',)
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
return self.execute(context)
|
|
||||||
|
|
||||||
@rnaOperator
|
def execute(self, context):
|
||||||
|
netsettings = context.scene.network_render
|
||||||
|
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
||||||
|
|
||||||
|
if conn:
|
||||||
|
conn.request("GET", "/status")
|
||||||
|
|
||||||
|
response = conn.getresponse()
|
||||||
|
print( response.status, response.reason )
|
||||||
|
|
||||||
|
jobs = (netrender.model.RenderJob.materialize(j) for j in eval(str(response.read(), encoding='utf8')))
|
||||||
|
|
||||||
|
while(len(netsettings.jobs) > 0):
|
||||||
|
netsettings.jobs.remove(0)
|
||||||
|
|
||||||
|
netrender.jobs = []
|
||||||
|
|
||||||
|
for j in jobs:
|
||||||
|
netrender.jobs.append(j)
|
||||||
|
netsettings.jobs.add()
|
||||||
|
job = netsettings.jobs[-1]
|
||||||
|
|
||||||
|
j.results = j.framesStatus() # cache frame status
|
||||||
|
|
||||||
|
job.name = j.name
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
return self.execute(context)
|
||||||
|
|
||||||
|
@rnaType
|
||||||
class RENDER_OT_netclientblacklistslave(bpy.types.Operator):
|
class RENDER_OT_netclientblacklistslave(bpy.types.Operator):
|
||||||
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
|
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
|
||||||
bl_idname = "render.netclientblacklistslave"
|
bl_idname = "render.netclientblacklistslave"
|
||||||
bl_label = "Client Blacklist Slave"
|
bl_label = "Client Blacklist Slave"
|
||||||
|
|
||||||
def poll(self, context):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
netsettings = context.scene.network_render
|
|
||||||
|
|
||||||
if netsettings.active_slave_index >= 0:
|
|
||||||
|
|
||||||
# deal with data
|
|
||||||
slave = netrender.slaves.pop(netsettings.active_slave_index)
|
|
||||||
netrender.blacklist.append(slave)
|
|
||||||
|
|
||||||
# deal with rna
|
|
||||||
netsettings.slaves_blacklist.add()
|
|
||||||
netsettings.slaves_blacklist[-1].name = slave.name
|
|
||||||
|
|
||||||
netsettings.slaves.remove(netsettings.active_slave_index)
|
|
||||||
netsettings.active_slave_index = -1
|
|
||||||
|
|
||||||
return ('FINISHED',)
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
return self.execute(context)
|
|
||||||
|
|
||||||
@rnaOperator
|
def poll(self, context):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
netsettings = context.scene.network_render
|
||||||
|
|
||||||
|
if netsettings.active_slave_index >= 0:
|
||||||
|
|
||||||
|
# deal with data
|
||||||
|
slave = netrender.slaves.pop(netsettings.active_slave_index)
|
||||||
|
netrender.blacklist.append(slave)
|
||||||
|
|
||||||
|
# deal with rna
|
||||||
|
netsettings.slaves_blacklist.add()
|
||||||
|
netsettings.slaves_blacklist[-1].name = slave.name
|
||||||
|
|
||||||
|
netsettings.slaves.remove(netsettings.active_slave_index)
|
||||||
|
netsettings.active_slave_index = -1
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
return self.execute(context)
|
||||||
|
|
||||||
|
@rnaType
|
||||||
class RENDER_OT_netclientwhitelistslave(bpy.types.Operator):
|
class RENDER_OT_netclientwhitelistslave(bpy.types.Operator):
|
||||||
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
|
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
|
||||||
bl_idname = "render.netclientwhitelistslave"
|
bl_idname = "render.netclientwhitelistslave"
|
||||||
bl_label = "Client Whitelist Slave"
|
bl_label = "Client Whitelist Slave"
|
||||||
|
|
||||||
def poll(self, context):
|
def poll(self, context):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
netsettings = context.scene.network_render
|
netsettings = context.scene.network_render
|
||||||
|
|
||||||
if netsettings.active_blacklisted_slave_index >= 0:
|
if netsettings.active_blacklisted_slave_index >= 0:
|
||||||
|
|
||||||
# deal with data
|
# deal with data
|
||||||
slave = netrender.blacklist.pop(netsettings.active_blacklisted_slave_index)
|
slave = netrender.blacklist.pop(netsettings.active_blacklisted_slave_index)
|
||||||
netrender.slaves.append(slave)
|
netrender.slaves.append(slave)
|
||||||
|
|
||||||
# deal with rna
|
# deal with rna
|
||||||
netsettings.slaves.add()
|
netsettings.slaves.add()
|
||||||
netsettings.slaves[-1].name = slave.name
|
netsettings.slaves[-1].name = slave.name
|
||||||
|
|
||||||
netsettings.slaves_blacklist.remove(netsettings.active_blacklisted_slave_index)
|
netsettings.slaves_blacklist.remove(netsettings.active_blacklisted_slave_index)
|
||||||
netsettings.active_blacklisted_slave_index = -1
|
netsettings.active_blacklisted_slave_index = -1
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
return self.execute(context)
|
return self.execute(context)
|
||||||
|
|
||||||
|
|
||||||
@rnaOperator
|
@rnaType
|
||||||
class RENDER_OT_netclientslaves(bpy.types.Operator):
|
class RENDER_OT_netclientslaves(bpy.types.Operator):
|
||||||
'''Refresh status about available Render slaves'''
|
'''Refresh status about available Render slaves'''
|
||||||
bl_idname = "render.netclientslaves"
|
bl_idname = "render.netclientslaves"
|
||||||
bl_label = "Client Slaves"
|
bl_label = "Client Slaves"
|
||||||
|
|
||||||
def poll(self, context):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
netsettings = context.scene.network_render
|
|
||||||
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
|
||||||
|
|
||||||
if conn:
|
|
||||||
conn.request("GET", "/slaves")
|
|
||||||
|
|
||||||
response = conn.getresponse()
|
|
||||||
print( response.status, response.reason )
|
|
||||||
|
|
||||||
slaves = (netrender.model.RenderSlave.materialize(s) for s in eval(str(response.read(), encoding='utf8')))
|
|
||||||
|
|
||||||
while(len(netsettings.slaves) > 0):
|
|
||||||
netsettings.slaves.remove(0)
|
|
||||||
|
|
||||||
netrender.slaves = []
|
|
||||||
|
|
||||||
for s in slaves:
|
|
||||||
for i in range(len(netrender.blacklist)):
|
|
||||||
slave = netrender.blacklist[i]
|
|
||||||
if slave.id == s.id:
|
|
||||||
netrender.blacklist[i] = s
|
|
||||||
netsettings.slaves_blacklist[i].name = s.name
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
netrender.slaves.append(s)
|
|
||||||
|
|
||||||
netsettings.slaves.add()
|
|
||||||
slave = netsettings.slaves[-1]
|
|
||||||
slave.name = s.name
|
|
||||||
|
|
||||||
return ('FINISHED',)
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
return self.execute(context)
|
|
||||||
|
|
||||||
@rnaOperator
|
def poll(self, context):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
netsettings = context.scene.network_render
|
||||||
|
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
||||||
|
|
||||||
|
if conn:
|
||||||
|
conn.request("GET", "/slaves")
|
||||||
|
|
||||||
|
response = conn.getresponse()
|
||||||
|
print( response.status, response.reason )
|
||||||
|
|
||||||
|
slaves = (netrender.model.RenderSlave.materialize(s) for s in eval(str(response.read(), encoding='utf8')))
|
||||||
|
|
||||||
|
while(len(netsettings.slaves) > 0):
|
||||||
|
netsettings.slaves.remove(0)
|
||||||
|
|
||||||
|
netrender.slaves = []
|
||||||
|
|
||||||
|
for s in slaves:
|
||||||
|
for i in range(len(netrender.blacklist)):
|
||||||
|
slave = netrender.blacklist[i]
|
||||||
|
if slave.id == s.id:
|
||||||
|
netrender.blacklist[i] = s
|
||||||
|
netsettings.slaves_blacklist[i].name = s.name
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
netrender.slaves.append(s)
|
||||||
|
|
||||||
|
netsettings.slaves.add()
|
||||||
|
slave = netsettings.slaves[-1]
|
||||||
|
slave.name = s.name
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
return self.execute(context)
|
||||||
|
|
||||||
|
@rnaType
|
||||||
class RENDER_OT_netclientcancel(bpy.types.Operator):
|
class RENDER_OT_netclientcancel(bpy.types.Operator):
|
||||||
'''Cancel the selected network rendering job.'''
|
'''Cancel the selected network rendering job.'''
|
||||||
bl_idname = "render.netclientcancel"
|
bl_idname = "render.netclientcancel"
|
||||||
bl_label = "Client Cancel"
|
bl_label = "Client Cancel"
|
||||||
|
|
||||||
def poll(self, context):
|
|
||||||
netsettings = context.scene.network_render
|
|
||||||
return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
netsettings = context.scene.network_render
|
|
||||||
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
|
||||||
|
|
||||||
if conn:
|
|
||||||
job = netrender.jobs[netsettings.active_job_index]
|
|
||||||
|
|
||||||
conn.request("POST", cancelURL(job.id))
|
|
||||||
|
|
||||||
response = conn.getresponse()
|
|
||||||
print( response.status, response.reason )
|
|
||||||
|
|
||||||
netsettings.jobs.remove(netsettings.active_job_index)
|
def poll(self, context):
|
||||||
|
netsettings = context.scene.network_render
|
||||||
return ('FINISHED',)
|
return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def execute(self, context):
|
||||||
return self.execute(context)
|
netsettings = context.scene.network_render
|
||||||
|
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
||||||
@rnaOperator
|
|
||||||
|
if conn:
|
||||||
|
job = netrender.jobs[netsettings.active_job_index]
|
||||||
|
|
||||||
|
conn.request("POST", cancelURL(job.id))
|
||||||
|
|
||||||
|
response = conn.getresponse()
|
||||||
|
print( response.status, response.reason )
|
||||||
|
|
||||||
|
netsettings.jobs.remove(netsettings.active_job_index)
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
return self.execute(context)
|
||||||
|
|
||||||
|
@rnaType
|
||||||
class RENDER_OT_netclientcancelall(bpy.types.Operator):
|
class RENDER_OT_netclientcancelall(bpy.types.Operator):
|
||||||
'''Cancel all running network rendering jobs.'''
|
'''Cancel all running network rendering jobs.'''
|
||||||
bl_idname = "render.netclientcancelall"
|
bl_idname = "render.netclientcancelall"
|
||||||
bl_label = "Client Cancel All"
|
bl_label = "Client Cancel All"
|
||||||
|
|
||||||
def poll(self, context):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
netsettings = context.scene.network_render
|
|
||||||
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
|
||||||
|
|
||||||
if conn:
|
|
||||||
conn.request("POST", "/clear")
|
|
||||||
|
|
||||||
response = conn.getresponse()
|
|
||||||
print( response.status, response.reason )
|
|
||||||
|
|
||||||
while(len(netsettings.jobs) > 0):
|
|
||||||
netsettings.jobs.remove(0)
|
|
||||||
|
|
||||||
return ('FINISHED',)
|
def poll(self, context):
|
||||||
|
return True
|
||||||
def invoke(self, context, event):
|
|
||||||
return self.execute(context)
|
|
||||||
|
|
||||||
@rnaOperator
|
def execute(self, context):
|
||||||
|
netsettings = context.scene.network_render
|
||||||
|
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
||||||
|
|
||||||
|
if conn:
|
||||||
|
conn.request("POST", "/clear")
|
||||||
|
|
||||||
|
response = conn.getresponse()
|
||||||
|
print( response.status, response.reason )
|
||||||
|
|
||||||
|
while(len(netsettings.jobs) > 0):
|
||||||
|
netsettings.jobs.remove(0)
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
return self.execute(context)
|
||||||
|
|
||||||
|
@rnaType
|
||||||
class netclientdownload(bpy.types.Operator):
|
class netclientdownload(bpy.types.Operator):
|
||||||
'''Download render results from the network'''
|
'''Download render results from the network'''
|
||||||
bl_idname = "render.netclientdownload"
|
bl_idname = "render.netclientdownload"
|
||||||
bl_label = "Client Download"
|
bl_label = "Client Download"
|
||||||
|
|
||||||
def poll(self, context):
|
|
||||||
netsettings = context.scene.network_render
|
|
||||||
return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
netsettings = context.scene.network_render
|
|
||||||
rd = context.scene.render_data
|
|
||||||
|
|
||||||
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
|
||||||
|
|
||||||
if conn:
|
|
||||||
job = netrender.jobs[netsettings.active_job_index]
|
|
||||||
|
|
||||||
for frame in job.frames:
|
|
||||||
client.requestResult(conn, job.id, frame.number)
|
|
||||||
response = conn.getresponse()
|
|
||||||
|
|
||||||
if response.status != http.client.OK:
|
|
||||||
print("missing", frame.number)
|
|
||||||
continue
|
|
||||||
|
|
||||||
print("got back", frame.number)
|
|
||||||
|
|
||||||
f = open(netsettings.path + "%06d" % frame.number + ".exr", "wb")
|
|
||||||
buf = response.read(1024)
|
|
||||||
|
|
||||||
while buf:
|
|
||||||
f.write(buf)
|
|
||||||
buf = response.read(1024)
|
|
||||||
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
return ('FINISHED',)
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
return self.execute(context)
|
|
||||||
|
|
||||||
@rnaOperator
|
def poll(self, context):
|
||||||
|
netsettings = context.scene.network_render
|
||||||
|
return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
netsettings = context.scene.network_render
|
||||||
|
rd = context.scene.render_data
|
||||||
|
|
||||||
|
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
||||||
|
|
||||||
|
if conn:
|
||||||
|
job = netrender.jobs[netsettings.active_job_index]
|
||||||
|
|
||||||
|
for frame in job.frames:
|
||||||
|
client.requestResult(conn, job.id, frame.number)
|
||||||
|
response = conn.getresponse()
|
||||||
|
|
||||||
|
if response.status != http.client.OK:
|
||||||
|
print("missing", frame.number)
|
||||||
|
continue
|
||||||
|
|
||||||
|
print("got back", frame.number)
|
||||||
|
|
||||||
|
f = open(netsettings.path + "%06d" % frame.number + ".exr", "wb")
|
||||||
|
buf = response.read(1024)
|
||||||
|
|
||||||
|
while buf:
|
||||||
|
f.write(buf)
|
||||||
|
buf = response.read(1024)
|
||||||
|
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
return self.execute(context)
|
||||||
|
|
||||||
|
@rnaType
|
||||||
class netclientscan(bpy.types.Operator):
|
class netclientscan(bpy.types.Operator):
|
||||||
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
|
__slots__ = []
|
||||||
bl_idname = "render.netclientscan"
|
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
|
||||||
bl_label = "Client Scan"
|
bl_idname = "render.netclientscan"
|
||||||
|
bl_label = "Client Scan"
|
||||||
def poll(self, context):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
address, port = clientScan(self.report)
|
|
||||||
|
|
||||||
if address:
|
def poll(self, context):
|
||||||
scene = context.scene
|
return True
|
||||||
netsettings = scene.network_render
|
|
||||||
netsettings.server_address = address
|
|
||||||
netsettings.server_port = port
|
|
||||||
|
|
||||||
return ('FINISHED',)
|
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def execute(self, context):
|
||||||
return self.execute(context)
|
address, port = clientScan(self.report)
|
||||||
|
|
||||||
@rnaOperator
|
if address:
|
||||||
|
scene = context.scene
|
||||||
|
netsettings = scene.network_render
|
||||||
|
netsettings.server_address = address
|
||||||
|
netsettings.server_port = port
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
print(dir(self))
|
||||||
|
return self.execute(context)
|
||||||
|
|
||||||
|
@rnaType
|
||||||
class netclientweb(bpy.types.Operator):
|
class netclientweb(bpy.types.Operator):
|
||||||
'''Open new window with information about running rendering jobs'''
|
'''Open new window with information about running rendering jobs'''
|
||||||
bl_idname = "render.netclientweb"
|
bl_idname = "render.netclientweb"
|
||||||
bl_label = "Open Master Monitor"
|
bl_label = "Open Master Monitor"
|
||||||
|
|
||||||
def poll(self, context):
|
def poll(self, context):
|
||||||
return True
|
netsettings = context.scene.network_render
|
||||||
|
return netsettings.server_address != "[default]"
|
||||||
def execute(self, context):
|
|
||||||
netsettings = context.scene.network_render
|
def execute(self, context):
|
||||||
|
netsettings = context.scene.network_render
|
||||||
|
|
||||||
# open connection to make sure server exists
|
|
||||||
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
# open connection to make sure server exists
|
||||||
|
conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
|
||||||
if conn:
|
|
||||||
conn.close()
|
if conn:
|
||||||
|
conn.close()
|
||||||
webbrowser.open("http://%s:%i" % (netsettings.server_address, netsettings.server_port))
|
|
||||||
|
webbrowser.open("http://%s:%i" % (netsettings.server_address, netsettings.server_port))
|
||||||
return ('FINISHED',)
|
|
||||||
|
return {'FINISHED'}
|
||||||
def invoke(self, context, event):
|
|
||||||
return self.execute(context)
|
def invoke(self, context, event):
|
||||||
|
return self.execute(context)
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
@@ -30,218 +30,218 @@ MAX_TIMEOUT = 10
|
|||||||
INCREMENT_TIMEOUT = 1
|
INCREMENT_TIMEOUT = 1
|
||||||
|
|
||||||
if platform.system() == 'Windows' and platform.version() >= '5': # Error mode is only available on Win2k or higher, that's version 5
|
if platform.system() == 'Windows' and platform.version() >= '5': # Error mode is only available on Win2k or higher, that's version 5
|
||||||
import ctypes
|
import ctypes
|
||||||
def SetErrorMode():
|
def SetErrorMode():
|
||||||
val = ctypes.windll.kernel32.SetErrorMode(0x0002)
|
val = ctypes.windll.kernel32.SetErrorMode(0x0002)
|
||||||
ctypes.windll.kernel32.SetErrorMode(val | 0x0002)
|
ctypes.windll.kernel32.SetErrorMode(val | 0x0002)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def RestoreErrorMode(val):
|
def RestoreErrorMode(val):
|
||||||
ctypes.windll.kernel32.SetErrorMode(val)
|
ctypes.windll.kernel32.SetErrorMode(val)
|
||||||
else:
|
else:
|
||||||
def SetErrorMode():
|
def SetErrorMode():
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def RestoreErrorMode(val):
|
def RestoreErrorMode(val):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def slave_Info():
|
def slave_Info():
|
||||||
sysname, nodename, release, version, machine, processor = platform.uname()
|
sysname, nodename, release, version, machine, processor = platform.uname()
|
||||||
slave = netrender.model.RenderSlave()
|
slave = netrender.model.RenderSlave()
|
||||||
slave.name = nodename
|
slave.name = nodename
|
||||||
slave.stats = sysname + " " + release + " " + machine + " " + processor
|
slave.stats = sysname + " " + release + " " + machine + " " + processor
|
||||||
return slave
|
return slave
|
||||||
|
|
||||||
def testCancel(conn, job_id, frame_number):
|
def testCancel(conn, job_id, frame_number):
|
||||||
conn.request("HEAD", "/status", headers={"job-id":job_id, "job-frame": str(frame_number)})
|
conn.request("HEAD", "/status", headers={"job-id":job_id, "job-frame": str(frame_number)})
|
||||||
|
|
||||||
# cancelled if job isn't found anymore
|
# cancelled if job isn't found anymore
|
||||||
if conn.getresponse().status == http.client.NO_CONTENT:
|
if conn.getresponse().status == http.client.NO_CONTENT:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def testFile(conn, job_id, slave_id, file_index, JOB_PREFIX, file_path, main_path = None):
|
def testFile(conn, job_id, slave_id, file_index, JOB_PREFIX, file_path, main_path = None):
|
||||||
job_full_path = prefixPath(JOB_PREFIX, file_path, main_path)
|
job_full_path = prefixPath(JOB_PREFIX, file_path, main_path)
|
||||||
|
|
||||||
if not os.path.exists(job_full_path):
|
if not os.path.exists(job_full_path):
|
||||||
temp_path = JOB_PREFIX + "slave.temp.blend"
|
temp_path = JOB_PREFIX + "slave.temp.blend"
|
||||||
conn.request("GET", fileURL(job_id, file_index), headers={"slave-id":slave_id})
|
conn.request("GET", fileURL(job_id, file_index), headers={"slave-id":slave_id})
|
||||||
response = conn.getresponse()
|
response = conn.getresponse()
|
||||||
|
|
||||||
if response.status != http.client.OK:
|
if response.status != http.client.OK:
|
||||||
return None # file for job not returned by server, need to return an error code to server
|
return None # file for job not returned by server, need to return an error code to server
|
||||||
|
|
||||||
f = open(temp_path, "wb")
|
f = open(temp_path, "wb")
|
||||||
buf = response.read(1024)
|
buf = response.read(1024)
|
||||||
|
|
||||||
while buf:
|
while buf:
|
||||||
f.write(buf)
|
f.write(buf)
|
||||||
buf = response.read(1024)
|
buf = response.read(1024)
|
||||||
|
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
os.renames(temp_path, job_full_path)
|
os.renames(temp_path, job_full_path)
|
||||||
|
|
||||||
return job_full_path
|
return job_full_path
|
||||||
|
|
||||||
def render_slave(engine, netsettings):
|
def render_slave(engine, netsettings):
|
||||||
timeout = 1
|
timeout = 1
|
||||||
|
|
||||||
engine.update_stats("", "Network render node initiation")
|
|
||||||
|
|
||||||
conn = clientConnection(netsettings.server_address, netsettings.server_port)
|
|
||||||
|
|
||||||
if conn:
|
|
||||||
conn.request("POST", "/slave", repr(slave_Info().serialize()))
|
|
||||||
response = conn.getresponse()
|
|
||||||
|
|
||||||
slave_id = response.getheader("slave-id")
|
|
||||||
|
|
||||||
NODE_PREFIX = netsettings.path + "slave_" + slave_id + os.sep
|
|
||||||
if not os.path.exists(NODE_PREFIX):
|
|
||||||
os.mkdir(NODE_PREFIX)
|
|
||||||
|
|
||||||
while not engine.test_break():
|
|
||||||
|
|
||||||
conn.request("GET", "/job", headers={"slave-id":slave_id})
|
|
||||||
response = conn.getresponse()
|
|
||||||
|
|
||||||
if response.status == http.client.OK:
|
|
||||||
timeout = 1 # reset timeout on new job
|
|
||||||
|
|
||||||
job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8')))
|
|
||||||
|
|
||||||
JOB_PREFIX = NODE_PREFIX + "job_" + job.id + os.sep
|
|
||||||
if not os.path.exists(JOB_PREFIX):
|
|
||||||
os.mkdir(JOB_PREFIX)
|
|
||||||
|
|
||||||
|
|
||||||
if job.type == netrender.model.JOB_BLENDER:
|
|
||||||
job_path = job.files[0].filepath # path of main file
|
|
||||||
main_path, main_file = os.path.split(job_path)
|
|
||||||
|
|
||||||
job_full_path = testFile(conn, job.id, slave_id, 0, JOB_PREFIX, job_path)
|
|
||||||
print("Fullpath", job_full_path)
|
|
||||||
print("File:", main_file, "and %i other files" % (len(job.files) - 1,))
|
|
||||||
engine.update_stats("", "Render File "+ main_file+ " for job "+ job.id)
|
|
||||||
|
|
||||||
for rfile in job.files[1:]:
|
|
||||||
print("\t", rfile.filepath)
|
|
||||||
testFile(conn, job.id, slave_id, rfile.index, JOB_PREFIX, rfile.filepath, main_path)
|
|
||||||
|
|
||||||
# announce log to master
|
engine.update_stats("", "Network render node initiation")
|
||||||
logfile = netrender.model.LogFile(job.id, slave_id, [frame.number for frame in job.frames])
|
|
||||||
conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'))
|
conn = clientConnection(netsettings.server_address, netsettings.server_port)
|
||||||
response = conn.getresponse()
|
|
||||||
|
if conn:
|
||||||
|
conn.request("POST", "/slave", repr(slave_Info().serialize()))
|
||||||
first_frame = job.frames[0].number
|
response = conn.getresponse()
|
||||||
|
|
||||||
# start render
|
slave_id = response.getheader("slave-id")
|
||||||
start_t = time.time()
|
|
||||||
|
NODE_PREFIX = netsettings.path + "slave_" + slave_id + os.sep
|
||||||
if job.type == netrender.model.JOB_BLENDER:
|
if not os.path.exists(NODE_PREFIX):
|
||||||
frame_args = []
|
os.mkdir(NODE_PREFIX)
|
||||||
|
|
||||||
for frame in job.frames:
|
while not engine.test_break():
|
||||||
print("frame", frame.number)
|
|
||||||
frame_args += ["-f", str(frame.number)]
|
conn.request("GET", "/job", headers={"slave-id":slave_id})
|
||||||
|
response = conn.getresponse()
|
||||||
val = SetErrorMode()
|
|
||||||
process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
if response.status == http.client.OK:
|
||||||
RestoreErrorMode(val)
|
timeout = 1 # reset timeout on new job
|
||||||
elif job.type == netrender.model.JOB_PROCESS:
|
|
||||||
command = job.frames[0].command
|
job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8')))
|
||||||
val = SetErrorMode()
|
|
||||||
process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
JOB_PREFIX = NODE_PREFIX + "job_" + job.id + os.sep
|
||||||
RestoreErrorMode(val)
|
if not os.path.exists(JOB_PREFIX):
|
||||||
|
os.mkdir(JOB_PREFIX)
|
||||||
headers = {"slave-id":slave_id}
|
|
||||||
|
|
||||||
cancelled = False
|
if job.type == netrender.model.JOB_BLENDER:
|
||||||
stdout = bytes()
|
job_path = job.files[0].filepath # path of main file
|
||||||
run_t = time.time()
|
main_path, main_file = os.path.split(job_path)
|
||||||
while process.poll() == None and not cancelled:
|
|
||||||
stdout += process.stdout.read(32)
|
job_full_path = testFile(conn, job.id, slave_id, 0, JOB_PREFIX, job_path)
|
||||||
current_t = time.time()
|
print("Fullpath", job_full_path)
|
||||||
cancelled = engine.test_break()
|
print("File:", main_file, "and %i other files" % (len(job.files) - 1,))
|
||||||
if current_t - run_t > CANCEL_POLL_SPEED:
|
engine.update_stats("", "Render File "+ main_file+ " for job "+ job.id)
|
||||||
|
|
||||||
# update logs if needed
|
for rfile in job.files[1:]:
|
||||||
if stdout:
|
print("\t", rfile.filepath)
|
||||||
# (only need to update on one frame, they are linked
|
testFile(conn, job.id, slave_id, rfile.index, JOB_PREFIX, rfile.filepath, main_path)
|
||||||
conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
|
|
||||||
response = conn.getresponse()
|
# announce log to master
|
||||||
|
logfile = netrender.model.LogFile(job.id, slave_id, [frame.number for frame in job.frames])
|
||||||
stdout = bytes()
|
conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'))
|
||||||
|
response = conn.getresponse()
|
||||||
run_t = current_t
|
|
||||||
if testCancel(conn, job.id, first_frame):
|
|
||||||
cancelled = True
|
first_frame = job.frames[0].number
|
||||||
|
|
||||||
# read leftovers if needed
|
# start render
|
||||||
stdout += process.stdout.read()
|
start_t = time.time()
|
||||||
|
|
||||||
if cancelled:
|
if job.type == netrender.model.JOB_BLENDER:
|
||||||
# kill process if needed
|
frame_args = []
|
||||||
if process.poll() == None:
|
|
||||||
process.terminate()
|
for frame in job.frames:
|
||||||
continue # to next frame
|
print("frame", frame.number)
|
||||||
|
frame_args += ["-f", str(frame.number)]
|
||||||
total_t = time.time() - start_t
|
|
||||||
|
val = SetErrorMode()
|
||||||
avg_t = total_t / len(job.frames)
|
process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
|
RestoreErrorMode(val)
|
||||||
status = process.returncode
|
elif job.type == netrender.model.JOB_PROCESS:
|
||||||
|
command = job.frames[0].command
|
||||||
print("status", status)
|
val = SetErrorMode()
|
||||||
|
process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
# flush the rest of the logs
|
RestoreErrorMode(val)
|
||||||
if stdout:
|
|
||||||
# (only need to update on one frame, they are linked
|
headers = {"slave-id":slave_id}
|
||||||
conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
|
|
||||||
if conn.getresponse().status == http.client.NO_CONTENT:
|
cancelled = False
|
||||||
continue
|
stdout = bytes()
|
||||||
|
run_t = time.time()
|
||||||
headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)}
|
while process.poll() == None and not cancelled:
|
||||||
|
stdout += process.stdout.read(32)
|
||||||
|
current_t = time.time()
|
||||||
if status == 0: # non zero status is error
|
cancelled = engine.test_break()
|
||||||
headers["job-result"] = str(DONE)
|
if current_t - run_t > CANCEL_POLL_SPEED:
|
||||||
for frame in job.frames:
|
|
||||||
headers["job-frame"] = str(frame.number)
|
# update logs if needed
|
||||||
|
if stdout:
|
||||||
if job.type == netrender.model.JOB_BLENDER:
|
# (only need to update on one frame, they are linked
|
||||||
# send image back to server
|
conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
|
||||||
f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb')
|
response = conn.getresponse()
|
||||||
conn.request("PUT", "/render", f, headers=headers)
|
|
||||||
f.close()
|
stdout = bytes()
|
||||||
if conn.getresponse().status == http.client.NO_CONTENT:
|
|
||||||
continue
|
run_t = current_t
|
||||||
elif job.type == netrender.model.JOB_PROCESS:
|
if testCancel(conn, job.id, first_frame):
|
||||||
conn.request("PUT", "/render", headers=headers)
|
cancelled = True
|
||||||
if conn.getresponse().status == http.client.NO_CONTENT:
|
|
||||||
continue
|
# read leftovers if needed
|
||||||
else:
|
stdout += process.stdout.read()
|
||||||
headers["job-result"] = str(ERROR)
|
|
||||||
for frame in job.frames:
|
if cancelled:
|
||||||
headers["job-frame"] = str(frame.number)
|
# kill process if needed
|
||||||
# send error result back to server
|
if process.poll() == None:
|
||||||
conn.request("PUT", "/render", headers=headers)
|
process.terminate()
|
||||||
if conn.getresponse().status == http.client.NO_CONTENT:
|
continue # to next frame
|
||||||
continue
|
|
||||||
else:
|
total_t = time.time() - start_t
|
||||||
if timeout < MAX_TIMEOUT:
|
|
||||||
timeout += INCREMENT_TIMEOUT
|
avg_t = total_t / len(job.frames)
|
||||||
|
|
||||||
for i in range(timeout):
|
status = process.returncode
|
||||||
time.sleep(1)
|
|
||||||
if engine.test_break():
|
print("status", status)
|
||||||
conn.close()
|
|
||||||
return
|
# flush the rest of the logs
|
||||||
|
if stdout:
|
||||||
conn.close()
|
# (only need to update on one frame, they are linked
|
||||||
|
conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
|
||||||
|
if conn.getresponse().status == http.client.NO_CONTENT:
|
||||||
|
continue
|
||||||
|
|
||||||
|
headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)}
|
||||||
|
|
||||||
|
|
||||||
|
if status == 0: # non zero status is error
|
||||||
|
headers["job-result"] = str(DONE)
|
||||||
|
for frame in job.frames:
|
||||||
|
headers["job-frame"] = str(frame.number)
|
||||||
|
|
||||||
|
if job.type == netrender.model.JOB_BLENDER:
|
||||||
|
# send image back to server
|
||||||
|
f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb')
|
||||||
|
conn.request("PUT", "/render", f, headers=headers)
|
||||||
|
f.close()
|
||||||
|
if conn.getresponse().status == http.client.NO_CONTENT:
|
||||||
|
continue
|
||||||
|
elif job.type == netrender.model.JOB_PROCESS:
|
||||||
|
conn.request("PUT", "/render", headers=headers)
|
||||||
|
if conn.getresponse().status == http.client.NO_CONTENT:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
headers["job-result"] = str(ERROR)
|
||||||
|
for frame in job.frames:
|
||||||
|
headers["job-frame"] = str(frame.number)
|
||||||
|
# send error result back to server
|
||||||
|
conn.request("PUT", "/render", headers=headers)
|
||||||
|
if conn.getresponse().status == http.client.NO_CONTENT:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if timeout < MAX_TIMEOUT:
|
||||||
|
timeout += INCREMENT_TIMEOUT
|
||||||
|
|
||||||
|
for i in range(timeout):
|
||||||
|
time.sleep(1)
|
||||||
|
if engine.test_break():
|
||||||
|
conn.close()
|
||||||
|
return
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
@@ -37,318 +37,319 @@ DONE = 2
|
|||||||
ERROR = 3
|
ERROR = 3
|
||||||
|
|
||||||
class RenderButtonsPanel(bpy.types.Panel):
|
class RenderButtonsPanel(bpy.types.Panel):
|
||||||
bl_space_type = "PROPERTIES"
|
bl_space_type = "PROPERTIES"
|
||||||
bl_region_type = "WINDOW"
|
bl_region_type = "WINDOW"
|
||||||
bl_context = "render"
|
bl_context = "render"
|
||||||
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
|
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
|
||||||
|
|
||||||
def poll(self, context):
|
def poll(self, context):
|
||||||
rd = context.scene.render_data
|
rd = context.scene.render_data
|
||||||
return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES)
|
return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES)
|
||||||
|
|
||||||
# Setting panel, use in the scene for now.
|
# Setting panel, use in the scene for now.
|
||||||
@rnaType
|
@rnaType
|
||||||
class RENDER_PT_network_settings(RenderButtonsPanel):
|
class RENDER_PT_network_settings(RenderButtonsPanel):
|
||||||
bl_label = "Network Settings"
|
bl_label = "Network Settings"
|
||||||
COMPAT_ENGINES = {'NET_RENDER'}
|
COMPAT_ENGINES = {'NET_RENDER'}
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
rd = scene.render_data
|
rd = scene.render_data
|
||||||
|
|
||||||
layout.active = True
|
|
||||||
|
|
||||||
split = layout.split()
|
|
||||||
|
|
||||||
col = split.column()
|
|
||||||
|
|
||||||
|
layout.active = True
|
||||||
if scene.network_render.mode in ("RENDER_MASTER", "RENDER_SLAVE"):
|
|
||||||
col.operator("screen.render", text="Start", icon='PLAY').animation = True
|
|
||||||
|
|
||||||
col.prop(scene.network_render, "mode")
|
split = layout.split()
|
||||||
col.prop(scene.network_render, "path")
|
|
||||||
col.prop(scene.network_render, "server_address")
|
col = split.column()
|
||||||
col.prop(scene.network_render, "server_port")
|
|
||||||
|
|
||||||
if scene.network_render.mode == "RENDER_MASTER":
|
if scene.network_render.mode in ("RENDER_MASTER", "RENDER_SLAVE"):
|
||||||
col.prop(scene.network_render, "server_broadcast")
|
col.operator("screen.render", text="Start", icon='PLAY').animation = True
|
||||||
else:
|
|
||||||
col.operator("render.netclientscan", icon='FILE_REFRESH', text="")
|
col.prop(scene.network_render, "mode")
|
||||||
|
col.prop(scene.network_render, "path")
|
||||||
|
col.prop(scene.network_render, "server_address")
|
||||||
|
col.prop(scene.network_render, "server_port")
|
||||||
|
|
||||||
|
if scene.network_render.mode == "RENDER_MASTER":
|
||||||
|
col.prop(scene.network_render, "server_broadcast")
|
||||||
|
else:
|
||||||
|
col.operator("render.netclientscan", icon='FILE_REFRESH', text="")
|
||||||
|
|
||||||
|
col.operator("render.netclientweb", icon='QUESTION')
|
||||||
|
|
||||||
@rnaType
|
@rnaType
|
||||||
class RENDER_PT_network_job(RenderButtonsPanel):
|
class RENDER_PT_network_job(RenderButtonsPanel):
|
||||||
bl_label = "Job Settings"
|
bl_label = "Job Settings"
|
||||||
COMPAT_ENGINES = {'NET_RENDER'}
|
COMPAT_ENGINES = {'NET_RENDER'}
|
||||||
|
|
||||||
def poll(self, context):
|
|
||||||
scene = context.scene
|
|
||||||
return (super().poll(context)
|
|
||||||
and scene.network_render.mode == "RENDER_CLIENT")
|
|
||||||
|
|
||||||
def draw(self, context):
|
def poll(self, context):
|
||||||
layout = self.layout
|
scene = context.scene
|
||||||
|
return (super().poll(context)
|
||||||
|
and scene.network_render.mode == "RENDER_CLIENT")
|
||||||
|
|
||||||
scene = context.scene
|
def draw(self, context):
|
||||||
rd = scene.render_data
|
layout = self.layout
|
||||||
|
|
||||||
layout.active = True
|
scene = context.scene
|
||||||
|
rd = scene.render_data
|
||||||
split = layout.split()
|
|
||||||
|
layout.active = True
|
||||||
col = split.column()
|
|
||||||
if scene.network_render.server_address != "[default]":
|
split = layout.split()
|
||||||
col.operator("render.netclientanim", icon='RENDER_ANIMATION')
|
|
||||||
col.operator("render.netclientsend", icon='FILE_BLEND')
|
col = split.column()
|
||||||
if scene.network_render.job_id:
|
if scene.network_render.server_address != "[default]":
|
||||||
col.operator("screen.render", text="Get Results", icon='RENDER_ANIMATION').animation = True
|
col.operator("render.netclientanim", icon='RENDER_ANIMATION')
|
||||||
col.operator("render.netclientweb", icon='QUESTION')
|
col.operator("render.netclientsend", icon='FILE_BLEND')
|
||||||
col.prop(scene.network_render, "job_name")
|
if scene.network_render.job_id:
|
||||||
col.prop(scene.network_render, "job_category")
|
col.operator("screen.render", text="Get Results", icon='RENDER_ANIMATION').animation = True
|
||||||
row = col.row()
|
col.prop(scene.network_render, "job_name")
|
||||||
row.prop(scene.network_render, "priority")
|
col.prop(scene.network_render, "job_category")
|
||||||
row.prop(scene.network_render, "chunks")
|
row = col.row()
|
||||||
|
row.prop(scene.network_render, "priority")
|
||||||
|
row.prop(scene.network_render, "chunks")
|
||||||
|
|
||||||
@rnaType
|
@rnaType
|
||||||
class RENDER_PT_network_slaves(RenderButtonsPanel):
|
class RENDER_PT_network_slaves(RenderButtonsPanel):
|
||||||
bl_label = "Slaves Status"
|
bl_label = "Slaves Status"
|
||||||
COMPAT_ENGINES = {'NET_RENDER'}
|
COMPAT_ENGINES = {'NET_RENDER'}
|
||||||
|
|
||||||
def poll(self, context):
|
|
||||||
scene = context.scene
|
|
||||||
return (super().poll(context)
|
|
||||||
and scene.network_render.mode == "RENDER_CLIENT"
|
|
||||||
and scene.network_render.server_address != "[default]")
|
|
||||||
|
|
||||||
def draw(self, context):
|
def poll(self, context):
|
||||||
layout = self.layout
|
scene = context.scene
|
||||||
|
return (super().poll(context)
|
||||||
scene = context.scene
|
and scene.network_render.mode == "RENDER_CLIENT"
|
||||||
netsettings = scene.network_render
|
and scene.network_render.server_address != "[default]")
|
||||||
|
|
||||||
row = layout.row()
|
def draw(self, context):
|
||||||
row.template_list(netsettings, "slaves", netsettings, "active_slave_index", rows=2)
|
layout = self.layout
|
||||||
|
|
||||||
sub = row.column(align=True)
|
scene = context.scene
|
||||||
sub.operator("render.netclientslaves", icon='FILE_REFRESH', text="")
|
netsettings = scene.network_render
|
||||||
sub.operator("render.netclientblacklistslave", icon='ZOOMOUT', text="")
|
|
||||||
|
|
||||||
if len(netrender.slaves) == 0 and len(netsettings.slaves) > 0:
|
|
||||||
while(len(netsettings.slaves) > 0):
|
|
||||||
netsettings.slaves.remove(0)
|
|
||||||
|
|
||||||
if netsettings.active_slave_index >= 0 and len(netsettings.slaves) > 0:
|
|
||||||
layout.separator()
|
|
||||||
|
|
||||||
slave = netrender.slaves[netsettings.active_slave_index]
|
|
||||||
|
|
||||||
layout.label(text="Name: " + slave.name)
|
row = layout.row()
|
||||||
layout.label(text="Address: " + slave.address[0])
|
row.template_list(netsettings, "slaves", netsettings, "active_slave_index", rows=2)
|
||||||
layout.label(text="Seen: " + time.ctime(slave.last_seen))
|
|
||||||
layout.label(text="Stats: " + slave.stats)
|
sub = row.column(align=True)
|
||||||
|
sub.operator("render.netclientslaves", icon='FILE_REFRESH', text="")
|
||||||
|
sub.operator("render.netclientblacklistslave", icon='ZOOMOUT', text="")
|
||||||
|
|
||||||
|
if len(netrender.slaves) == 0 and len(netsettings.slaves) > 0:
|
||||||
|
while(len(netsettings.slaves) > 0):
|
||||||
|
netsettings.slaves.remove(0)
|
||||||
|
|
||||||
|
if netsettings.active_slave_index >= 0 and len(netsettings.slaves) > 0:
|
||||||
|
layout.separator()
|
||||||
|
|
||||||
|
slave = netrender.slaves[netsettings.active_slave_index]
|
||||||
|
|
||||||
|
layout.label(text="Name: " + slave.name)
|
||||||
|
layout.label(text="Address: " + slave.address[0])
|
||||||
|
layout.label(text="Seen: " + time.ctime(slave.last_seen))
|
||||||
|
layout.label(text="Stats: " + slave.stats)
|
||||||
|
|
||||||
@rnaType
|
@rnaType
|
||||||
class RENDER_PT_network_slaves_blacklist(RenderButtonsPanel):
|
class RENDER_PT_network_slaves_blacklist(RenderButtonsPanel):
|
||||||
bl_label = "Slaves Blacklist"
|
bl_label = "Slaves Blacklist"
|
||||||
COMPAT_ENGINES = {'NET_RENDER'}
|
COMPAT_ENGINES = {'NET_RENDER'}
|
||||||
|
|
||||||
def poll(self, context):
|
|
||||||
scene = context.scene
|
|
||||||
return (super().poll(context)
|
|
||||||
and scene.network_render.mode == "RENDER_CLIENT"
|
|
||||||
and scene.network_render.server_address != "[default]")
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
|
|
||||||
scene = context.scene
|
|
||||||
netsettings = scene.network_render
|
|
||||||
|
|
||||||
row = layout.row()
|
def poll(self, context):
|
||||||
row.template_list(netsettings, "slaves_blacklist", netsettings, "active_blacklisted_slave_index", rows=2)
|
scene = context.scene
|
||||||
|
return (super().poll(context)
|
||||||
|
and scene.network_render.mode == "RENDER_CLIENT"
|
||||||
|
and scene.network_render.server_address != "[default]")
|
||||||
|
|
||||||
sub = row.column(align=True)
|
def draw(self, context):
|
||||||
sub.operator("render.netclientwhitelistslave", icon='ZOOMOUT', text="")
|
layout = self.layout
|
||||||
|
|
||||||
if len(netrender.blacklist) == 0 and len(netsettings.slaves_blacklist) > 0:
|
scene = context.scene
|
||||||
while(len(netsettings.slaves_blacklist) > 0):
|
netsettings = scene.network_render
|
||||||
netsettings.slaves_blacklist.remove(0)
|
|
||||||
|
|
||||||
if netsettings.active_blacklisted_slave_index >= 0 and len(netsettings.slaves_blacklist) > 0:
|
|
||||||
layout.separator()
|
|
||||||
|
|
||||||
slave = netrender.blacklist[netsettings.active_blacklisted_slave_index]
|
|
||||||
|
|
||||||
layout.label(text="Name: " + slave.name)
|
row = layout.row()
|
||||||
layout.label(text="Address: " + slave.address[0])
|
row.template_list(netsettings, "slaves_blacklist", netsettings, "active_blacklisted_slave_index", rows=2)
|
||||||
layout.label(text="Seen: " + time.ctime(slave.last_seen))
|
|
||||||
layout.label(text="Stats: " + slave.stats)
|
sub = row.column(align=True)
|
||||||
|
sub.operator("render.netclientwhitelistslave", icon='ZOOMOUT', text="")
|
||||||
|
|
||||||
|
if len(netrender.blacklist) == 0 and len(netsettings.slaves_blacklist) > 0:
|
||||||
|
while(len(netsettings.slaves_blacklist) > 0):
|
||||||
|
netsettings.slaves_blacklist.remove(0)
|
||||||
|
|
||||||
|
if netsettings.active_blacklisted_slave_index >= 0 and len(netsettings.slaves_blacklist) > 0:
|
||||||
|
layout.separator()
|
||||||
|
|
||||||
|
slave = netrender.blacklist[netsettings.active_blacklisted_slave_index]
|
||||||
|
|
||||||
|
layout.label(text="Name: " + slave.name)
|
||||||
|
layout.label(text="Address: " + slave.address[0])
|
||||||
|
layout.label(text="Seen: " + time.ctime(slave.last_seen))
|
||||||
|
layout.label(text="Stats: " + slave.stats)
|
||||||
|
|
||||||
@rnaType
|
@rnaType
|
||||||
class RENDER_PT_network_jobs(RenderButtonsPanel):
|
class RENDER_PT_network_jobs(RenderButtonsPanel):
|
||||||
bl_label = "Jobs"
|
bl_label = "Jobs"
|
||||||
COMPAT_ENGINES = {'NET_RENDER'}
|
COMPAT_ENGINES = {'NET_RENDER'}
|
||||||
|
|
||||||
def poll(self, context):
|
|
||||||
scene = context.scene
|
|
||||||
return (super().poll(context)
|
|
||||||
and scene.network_render.mode == "RENDER_CLIENT"
|
|
||||||
and scene.network_render.server_address != "[default]")
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
|
|
||||||
scene = context.scene
|
|
||||||
netsettings = scene.network_render
|
|
||||||
|
|
||||||
row = layout.row()
|
def poll(self, context):
|
||||||
row.template_list(netsettings, "jobs", netsettings, "active_job_index", rows=2)
|
scene = context.scene
|
||||||
|
return (super().poll(context)
|
||||||
|
and scene.network_render.mode == "RENDER_CLIENT"
|
||||||
|
and scene.network_render.server_address != "[default]")
|
||||||
|
|
||||||
sub = row.column(align=True)
|
def draw(self, context):
|
||||||
sub.operator("render.netclientstatus", icon='FILE_REFRESH', text="")
|
layout = self.layout
|
||||||
sub.operator("render.netclientcancel", icon='ZOOMOUT', text="")
|
|
||||||
sub.operator("render.netclientcancelall", icon='PANEL_CLOSE', text="")
|
|
||||||
sub.operator("render.netclientdownload", icon='RENDER_ANIMATION', text="")
|
|
||||||
|
|
||||||
if len(netrender.jobs) == 0 and len(netsettings.jobs) > 0:
|
scene = context.scene
|
||||||
while(len(netsettings.jobs) > 0):
|
netsettings = scene.network_render
|
||||||
netsettings.jobs.remove(0)
|
|
||||||
|
|
||||||
if netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0:
|
|
||||||
layout.separator()
|
|
||||||
|
|
||||||
job = netrender.jobs[netsettings.active_job_index]
|
|
||||||
|
|
||||||
layout.label(text="Name: %s" % job.name)
|
row = layout.row()
|
||||||
layout.label(text="Length: %04i" % len(job))
|
row.template_list(netsettings, "jobs", netsettings, "active_job_index", rows=2)
|
||||||
layout.label(text="Done: %04i" % job.results[DONE])
|
|
||||||
layout.label(text="Error: %04i" % job.results[ERROR])
|
sub = row.column(align=True)
|
||||||
|
sub.operator("render.netclientstatus", icon='FILE_REFRESH', text="")
|
||||||
|
sub.operator("render.netclientcancel", icon='ZOOMOUT', text="")
|
||||||
|
sub.operator("render.netclientcancelall", icon='PANEL_CLOSE', text="")
|
||||||
|
sub.operator("render.netclientdownload", icon='RENDER_ANIMATION', text="")
|
||||||
|
|
||||||
|
if len(netrender.jobs) == 0 and len(netsettings.jobs) > 0:
|
||||||
|
while(len(netsettings.jobs) > 0):
|
||||||
|
netsettings.jobs.remove(0)
|
||||||
|
|
||||||
|
if netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0:
|
||||||
|
layout.separator()
|
||||||
|
|
||||||
|
job = netrender.jobs[netsettings.active_job_index]
|
||||||
|
|
||||||
|
layout.label(text="Name: %s" % job.name)
|
||||||
|
layout.label(text="Length: %04i" % len(job))
|
||||||
|
layout.label(text="Done: %04i" % job.results[DONE])
|
||||||
|
layout.label(text="Error: %04i" % job.results[ERROR])
|
||||||
|
|
||||||
@rnaType
|
@rnaType
|
||||||
class NetRenderSettings(bpy.types.IDPropertyGroup):
|
class NetRenderSettings(bpy.types.IDPropertyGroup):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@rnaType
|
@rnaType
|
||||||
class NetRenderSlave(bpy.types.IDPropertyGroup):
|
class NetRenderSlave(bpy.types.IDPropertyGroup):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@rnaType
|
@rnaType
|
||||||
class NetRenderJob(bpy.types.IDPropertyGroup):
|
class NetRenderJob(bpy.types.IDPropertyGroup):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
bpy.types.Scene.PointerProperty(attr="network_render", type=NetRenderSettings, name="Network Render", description="Network Render Settings")
|
bpy.types.Scene.PointerProperty(attr="network_render", type=NetRenderSettings, name="Network Render", description="Network Render Settings")
|
||||||
|
|
||||||
NetRenderSettings.StringProperty( attr="server_address",
|
NetRenderSettings.StringProperty( attr="server_address",
|
||||||
name="Server address",
|
name="Server address",
|
||||||
description="IP or name of the master render server",
|
description="IP or name of the master render server",
|
||||||
maxlen = 128,
|
maxlen = 128,
|
||||||
default = "[default]")
|
default = "[default]")
|
||||||
|
|
||||||
NetRenderSettings.IntProperty( attr="server_port",
|
NetRenderSettings.IntProperty( attr="server_port",
|
||||||
name="Server port",
|
name="Server port",
|
||||||
description="port of the master render server",
|
description="port of the master render server",
|
||||||
default = 8000,
|
default = 8000,
|
||||||
min=1,
|
min=1,
|
||||||
max=65535)
|
max=65535)
|
||||||
|
|
||||||
NetRenderSettings.BoolProperty( attr="server_broadcast",
|
NetRenderSettings.BoolProperty( attr="server_broadcast",
|
||||||
name="Broadcast server address",
|
name="Broadcast server address",
|
||||||
description="broadcast server address on local network",
|
description="broadcast server address on local network",
|
||||||
default = True)
|
default = True)
|
||||||
|
|
||||||
default_path = os.environ.get("TEMP", None)
|
default_path = os.environ.get("TEMP", None)
|
||||||
|
|
||||||
if not default_path:
|
if not default_path:
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
default_path = "c:/tmp/"
|
default_path = "c:/tmp/"
|
||||||
else:
|
else:
|
||||||
default_path = "/tmp/"
|
default_path = "/tmp/"
|
||||||
elif not default_path.endswith(os.sep):
|
elif not default_path.endswith(os.sep):
|
||||||
default_path += os.sep
|
default_path += os.sep
|
||||||
|
|
||||||
NetRenderSettings.StringProperty( attr="path",
|
NetRenderSettings.StringProperty( attr="path",
|
||||||
name="Path",
|
name="Path",
|
||||||
description="Path for temporary files",
|
description="Path for temporary files",
|
||||||
maxlen = 128,
|
maxlen = 128,
|
||||||
default = default_path)
|
default = default_path)
|
||||||
|
|
||||||
NetRenderSettings.StringProperty( attr="job_name",
|
NetRenderSettings.StringProperty( attr="job_name",
|
||||||
name="Job name",
|
name="Job name",
|
||||||
description="Name of the job",
|
description="Name of the job",
|
||||||
maxlen = 128,
|
maxlen = 128,
|
||||||
default = "[default]")
|
default = "[default]")
|
||||||
|
|
||||||
NetRenderSettings.StringProperty( attr="job_category",
|
NetRenderSettings.StringProperty( attr="job_category",
|
||||||
name="Job category",
|
name="Job category",
|
||||||
description="Category of the job",
|
description="Category of the job",
|
||||||
maxlen = 128,
|
maxlen = 128,
|
||||||
default = "")
|
default = "")
|
||||||
|
|
||||||
NetRenderSettings.IntProperty( attr="chunks",
|
NetRenderSettings.IntProperty( attr="chunks",
|
||||||
name="Chunks",
|
name="Chunks",
|
||||||
description="Number of frame to dispatch to each slave in one chunk",
|
description="Number of frame to dispatch to each slave in one chunk",
|
||||||
default = 5,
|
default = 5,
|
||||||
min=1,
|
min=1,
|
||||||
max=65535)
|
max=65535)
|
||||||
|
|
||||||
NetRenderSettings.IntProperty( attr="priority",
|
NetRenderSettings.IntProperty( attr="priority",
|
||||||
name="Priority",
|
name="Priority",
|
||||||
description="Priority of the job",
|
description="Priority of the job",
|
||||||
default = 1,
|
default = 1,
|
||||||
min=1,
|
min=1,
|
||||||
max=10)
|
max=10)
|
||||||
|
|
||||||
NetRenderSettings.StringProperty( attr="job_id",
|
NetRenderSettings.StringProperty( attr="job_id",
|
||||||
name="Network job id",
|
name="Network job id",
|
||||||
description="id of the last sent render job",
|
description="id of the last sent render job",
|
||||||
maxlen = 64,
|
maxlen = 64,
|
||||||
default = "")
|
default = "")
|
||||||
|
|
||||||
NetRenderSettings.IntProperty( attr="active_slave_index",
|
NetRenderSettings.IntProperty( attr="active_slave_index",
|
||||||
name="Index of the active slave",
|
name="Index of the active slave",
|
||||||
description="",
|
description="",
|
||||||
default = -1,
|
default = -1,
|
||||||
min= -1,
|
min= -1,
|
||||||
max=65535)
|
max=65535)
|
||||||
|
|
||||||
NetRenderSettings.IntProperty( attr="active_blacklisted_slave_index",
|
NetRenderSettings.IntProperty( attr="active_blacklisted_slave_index",
|
||||||
name="Index of the active slave",
|
name="Index of the active slave",
|
||||||
description="",
|
description="",
|
||||||
default = -1,
|
default = -1,
|
||||||
min= -1,
|
min= -1,
|
||||||
max=65535)
|
max=65535)
|
||||||
|
|
||||||
NetRenderSettings.IntProperty( attr="active_job_index",
|
NetRenderSettings.IntProperty( attr="active_job_index",
|
||||||
name="Index of the active job",
|
name="Index of the active job",
|
||||||
description="",
|
description="",
|
||||||
default = -1,
|
default = -1,
|
||||||
min= -1,
|
min= -1,
|
||||||
max=65535)
|
max=65535)
|
||||||
|
|
||||||
NetRenderSettings.EnumProperty(attr="mode",
|
NetRenderSettings.EnumProperty(attr="mode",
|
||||||
items=(
|
items=(
|
||||||
("RENDER_CLIENT", "Client", "Act as render client"),
|
("RENDER_CLIENT", "Client", "Act as render client"),
|
||||||
("RENDER_MASTER", "Master", "Act as render master"),
|
("RENDER_MASTER", "Master", "Act as render master"),
|
||||||
("RENDER_SLAVE", "Slave", "Act as render slave"),
|
("RENDER_SLAVE", "Slave", "Act as render slave"),
|
||||||
),
|
),
|
||||||
name="Network mode",
|
name="Network mode",
|
||||||
description="Mode of operation of this instance",
|
description="Mode of operation of this instance",
|
||||||
default="RENDER_CLIENT")
|
default="RENDER_CLIENT")
|
||||||
|
|
||||||
NetRenderSettings.CollectionProperty(attr="slaves", type=NetRenderSlave, name="Slaves", description="")
|
NetRenderSettings.CollectionProperty(attr="slaves", type=NetRenderSlave, name="Slaves", description="")
|
||||||
NetRenderSettings.CollectionProperty(attr="slaves_blacklist", type=NetRenderSlave, name="Slaves Blacklist", description="")
|
NetRenderSettings.CollectionProperty(attr="slaves_blacklist", type=NetRenderSlave, name="Slaves Blacklist", description="")
|
||||||
NetRenderSettings.CollectionProperty(attr="jobs", type=NetRenderJob, name="Job List", description="")
|
NetRenderSettings.CollectionProperty(attr="jobs", type=NetRenderJob, name="Job List", description="")
|
||||||
|
|
||||||
NetRenderSlave.StringProperty( attr="name",
|
NetRenderSlave.StringProperty( attr="name",
|
||||||
name="Name of the slave",
|
name="Name of the slave",
|
||||||
description="",
|
description="",
|
||||||
maxlen = 64,
|
maxlen = 64,
|
||||||
default = "")
|
default = "")
|
||||||
|
|
||||||
NetRenderJob.StringProperty( attr="name",
|
NetRenderJob.StringProperty( attr="name",
|
||||||
name="Name of the job",
|
name="Name of the job",
|
||||||
description="",
|
description="",
|
||||||
maxlen = 128,
|
maxlen = 128,
|
||||||
default = "")
|
default = "")
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
# as published by the Free Software Foundation; either version 2
|
# as published by the Free Software Foundation; either version 2
|
||||||
# of the License, or (at your option) any later version.
|
# of the License, or (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
@@ -51,26 +51,22 @@ DONE = 2
|
|||||||
ERROR = 3
|
ERROR = 3
|
||||||
|
|
||||||
FRAME_STATUS_TEXT = {
|
FRAME_STATUS_TEXT = {
|
||||||
QUEUED: "Queued",
|
QUEUED: "Queued",
|
||||||
DISPATCHED: "Dispatched",
|
DISPATCHED: "Dispatched",
|
||||||
DONE: "Done",
|
DONE: "Done",
|
||||||
ERROR: "Error"
|
ERROR: "Error"
|
||||||
}
|
}
|
||||||
|
|
||||||
def rnaType(rna_type):
|
def rnaType(rna_type):
|
||||||
if bpy: bpy.types.register(rna_type)
|
if bpy: bpy.types.register(rna_type)
|
||||||
return rna_type
|
return rna_type
|
||||||
|
|
||||||
def rnaOperator(rna_op):
|
|
||||||
if bpy: bpy.ops.add(rna_op)
|
|
||||||
return rna_op
|
|
||||||
|
|
||||||
def reporting(report, message, errorType = None):
|
def reporting(report, message, errorType = None):
|
||||||
if errorType:
|
if errorType:
|
||||||
t = 'ERROR'
|
t = 'ERROR'
|
||||||
else:
|
else:
|
||||||
t = 'INFO'
|
t = 'INFO'
|
||||||
|
|
||||||
if report:
|
if report:
|
||||||
report(t, message)
|
report(t, message)
|
||||||
return None
|
return None
|
||||||
@@ -86,14 +82,14 @@ def clientScan(report = None):
|
|||||||
s.settimeout(30)
|
s.settimeout(30)
|
||||||
|
|
||||||
s.bind(('', 8000))
|
s.bind(('', 8000))
|
||||||
|
|
||||||
buf, address = s.recvfrom(64)
|
buf, address = s.recvfrom(64)
|
||||||
|
|
||||||
address = address[0]
|
address = address[0]
|
||||||
port = int(str(buf, encoding='utf8'))
|
port = int(str(buf, encoding='utf8'))
|
||||||
|
|
||||||
reporting(report, "Master server found")
|
reporting(report, "Master server found")
|
||||||
|
|
||||||
return (address, port)
|
return (address, port)
|
||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
reporting(report, "No master server on network", IOError)
|
reporting(report, "No master server on network", IOError)
|
||||||
@@ -109,10 +105,10 @@ def clientConnection(address, port, report = None):
|
|||||||
address, port = clientScan()
|
address, port = clientScan()
|
||||||
if address == "":
|
if address == "":
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
conn = http.client.HTTPConnection(address, port)
|
conn = http.client.HTTPConnection(address, port)
|
||||||
|
|
||||||
if conn:
|
if conn:
|
||||||
if clientVerifyVersion(conn):
|
if clientVerifyVersion(conn):
|
||||||
return conn
|
return conn
|
||||||
@@ -127,21 +123,21 @@ def clientConnection(address, port, report = None):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
def clientVerifyVersion(conn):
|
def clientVerifyVersion(conn):
|
||||||
conn.request("GET", "/version")
|
conn.request("GET", "/version")
|
||||||
response = conn.getresponse()
|
response = conn.getresponse()
|
||||||
|
|
||||||
if response.status != http.client.OK:
|
if response.status != http.client.OK:
|
||||||
conn.close()
|
conn.close()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
server_version = response.read()
|
server_version = response.read()
|
||||||
|
|
||||||
if server_version != VERSION:
|
if server_version != VERSION:
|
||||||
print("Incorrect server version!")
|
print("Incorrect server version!")
|
||||||
print("expected", str(VERSION, encoding='utf8'), "received", str(server_version, encoding='utf8'))
|
print("expected", str(VERSION, encoding='utf8'), "received", str(server_version, encoding='utf8'))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def fileURL(job_id, file_index):
|
def fileURL(job_id, file_index):
|
||||||
return "/file_%s_%i" % (job_id, file_index)
|
return "/file_%s_%i" % (job_id, file_index)
|
||||||
@@ -156,20 +152,20 @@ def cancelURL(job_id):
|
|||||||
return "/cancel_%s" % (job_id)
|
return "/cancel_%s" % (job_id)
|
||||||
|
|
||||||
def prefixPath(prefix_directory, file_path, prefix_path):
|
def prefixPath(prefix_directory, file_path, prefix_path):
|
||||||
if os.path.isabs(file_path):
|
if os.path.isabs(file_path):
|
||||||
# if an absolute path, make sure path exists, if it doesn't, use relative local path
|
# if an absolute path, make sure path exists, if it doesn't, use relative local path
|
||||||
full_path = file_path
|
full_path = file_path
|
||||||
if not os.path.exists(full_path):
|
if not os.path.exists(full_path):
|
||||||
p, n = os.path.split(full_path)
|
p, n = os.path.split(full_path)
|
||||||
|
|
||||||
if prefix_path and p.startswith(prefix_path):
|
if prefix_path and p.startswith(prefix_path):
|
||||||
directory = prefix_directory + p[len(prefix_path):]
|
directory = prefix_directory + p[len(prefix_path):]
|
||||||
full_path = directory + os.sep + n
|
full_path = directory + os.sep + n
|
||||||
if not os.path.exists(directory):
|
if not os.path.exists(directory):
|
||||||
os.mkdir(directory)
|
os.mkdir(directory)
|
||||||
else:
|
else:
|
||||||
full_path = prefix_directory + n
|
full_path = prefix_directory + n
|
||||||
else:
|
else:
|
||||||
full_path = prefix_directory + file_path
|
full_path = prefix_directory + file_path
|
||||||
|
|
||||||
return full_path
|
return full_path
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ def _main():
|
|||||||
# a bit nasty but this prevents help() and input() from locking blender
|
# a bit nasty but this prevents help() and input() from locking blender
|
||||||
# Ideally we could have some way for the console to replace sys.stdin but
|
# Ideally we could have some way for the console to replace sys.stdin but
|
||||||
# python would lock blender while waiting for a return value, not easy :|
|
# python would lock blender while waiting for a return value, not easy :|
|
||||||
import sys
|
|
||||||
sys.stdin = None
|
sys.stdin = None
|
||||||
|
|
||||||
# if "-d" in sys.argv: # Enable this to measure startup speed
|
# if "-d" in sys.argv: # Enable this to measure startup speed
|
||||||
@@ -100,4 +99,10 @@ def _main():
|
|||||||
else:
|
else:
|
||||||
load_scripts()
|
load_scripts()
|
||||||
|
|
||||||
|
|
||||||
|
# constants
|
||||||
|
version = _bpy._VERSION
|
||||||
|
version_string = _bpy._VERSION_STR
|
||||||
|
home = _bpy._HOME
|
||||||
|
|
||||||
_main()
|
_main()
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
# for slightly faster access
|
# for slightly faster access
|
||||||
from _bpy import ops as ops_module
|
from _bpy import ops as ops_module
|
||||||
|
|
||||||
op_add = ops_module.add
|
# op_add = ops_module.add
|
||||||
op_remove = ops_module.remove
|
op_remove = ops_module.remove
|
||||||
op_add_macro = ops_module.add_macro
|
op_add_macro = ops_module.add_macro
|
||||||
op_dir = ops_module.dir
|
op_dir = ops_module.dir
|
||||||
|
|||||||
@@ -42,25 +42,27 @@ class Object(bpy_types.ID):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def children(self):
|
def children(self):
|
||||||
|
"""All the children of this object"""
|
||||||
import bpy
|
import bpy
|
||||||
return [child for child in bpy.data.objects if child.parent == self]
|
return [child for child in bpy.data.objects if child.parent == self]
|
||||||
|
|
||||||
|
|
||||||
class _GenericBone:
|
class _GenericBone:
|
||||||
'''
|
"""
|
||||||
functions for bones, common between Armature/Pose/Edit bones.
|
functions for bones, common between Armature/Pose/Edit bones.
|
||||||
internal subclassing use only.
|
internal subclassing use only.
|
||||||
'''
|
"""
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
def translate(self, vec):
|
def translate(self, vec):
|
||||||
|
"""Utility function to add *vec* to the head and tail of this bone."""
|
||||||
self.head += vec
|
self.head += vec
|
||||||
self.tail += vec
|
self.tail += vec
|
||||||
|
|
||||||
def parent_index(self, parent_test):
|
def parent_index(self, parent_test):
|
||||||
'''
|
"""
|
||||||
The same as 'bone in other_bone.parent_recursive' but saved generating a list.
|
The same as 'bone in other_bone.parent_recursive' but saved generating a list.
|
||||||
'''
|
"""
|
||||||
# use the name so different types can be tested.
|
# use the name so different types can be tested.
|
||||||
name = parent_test.name
|
name = parent_test.name
|
||||||
|
|
||||||
@@ -76,11 +78,13 @@ class _GenericBone:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def basename(self):
|
def basename(self):
|
||||||
|
"""The name of this bone before any '.' character"""
|
||||||
#return self.name.rsplit(".", 1)[0]
|
#return self.name.rsplit(".", 1)[0]
|
||||||
return self.name.split(".")[0]
|
return self.name.split(".")[0]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parent_recursive(self):
|
def parent_recursive(self):
|
||||||
|
"""A list of parents, starting with the immediate parent"""
|
||||||
parent_list = []
|
parent_list = []
|
||||||
parent = self.parent
|
parent = self.parent
|
||||||
|
|
||||||
@@ -94,23 +98,26 @@ class _GenericBone:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def length(self):
|
def length(self):
|
||||||
|
"""The distance from head to tail, when set the head is moved to fit the length."""
|
||||||
return self.vector.length
|
return self.vector.length
|
||||||
|
|
||||||
@length.setter
|
@length.setter
|
||||||
def length(self, value):
|
def length(self, value):
|
||||||
"""The distance from head to tail"""
|
|
||||||
self.tail = self.head + ((self.tail - self.head).normalize() * value)
|
self.tail = self.head + ((self.tail - self.head).normalize() * value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def vector(self):
|
def vector(self):
|
||||||
|
"""The direction this bone is pointing. Utility function for (tail - head)"""
|
||||||
return (self.tail - self.head)
|
return (self.tail - self.head)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def children(self):
|
def children(self):
|
||||||
|
"""A list of all the bones children."""
|
||||||
return [child for child in self._other_bones if child.parent == self]
|
return [child for child in self._other_bones if child.parent == self]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def children_recursive(self):
|
def children_recursive(self):
|
||||||
|
"""a list of all children from this bone."""
|
||||||
bones_children = []
|
bones_children = []
|
||||||
for bone in self._other_bones:
|
for bone in self._other_bones:
|
||||||
index = bone.parent_index(self)
|
index = bone.parent_index(self)
|
||||||
@@ -123,10 +130,11 @@ class _GenericBone:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def children_recursive_basename(self):
|
def children_recursive_basename(self):
|
||||||
'''
|
"""
|
||||||
Returns a chain of children with the same base name as this bone
|
Returns a chain of children with the same base name as this bone
|
||||||
Only direct chains are supported, forks caused by multiple children with matching basenames will.
|
Only direct chains are supported, forks caused by multiple children with matching basenames will
|
||||||
'''
|
terminate the function and not be returned.
|
||||||
|
"""
|
||||||
basename = self.basename
|
basename = self.basename
|
||||||
chain = []
|
chain = []
|
||||||
|
|
||||||
@@ -177,10 +185,10 @@ class EditBone(StructRNA, _GenericBone):
|
|||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
def align_orientation(self, other):
|
def align_orientation(self, other):
|
||||||
'''
|
"""
|
||||||
Align this bone to another by moving its tail and settings its roll
|
Align this bone to another by moving its tail and settings its roll
|
||||||
the length of the other bone is not used.
|
the length of the other bone is not used.
|
||||||
'''
|
"""
|
||||||
vec = other.vector.normalize() * self.length
|
vec = other.vector.normalize() * self.length
|
||||||
self.tail = self.head + vec
|
self.tail = self.head + vec
|
||||||
self.roll = other.roll
|
self.roll = other.roll
|
||||||
@@ -196,10 +204,10 @@ class Mesh(bpy_types.ID):
|
|||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
def from_pydata(self, verts, edges, faces):
|
def from_pydata(self, verts, edges, faces):
|
||||||
'''
|
"""
|
||||||
Make a mesh from a list of verts/edges/faces
|
Make a mesh from a list of verts/edges/faces
|
||||||
Until we have a nicer way to make geometry, use this.
|
Until we have a nicer way to make geometry, use this.
|
||||||
'''
|
"""
|
||||||
self.add_geometry(len(verts), len(edges), len(faces))
|
self.add_geometry(len(verts), len(edges), len(faces))
|
||||||
|
|
||||||
verts_flat = [f for v in verts for f in v]
|
verts_flat = [f for v in verts for f in v]
|
||||||
@@ -244,7 +252,7 @@ class Mesh(bpy_types.ID):
|
|||||||
return [edge_face_count_dict.get(ed.key, 0) for ed in mesh.edges]
|
return [edge_face_count_dict.get(ed.key, 0) for ed in mesh.edges]
|
||||||
|
|
||||||
def edge_loops(self, faces=None, seams=()):
|
def edge_loops(self, faces=None, seams=()):
|
||||||
'''
|
"""
|
||||||
Edge loops defined by faces
|
Edge loops defined by faces
|
||||||
|
|
||||||
Takes me.faces or a list of faces and returns the edge loops
|
Takes me.faces or a list of faces and returns the edge loops
|
||||||
@@ -255,12 +263,12 @@ class Mesh(bpy_types.ID):
|
|||||||
[ [(0,1), (4, 8), (3,8)], ...]
|
[ [(0,1), (4, 8), (3,8)], ...]
|
||||||
|
|
||||||
optionaly, seams are edge keys that will be removed
|
optionaly, seams are edge keys that will be removed
|
||||||
'''
|
"""
|
||||||
|
|
||||||
OTHER_INDEX = 2,3,0,1 # opposite face index
|
OTHER_INDEX = 2, 3, 0, 1 # opposite face index
|
||||||
|
|
||||||
if faces is None:
|
if faces is None:
|
||||||
faces= self.faces
|
faces = self.faces
|
||||||
|
|
||||||
edges = {}
|
edges = {}
|
||||||
|
|
||||||
@@ -278,7 +286,7 @@ class Mesh(bpy_types.ID):
|
|||||||
edge_loops = []
|
edge_loops = []
|
||||||
|
|
||||||
for edkey, ed_adj in edges.items():
|
for edkey, ed_adj in edges.items():
|
||||||
if 0 <len(ed_adj) < 3: # 1 or 2
|
if 0 < len(ed_adj) < 3: # 1 or 2
|
||||||
# Seek the first edge
|
# Seek the first edge
|
||||||
context_loop = [edkey, ed_adj[0]]
|
context_loop = [edkey, ed_adj[0]]
|
||||||
edge_loops.append(context_loop)
|
edge_loops.append(context_loop)
|
||||||
@@ -296,7 +304,7 @@ class Mesh(bpy_types.ID):
|
|||||||
ed_adj = edges[context_loop[-1]]
|
ed_adj = edges[context_loop[-1]]
|
||||||
if len(ed_adj) != 2:
|
if len(ed_adj) != 2:
|
||||||
|
|
||||||
if other_dir and flipped==False: # the original edge had 2 other edges
|
if other_dir and flipped == False: # the original edge had 2 other edges
|
||||||
flipped = True # only flip the list once
|
flipped = True # only flip the list once
|
||||||
context_loop.reverse()
|
context_loop.reverse()
|
||||||
ed_adj[:] = []
|
ed_adj[:] = []
|
||||||
@@ -311,7 +319,7 @@ class Mesh(bpy_types.ID):
|
|||||||
break
|
break
|
||||||
|
|
||||||
i = ed_adj.index(context_loop[-2])
|
i = ed_adj.index(context_loop[-2])
|
||||||
context_loop.append( ed_adj[ not i] )
|
context_loop.append(ed_adj[not i])
|
||||||
|
|
||||||
# Dont look at this again
|
# Dont look at this again
|
||||||
ed_adj[:] = []
|
ed_adj[:] = []
|
||||||
@@ -372,6 +380,33 @@ class Macro(StructRNA, metaclass=OrderedMeta):
|
|||||||
class Menu(StructRNA):
|
class Menu(StructRNA):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _dyn_menu_initialize(cls):
|
||||||
|
draw_funcs = getattr(cls.draw, "_draw_funcs", None)
|
||||||
|
|
||||||
|
if draw_funcs is None:
|
||||||
|
|
||||||
|
def draw_ls(*args):
|
||||||
|
for func in draw_ls._draw_funcs:
|
||||||
|
func(*args)
|
||||||
|
|
||||||
|
draw_funcs = draw_ls._draw_funcs = [cls.draw]
|
||||||
|
cls.draw = draw_ls
|
||||||
|
|
||||||
|
return draw_funcs
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def append(cls, draw_func):
|
||||||
|
"""Prepend an draw function to this menu, takes the same arguments as the menus draw function."""
|
||||||
|
draw_funcs = cls._dyn_menu_initialize()
|
||||||
|
draw_funcs.append(draw_func)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def prepend(cls, draw_func):
|
||||||
|
"""Prepend a draw function to this menu, takes the same arguments as the menus draw function."""
|
||||||
|
draw_funcs = cls._dyn_menu_initialize()
|
||||||
|
draw_funcs.insert(0, draw_func)
|
||||||
|
|
||||||
def path_menu(self, searchpaths, operator):
|
def path_menu(self, searchpaths, operator):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
# hard coded to set the operators 'path' to the filename.
|
# hard coded to set the operators 'path' to the filename.
|
||||||
@@ -396,9 +431,9 @@ class Menu(StructRNA):
|
|||||||
layout.operator(operator, text=bpy.utils.display_name(f)).path = path
|
layout.operator(operator, text=bpy.utils.display_name(f)).path = path
|
||||||
|
|
||||||
def draw_preset(self, context):
|
def draw_preset(self, context):
|
||||||
'''Define these on the subclass
|
"""Define these on the subclass
|
||||||
- preset_operator
|
- preset_operator
|
||||||
- preset_subdir
|
- preset_subdir
|
||||||
'''
|
"""
|
||||||
import bpy
|
import bpy
|
||||||
self.path_menu(bpy.utils.preset_paths(self.preset_subdir), self.preset_operator)
|
self.path_menu(bpy.utils.preset_paths(self.preset_subdir), self.preset_operator)
|
||||||
|
|||||||
@@ -1,118 +0,0 @@
|
|||||||
# ##### 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 bpy
|
|
||||||
|
|
||||||
|
|
||||||
def collect_baseclasses(_class, bases):
|
|
||||||
|
|
||||||
if _class is type or _class is object:
|
|
||||||
return bases
|
|
||||||
|
|
||||||
bases.append(_class)
|
|
||||||
for _superclass in _class.__bases__:
|
|
||||||
collect_baseclasses(_superclass, bases)
|
|
||||||
|
|
||||||
return bases
|
|
||||||
|
|
||||||
|
|
||||||
def collect_subclasses(_class, subs):
|
|
||||||
|
|
||||||
if _class is type or _class is object:
|
|
||||||
return subs
|
|
||||||
|
|
||||||
subs.append(_class)
|
|
||||||
for _subclass in _class.__subclasses__():
|
|
||||||
collect_subclasses(_subclass, subs)
|
|
||||||
|
|
||||||
return subs
|
|
||||||
|
|
||||||
|
|
||||||
class DynMenu(bpy.types.Menu):
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
'''
|
|
||||||
This is a draw function that is used to call all subclasses draw functions
|
|
||||||
starting from the registered classes draw function and working down.
|
|
||||||
|
|
||||||
DynMenu.setup() must be called first.
|
|
||||||
|
|
||||||
Sort/group classes could be nice
|
|
||||||
'''
|
|
||||||
|
|
||||||
subclass_ls = []
|
|
||||||
collect_subclasses(self.__class__, subclass_ls)
|
|
||||||
# print(subclass_ls)
|
|
||||||
|
|
||||||
for subclass in subclass_ls:
|
|
||||||
# print("drawwing", subclass) # , dir(subclass))
|
|
||||||
subclass.internal_draw(self, context)
|
|
||||||
# print("subclass.internal_draw", subclass.internal_draw)
|
|
||||||
|
|
||||||
|
|
||||||
def setup(menu_class):
|
|
||||||
'''
|
|
||||||
Setup subclasses (not needed when self.add() is used)
|
|
||||||
'''
|
|
||||||
bases = collect_baseclasses(menu_class, [])
|
|
||||||
|
|
||||||
# Incase 'DynMenu' isnt last
|
|
||||||
while bases[-1] is not DynMenu:
|
|
||||||
bases.pop()
|
|
||||||
bases.pop() # remove 'DynMenu'
|
|
||||||
|
|
||||||
root_class = bases[-1] # this is the registered class
|
|
||||||
|
|
||||||
for subclass in collect_subclasses(root_class, []):
|
|
||||||
#print(subclass)
|
|
||||||
|
|
||||||
draw = getattr(subclass, 'draw', None)
|
|
||||||
if draw and not hasattr(subclass, 'internal_draw'):
|
|
||||||
# print("replace", subclass, draw)
|
|
||||||
try:
|
|
||||||
del subclass.draw
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
subclass.internal_draw = draw
|
|
||||||
|
|
||||||
root_class.draw = DynMenu.draw
|
|
||||||
|
|
||||||
|
|
||||||
def add(menu_class, func):
|
|
||||||
'''
|
|
||||||
Add a single function directly without having to make a class
|
|
||||||
|
|
||||||
important that the returned value should be stored in the module that called it.
|
|
||||||
'''
|
|
||||||
|
|
||||||
newclass = type('<menuclass>', (menu_class,), {})
|
|
||||||
newclass.internal_draw = func
|
|
||||||
setup(menu_class)
|
|
||||||
return newclass
|
|
||||||
|
|
||||||
'''
|
|
||||||
# so we dont need to import this module
|
|
||||||
DynMenu.setup = setup
|
|
||||||
DynMenu.add = add
|
|
||||||
|
|
||||||
# Only so we can access as bpy.types.
|
|
||||||
# dont ever use this directly!
|
|
||||||
bpy.types.register(DynMenu)
|
|
||||||
'''
|
|
||||||
@@ -19,9 +19,8 @@
|
|||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from rigify import RigifyError, get_layer_dict
|
from rigify import RigifyError
|
||||||
from rigify_utils import bone_class_instance, copy_bone_simple, blend_bone_list, get_side_name, get_base_name, add_pole_target_bone
|
from rigify_utils import bone_class_instance, copy_bone_simple, add_pole_target_bone
|
||||||
from rna_prop_ui import rna_idprop_ui_prop_get
|
|
||||||
from Mathutils import Vector
|
from Mathutils import Vector
|
||||||
|
|
||||||
METARIG_NAMES = "hips", "thigh", "shin", "foot", "toe"
|
METARIG_NAMES = "hips", "thigh", "shin", "foot", "toe"
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ def metarig_template():
|
|||||||
pbone = obj.pose.bones['rib_cage']
|
pbone = obj.pose.bones['rib_cage']
|
||||||
pbone['type'] = 'spine_pivot_flex'
|
pbone['type'] = 'spine_pivot_flex'
|
||||||
|
|
||||||
|
|
||||||
def metarig_definition(obj, orig_bone_name):
|
def metarig_definition(obj, orig_bone_name):
|
||||||
'''
|
'''
|
||||||
The bone given is the second in a chain.
|
The bone given is the second in a chain.
|
||||||
|
|||||||
@@ -16,13 +16,37 @@
|
|||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
# classes for extracting info from blenders internal classes
|
# classes for extracting info from blenders internal classes
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
|
# use to strip python paths
|
||||||
|
script_paths = bpy.utils.script_paths()
|
||||||
|
|
||||||
|
|
||||||
|
def range_str(val):
|
||||||
|
if val < -10000000:
|
||||||
|
return '-inf'
|
||||||
|
elif val > 10000000:
|
||||||
|
return 'inf'
|
||||||
|
elif type(val) == float:
|
||||||
|
return '%g' % val
|
||||||
|
else:
|
||||||
|
return str(val)
|
||||||
|
|
||||||
|
|
||||||
|
def float_as_string(f):
|
||||||
|
val_str = "%g" % f
|
||||||
|
if '.' not in val_str and '-' not in val_str: # value could be 1e-05
|
||||||
|
val_str += '.0'
|
||||||
|
return val_str
|
||||||
|
|
||||||
|
|
||||||
class InfoStructRNA:
|
class InfoStructRNA:
|
||||||
global_lookup = {}
|
global_lookup = {}
|
||||||
|
|
||||||
def __init__(self, rna_type):
|
def __init__(self, rna_type):
|
||||||
self.bl_rna = rna_type
|
self.bl_rna = rna_type
|
||||||
|
|
||||||
@@ -43,18 +67,53 @@ class InfoStructRNA:
|
|||||||
def build(self):
|
def build(self):
|
||||||
rna_type = self.bl_rna
|
rna_type = self.bl_rna
|
||||||
parent_id = self.identifier
|
parent_id = self.identifier
|
||||||
self.properties[:] = [GetInfoPropertyRNA(rna_prop, parent_id) for rna_prop in rna_type.properties.values()]
|
self.properties[:] = [GetInfoPropertyRNA(rna_prop, parent_id) for rna_id, rna_prop in rna_type.properties.items() if rna_id != "rna_type"]
|
||||||
self.functions[:] = [GetInfoFunctionRNA(rna_prop, parent_id) for rna_prop in rna_type.functions.values()]
|
self.functions[:] = [GetInfoFunctionRNA(rna_prop, parent_id) for rna_prop in rna_type.functions.values()]
|
||||||
|
|
||||||
def getNestedProperties(self, ls = None):
|
def get_bases(self):
|
||||||
|
bases = []
|
||||||
|
item = self
|
||||||
|
|
||||||
|
while item:
|
||||||
|
item = item.base
|
||||||
|
if item:
|
||||||
|
bases.append(item)
|
||||||
|
|
||||||
|
return bases
|
||||||
|
|
||||||
|
def get_nested_properties(self, ls=None):
|
||||||
if not ls:
|
if not ls:
|
||||||
ls = self.properties[:]
|
ls = self.properties[:]
|
||||||
|
|
||||||
if self.nested:
|
if self.nested:
|
||||||
self.nested.getNestedProperties(ls)
|
self.nested.get_nested_properties(ls)
|
||||||
|
|
||||||
return ls
|
return ls
|
||||||
|
|
||||||
|
def _get_py_visible_attrs(self):
|
||||||
|
attrs = []
|
||||||
|
py_class = getattr(bpy.types, self.identifier)
|
||||||
|
for attr_str in dir(py_class):
|
||||||
|
if attr_str.startswith("_"):
|
||||||
|
continue
|
||||||
|
attrs.append((attr_str, getattr(py_class, attr_str)))
|
||||||
|
return attrs
|
||||||
|
|
||||||
|
def get_py_properties(self):
|
||||||
|
properties = []
|
||||||
|
for identifier, attr in self._get_py_visible_attrs():
|
||||||
|
if type(attr) is property:
|
||||||
|
properties.append((identifier, attr))
|
||||||
|
return properties
|
||||||
|
|
||||||
|
def get_py_functions(self):
|
||||||
|
import types
|
||||||
|
functions = []
|
||||||
|
for identifier, attr in self._get_py_visible_attrs():
|
||||||
|
if type(attr) in (types.FunctionType, types.MethodType):
|
||||||
|
functions.append((identifier, attr))
|
||||||
|
return functions
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|
||||||
txt = ''
|
txt = ''
|
||||||
@@ -74,44 +133,137 @@ class InfoStructRNA:
|
|||||||
|
|
||||||
class InfoPropertyRNA:
|
class InfoPropertyRNA:
|
||||||
global_lookup = {}
|
global_lookup = {}
|
||||||
|
|
||||||
def __init__(self, rna_prop):
|
def __init__(self, rna_prop):
|
||||||
self.bl_prop = rna_prop
|
self.bl_prop = rna_prop
|
||||||
self.identifier = rna_prop.identifier
|
self.identifier = rna_prop.identifier
|
||||||
self.name = rna_prop.name
|
self.name = rna_prop.name
|
||||||
self.description = rna_prop.description.strip()
|
self.description = rna_prop.description.strip()
|
||||||
|
self.default_str = "<UNKNOWN>"
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
rna_prop = self.bl_prop
|
rna_prop = self.bl_prop
|
||||||
|
|
||||||
self.enum_items = []
|
self.enum_items = []
|
||||||
self.min = -1
|
self.min = getattr(rna_prop, "hard_min", -1)
|
||||||
self.max = -1
|
self.max = getattr(rna_prop, "hard_max", -1)
|
||||||
self.array_length = getattr(rna_prop, "array_length", 0)
|
self.array_length = getattr(rna_prop, "array_length", 0)
|
||||||
|
self.collection_type = GetInfoStructRNA(rna_prop.srna)
|
||||||
|
self.is_required = rna_prop.is_required
|
||||||
|
self.is_readonly = rna_prop.is_readonly
|
||||||
|
self.is_never_none = rna_prop.is_never_none
|
||||||
|
|
||||||
self.type = rna_prop.type.lower()
|
self.type = rna_prop.type.lower()
|
||||||
self.fixed_type = GetInfoStructRNA(rna_prop.fixed_type) # valid for pointer/collections
|
fixed_type = getattr(rna_prop, "fixed_type", "")
|
||||||
|
if fixed_type:
|
||||||
|
self.fixed_type = GetInfoStructRNA(fixed_type) # valid for pointer/collections
|
||||||
|
else:
|
||||||
|
self.fixed_type = None
|
||||||
|
|
||||||
|
if self.type == "enum":
|
||||||
|
self.enum_items[:] = rna_prop.items.keys()
|
||||||
|
|
||||||
|
if self.array_length:
|
||||||
|
self.default = tuple(getattr(rna_prop, "default_array", ()))
|
||||||
|
self.default_str = ''
|
||||||
|
# special case for floats
|
||||||
|
if len(self.default) > 0:
|
||||||
|
if type(self.default[0]) is float:
|
||||||
|
self.default_str = "(%s)" % ", ".join([float_as_string(f) for f in self.default])
|
||||||
|
if not self.default_str:
|
||||||
|
self.default_str = str(self.default)
|
||||||
|
else:
|
||||||
|
self.default = getattr(rna_prop, "default", "")
|
||||||
|
if type(self.default) is float:
|
||||||
|
self.default_str = float_as_string(self.default)
|
||||||
|
else:
|
||||||
|
self.default_str = str(self.default)
|
||||||
|
|
||||||
self.srna = GetInfoStructRNA(rna_prop.srna) # valid for pointer/collections
|
self.srna = GetInfoStructRNA(rna_prop.srna) # valid for pointer/collections
|
||||||
|
|
||||||
|
def get_default_string(self):
|
||||||
|
# pointer has no default, just set as None
|
||||||
|
if self.type == "pointer":
|
||||||
|
return "None"
|
||||||
|
elif self.type == "string":
|
||||||
|
return '"' + self.default_str + '"'
|
||||||
|
elif self.type == "enum":
|
||||||
|
if self.default_str:
|
||||||
|
return "'" + self.default_str + "'"
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
return self.default_str
|
||||||
|
|
||||||
|
def get_arg_default(self, force=True):
|
||||||
|
default = self.get_default_string()
|
||||||
|
if default and (force or self.is_required == False):
|
||||||
|
return "%s=%s" % (self.identifier, default)
|
||||||
|
return self.identifier
|
||||||
|
|
||||||
|
def get_type_description(self, as_arg=False, class_fmt="%s"):
|
||||||
|
type_str = ""
|
||||||
|
if self.fixed_type is None:
|
||||||
|
type_str += self.type
|
||||||
|
if self.array_length:
|
||||||
|
type_str += " array of %d items" % (self.array_length)
|
||||||
|
|
||||||
|
if self.type in ("float", "int"):
|
||||||
|
type_str += " in [%s, %s]" % (range_str(self.min), range_str(self.max))
|
||||||
|
elif self.type == "enum":
|
||||||
|
type_str += " in [%s]" % ', '.join([("'%s'" % s) for s in self.enum_items])
|
||||||
|
else:
|
||||||
|
if self.type == "collection":
|
||||||
|
if self.collection_type:
|
||||||
|
collection_str = (class_fmt % self.collection_type.identifier) + " collection of "
|
||||||
|
else:
|
||||||
|
collection_str = "Collection of "
|
||||||
|
else:
|
||||||
|
collection_str = ""
|
||||||
|
|
||||||
|
type_str += collection_str + (class_fmt % self.fixed_type.identifier)
|
||||||
|
|
||||||
|
if as_arg:
|
||||||
|
if not self.is_required:
|
||||||
|
type_str += ", (optional)"
|
||||||
|
else: # readonly is only useful for selfs, not args
|
||||||
|
if self.is_readonly:
|
||||||
|
type_str += ", (readonly)"
|
||||||
|
|
||||||
|
if self.is_never_none:
|
||||||
|
type_str += ", (never None)"
|
||||||
|
|
||||||
|
return type_str
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
txt = ''
|
txt = ''
|
||||||
txt += ' * ' + self.identifier + ': ' + self.description
|
txt += ' * ' + self.identifier + ': ' + self.description
|
||||||
|
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
|
||||||
class InfoFunctionRNA:
|
class InfoFunctionRNA:
|
||||||
global_lookup = {}
|
global_lookup = {}
|
||||||
|
|
||||||
def __init__(self, rna_func):
|
def __init__(self, rna_func):
|
||||||
self.bl_func = rna_func
|
self.bl_func = rna_func
|
||||||
self.identifier = rna_func.identifier
|
self.identifier = rna_func.identifier
|
||||||
# self.name = rna_func.name # functions have no name!
|
# self.name = rna_func.name # functions have no name!
|
||||||
self.description = rna_func.description.strip()
|
self.description = rna_func.description.strip()
|
||||||
|
|
||||||
self.args = [] # todo
|
self.args = []
|
||||||
self.return_value = None # todo
|
self.return_value = None
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
rna_prop = self.bl_prop
|
rna_func = self.bl_func
|
||||||
pass
|
parent_id = rna_func
|
||||||
|
|
||||||
|
for rna_prop in rna_func.parameters.values():
|
||||||
|
prop = GetInfoPropertyRNA(rna_prop, parent_id)
|
||||||
|
if rna_prop.use_return:
|
||||||
|
self.return_value = prop
|
||||||
|
else:
|
||||||
|
self.args.append(prop)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
txt = ''
|
txt = ''
|
||||||
@@ -123,6 +275,56 @@ class InfoFunctionRNA:
|
|||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
|
||||||
|
class InfoOperatorRNA:
|
||||||
|
global_lookup = {}
|
||||||
|
|
||||||
|
def __init__(self, rna_op):
|
||||||
|
self.bl_op = rna_op
|
||||||
|
self.identifier = rna_op.identifier
|
||||||
|
|
||||||
|
mod, name = self.identifier.split("_OT_", 1)
|
||||||
|
self.module_name = mod.lower()
|
||||||
|
self.func_name = name
|
||||||
|
|
||||||
|
# self.name = rna_func.name # functions have no name!
|
||||||
|
self.description = rna_op.description.strip()
|
||||||
|
|
||||||
|
self.args = []
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
rna_op = self.bl_op
|
||||||
|
parent_id = self.identifier
|
||||||
|
for rna_id, rna_prop in rna_op.properties.items():
|
||||||
|
if rna_id == "rna_type":
|
||||||
|
continue
|
||||||
|
|
||||||
|
prop = GetInfoPropertyRNA(rna_prop, parent_id)
|
||||||
|
self.args.append(prop)
|
||||||
|
|
||||||
|
def get_location(self):
|
||||||
|
op_class = getattr(bpy.types, self.identifier)
|
||||||
|
op_func = getattr(op_class, "execute", None)
|
||||||
|
if op_func is None:
|
||||||
|
op_func = getattr(op_class, "invoke", None)
|
||||||
|
if op_func is None:
|
||||||
|
op_func = getattr(op_class, "poll", None)
|
||||||
|
|
||||||
|
if op_func:
|
||||||
|
op_code = op_func.__code__
|
||||||
|
source_path = op_code.co_filename
|
||||||
|
|
||||||
|
# clear the prefix
|
||||||
|
for p in script_paths:
|
||||||
|
source_path = source_path.split(p)[-1]
|
||||||
|
|
||||||
|
if source_path[0] in "/\\":
|
||||||
|
source_path = source_path[1:]
|
||||||
|
|
||||||
|
return source_path, op_code.co_firstlineno
|
||||||
|
else:
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
|
||||||
def _GetInfoRNA(bl_rna, cls, parent_id=''):
|
def _GetInfoRNA(bl_rna, cls, parent_id=''):
|
||||||
|
|
||||||
if bl_rna == None:
|
if bl_rna == None:
|
||||||
@@ -139,21 +341,27 @@ def _GetInfoRNA(bl_rna, cls, parent_id=''):
|
|||||||
def GetInfoStructRNA(bl_rna):
|
def GetInfoStructRNA(bl_rna):
|
||||||
return _GetInfoRNA(bl_rna, InfoStructRNA)
|
return _GetInfoRNA(bl_rna, InfoStructRNA)
|
||||||
|
|
||||||
|
|
||||||
def GetInfoPropertyRNA(bl_rna, parent_id):
|
def GetInfoPropertyRNA(bl_rna, parent_id):
|
||||||
return _GetInfoRNA(bl_rna, InfoPropertyRNA, parent_id)
|
return _GetInfoRNA(bl_rna, InfoPropertyRNA, parent_id)
|
||||||
|
|
||||||
|
|
||||||
def GetInfoFunctionRNA(bl_rna, parent_id):
|
def GetInfoFunctionRNA(bl_rna, parent_id):
|
||||||
return _GetInfoRNA(bl_rna, InfoFunctionRNA, parent_id)
|
return _GetInfoRNA(bl_rna, InfoFunctionRNA, parent_id)
|
||||||
|
|
||||||
|
|
||||||
|
def GetInfoOperatorRNA(bl_rna):
|
||||||
|
return _GetInfoRNA(bl_rna, InfoOperatorRNA)
|
||||||
|
|
||||||
|
|
||||||
def BuildRNAInfo():
|
def BuildRNAInfo():
|
||||||
# Use for faster lookups
|
# Use for faster lookups
|
||||||
# use rna_struct.identifier as the key for each dict
|
# use rna_struct.identifier as the key for each dict
|
||||||
rna_struct_dict = {} # store identifier:rna lookups
|
rna_struct_dict = {} # store identifier:rna lookups
|
||||||
rna_full_path_dict = {} # store the result of full_rna_struct_path(rna_struct)
|
rna_full_path_dict = {} # store the result of full_rna_struct_path(rna_struct)
|
||||||
rna_children_dict = {} # store all rna_structs nested from here
|
rna_children_dict = {} # store all rna_structs nested from here
|
||||||
rna_references_dict = {} # store a list of rna path strings that reference this type
|
rna_references_dict = {} # store a list of rna path strings that reference this type
|
||||||
rna_functions_dict = {} # store all functions directly in this type (not inherited)
|
rna_functions_dict = {} # store all functions directly in this type (not inherited)
|
||||||
rna_words = set()
|
rna_words = set()
|
||||||
|
|
||||||
def rna_id_ignore(rna_id):
|
def rna_id_ignore(rna_id):
|
||||||
@@ -166,7 +374,8 @@ def BuildRNAInfo():
|
|||||||
return True
|
return True
|
||||||
if "_PT_" in rna_id:
|
if "_PT_" in rna_id:
|
||||||
return True
|
return True
|
||||||
|
if "_HT_" in rna_id:
|
||||||
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def full_rna_struct_path(rna_struct):
|
def full_rna_struct_path(rna_struct):
|
||||||
@@ -181,8 +390,10 @@ def BuildRNAInfo():
|
|||||||
|
|
||||||
# def write_func(rna_func, ident):
|
# def write_func(rna_func, ident):
|
||||||
def base_id(rna_struct):
|
def base_id(rna_struct):
|
||||||
try: return rna_struct.base.identifier
|
try:
|
||||||
except: return '' # invalid id
|
return rna_struct.base.identifier
|
||||||
|
except:
|
||||||
|
return "" # invalid id
|
||||||
|
|
||||||
#structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpy.doc.structs.values()]
|
#structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpy.doc.structs.values()]
|
||||||
'''
|
'''
|
||||||
@@ -194,8 +405,7 @@ def BuildRNAInfo():
|
|||||||
for rna_type_name in dir(bpy.types):
|
for rna_type_name in dir(bpy.types):
|
||||||
rna_type = getattr(bpy.types, rna_type_name)
|
rna_type = getattr(bpy.types, rna_type_name)
|
||||||
|
|
||||||
try: rna_struct = rna_type.bl_rna
|
rna_struct = getattr(rna_type, "bl_rna", None)
|
||||||
except: rna_struct = None
|
|
||||||
|
|
||||||
if rna_struct:
|
if rna_struct:
|
||||||
#if not rna_type_name.startswith('__'):
|
#if not rna_type_name.startswith('__'):
|
||||||
@@ -203,7 +413,7 @@ def BuildRNAInfo():
|
|||||||
identifier = rna_struct.identifier
|
identifier = rna_struct.identifier
|
||||||
|
|
||||||
if not rna_id_ignore(identifier):
|
if not rna_id_ignore(identifier):
|
||||||
structs.append( (base_id(rna_struct), identifier, rna_struct) )
|
structs.append((base_id(rna_struct), identifier, rna_struct))
|
||||||
|
|
||||||
# Simple lookup
|
# Simple lookup
|
||||||
rna_struct_dict[identifier] = rna_struct
|
rna_struct_dict[identifier] = rna_struct
|
||||||
@@ -212,12 +422,12 @@ def BuildRNAInfo():
|
|||||||
rna_full_path_dict[identifier] = full_rna_struct_path(rna_struct)
|
rna_full_path_dict[identifier] = full_rna_struct_path(rna_struct)
|
||||||
|
|
||||||
# Store a list of functions, remove inherited later
|
# Store a list of functions, remove inherited later
|
||||||
rna_functions_dict[identifier]= list(rna_struct.functions)
|
rna_functions_dict[identifier] = list(rna_struct.functions)
|
||||||
|
|
||||||
|
|
||||||
# fill in these later
|
# fill in these later
|
||||||
rna_children_dict[identifier]= []
|
rna_children_dict[identifier] = []
|
||||||
rna_references_dict[identifier]= []
|
rna_references_dict[identifier] = []
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@@ -247,11 +457,11 @@ def BuildRNAInfo():
|
|||||||
data = structs.pop(i)
|
data = structs.pop(i)
|
||||||
ok = False
|
ok = False
|
||||||
while i < len(structs):
|
while i < len(structs):
|
||||||
if structs[i][1]==rna_base:
|
if structs[i][1] == rna_base:
|
||||||
structs.insert(i+1, data) # insert after the item we depend on.
|
structs.insert(i + 1, data) # insert after the item we depend on.
|
||||||
ok = True
|
ok = True
|
||||||
break
|
break
|
||||||
i+=1
|
i += 1
|
||||||
|
|
||||||
if not ok:
|
if not ok:
|
||||||
print('Dependancy "%s" could not be found for "%s"' % (identifier, rna_base))
|
print('Dependancy "%s" could not be found for "%s"' % (identifier, rna_base))
|
||||||
@@ -269,37 +479,40 @@ def BuildRNAInfo():
|
|||||||
rna_base_func_keys = [f.identifier for f in rna_struct_dict[rna_base].functions]
|
rna_base_func_keys = [f.identifier for f in rna_struct_dict[rna_base].functions]
|
||||||
else:
|
else:
|
||||||
rna_base_prop_keys = []
|
rna_base_prop_keys = []
|
||||||
rna_base_func_keys= []
|
rna_base_func_keys = []
|
||||||
|
|
||||||
# rna_struct_path = full_rna_struct_path(rna_struct)
|
# rna_struct_path = full_rna_struct_path(rna_struct)
|
||||||
rna_struct_path = rna_full_path_dict[identifier]
|
rna_struct_path = rna_full_path_dict[identifier]
|
||||||
|
|
||||||
for rna_prop_identifier, rna_prop in rna_struct.properties.items():
|
for rna_prop_identifier, rna_prop in rna_struct.properties.items():
|
||||||
|
|
||||||
if rna_prop_identifier=='RNA': continue
|
if rna_prop_identifier == 'RNA' or \
|
||||||
if rna_id_ignore(rna_prop_identifier): continue
|
rna_id_ignore(rna_prop_identifier) or \
|
||||||
if rna_prop_identifier in rna_base_prop_keys: continue
|
rna_prop_identifier in rna_base_prop_keys:
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
for rna_prop_ptr in (getattr(rna_prop, "fixed_type", None), getattr(rna_prop, "srna", None)):
|
for rna_prop_ptr in (getattr(rna_prop, "fixed_type", None), getattr(rna_prop, "srna", None)):
|
||||||
# Does this property point to me?
|
# Does this property point to me?
|
||||||
if rna_prop_ptr:
|
if rna_prop_ptr:
|
||||||
rna_references_dict[rna_prop_ptr.identifier].append( "%s.%s" % (rna_struct_path, rna_prop_identifier) )
|
rna_references_dict[rna_prop_ptr.identifier].append("%s.%s" % (rna_struct_path, rna_prop_identifier))
|
||||||
|
|
||||||
for rna_func in rna_struct.functions:
|
for rna_func in rna_struct.functions:
|
||||||
for rna_prop_identifier, rna_prop in rna_func.parameters.items():
|
for rna_prop_identifier, rna_prop in rna_func.parameters.items():
|
||||||
|
|
||||||
if rna_prop_identifier=='RNA': continue
|
if rna_prop_identifier == 'RNA' or \
|
||||||
if rna_id_ignore(rna_prop_identifier): continue
|
rna_id_ignore(rna_prop_identifier) or \
|
||||||
if rna_prop_identifier in rna_base_func_keys: continue
|
rna_prop_identifier in rna_base_func_keys:
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
try: rna_prop_ptr = rna_prop.fixed_type
|
rna_prop_ptr = rna_prop.fixed_type
|
||||||
except: rna_prop_ptr = None
|
except:
|
||||||
|
rna_prop_ptr = None
|
||||||
|
|
||||||
# Does this property point to me?
|
# Does this property point to me?
|
||||||
if rna_prop_ptr:
|
if rna_prop_ptr:
|
||||||
rna_references_dict[rna_prop_ptr.identifier].append( "%s.%s" % (rna_struct_path, rna_func.identifier) )
|
rna_references_dict[rna_prop_ptr.identifier].append("%s.%s" % (rna_struct_path, rna_func.identifier))
|
||||||
|
|
||||||
|
|
||||||
# Store nested children
|
# Store nested children
|
||||||
@@ -309,11 +522,11 @@ def BuildRNAInfo():
|
|||||||
|
|
||||||
|
|
||||||
if rna_base:
|
if rna_base:
|
||||||
rna_funcs = rna_functions_dict[identifier]
|
rna_funcs = rna_functions_dict[identifier]
|
||||||
if rna_funcs:
|
if rna_funcs:
|
||||||
# Remove inherited functions if we have any
|
# Remove inherited functions if we have any
|
||||||
rna_base_funcs = rna_functions_dict__copy[rna_base]
|
rna_base_funcs = rna_functions_dict__copy[rna_base]
|
||||||
rna_funcs[:] = [f for f in rna_funcs if f not in rna_base_funcs]
|
rna_funcs[:] = [f for f in rna_funcs if f not in rna_base_funcs]
|
||||||
|
|
||||||
rna_functions_dict__copy.clear()
|
rna_functions_dict__copy.clear()
|
||||||
del rna_functions_dict__copy
|
del rna_functions_dict__copy
|
||||||
@@ -329,7 +542,7 @@ def BuildRNAInfo():
|
|||||||
# continue
|
# continue
|
||||||
|
|
||||||
#write_struct(rna_struct, '')
|
#write_struct(rna_struct, '')
|
||||||
info_struct= GetInfoStructRNA(rna_struct)
|
info_struct = GetInfoStructRNA(rna_struct)
|
||||||
if rna_base:
|
if rna_base:
|
||||||
info_struct.base = GetInfoStructRNA(rna_struct_dict[rna_base])
|
info_struct.base = GetInfoStructRNA(rna_struct_dict[rna_base])
|
||||||
info_struct.nested = GetInfoStructRNA(rna_struct.nested)
|
info_struct.nested = GetInfoStructRNA(rna_struct.nested)
|
||||||
@@ -347,9 +560,42 @@ def BuildRNAInfo():
|
|||||||
|
|
||||||
for rna_info in InfoStructRNA.global_lookup.values():
|
for rna_info in InfoStructRNA.global_lookup.values():
|
||||||
rna_info.build()
|
rna_info.build()
|
||||||
|
for prop in rna_info.properties:
|
||||||
|
prop.build()
|
||||||
|
for func in rna_info.functions:
|
||||||
|
func.build()
|
||||||
|
for prop in func.args:
|
||||||
|
prop.build()
|
||||||
|
if func.return_value:
|
||||||
|
func.return_value.build()
|
||||||
|
|
||||||
for rna_info in InfoStructRNA.global_lookup.values():
|
# now for operators
|
||||||
print(rna_info)
|
op_mods = dir(bpy.ops)
|
||||||
|
|
||||||
return InfoStructRNA.global_lookup, InfoFunctionRNA.global_lookup, InfoPropertyRNA.global_lookup
|
for op_mod_name in sorted(op_mods):
|
||||||
|
if op_mod_name.startswith('__') or op_mod_name in ("add", "remove"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
op_mod = getattr(bpy.ops, op_mod_name)
|
||||||
|
operators = dir(op_mod)
|
||||||
|
for op in sorted(operators):
|
||||||
|
try:
|
||||||
|
rna_prop = getattr(op_mod, op).get_rna()
|
||||||
|
except AttributeError:
|
||||||
|
rna_prop = None
|
||||||
|
except TypeError:
|
||||||
|
rna_prop = None
|
||||||
|
|
||||||
|
if rna_prop:
|
||||||
|
GetInfoOperatorRNA(rna_prop.bl_rna)
|
||||||
|
|
||||||
|
for rna_info in InfoOperatorRNA.global_lookup.values():
|
||||||
|
rna_info.build()
|
||||||
|
for rna_prop in rna_info.args:
|
||||||
|
rna_prop.build()
|
||||||
|
|
||||||
|
|
||||||
|
#for rna_info in InfoStructRNA.global_lookup.values():
|
||||||
|
# print(rna_info)
|
||||||
|
|
||||||
|
return InfoStructRNA.global_lookup, InfoFunctionRNA.global_lookup, InfoOperatorRNA.global_lookup, InfoPropertyRNA.global_lookup
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ rna_max = FloatProperty(name="Max", default=1.0, precision=3)
|
|||||||
class WM_OT_properties_edit(bpy.types.Operator):
|
class WM_OT_properties_edit(bpy.types.Operator):
|
||||||
'''Internal use (edit a property path)'''
|
'''Internal use (edit a property path)'''
|
||||||
bl_idname = "wm.properties_edit"
|
bl_idname = "wm.properties_edit"
|
||||||
bl_label = "Edit Property!"
|
bl_label = "Edit Property"
|
||||||
|
|
||||||
path = rna_path
|
path = rna_path
|
||||||
property = rna_property
|
property = rna_property
|
||||||
@@ -196,7 +196,7 @@ class WM_OT_properties_edit(bpy.types.Operator):
|
|||||||
|
|
||||||
prop_ui['description'] = self.properties.description
|
prop_ui['description'] = self.properties.description
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ class WM_OT_properties_edit(bpy.types.Operator):
|
|||||||
#return wm.invoke_props_popup(self, event)
|
#return wm.invoke_props_popup(self, event)
|
||||||
|
|
||||||
wm.invoke_props_popup(self, event)
|
wm.invoke_props_popup(self, event)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_properties_add(bpy.types.Operator):
|
class WM_OT_properties_add(bpy.types.Operator):
|
||||||
@@ -242,7 +242,7 @@ class WM_OT_properties_add(bpy.types.Operator):
|
|||||||
property = unique_name(item.keys())
|
property = unique_name(item.keys())
|
||||||
|
|
||||||
item[property] = 1.0
|
item[property] = 1.0
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_properties_remove(bpy.types.Operator):
|
class WM_OT_properties_remove(bpy.types.Operator):
|
||||||
@@ -256,4 +256,4 @@ class WM_OT_properties_remove(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
item = eval("context.%s" % self.properties.path)
|
item = eval("context.%s" % self.properties.path)
|
||||||
del item[self.properties.property]
|
del item[self.properties.property]
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ from math import cos, sin, pi
|
|||||||
|
|
||||||
# could this be stored elsewhere?
|
# could this be stored elsewhere?
|
||||||
|
|
||||||
|
|
||||||
def metarig_template():
|
def metarig_template():
|
||||||
# generated by rigify.write_meta_rig
|
# generated by rigify.write_meta_rig
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
@@ -607,17 +608,16 @@ class AddHuman(bpy.types.Operator):
|
|||||||
bones.remove(bones[0])
|
bones.remove(bones[0])
|
||||||
metarig_template()
|
metarig_template()
|
||||||
bpy.ops.object.mode_set(mode=mode_orig)
|
bpy.ops.object.mode_set(mode=mode_orig)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
# Register the operator
|
# Register the operator
|
||||||
bpy.ops.add(AddHuman)
|
bpy.types.register(AddHuman)
|
||||||
|
|
||||||
# Add to a menu
|
# Add to a menu
|
||||||
import dynamic_menu
|
menu_func = (lambda self, context: self.layout.operator(AddHuman.bl_idname,
|
||||||
|
icon='OUTLINER_OB_ARMATURE', text="Human (Meta-Rig)"))
|
||||||
|
|
||||||
menu_func = (lambda self, context: self.layout.operator(AddHuman.bl_idname, icon='OUTLINER_OB_ARMATURE', text="Human (Meta-Rig)"))
|
bpy.types.INFO_MT_armature_add.append(menu_func)
|
||||||
|
|
||||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_armature_add, menu_func)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
bpy.ops.mesh.armature_human_advanced_add()
|
bpy.ops.mesh.armature_human_advanced_add()
|
||||||
|
|||||||
@@ -122,18 +122,16 @@ class AddTorus(bpy.types.Operator):
|
|||||||
|
|
||||||
ob_new.location = tuple(context.scene.cursor_location)
|
ob_new.location = tuple(context.scene.cursor_location)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
# Register the operator
|
# Register the operator
|
||||||
bpy.ops.add(AddTorus)
|
bpy.types.register(AddTorus)
|
||||||
|
|
||||||
# Add to a menu
|
|
||||||
import dynamic_menu
|
|
||||||
|
|
||||||
|
# Add to the menu
|
||||||
menu_func = (lambda self, context: self.layout.operator(AddTorus.bl_idname,
|
menu_func = (lambda self, context: self.layout.operator(AddTorus.bl_idname,
|
||||||
text="Torus", icon='MESH_DONUT'))
|
text="Torus", icon='MESH_DONUT'))
|
||||||
|
|
||||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_mesh_add, menu_func)
|
bpy.types.INFO_MT_mesh_add.append(menu_func)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
bpy.ops.mesh.primitive_torus_add()
|
bpy.ops.mesh.primitive_torus_add()
|
||||||
|
|||||||
@@ -79,10 +79,10 @@ def execute(context):
|
|||||||
try:
|
try:
|
||||||
line = sc.history[-1].line
|
line = sc.history[-1].line
|
||||||
except:
|
except:
|
||||||
return ('CANCELLED',)
|
return {'CANCELLED'}
|
||||||
|
|
||||||
if sc.console_type != 'PYTHON':
|
if sc.console_type != 'PYTHON':
|
||||||
return ('CANCELLED',)
|
return {'CANCELLED'}
|
||||||
|
|
||||||
console, stdout, stderr = get_console(hash(context.region))
|
console, stdout, stderr = get_console(hash(context.region))
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ def execute(context):
|
|||||||
if output_err:
|
if output_err:
|
||||||
add_scrollback(output_err, 'ERROR')
|
add_scrollback(output_err, 'ERROR')
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
def autocomplete(context):
|
def autocomplete(context):
|
||||||
@@ -150,10 +150,10 @@ def autocomplete(context):
|
|||||||
line = current_line.line
|
line = current_line.line
|
||||||
|
|
||||||
if not console:
|
if not console:
|
||||||
return ('CANCELLED',)
|
return {'CANCELLED'}
|
||||||
|
|
||||||
if sc.console_type != 'PYTHON':
|
if sc.console_type != 'PYTHON':
|
||||||
return ('CANCELLED',)
|
return {'CANCELLED'}
|
||||||
|
|
||||||
# This function isnt aware of the text editor or being an operator
|
# This function isnt aware of the text editor or being an operator
|
||||||
# just does the autocomp then copy its results back
|
# just does the autocomp then copy its results back
|
||||||
@@ -172,7 +172,7 @@ def autocomplete(context):
|
|||||||
|
|
||||||
context.area.tag_redraw()
|
context.area.tag_redraw()
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
def banner(context):
|
def banner(context):
|
||||||
@@ -195,4 +195,4 @@ def banner(context):
|
|||||||
console = get_console(hash(context.region))[0]
|
console = get_console(hash(context.region))[0]
|
||||||
console.locals["C"] = bpy.context
|
console.locals["C"] = bpy.context
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ def execute(context):
|
|||||||
try:
|
try:
|
||||||
line = sc.history[-1].line
|
line = sc.history[-1].line
|
||||||
except:
|
except:
|
||||||
return ('CANCELLED',)
|
return {'CANCELLED'}
|
||||||
|
|
||||||
bpy.ops.console.scrollback_append(text=sc.prompt + line, type='INPUT')
|
bpy.ops.console.scrollback_append(text=sc.prompt + line, type='INPUT')
|
||||||
|
|
||||||
@@ -60,13 +60,13 @@ def execute(context):
|
|||||||
remove_duplicates=True)
|
remove_duplicates=True)
|
||||||
|
|
||||||
sc.prompt = os.getcwd() + PROMPT
|
sc.prompt = os.getcwd() + PROMPT
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
def autocomplete(context):
|
def autocomplete(context):
|
||||||
# sc = context.space_data
|
# sc = context.space_data
|
||||||
# TODO
|
# TODO
|
||||||
return ('CANCELLED',)
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
|
||||||
def banner(context):
|
def banner(context):
|
||||||
@@ -75,4 +75,4 @@ def banner(context):
|
|||||||
shell_run("bash --version")
|
shell_run("bash --version")
|
||||||
sc.prompt = os.getcwd() + PROMPT
|
sc.prompt = os.getcwd() + PROMPT
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|||||||
@@ -65,11 +65,11 @@ class MeshSelectInteriorFaces(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
main(context)
|
main(context)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
# Register the operator
|
# Register the operator
|
||||||
bpy.ops.add(MeshSelectInteriorFaces)
|
bpy.types.register(MeshSelectInteriorFaces)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
bpy.ops.mesh.faces_select_interior()
|
bpy.ops.mesh.faces_select_interior()
|
||||||
|
|||||||
@@ -249,17 +249,16 @@ def mesh_faces_extend(me, faces, mat_idx = 0):
|
|||||||
|
|
||||||
|
|
||||||
def getSelectedEdges(context, me, ob):
|
def getSelectedEdges(context, me, ob):
|
||||||
MESH_MODE= context.scene.tool_settings.mesh_selection_mode
|
MESH_MODE = tuple(context.tool_settings.mesh_selection_mode)
|
||||||
|
context.tool_settings.mesh_selection_mode = False, True, False
|
||||||
|
|
||||||
if MESH_MODE in ('EDGE', 'VERTEX'):
|
if not MESH_MODE[2]:
|
||||||
context.scene.tool_settings.mesh_selection_mode = 'EDGE'
|
|
||||||
edges= [ ed for ed in me.edges if ed.selected ]
|
edges= [ ed for ed in me.edges if ed.selected ]
|
||||||
# print len(edges), len(me.edges)
|
# print len(edges), len(me.edges)
|
||||||
context.scene.tool_settings.mesh_selection_mode = MESH_MODE
|
context.scene.tool_settings.mesh_selection_mode = MESH_MODE
|
||||||
return edges
|
return edges
|
||||||
|
|
||||||
if MESH_MODE == 'FACE':
|
else:
|
||||||
context.scene.tool_settings.mesh_selection_mode = 'EDGE'
|
|
||||||
# value is [edge, face_sel_user_in]
|
# value is [edge, face_sel_user_in]
|
||||||
edge_dict= dict((ed.key, [ed, 0]) for ed in me.edges)
|
edge_dict= dict((ed.key, [ed, 0]) for ed in me.edges)
|
||||||
|
|
||||||
@@ -268,7 +267,7 @@ def getSelectedEdges(context, me, ob):
|
|||||||
for edkey in f.edge_keys:
|
for edkey in f.edge_keys:
|
||||||
edge_dict[edkey][1] += 1
|
edge_dict[edkey][1] += 1
|
||||||
|
|
||||||
context.scene.tool_settings.mesh_selection_mode = MESH_MODE
|
context.tool_settings.mesh_selection_mode = MESH_MODE
|
||||||
return [ ed_data[0] for ed_data in edge_dict.values() if ed_data[1] == 1 ]
|
return [ ed_data[0] for ed_data in edge_dict.values() if ed_data[1] == 1 ]
|
||||||
|
|
||||||
|
|
||||||
@@ -644,15 +643,14 @@ class MESH_OT_skin(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
main(context)
|
main(context)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
# Register the operator
|
# Register the operator
|
||||||
bpy.ops.add(MESH_OT_skin)
|
bpy.types.register(MESH_OT_skin)
|
||||||
|
|
||||||
# Add to a menu
|
# Add to a menu
|
||||||
import dynamic_menu
|
bpy.types.VIEW3D_MT_edit_mesh_faces.append((lambda self, context: self.layout.operator("mesh.skin", text="Bridge Faces")))
|
||||||
menu_item = dynamic_menu.add(bpy.types.VIEW3D_MT_edit_mesh_faces, (lambda self, context: self.layout.operator("mesh.skin", text="Bridge Faces")) )
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
bpy.ops.mesh.skin()
|
bpy.ops.mesh.skin()
|
||||||
|
|||||||
@@ -57,13 +57,13 @@ class SelectPattern(bpy.types.Operator):
|
|||||||
elif not self.properties.extend:
|
elif not self.properties.extend:
|
||||||
item.selected = False
|
item.selected = False
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
# return wm.invoke_props_popup(self, event)
|
# return wm.invoke_props_popup(self, event)
|
||||||
wm.invoke_props_popup(self, event)
|
wm.invoke_props_popup(self, event)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
@@ -84,27 +84,45 @@ class SubdivisionSet(bpy.types.Operator):
|
|||||||
bl_undo = True
|
bl_undo = True
|
||||||
|
|
||||||
level = IntProperty(name="Level",
|
level = IntProperty(name="Level",
|
||||||
default=1, min=0, max=100, soft_min=0, soft_max=6)
|
default=1, min=-100, max=100, soft_min=-6, soft_max=6)
|
||||||
|
|
||||||
|
relative = BoolProperty(name="Relative", description="Apply the subsurf level as an offset relative to the current level", default=False)
|
||||||
|
|
||||||
def poll(self, context):
|
def poll(self, context):
|
||||||
ob = context.active_object
|
obs = context.selected_editable_objects
|
||||||
return (ob and ob.type == 'MESH')
|
return (obs is not None)
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
level = self.properties.level
|
level = self.properties.level
|
||||||
|
relative = self.properties.relative
|
||||||
|
|
||||||
|
if relative and level == 0:
|
||||||
|
return {'CANCELLED'} # nothing to do
|
||||||
|
|
||||||
def set_object_subd(obj):
|
def set_object_subd(obj):
|
||||||
for mod in obj.modifiers:
|
for mod in obj.modifiers:
|
||||||
if mod.type == 'MULTIRES':
|
if mod.type == 'MULTIRES':
|
||||||
if level < mod.total_levels:
|
if level <= mod.total_levels:
|
||||||
if obj.mode == 'SCULPT' and mod.sculpt_levels != level:
|
if obj.mode == 'SCULPT':
|
||||||
mod.sculpt_levels = level
|
if relative:
|
||||||
elif obj.mode == 'OBJECT' and mod.levels != level:
|
mod.sculpt_levels += level
|
||||||
mod.levels = level
|
else:
|
||||||
|
if mod.sculpt_levels != level:
|
||||||
|
mod.sculpt_levels = level
|
||||||
|
elif obj.mode == 'OBJECT':
|
||||||
|
if relative:
|
||||||
|
mod.levels += level
|
||||||
|
else:
|
||||||
|
if mod.levels != level:
|
||||||
|
mod.levels = level
|
||||||
return
|
return
|
||||||
elif mod.type == 'SUBSURF':
|
elif mod.type == 'SUBSURF':
|
||||||
if mod.levels != level:
|
if relative:
|
||||||
mod.levels = level
|
mod.levels += level
|
||||||
|
else:
|
||||||
|
if mod.levels != level:
|
||||||
|
mod.levels = level
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# adda new modifier
|
# adda new modifier
|
||||||
@@ -114,7 +132,7 @@ class SubdivisionSet(bpy.types.Operator):
|
|||||||
for obj in context.selected_editable_objects:
|
for obj in context.selected_editable_objects:
|
||||||
set_object_subd(obj)
|
set_object_subd(obj)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class Retopo(bpy.types.Operator):
|
class Retopo(bpy.types.Operator):
|
||||||
@@ -128,9 +146,175 @@ class Retopo(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
import retopo
|
import retopo
|
||||||
retopo.main()
|
retopo.main()
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
bpy.ops.add(SelectPattern)
|
class ShapeTransfer(bpy.types.Operator):
|
||||||
bpy.ops.add(SubdivisionSet)
|
'''Copy the active objects current shape to other selected objects with the same number of verts'''
|
||||||
bpy.ops.add(Retopo)
|
|
||||||
|
bl_idname = "object.shape_key_transfer"
|
||||||
|
bl_label = "Transfer Shape Key"
|
||||||
|
bl_register = True
|
||||||
|
bl_undo = True
|
||||||
|
|
||||||
|
mode = EnumProperty(items=(
|
||||||
|
('OFFSET', "Offset", "Apply the relative positional offset"),
|
||||||
|
('RELATIVE_FACE', "Relative Face", "Calculate the geometricly relative position (using faces)."),
|
||||||
|
('RELATIVE_EDGE', "Relative Edge", "Calculate the geometricly relative position (using edges).")),
|
||||||
|
name="Transformation Mode",
|
||||||
|
description="Method to apply relative shape positions to the new shape",
|
||||||
|
default='OFFSET')
|
||||||
|
|
||||||
|
use_clamp = BoolProperty(name="Clamp Offset",
|
||||||
|
description="Clamp the transformation to the distance each vertex moves in the original shape.",
|
||||||
|
default=False)
|
||||||
|
|
||||||
|
def _main(self, ob_act, objects, mode='OFFSET', use_clamp=False):
|
||||||
|
def me_nos(verts):
|
||||||
|
return [v.normal.copy() for v in verts]
|
||||||
|
|
||||||
|
def me_cos(verts):
|
||||||
|
return [v.co.copy() for v in verts]
|
||||||
|
|
||||||
|
def ob_add_shape(ob):
|
||||||
|
me = ob.data
|
||||||
|
ob.add_shape_key(from_mix=False)
|
||||||
|
if len(me.shape_keys.keys) == 1:
|
||||||
|
ob.add_shape_key(from_mix=False) # we need a rest
|
||||||
|
ob.active_shape_key_index = len(me.shape_keys.keys) - 1
|
||||||
|
ob.shape_key_lock = True
|
||||||
|
|
||||||
|
from Geometry import BarycentricTransform
|
||||||
|
from Mathutils import Vector
|
||||||
|
|
||||||
|
if use_clamp and mode == 'OFFSET':
|
||||||
|
use_clamp = False
|
||||||
|
|
||||||
|
me = ob_act.data
|
||||||
|
|
||||||
|
orig_shape_coords = me_cos(ob_act.active_shape_key.data)
|
||||||
|
|
||||||
|
orig_normals = me_nos(me.verts)
|
||||||
|
orig_coords = me_cos(me.verts)
|
||||||
|
|
||||||
|
for ob_other in objects:
|
||||||
|
me_other = ob_other.data
|
||||||
|
if len(me_other.verts) != len(me.verts):
|
||||||
|
self.report({'WARNING'}, "Skipping '%s', vertex count differs" % ob_other.name)
|
||||||
|
continue
|
||||||
|
|
||||||
|
target_normals = me_nos(me_other.verts)
|
||||||
|
target_coords = me_cos(me_other.verts)
|
||||||
|
|
||||||
|
ob_add_shape(ob_other)
|
||||||
|
|
||||||
|
# editing the final coords, only list that stores wrapped coords
|
||||||
|
target_shape_coords = [v.co for v in ob_other.active_shape_key.data]
|
||||||
|
|
||||||
|
median_coords = [[] for i in range(len(me.verts))]
|
||||||
|
|
||||||
|
# Method 1, edge
|
||||||
|
if mode == 'OFFSET':
|
||||||
|
for i, vert_cos in enumerate(median_coords):
|
||||||
|
vert_cos.append(target_coords[i] + (orig_shape_coords[i] - orig_coords[i]))
|
||||||
|
|
||||||
|
elif mode == 'RELATIVE_FACE':
|
||||||
|
for face in me.faces:
|
||||||
|
i1, i2, i3, i4 = face.verts_raw
|
||||||
|
if i4 != 0:
|
||||||
|
pt = BarycentricTransform(orig_shape_coords[i1],
|
||||||
|
orig_coords[i4], orig_coords[i1], orig_coords[i2],
|
||||||
|
target_coords[i4], target_coords[i1], target_coords[i2])
|
||||||
|
median_coords[i1].append(pt)
|
||||||
|
|
||||||
|
pt = BarycentricTransform(orig_shape_coords[i2],
|
||||||
|
orig_coords[i1], orig_coords[i2], orig_coords[i3],
|
||||||
|
target_coords[i1], target_coords[i2], target_coords[i3])
|
||||||
|
median_coords[i2].append(pt)
|
||||||
|
|
||||||
|
pt = BarycentricTransform(orig_shape_coords[i3],
|
||||||
|
orig_coords[i2], orig_coords[i3], orig_coords[i4],
|
||||||
|
target_coords[i2], target_coords[i3], target_coords[i4])
|
||||||
|
median_coords[i3].append(pt)
|
||||||
|
|
||||||
|
pt = BarycentricTransform(orig_shape_coords[i4],
|
||||||
|
orig_coords[i3], orig_coords[i4], orig_coords[i1],
|
||||||
|
target_coords[i3], target_coords[i4], target_coords[i1])
|
||||||
|
median_coords[i4].append(pt)
|
||||||
|
|
||||||
|
else:
|
||||||
|
pt = BarycentricTransform(orig_shape_coords[i1],
|
||||||
|
orig_coords[i3], orig_coords[i1], orig_coords[i2],
|
||||||
|
target_coords[i3], target_coords[i1], target_coords[i2])
|
||||||
|
median_coords[i1].append(pt)
|
||||||
|
|
||||||
|
pt = BarycentricTransform(orig_shape_coords[i2],
|
||||||
|
orig_coords[i1], orig_coords[i2], orig_coords[i3],
|
||||||
|
target_coords[i1], target_coords[i2], target_coords[i3])
|
||||||
|
median_coords[i2].append(pt)
|
||||||
|
|
||||||
|
pt = BarycentricTransform(orig_shape_coords[i3],
|
||||||
|
orig_coords[i2], orig_coords[i3], orig_coords[i1],
|
||||||
|
target_coords[i2], target_coords[i3], target_coords[i1])
|
||||||
|
median_coords[i3].append(pt)
|
||||||
|
|
||||||
|
elif mode == 'RELATIVE_EDGE':
|
||||||
|
for ed in me.edges:
|
||||||
|
i1, i2 = ed.verts
|
||||||
|
v1, v2 = orig_coords[i1], orig_coords[i2]
|
||||||
|
edge_length = (v1 - v2).length
|
||||||
|
n1loc = v1 + orig_normals[i1] * edge_length
|
||||||
|
n2loc = v2 + orig_normals[i2] * edge_length
|
||||||
|
|
||||||
|
|
||||||
|
# now get the target nloc's
|
||||||
|
v1_to, v2_to = target_coords[i1], target_coords[i2]
|
||||||
|
edlen_to = (v1_to - v2_to).length
|
||||||
|
n1loc_to = v1_to + target_normals[i1] * edlen_to
|
||||||
|
n2loc_to = v2_to + target_normals[i2] * edlen_to
|
||||||
|
|
||||||
|
pt = BarycentricTransform(orig_shape_coords[i1],
|
||||||
|
v2, v1, n1loc,
|
||||||
|
v2_to, v1_to, n1loc_to)
|
||||||
|
median_coords[i1].append(pt)
|
||||||
|
|
||||||
|
pt = BarycentricTransform(orig_shape_coords[i2],
|
||||||
|
v1, v2, n2loc,
|
||||||
|
v1_to, v2_to, n2loc_to)
|
||||||
|
median_coords[i2].append(pt)
|
||||||
|
|
||||||
|
# apply the offsets to the new shape
|
||||||
|
from functools import reduce
|
||||||
|
VectorAdd = Vector.__add__
|
||||||
|
|
||||||
|
for i, vert_cos in enumerate(median_coords):
|
||||||
|
if vert_cos:
|
||||||
|
co = reduce(VectorAdd, vert_cos) / len(vert_cos)
|
||||||
|
|
||||||
|
if use_clamp:
|
||||||
|
# clamp to the same movement as the original
|
||||||
|
# breaks copy between different scaled meshes.
|
||||||
|
len_from = (orig_shape_coords[i] - orig_coords[i]).length
|
||||||
|
ofs = co - target_coords[i]
|
||||||
|
ofs.length = len_from
|
||||||
|
co = target_coords[i] + ofs
|
||||||
|
|
||||||
|
target_shape_coords[i][:] = co
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
def poll(self, context):
|
||||||
|
obj = context.active_object
|
||||||
|
return (obj and obj.mode != 'EDIT')
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
C = bpy.context
|
||||||
|
ob_act = C.active_object
|
||||||
|
objects = [ob for ob in C.selected_editable_objects if ob != ob_act]
|
||||||
|
return self._main(ob_act, objects, self.properties.mode, self.properties.use_clamp)
|
||||||
|
|
||||||
|
|
||||||
|
bpy.types.register(SelectPattern)
|
||||||
|
bpy.types.register(SubdivisionSet)
|
||||||
|
bpy.types.register(Retopo)
|
||||||
|
bpy.types.register(ShapeTransfer)
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class AddPresetBase(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
|
||||||
if not self.properties.name:
|
if not self.properties.name:
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
filename = self._as_filename(self.properties.name) + ".py"
|
filename = self._as_filename(self.properties.name) + ".py"
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ class AddPresetBase(bpy.types.Operator):
|
|||||||
|
|
||||||
file_preset.close()
|
file_preset.close()
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
@@ -61,7 +61,7 @@ class AddPresetBase(bpy.types.Operator):
|
|||||||
#return wm.invoke_props_popup(self, event)
|
#return wm.invoke_props_popup(self, event)
|
||||||
|
|
||||||
wm.invoke_props_popup(self, event)
|
wm.invoke_props_popup(self, event)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
class AddPresetRender(AddPresetBase):
|
class AddPresetRender(AddPresetBase):
|
||||||
@@ -125,6 +125,6 @@ class AddPresetCloth(AddPresetBase):
|
|||||||
|
|
||||||
preset_subdir = "cloth"
|
preset_subdir = "cloth"
|
||||||
|
|
||||||
bpy.ops.add(AddPresetRender)
|
bpy.types.register(AddPresetRender)
|
||||||
bpy.ops.add(AddPresetSSS)
|
bpy.types.register(AddPresetSSS)
|
||||||
bpy.ops.add(AddPresetCloth)
|
bpy.types.register(AddPresetCloth)
|
||||||
|
|||||||
@@ -17,37 +17,40 @@
|
|||||||
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#
|
#
|
||||||
# ***** END GPL LICENCE BLOCK *****
|
# ***** END GPL LICENCE BLOCK *****
|
||||||
# --------------------------------------------------------------------------
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
# History
|
# History
|
||||||
#
|
#
|
||||||
# Originally written by Matt Ebb
|
# Originally written by Matt Ebb
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import subprocess, os, platform
|
import subprocess
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
|
||||||
# from BKE_add_image_extension()
|
# from BKE_add_image_extension()
|
||||||
img_format_exts = {
|
img_format_exts = {
|
||||||
'IRIS':'.rgb',
|
'IRIS': '.rgb',
|
||||||
'RADHDR':'.hdr',
|
'RADHDR': '.hdr',
|
||||||
'PNG':'png',
|
'PNG': 'png',
|
||||||
'TARGA':'tga',
|
'TARGA': 'tga',
|
||||||
'RAWTARGA':'tga',
|
'RAWTARGA': 'tga',
|
||||||
'BMP':'bmp',
|
'BMP': 'bmp',
|
||||||
'TIFF':'tif',
|
'TIFF': 'tif',
|
||||||
'OPENEXR':'exr',
|
'OPENEXR': 'exr',
|
||||||
'MULTILAYER':'exr',
|
'MULTILAYER': 'exr',
|
||||||
'CINEON':'cin',
|
'CINEON': 'cin',
|
||||||
'DPX':'dpx',
|
'DPX': 'dpx',
|
||||||
'JPEG':'jpg',
|
'JPEG': 'jpg',
|
||||||
'JPEG2000':'jp2',
|
'JPEG2000': 'jp2',
|
||||||
'QUICKTIME_QTKIT':'mov',
|
'QUICKTIME_QTKIT': 'mov',
|
||||||
'QUICKTIME_CARBON':'mov',
|
'QUICKTIME_CARBON': 'mov',
|
||||||
'AVIRAW':'avi',
|
'AVIRAW': 'avi',
|
||||||
'AVIJPEG':'avi',
|
'AVIJPEG': 'avi',
|
||||||
'AVICODEC':'avi',
|
'AVICODEC': 'avi',
|
||||||
'XVID':'avi',
|
'XVID': 'avi',
|
||||||
'THEORA':'ogg',
|
'THEORA': 'ogg',
|
||||||
}
|
}
|
||||||
|
|
||||||
movie_formats = ('QUICKTIME_QTKIT',
|
movie_formats = ('QUICKTIME_QTKIT',
|
||||||
@@ -56,8 +59,8 @@ movie_formats = ('QUICKTIME_QTKIT',
|
|||||||
'AVIJPEG',
|
'AVIJPEG',
|
||||||
'AVICODEC',
|
'AVICODEC',
|
||||||
'XVID',
|
'XVID',
|
||||||
'THEORA'
|
'THEORA')
|
||||||
)
|
|
||||||
|
|
||||||
def guess_player_path(preset):
|
def guess_player_path(preset):
|
||||||
if preset == 'BLENDER24':
|
if preset == 'BLENDER24':
|
||||||
@@ -146,4 +149,4 @@ class PlayRenderedAnim(bpy.types.Operator):
|
|||||||
|
|
||||||
return('FINISHED',)
|
return('FINISHED',)
|
||||||
|
|
||||||
bpy.ops.add(PlayRenderedAnim)
|
bpy.types.register(PlayRenderedAnim)
|
||||||
|
|||||||
@@ -257,16 +257,13 @@ class FollowActiveQuads(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
main(context, self)
|
main(context, self)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
bpy.ops.add(FollowActiveQuads)
|
bpy.types.register(FollowActiveQuads)
|
||||||
|
|
||||||
# Add to a menu
|
# Add to a menu
|
||||||
import dynamic_menu
|
|
||||||
|
|
||||||
menu_func = (lambda self, context: self.layout.operator(FollowActiveQuads.bl_idname))
|
menu_func = (lambda self, context: self.layout.operator(FollowActiveQuads.bl_idname))
|
||||||
|
bpy.types.VIEW3D_MT_uv_map.append(menu_func)
|
||||||
menu_item = dynamic_menu.add(bpy.types.VIEW3D_MT_uv_map, menu_func)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
bpy.ops.uv.follow_active_quads()
|
bpy.ops.uv.follow_active_quads()
|
||||||
|
|||||||
@@ -1109,6 +1109,8 @@ def main(context, island_margin, projection_limit):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from bpy.props import *
|
from bpy.props import *
|
||||||
|
|
||||||
|
|
||||||
class SmartProject(bpy.types.Operator):
|
class SmartProject(bpy.types.Operator):
|
||||||
'''This script projection unwraps the selected faces of a mesh. it operates on all selected mesh objects, and can be used unwrap selected faces, or all faces.'''
|
'''This script projection unwraps the selected faces of a mesh. it operates on all selected mesh objects, and can be used unwrap selected faces, or all faces.'''
|
||||||
bl_idname = "uv.smart_project"
|
bl_idname = "uv.smart_project"
|
||||||
@@ -1130,18 +1132,15 @@ class SmartProject(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
main(context, self.properties.island_margin, self.properties.angle_limit)
|
main(context, self.properties.island_margin, self.properties.angle_limit)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
bpy.ops.add(SmartProject)
|
bpy.types.register(SmartProject)
|
||||||
|
|
||||||
# Add to a menu
|
# Add to a menu
|
||||||
import dynamic_menu
|
|
||||||
|
|
||||||
menu_func = (lambda self, context: self.layout.operator(SmartProject.bl_idname,
|
menu_func = (lambda self, context: self.layout.operator(SmartProject.bl_idname,
|
||||||
text="Smart Project"))
|
text="Smart Project"))
|
||||||
|
|
||||||
menu_item = dynamic_menu.add(bpy.types.VIEW3D_MT_uv_map, menu_func)
|
bpy.types.VIEW3D_MT_uv_map.append(menu_func)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
bpy.ops.uv.smart_project()
|
bpy.ops.uv.smart_project()
|
||||||
|
|
||||||
|
|||||||
@@ -158,24 +158,23 @@ class VertexPaintDirt(bpy.types.Operator):
|
|||||||
dirt_only = BoolProperty(name="Dirt Only", description="Dont calculate cleans for convex areas", default=False)
|
dirt_only = BoolProperty(name="Dirt Only", description="Dont calculate cleans for convex areas", default=False)
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
sce = context.scene
|
obj = context.object
|
||||||
ob = context.object
|
|
||||||
|
|
||||||
if not ob or ob.type != 'MESH':
|
if not obj or obj.type != 'MESH':
|
||||||
print('Error, no active mesh object, aborting.')
|
print('Error, no active mesh object, aborting.')
|
||||||
return('CANCELLED',)
|
return('CANCELLED',)
|
||||||
|
|
||||||
me = ob.data
|
mesh = obj.data
|
||||||
|
|
||||||
t = time.time()
|
t = time.time()
|
||||||
|
|
||||||
applyVertexDirt(me, self.properties.blur_iterations, self.properties.blur_strength, math.radians(self.properties.dirt_angle), math.radians(self.properties.clean_angle), self.properties.dirt_only)
|
applyVertexDirt(mesh, self.properties.blur_iterations, self.properties.blur_strength, math.radians(self.properties.dirt_angle), math.radians(self.properties.clean_angle), self.properties.dirt_only)
|
||||||
|
|
||||||
print('Dirt calculated in %.6f' % (time.time() - t))
|
print('Dirt calculated in %.6f' % (time.time() - t))
|
||||||
|
|
||||||
return('FINISHED',)
|
return('FINISHED',)
|
||||||
|
|
||||||
bpy.ops.add(VertexPaintDirt)
|
bpy.types.register(VertexPaintDirt)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
bpy.ops.mesh.vertex_paint_dirt()
|
bpy.ops.mesh.vertex_paint_dirt()
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class MESH_OT_delete_edgeloop(bpy.types.Operator):
|
|||||||
bpy.ops.mesh.select_more()
|
bpy.ops.mesh.select_more()
|
||||||
bpy.ops.mesh.remove_doubles()
|
bpy.ops.mesh.remove_doubles()
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
rna_path_prop = StringProperty(name="Context Attributes",
|
rna_path_prop = StringProperty(name="Context Attributes",
|
||||||
description="rna context string", maxlen=1024, default="")
|
description="rna context string", maxlen=1024, default="")
|
||||||
@@ -60,15 +60,16 @@ def context_path_validate(context, path):
|
|||||||
|
|
||||||
def execute_context_assign(self, context):
|
def execute_context_assign(self, context):
|
||||||
if context_path_validate(context, self.properties.path) is Ellipsis:
|
if context_path_validate(context, self.properties.path) is Ellipsis:
|
||||||
return ('PASS_THROUGH',)
|
return {'PASS_THROUGH'}
|
||||||
exec("context.%s=self.properties.value" % self.properties.path)
|
exec("context.%s=self.properties.value" % self.properties.path)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_context_set_boolean(bpy.types.Operator):
|
class WM_OT_context_set_boolean(bpy.types.Operator):
|
||||||
'''Set a context value.'''
|
'''Set a context value.'''
|
||||||
bl_idname = "wm.context_set_boolean"
|
bl_idname = "wm.context_set_boolean"
|
||||||
bl_label = "Context Set"
|
bl_label = "Context Set Boolean"
|
||||||
|
bl_undo = True
|
||||||
|
|
||||||
path = rna_path_prop
|
path = rna_path_prop
|
||||||
value = BoolProperty(name="Value",
|
value = BoolProperty(name="Value",
|
||||||
@@ -81,6 +82,7 @@ class WM_OT_context_set_int(bpy.types.Operator): # same as enum
|
|||||||
'''Set a context value.'''
|
'''Set a context value.'''
|
||||||
bl_idname = "wm.context_set_int"
|
bl_idname = "wm.context_set_int"
|
||||||
bl_label = "Context Set"
|
bl_label = "Context Set"
|
||||||
|
bl_undo = True
|
||||||
|
|
||||||
path = rna_path_prop
|
path = rna_path_prop
|
||||||
value = IntProperty(name="Value", description="Assign value", default=0)
|
value = IntProperty(name="Value", description="Assign value", default=0)
|
||||||
@@ -91,7 +93,8 @@ class WM_OT_context_set_int(bpy.types.Operator): # same as enum
|
|||||||
class WM_OT_context_set_float(bpy.types.Operator): # same as enum
|
class WM_OT_context_set_float(bpy.types.Operator): # same as enum
|
||||||
'''Set a context value.'''
|
'''Set a context value.'''
|
||||||
bl_idname = "wm.context_set_float"
|
bl_idname = "wm.context_set_float"
|
||||||
bl_label = "Context Set"
|
bl_label = "Context Set Float"
|
||||||
|
bl_undo = True
|
||||||
|
|
||||||
path = rna_path_prop
|
path = rna_path_prop
|
||||||
value = FloatProperty(name="Value",
|
value = FloatProperty(name="Value",
|
||||||
@@ -103,7 +106,8 @@ class WM_OT_context_set_float(bpy.types.Operator): # same as enum
|
|||||||
class WM_OT_context_set_string(bpy.types.Operator): # same as enum
|
class WM_OT_context_set_string(bpy.types.Operator): # same as enum
|
||||||
'''Set a context value.'''
|
'''Set a context value.'''
|
||||||
bl_idname = "wm.context_set_string"
|
bl_idname = "wm.context_set_string"
|
||||||
bl_label = "Context Set"
|
bl_label = "Context Set String"
|
||||||
|
bl_undo = True
|
||||||
|
|
||||||
path = rna_path_prop
|
path = rna_path_prop
|
||||||
value = StringProperty(name="Value",
|
value = StringProperty(name="Value",
|
||||||
@@ -115,7 +119,8 @@ class WM_OT_context_set_string(bpy.types.Operator): # same as enum
|
|||||||
class WM_OT_context_set_enum(bpy.types.Operator):
|
class WM_OT_context_set_enum(bpy.types.Operator):
|
||||||
'''Set a context value.'''
|
'''Set a context value.'''
|
||||||
bl_idname = "wm.context_set_enum"
|
bl_idname = "wm.context_set_enum"
|
||||||
bl_label = "Context Set"
|
bl_label = "Context Set Enum"
|
||||||
|
bl_undo = True
|
||||||
|
|
||||||
path = rna_path_prop
|
path = rna_path_prop
|
||||||
value = StringProperty(name="Value",
|
value = StringProperty(name="Value",
|
||||||
@@ -125,27 +130,48 @@ class WM_OT_context_set_enum(bpy.types.Operator):
|
|||||||
execute = execute_context_assign
|
execute = execute_context_assign
|
||||||
|
|
||||||
|
|
||||||
|
class WM_OT_context_set_value(bpy.types.Operator):
|
||||||
|
'''Set a context value.'''
|
||||||
|
bl_idname = "wm.context_set_value"
|
||||||
|
bl_label = "Context Set Value"
|
||||||
|
bl_undo = True
|
||||||
|
|
||||||
|
path = rna_path_prop
|
||||||
|
value = StringProperty(name="Value",
|
||||||
|
description="Assignment value (as a string)",
|
||||||
|
maxlen=1024, default="")
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
if context_path_validate(context, self.properties.path) is Ellipsis:
|
||||||
|
return {'PASS_THROUGH'}
|
||||||
|
exec("context.%s=%s" % (self.properties.path, self.properties.value))
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_context_toggle(bpy.types.Operator):
|
class WM_OT_context_toggle(bpy.types.Operator):
|
||||||
'''Toggle a context value.'''
|
'''Toggle a context value.'''
|
||||||
bl_idname = "wm.context_toggle"
|
bl_idname = "wm.context_toggle"
|
||||||
bl_label = "Context Toggle"
|
bl_label = "Context Toggle"
|
||||||
|
bl_undo = True
|
||||||
|
|
||||||
path = rna_path_prop
|
path = rna_path_prop
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
|
||||||
if context_path_validate(context, self.properties.path) is Ellipsis:
|
if context_path_validate(context, self.properties.path) is Ellipsis:
|
||||||
return ('PASS_THROUGH',)
|
return {'PASS_THROUGH'}
|
||||||
|
|
||||||
exec("context.%s=not (context.%s)" %
|
exec("context.%s=not (context.%s)" %
|
||||||
(self.properties.path, self.properties.path))
|
(self.properties.path, self.properties.path))
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_context_toggle_enum(bpy.types.Operator):
|
class WM_OT_context_toggle_enum(bpy.types.Operator):
|
||||||
'''Toggle a context value.'''
|
'''Toggle a context value.'''
|
||||||
bl_idname = "wm.context_toggle_enum"
|
bl_idname = "wm.context_toggle_enum"
|
||||||
bl_label = "Context Toggle Values"
|
bl_label = "Context Toggle Values"
|
||||||
|
bl_undo = True
|
||||||
|
|
||||||
path = rna_path_prop
|
path = rna_path_prop
|
||||||
value_1 = StringProperty(name="Value", \
|
value_1 = StringProperty(name="Value", \
|
||||||
@@ -157,14 +183,14 @@ class WM_OT_context_toggle_enum(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
|
||||||
if context_path_validate(context, self.properties.path) is Ellipsis:
|
if context_path_validate(context, self.properties.path) is Ellipsis:
|
||||||
return ('PASS_THROUGH',)
|
return {'PASS_THROUGH'}
|
||||||
|
|
||||||
exec("context.%s = ['%s', '%s'][context.%s!='%s']" % \
|
exec("context.%s = ['%s', '%s'][context.%s!='%s']" % \
|
||||||
(self.properties.path, self.properties.value_1,\
|
(self.properties.path, self.properties.value_1,\
|
||||||
self.properties.value_2, self.properties.path,
|
self.properties.value_2, self.properties.path,
|
||||||
self.properties.value_2))
|
self.properties.value_2))
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_context_cycle_int(bpy.types.Operator):
|
class WM_OT_context_cycle_int(bpy.types.Operator):
|
||||||
@@ -172,6 +198,8 @@ class WM_OT_context_cycle_int(bpy.types.Operator):
|
|||||||
vertex keys, groups' etc.'''
|
vertex keys, groups' etc.'''
|
||||||
bl_idname = "wm.context_cycle_int"
|
bl_idname = "wm.context_cycle_int"
|
||||||
bl_label = "Context Int Cycle"
|
bl_label = "Context Int Cycle"
|
||||||
|
bl_undo = True
|
||||||
|
|
||||||
path = rna_path_prop
|
path = rna_path_prop
|
||||||
reverse = rna_reverse_prop
|
reverse = rna_reverse_prop
|
||||||
|
|
||||||
@@ -179,7 +207,7 @@ class WM_OT_context_cycle_int(bpy.types.Operator):
|
|||||||
|
|
||||||
value = context_path_validate(context, self.properties.path)
|
value = context_path_validate(context, self.properties.path)
|
||||||
if value is Ellipsis:
|
if value is Ellipsis:
|
||||||
return ('PASS_THROUGH',)
|
return {'PASS_THROUGH'}
|
||||||
|
|
||||||
self.properties.value = value
|
self.properties.value = value
|
||||||
if self.properties.reverse:
|
if self.properties.reverse:
|
||||||
@@ -196,13 +224,14 @@ class WM_OT_context_cycle_int(bpy.types.Operator):
|
|||||||
self.properties.value = - (1 << 32)
|
self.properties.value = - (1 << 32)
|
||||||
execute_context_assign(self, context)
|
execute_context_assign(self, context)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_context_cycle_enum(bpy.types.Operator):
|
class WM_OT_context_cycle_enum(bpy.types.Operator):
|
||||||
'''Toggle a context value.'''
|
'''Toggle a context value.'''
|
||||||
bl_idname = "wm.context_cycle_enum"
|
bl_idname = "wm.context_cycle_enum"
|
||||||
bl_label = "Context Enum Cycle"
|
bl_label = "Context Enum Cycle"
|
||||||
|
bl_undo = True
|
||||||
|
|
||||||
path = rna_path_prop
|
path = rna_path_prop
|
||||||
reverse = rna_reverse_prop
|
reverse = rna_reverse_prop
|
||||||
@@ -211,7 +240,7 @@ class WM_OT_context_cycle_enum(bpy.types.Operator):
|
|||||||
|
|
||||||
value = context_path_validate(context, self.properties.path)
|
value = context_path_validate(context, self.properties.path)
|
||||||
if value is Ellipsis:
|
if value is Ellipsis:
|
||||||
return ('PASS_THROUGH',)
|
return {'PASS_THROUGH'}
|
||||||
|
|
||||||
orig_value = value
|
orig_value = value
|
||||||
|
|
||||||
@@ -247,7 +276,7 @@ class WM_OT_context_cycle_enum(bpy.types.Operator):
|
|||||||
|
|
||||||
# set the new value
|
# set the new value
|
||||||
exec("context.%s=advance_enum" % self.properties.path)
|
exec("context.%s=advance_enum" % self.properties.path)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
doc_id = StringProperty(name="Doc ID",
|
doc_id = StringProperty(name="Doc ID",
|
||||||
description="", maxlen=1024, default="", hidden=True)
|
description="", maxlen=1024, default="", hidden=True)
|
||||||
@@ -275,26 +304,26 @@ class WM_OT_doc_view(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
id_split = self.properties.doc_id.split('.')
|
id_split = self.properties.doc_id.split('.')
|
||||||
if len(id_split) == 1: # rna, class
|
if len(id_split) == 1: # rna, class
|
||||||
url = '%s/bpy.types.%s-class.html' % (self._prefix, id_split[0])
|
url = '%s/bpy.types.%s.html' % (self._prefix, id_split[0])
|
||||||
elif len(id_split) == 2: # rna, class.prop
|
elif len(id_split) == 2: # rna, class.prop
|
||||||
class_name, class_prop = id_split
|
class_name, class_prop = id_split
|
||||||
|
|
||||||
if hasattr(bpy.types, class_name.upper() + '_OT_' + class_prop):
|
if hasattr(bpy.types, class_name.upper() + '_OT_' + class_prop):
|
||||||
url = '%s/bpy.ops.%s-module.html#%s' % \
|
url = '%s/bpy.ops.%s.html#bpy.ops.%s.%s' % \
|
||||||
(self._prefix, class_name, class_prop)
|
(self._prefix, class_name, class_name, class_prop)
|
||||||
else:
|
else:
|
||||||
# It so happens that epydoc nests these
|
# It so happens that epydoc nests these, not sphinx
|
||||||
class_name_full = self._nested_class_string(class_name)
|
# class_name_full = self._nested_class_string(class_name)
|
||||||
url = '%s/bpy.types.%s-class.html#%s' % \
|
url = '%s/bpy.types.%s.html#bpy.types.%s.%s' % \
|
||||||
(self._prefix, class_name_full, class_prop)
|
(self._prefix, class_name, class_name, class_prop)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return ('PASS_THROUGH',)
|
return {'PASS_THROUGH'}
|
||||||
|
|
||||||
import webbrowser
|
import webbrowser
|
||||||
webbrowser.open(url)
|
webbrowser.open(url)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_doc_edit(bpy.types.Operator):
|
class WM_OT_doc_edit(bpy.types.Operator):
|
||||||
@@ -325,7 +354,7 @@ class WM_OT_doc_edit(bpy.types.Operator):
|
|||||||
class_name, class_prop = doc_id.split('.')
|
class_name, class_prop = doc_id.split('.')
|
||||||
|
|
||||||
if not doc_new:
|
if not doc_new:
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
# check if this is an operator
|
# check if this is an operator
|
||||||
op_name = class_name.upper() + '_OT_' + class_prop
|
op_name = class_name.upper() + '_OT_' + class_prop
|
||||||
@@ -338,7 +367,7 @@ class WM_OT_doc_edit(bpy.types.Operator):
|
|||||||
rna = op_class.bl_rna
|
rna = op_class.bl_rna
|
||||||
doc_orig = rna.description
|
doc_orig = rna.description
|
||||||
if doc_orig == doc_new:
|
if doc_orig == doc_new:
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
print("op - old:'%s' -> new:'%s'" % (doc_orig, doc_new))
|
print("op - old:'%s' -> new:'%s'" % (doc_orig, doc_new))
|
||||||
upload["title"] = 'OPERATOR %s:%s' % (doc_id, doc_orig)
|
upload["title"] = 'OPERATOR %s:%s' % (doc_id, doc_orig)
|
||||||
@@ -350,7 +379,7 @@ class WM_OT_doc_edit(bpy.types.Operator):
|
|||||||
rna = getattr(bpy.types, class_name).bl_rna
|
rna = getattr(bpy.types, class_name).bl_rna
|
||||||
doc_orig = rna.properties[class_prop].description
|
doc_orig = rna.properties[class_prop].description
|
||||||
if doc_orig == doc_new:
|
if doc_orig == doc_new:
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
print("rna - old:'%s' -> new:'%s'" % (doc_orig, doc_new))
|
print("rna - old:'%s' -> new:'%s'" % (doc_orig, doc_new))
|
||||||
upload["title"] = 'RNA %s:%s' % (doc_id, doc_orig)
|
upload["title"] = 'RNA %s:%s' % (doc_id, doc_orig)
|
||||||
@@ -359,7 +388,7 @@ class WM_OT_doc_edit(bpy.types.Operator):
|
|||||||
|
|
||||||
self._send_xmlrpc(upload)
|
self._send_xmlrpc(upload)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
@@ -374,28 +403,29 @@ class WM_OT_reload_scripts(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
MOD = type(bpy)
|
MOD = type(bpy)
|
||||||
bpy.load_scripts(True)
|
bpy.load_scripts(True)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
bpy.ops.add(MESH_OT_delete_edgeloop)
|
bpy.types.register(MESH_OT_delete_edgeloop)
|
||||||
|
|
||||||
bpy.ops.add(WM_OT_context_set_boolean)
|
bpy.types.register(WM_OT_context_set_boolean)
|
||||||
bpy.ops.add(WM_OT_context_set_int)
|
bpy.types.register(WM_OT_context_set_int)
|
||||||
bpy.ops.add(WM_OT_context_set_float)
|
bpy.types.register(WM_OT_context_set_float)
|
||||||
bpy.ops.add(WM_OT_context_set_string)
|
bpy.types.register(WM_OT_context_set_string)
|
||||||
bpy.ops.add(WM_OT_context_set_enum)
|
bpy.types.register(WM_OT_context_set_enum)
|
||||||
bpy.ops.add(WM_OT_context_toggle)
|
bpy.types.register(WM_OT_context_set_value)
|
||||||
bpy.ops.add(WM_OT_context_toggle_enum)
|
bpy.types.register(WM_OT_context_toggle)
|
||||||
bpy.ops.add(WM_OT_context_cycle_enum)
|
bpy.types.register(WM_OT_context_toggle_enum)
|
||||||
bpy.ops.add(WM_OT_context_cycle_int)
|
bpy.types.register(WM_OT_context_cycle_enum)
|
||||||
|
bpy.types.register(WM_OT_context_cycle_int)
|
||||||
|
|
||||||
bpy.ops.add(WM_OT_doc_view)
|
bpy.types.register(WM_OT_doc_view)
|
||||||
bpy.ops.add(WM_OT_doc_edit)
|
bpy.types.register(WM_OT_doc_edit)
|
||||||
|
|
||||||
bpy.ops.add(WM_OT_reload_scripts)
|
bpy.types.register(WM_OT_reload_scripts)
|
||||||
|
|
||||||
# experemental!
|
# experemental!
|
||||||
import rna_prop_ui
|
import rna_prop_ui
|
||||||
bpy.ops.add(rna_prop_ui.WM_OT_properties_edit)
|
bpy.types.register(rna_prop_ui.WM_OT_properties_edit)
|
||||||
bpy.ops.add(rna_prop_ui.WM_OT_properties_add)
|
bpy.types.register(rna_prop_ui.WM_OT_properties_add)
|
||||||
bpy.ops.add(rna_prop_ui.WM_OT_properties_remove)
|
bpy.types.register(rna_prop_ui.WM_OT_properties_remove)
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ bpy.context.scene.render_data.resolution_percentage = 100
|
|||||||
bpy.context.scene.render_data.pixel_aspect_x = 1
|
bpy.context.scene.render_data.pixel_aspect_x = 1
|
||||||
bpy.context.scene.render_data.pixel_aspect_y = 1
|
bpy.context.scene.render_data.pixel_aspect_y = 1
|
||||||
bpy.context.scene.render_data.fps = 24
|
bpy.context.scene.render_data.fps = 24
|
||||||
bpy.context.scene.render_data.fps_base = 1
|
bpy.context.scene.render_data.fps_base = 1
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ bpy.context.scene.render_data.resolution_percentage = 100
|
|||||||
bpy.context.scene.render_data.pixel_aspect_x = 1
|
bpy.context.scene.render_data.pixel_aspect_x = 1
|
||||||
bpy.context.scene.render_data.pixel_aspect_y = 1
|
bpy.context.scene.render_data.pixel_aspect_y = 1
|
||||||
bpy.context.scene.render_data.fps = 24
|
bpy.context.scene.render_data.fps = 24
|
||||||
bpy.context.scene.render_data.fps_base = 1
|
bpy.context.scene.render_data.fps_base = 1
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ bpy.context.scene.render_data.resolution_percentage = 100
|
|||||||
bpy.context.scene.render_data.pixel_aspect_x = 54
|
bpy.context.scene.render_data.pixel_aspect_x = 54
|
||||||
bpy.context.scene.render_data.pixel_aspect_y = 51
|
bpy.context.scene.render_data.pixel_aspect_y = 51
|
||||||
bpy.context.scene.render_data.fps = 25
|
bpy.context.scene.render_data.fps = 25
|
||||||
bpy.context.scene.render_data.fps_base = 1
|
bpy.context.scene.render_data.fps_base = 1
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ bpy.context.scene.render_data.resolution_percentage = 100
|
|||||||
bpy.context.scene.render_data.pixel_aspect_x = 64
|
bpy.context.scene.render_data.pixel_aspect_x = 64
|
||||||
bpy.context.scene.render_data.pixel_aspect_y = 45
|
bpy.context.scene.render_data.pixel_aspect_y = 45
|
||||||
bpy.context.scene.render_data.fps = 25
|
bpy.context.scene.render_data.fps = 25
|
||||||
bpy.context.scene.render_data.fps_base = 1
|
bpy.context.scene.render_data.fps_base = 1
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class ExportSomeData(bpy.types.Operator):
|
|||||||
|
|
||||||
write_some_data(self.properties.path, context, self.properties.use_setting)
|
write_some_data(self.properties.path, context, self.properties.use_setting)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
@@ -38,7 +38,7 @@ class ExportSomeData(bpy.types.Operator):
|
|||||||
if True:
|
if True:
|
||||||
# File selector
|
# File selector
|
||||||
wm.add_fileselect(self) # will run self.execute()
|
wm.add_fileselect(self) # will run self.execute()
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
elif 0:
|
elif 0:
|
||||||
# Redo popup
|
# Redo popup
|
||||||
return wm.invoke_props_popup(self, event) #
|
return wm.invoke_props_popup(self, event) #
|
||||||
@@ -46,13 +46,11 @@ class ExportSomeData(bpy.types.Operator):
|
|||||||
return self.execute(context)
|
return self.execute(context)
|
||||||
|
|
||||||
|
|
||||||
bpy.ops.add(ExportSomeData)
|
bpy.types.register(ExportSomeData)
|
||||||
|
|
||||||
# Only needed if you want to add into a dynamic menu
|
# Only needed if you want to add into a dynamic menu
|
||||||
import dynamic_menu
|
|
||||||
menu_func = lambda self, context: self.layout.operator("export.some_data", text="Example Exporter...")
|
menu_func = lambda self, context: self.layout.operator("export.some_data", text="Example Exporter...")
|
||||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
|
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||||
|
|
||||||
# Use for running this script directly
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
bpy.ops.export.some_data(path="/tmp/test.ply")
|
bpy.ops.export.some_data(path="/tmp/test.ply")
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ class SimpleOperator(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
main(context)
|
main(context)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
bpy.ops.add(SimpleOperator)
|
bpy.types.register(SimpleOperator)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
bpy.ops.object.simple_operator()
|
bpy.ops.object.simple_operator()
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ class DATA_PT_iksolver_itasc(DataButtonsPanel):
|
|||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(ob.pose, "ik_solver")
|
row.prop(ob.pose, "ik_solver")
|
||||||
|
|
||||||
if itasc:
|
if itasc:
|
||||||
layout.prop(itasc, "mode", expand=True)
|
layout.prop(itasc, "mode", expand=True)
|
||||||
simulation = (itasc.mode == 'SIMULATION')
|
simulation = (itasc.mode == 'SIMULATION')
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ class Reload(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
DATA_PT_template.templates[:] = metarig_templates()
|
DATA_PT_template.templates[:] = metarig_templates()
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
def rigify_report_exception(operator, exception):
|
def rigify_report_exception(operator, exception):
|
||||||
@@ -180,7 +180,7 @@ class Generate(bpy.types.Operator):
|
|||||||
except rigify.RigifyError as rig_exception:
|
except rigify.RigifyError as rig_exception:
|
||||||
rigify_report_exception(self, rig_exception)
|
rigify_report_exception(self, rig_exception)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class Validate(bpy.types.Operator):
|
class Validate(bpy.types.Operator):
|
||||||
@@ -196,7 +196,7 @@ class Validate(bpy.types.Operator):
|
|||||||
rigify.validate_rig(context, context.object)
|
rigify.validate_rig(context, context.object)
|
||||||
except rigify.RigifyError as rig_exception:
|
except rigify.RigifyError as rig_exception:
|
||||||
rigify_report_exception(self, rig_exception)
|
rigify_report_exception(self, rig_exception)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class Sample(bpy.types.Operator):
|
class Sample(bpy.types.Operator):
|
||||||
@@ -219,7 +219,7 @@ class Sample(bpy.types.Operator):
|
|||||||
if obj_gen:
|
if obj_gen:
|
||||||
obj_gen.location.x = i * 1.0
|
obj_gen.location.x = i * 1.0
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class Graph(bpy.types.Operator):
|
class Graph(bpy.types.Operator):
|
||||||
@@ -244,7 +244,7 @@ class Graph(bpy.types.Operator):
|
|||||||
os.system("dot -Tpng %s > %s; gnome-open %s &" % (path_dot, path_png, path_png))
|
os.system("dot -Tpng %s > %s; gnome-open %s &" % (path_dot, path_png, path_png))
|
||||||
#os.system("python /b/xdot.py '%s' &" % path_dot)
|
#os.system("python /b/xdot.py '%s' &" % path_dot)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class AsScript(bpy.types.Operator):
|
class AsScript(bpy.types.Operator):
|
||||||
@@ -267,7 +267,7 @@ class AsScript(bpy.types.Operator):
|
|||||||
file.write(code)
|
file.write(code)
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
import os
|
import os
|
||||||
@@ -275,7 +275,7 @@ class AsScript(bpy.types.Operator):
|
|||||||
self.properties.path = os.path.splitext(bpy.data.filename)[0] + "-" + bpy.utils.clean_name(obj.name) + ".py"
|
self.properties.path = os.path.splitext(bpy.data.filename)[0] + "-" + bpy.utils.clean_name(obj.name) + ".py"
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
# operators that use the GUI
|
# operators that use the GUI
|
||||||
@@ -294,7 +294,7 @@ class ActiveAssign(bpy.types.Operator):
|
|||||||
pose_templates = scene.pose_templates
|
pose_templates = scene.pose_templates
|
||||||
template_name = DATA_PT_template.templates[pose_templates.active_template_index]
|
template_name = DATA_PT_template.templates[pose_templates.active_template_index]
|
||||||
context.active_pose_bone["type"] = template_name
|
context.active_pose_bone["type"] = template_name
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class ActiveClear(bpy.types.Operator):
|
class ActiveClear(bpy.types.Operator):
|
||||||
@@ -310,14 +310,10 @@ class ActiveClear(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
del context.active_pose_bone["type"]
|
del context.active_pose_bone["type"]
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
import space_info
|
class INFO_MT_armature_metarig_add(bpy.types.Menu):
|
||||||
import dynamic_menu
|
|
||||||
|
|
||||||
|
|
||||||
class INFO_MT_armature_metarig_add(dynamic_menu.DynMenu):
|
|
||||||
bl_idname = "INFO_MT_armature_metarig_add"
|
bl_idname = "INFO_MT_armature_metarig_add"
|
||||||
bl_label = "Meta-Rig"
|
bl_label = "Meta-Rig"
|
||||||
|
|
||||||
@@ -336,18 +332,19 @@ bpy.types.register(DATA_PT_template)
|
|||||||
bpy.types.register(PoseTemplateSettings)
|
bpy.types.register(PoseTemplateSettings)
|
||||||
bpy.types.register(PoseTemplate)
|
bpy.types.register(PoseTemplate)
|
||||||
|
|
||||||
bpy.ops.add(Reload)
|
bpy.types.register(Reload)
|
||||||
bpy.ops.add(Generate)
|
bpy.types.register(Generate)
|
||||||
bpy.ops.add(Validate)
|
bpy.types.register(Validate)
|
||||||
bpy.ops.add(Sample)
|
bpy.types.register(Sample)
|
||||||
bpy.ops.add(Graph)
|
bpy.types.register(Graph)
|
||||||
bpy.ops.add(AsScript)
|
bpy.types.register(AsScript)
|
||||||
|
|
||||||
bpy.ops.add(ActiveAssign)
|
bpy.types.register(ActiveAssign)
|
||||||
bpy.ops.add(ActiveClear)
|
bpy.types.register(ActiveClear)
|
||||||
|
|
||||||
|
|
||||||
bpy.types.register(INFO_MT_armature_metarig_add)
|
bpy.types.register(INFO_MT_armature_metarig_add)
|
||||||
|
|
||||||
|
import space_info
|
||||||
menu_func = (lambda self, context: self.layout.menu("INFO_MT_armature_metarig_add", icon='OUTLINER_OB_ARMATURE'))
|
menu_func = (lambda self, context: self.layout.menu("INFO_MT_armature_metarig_add", icon='OUTLINER_OB_ARMATURE'))
|
||||||
menu_item = dynamic_menu.add(bpy.types.INFO_MT_armature_add, menu_func)
|
space_info.INFO_MT_armature_add.append(menu_func)
|
||||||
|
|||||||
@@ -602,16 +602,24 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
|||||||
layout.label(text="See Soft Body panel.")
|
layout.label(text="See Soft Body panel.")
|
||||||
|
|
||||||
def SOLIDIFY(self, layout, ob, md, wide_ui):
|
def SOLIDIFY(self, layout, ob, md, wide_ui):
|
||||||
|
layout.prop(md, "offset")
|
||||||
|
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.prop(md, "offset")
|
col.label(text="Crease:")
|
||||||
|
col.prop(md, "edge_crease_inner",text="Inner")
|
||||||
|
col.prop(md, "edge_crease_outer", text="Outer")
|
||||||
|
col.prop(md, "edge_crease_rim", text="Rim")
|
||||||
|
|
||||||
|
if wide_ui:
|
||||||
|
col = split.column()
|
||||||
|
col.label()
|
||||||
col.prop(md, "use_rim")
|
col.prop(md, "use_rim")
|
||||||
col.prop(md, "use_even_offset")
|
col.prop(md, "use_even_offset")
|
||||||
col.prop(md, "use_quality_normals")
|
col.prop(md, "use_quality_normals")
|
||||||
col.prop(md, "edge_crease_inner")
|
|
||||||
col.prop(md, "edge_crease_outer")
|
# col = layout.column()
|
||||||
col.prop(md, "edge_crease_rim")
|
|
||||||
# col.label(text="Vertex Group:")
|
# col.label(text="Vertex Group:")
|
||||||
# col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
|
# col.prop_object(md, "vertex_group", ob, "vertex_groups", text="")
|
||||||
|
|
||||||
@@ -638,14 +646,15 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
|||||||
def UV_PROJECT(self, layout, ob, md, wide_ui):
|
def UV_PROJECT(self, layout, ob, md, wide_ui):
|
||||||
if ob.type == 'MESH':
|
if ob.type == 'MESH':
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.label(text="UV Layer:")
|
col.label(text="Image:")
|
||||||
col.prop_object(md, "uv_layer", ob.data, "uv_textures", text="")
|
col.prop(md, "image", text="")
|
||||||
|
|
||||||
if wide_ui:
|
if wide_ui:
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.label(text="Image:")
|
col.label(text="UV Layer:")
|
||||||
col.prop(md, "image", text="")
|
col.prop_object(md, "uv_layer", ob.data, "uv_textures", text="")
|
||||||
|
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
col = split.column()
|
col = split.column()
|
||||||
@@ -720,4 +729,4 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
|||||||
col.prop(md, "width", slider=True)
|
col.prop(md, "width", slider=True)
|
||||||
col.prop(md, "narrowness", slider=True)
|
col.prop(md, "narrowness", slider=True)
|
||||||
|
|
||||||
bpy.types.register(DATA_PT_modifiers)
|
bpy.types.register(DATA_PT_modifiers)
|
||||||
@@ -274,8 +274,7 @@ class RENDER_PT_game_stereo(RenderButtonsPanel):
|
|||||||
# stereo:
|
# stereo:
|
||||||
if stereo_mode == 'STEREO':
|
if stereo_mode == 'STEREO':
|
||||||
layout.prop(gs, "stereo_mode")
|
layout.prop(gs, "stereo_mode")
|
||||||
# layout.label(text="To do: Focal Length") # to be done after 2.5alpha0 is out
|
layout.prop(gs, "eye_separation")
|
||||||
# layout.label(text="To do: Eye Separation") # to be done after 2.5alpha0 is out
|
|
||||||
|
|
||||||
# dome:
|
# dome:
|
||||||
elif stereo_mode == 'DOME':
|
elif stereo_mode == 'DOME':
|
||||||
|
|||||||
@@ -264,6 +264,7 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel):
|
|||||||
|
|
||||||
layout.label(text="Diagnostics:")
|
layout.label(text="Diagnostics:")
|
||||||
layout.prop(softbody, "diagnose")
|
layout.prop(softbody, "diagnose")
|
||||||
|
layout.prop(softbody, "estimate_matrix")
|
||||||
|
|
||||||
|
|
||||||
class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel):
|
class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel):
|
||||||
|
|||||||
@@ -581,8 +581,42 @@ class RENDER_PT_stamp(RenderButtonsPanel):
|
|||||||
sub.prop(rd, "stamp_note_text", text="")
|
sub.prop(rd, "stamp_note_text", text="")
|
||||||
|
|
||||||
|
|
||||||
bpy.types.register(RENDER_MT_presets)
|
class RENDER_PT_bake(RenderButtonsPanel):
|
||||||
|
bl_label = "Bake"
|
||||||
|
bl_default_closed = True
|
||||||
|
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
rd = context.scene.render_data
|
||||||
|
wide_ui = context.region.width > narrowui
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.operator("object.bake_image", icon='RENDER_STILL')
|
||||||
|
row.prop(rd, "bake_type", text="")
|
||||||
|
|
||||||
|
col = layout.column()
|
||||||
|
col.active = (rd.bake_type == 'NORMALS')
|
||||||
|
col.prop(rd, "bake_normal_space")
|
||||||
|
# col.prop(rd, "bake_aa_mode")
|
||||||
|
# col.prop(rd, "bake_enable_aa")
|
||||||
|
|
||||||
|
col = layout.column()
|
||||||
|
row = col.row(align=True)
|
||||||
|
row.prop(rd, "bake_active")
|
||||||
|
row.prop(rd, "bake_normalized")
|
||||||
|
|
||||||
|
row = col.row(align=True)
|
||||||
|
row.prop(rd, "bake_clear")
|
||||||
|
row.prop(rd, "bake_margin")
|
||||||
|
|
||||||
|
row = col.row(align=True)
|
||||||
|
row.prop(rd, "bake_distance")
|
||||||
|
row.prop(rd, "bake_bias")
|
||||||
|
|
||||||
|
|
||||||
|
bpy.types.register(RENDER_MT_presets)
|
||||||
bpy.types.register(RENDER_PT_render)
|
bpy.types.register(RENDER_PT_render)
|
||||||
bpy.types.register(RENDER_PT_layers)
|
bpy.types.register(RENDER_PT_layers)
|
||||||
bpy.types.register(RENDER_PT_dimensions)
|
bpy.types.register(RENDER_PT_dimensions)
|
||||||
@@ -593,3 +627,4 @@ bpy.types.register(RENDER_PT_encoding)
|
|||||||
bpy.types.register(RENDER_PT_performance)
|
bpy.types.register(RENDER_PT_performance)
|
||||||
bpy.types.register(RENDER_PT_post_processing)
|
bpy.types.register(RENDER_PT_post_processing)
|
||||||
bpy.types.register(RENDER_PT_stamp)
|
bpy.types.register(RENDER_PT_stamp)
|
||||||
|
bpy.types.register(RENDER_PT_bake)
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ class ConsoleExec(bpy.types.Operator):
|
|||||||
return execute(context)
|
return execute(context)
|
||||||
else:
|
else:
|
||||||
print("Error: bpy.ops.console.execute_" + sc.language + " - not found")
|
print("Error: bpy.ops.console.execute_" + sc.language + " - not found")
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class ConsoleAutocomplete(bpy.types.Operator):
|
class ConsoleAutocomplete(bpy.types.Operator):
|
||||||
@@ -153,11 +153,13 @@ class ConsoleAutocomplete(bpy.types.Operator):
|
|||||||
return autocomplete(context)
|
return autocomplete(context)
|
||||||
else:
|
else:
|
||||||
print("Error: bpy.ops.console.autocomplete_" + sc.language + " - not found")
|
print("Error: bpy.ops.console.autocomplete_" + sc.language + " - not found")
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class ConsoleBanner(bpy.types.Operator):
|
class ConsoleBanner(bpy.types.Operator):
|
||||||
|
'''Print a message whem the terminal initializes'''
|
||||||
bl_idname = "console.banner"
|
bl_idname = "console.banner"
|
||||||
|
bl_label = "Console Banner"
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
sc = context.space_data
|
sc = context.space_data
|
||||||
@@ -173,12 +175,13 @@ class ConsoleBanner(bpy.types.Operator):
|
|||||||
return banner(context)
|
return banner(context)
|
||||||
else:
|
else:
|
||||||
print("Error: bpy.ops.console.banner_" + sc.language + " - not found")
|
print("Error: bpy.ops.console.banner_" + sc.language + " - not found")
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class ConsoleLanguage(bpy.types.Operator):
|
class ConsoleLanguage(bpy.types.Operator):
|
||||||
'''Set the current language for this console'''
|
'''Set the current language for this console'''
|
||||||
bl_idname = "console.language"
|
bl_idname = "console.language"
|
||||||
|
bl_label = "Console Language"
|
||||||
language = StringProperty(name="Language", maxlen=32, default="")
|
language = StringProperty(name="Language", maxlen=32, default="")
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
@@ -193,7 +196,7 @@ class ConsoleLanguage(bpy.types.Operator):
|
|||||||
bpy.ops.console.history_append(text="", current_character=0,
|
bpy.ops.console.history_append(text="", current_character=0,
|
||||||
remove_duplicates=True)
|
remove_duplicates=True)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
bpy.types.register(CONSOLE_HT_header)
|
bpy.types.register(CONSOLE_HT_header)
|
||||||
@@ -202,9 +205,9 @@ bpy.types.register(CONSOLE_MT_report)
|
|||||||
bpy.types.register(CONSOLE_MT_language)
|
bpy.types.register(CONSOLE_MT_language)
|
||||||
|
|
||||||
# Stubs that call the language operators
|
# Stubs that call the language operators
|
||||||
bpy.ops.add(ConsoleExec)
|
bpy.types.register(ConsoleExec)
|
||||||
bpy.ops.add(ConsoleAutocomplete)
|
bpy.types.register(ConsoleAutocomplete)
|
||||||
bpy.ops.add(ConsoleBanner)
|
bpy.types.register(ConsoleBanner)
|
||||||
|
|
||||||
# Set the language and call the banner
|
# Set the language and call the banner
|
||||||
bpy.ops.add(ConsoleLanguage)
|
bpy.types.register(ConsoleLanguage)
|
||||||
|
|||||||
@@ -19,9 +19,6 @@
|
|||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
import dynamic_menu
|
|
||||||
# reload(dynamic_menu)
|
|
||||||
|
|
||||||
|
|
||||||
class INFO_HT_header(bpy.types.Header):
|
class INFO_HT_header(bpy.types.Header):
|
||||||
bl_space_type = 'INFO'
|
bl_space_type = 'INFO'
|
||||||
@@ -79,7 +76,7 @@ class INFO_MT_file(bpy.types.Menu):
|
|||||||
layout.operator("wm.read_homefile", text="New", icon='NEW')
|
layout.operator("wm.read_homefile", text="New", icon='NEW')
|
||||||
layout.operator_context = 'INVOKE_AREA'
|
layout.operator_context = 'INVOKE_AREA'
|
||||||
layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
|
layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
|
||||||
layout.operator_menu_enum("wm.open_recentfile", "file", text="Open Recent")
|
layout.menu("INFO_MT_file_open_recent")
|
||||||
layout.operator("wm.recover_last_session")
|
layout.operator("wm.recover_last_session")
|
||||||
layout.operator("wm.recover_auto_save", text="Recover Auto Save...")
|
layout.operator("wm.recover_auto_save", text="Recover Auto Save...")
|
||||||
|
|
||||||
@@ -115,21 +112,22 @@ class INFO_MT_file(bpy.types.Menu):
|
|||||||
layout.operator_context = 'EXEC_AREA'
|
layout.operator_context = 'EXEC_AREA'
|
||||||
layout.operator("wm.exit_blender", text="Quit", icon='QUIT')
|
layout.operator("wm.exit_blender", text="Quit", icon='QUIT')
|
||||||
|
|
||||||
# test for expanding menus
|
|
||||||
'''
|
class INFO_MT_file_open_recent(bpy.types.Menu):
|
||||||
class INFO_MT_file_more(INFO_MT_file):
|
bl_idname = "INFO_MT_file_open_recent"
|
||||||
bl_label = "File"
|
bl_label = "Open Recent..."
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
|
import os
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
layout.operator_context = 'EXEC_AREA'
|
||||||
|
file = open(os.path.join(bpy.home, ".Blog"), "rU")
|
||||||
|
for line in file:
|
||||||
|
line = line.rstrip()
|
||||||
|
layout.operator("wm.open_mainfile", text=line, icon='FILE_BLEND').path = line
|
||||||
|
file.close()
|
||||||
|
|
||||||
layout.operator("wm.read_homefile", text="TESTING ")
|
class INFO_MT_file_import(bpy.types.Menu):
|
||||||
|
|
||||||
dynamic_menu.setup(INFO_MT_file_more)
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
class INFO_MT_file_import(dynamic_menu.DynMenu):
|
|
||||||
bl_idname = "INFO_MT_file_import"
|
bl_idname = "INFO_MT_file_import"
|
||||||
bl_label = "Import"
|
bl_label = "Import"
|
||||||
|
|
||||||
@@ -138,7 +136,7 @@ class INFO_MT_file_import(dynamic_menu.DynMenu):
|
|||||||
self.layout.operator("wm.collada_import", text="COLLADA (.dae)...")
|
self.layout.operator("wm.collada_import", text="COLLADA (.dae)...")
|
||||||
|
|
||||||
|
|
||||||
class INFO_MT_file_export(dynamic_menu.DynMenu):
|
class INFO_MT_file_export(bpy.types.Menu):
|
||||||
bl_idname = "INFO_MT_file_export"
|
bl_idname = "INFO_MT_file_export"
|
||||||
bl_label = "Export"
|
bl_label = "Export"
|
||||||
|
|
||||||
@@ -164,9 +162,9 @@ class INFO_MT_file_external_data(bpy.types.Menu):
|
|||||||
layout.operator("file.find_missing_files")
|
layout.operator("file.find_missing_files")
|
||||||
|
|
||||||
|
|
||||||
class INFO_MT_mesh_add(dynamic_menu.DynMenu):
|
class INFO_MT_mesh_add(bpy.types.Menu):
|
||||||
bl_idname = "INFO_MT_mesh_add"
|
bl_idname = "INFO_MT_mesh_add"
|
||||||
bl_label = "Mesh"
|
bl_label = "Add Mesh"
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
@@ -183,7 +181,7 @@ class INFO_MT_mesh_add(dynamic_menu.DynMenu):
|
|||||||
layout.operator("mesh.primitive_monkey_add", icon='MESH_MONKEY', text="Monkey")
|
layout.operator("mesh.primitive_monkey_add", icon='MESH_MONKEY', text="Monkey")
|
||||||
|
|
||||||
|
|
||||||
class INFO_MT_armature_add(dynamic_menu.DynMenu):
|
class INFO_MT_armature_add(bpy.types.Menu):
|
||||||
bl_idname = "INFO_MT_armature_add"
|
bl_idname = "INFO_MT_armature_add"
|
||||||
bl_label = "Armature"
|
bl_label = "Armature"
|
||||||
|
|
||||||
@@ -290,6 +288,7 @@ class INFO_MT_help(bpy.types.Menu):
|
|||||||
|
|
||||||
bpy.types.register(INFO_HT_header)
|
bpy.types.register(INFO_HT_header)
|
||||||
bpy.types.register(INFO_MT_file)
|
bpy.types.register(INFO_MT_file)
|
||||||
|
bpy.types.register(INFO_MT_file_open_recent)
|
||||||
bpy.types.register(INFO_MT_file_import)
|
bpy.types.register(INFO_MT_file_import)
|
||||||
bpy.types.register(INFO_MT_file_export)
|
bpy.types.register(INFO_MT_file_export)
|
||||||
bpy.types.register(INFO_MT_file_external_data)
|
bpy.types.register(INFO_MT_file_external_data)
|
||||||
@@ -308,7 +307,7 @@ class HelpOperator(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
import webbrowser
|
import webbrowser
|
||||||
webbrowser.open(self._url)
|
webbrowser.open(self._url)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class HELP_OT_manual(HelpOperator):
|
class HELP_OT_manual(HelpOperator):
|
||||||
@@ -391,14 +390,14 @@ class HELP_OT_operator_cheat_sheet(bpy.types.Operator):
|
|||||||
textblock.write('\n'.join(op_strings))
|
textblock.write('\n'.join(op_strings))
|
||||||
textblock.name = "OperatorList.txt"
|
textblock.name = "OperatorList.txt"
|
||||||
print("See OperatorList.txt textblock")
|
print("See OperatorList.txt textblock")
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
bpy.ops.add(HELP_OT_manual)
|
bpy.types.register(HELP_OT_manual)
|
||||||
bpy.ops.add(HELP_OT_release_logs)
|
bpy.types.register(HELP_OT_release_logs)
|
||||||
bpy.ops.add(HELP_OT_blender_website)
|
bpy.types.register(HELP_OT_blender_website)
|
||||||
bpy.ops.add(HELP_OT_blender_eshop)
|
bpy.types.register(HELP_OT_blender_eshop)
|
||||||
bpy.ops.add(HELP_OT_developer_community)
|
bpy.types.register(HELP_OT_developer_community)
|
||||||
bpy.ops.add(HELP_OT_user_community)
|
bpy.types.register(HELP_OT_user_community)
|
||||||
bpy.ops.add(HELP_OT_report_bug)
|
bpy.types.register(HELP_OT_report_bug)
|
||||||
bpy.ops.add(HELP_OT_python_api)
|
bpy.types.register(HELP_OT_python_api)
|
||||||
bpy.ops.add(HELP_OT_operator_cheat_sheet)
|
bpy.types.register(HELP_OT_operator_cheat_sheet)
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ class TIME_MT_view(bpy.types.Menu):
|
|||||||
|
|
||||||
layout.operator("marker.camera_bind")
|
layout.operator("marker.camera_bind")
|
||||||
|
|
||||||
|
|
||||||
class TIME_MT_frame(bpy.types.Menu):
|
class TIME_MT_frame(bpy.types.Menu):
|
||||||
bl_label = "Frame"
|
bl_label = "Frame"
|
||||||
|
|
||||||
|
|||||||
@@ -21,71 +21,79 @@ import bpy
|
|||||||
|
|
||||||
KM_HIERARCHY = [
|
KM_HIERARCHY = [
|
||||||
('Window', 'EMPTY', 'WINDOW', []), # file save, window change, exit
|
('Window', 'EMPTY', 'WINDOW', []), # file save, window change, exit
|
||||||
('Screen Editing', 'EMPTY', 'WINDOW', []), # resizing, action corners
|
('Screen', 'EMPTY', 'WINDOW', [ # full screen, undo, screenshot
|
||||||
('Screen', 'EMPTY', 'WINDOW', []), # full screen, undo, screenshot
|
('Screen Editing', 'EMPTY', 'WINDOW', []), # resizing, action corners
|
||||||
|
]),
|
||||||
|
|
||||||
('View2D', 'EMPTY', 'WINDOW', []), # view 2d navigation (per region)
|
('View2D', 'EMPTY', 'WINDOW', []), # view 2d navigation (per region)
|
||||||
('Frames', 'EMPTY', 'WINDOW', []), # frame navigation (per region)
|
('View2D Buttons List', 'EMPTY', 'WINDOW', []), # view 2d with buttons navigation
|
||||||
('Header', 'EMPTY', 'WINDOW', []), # header stuff (per region)
|
('Header', 'EMPTY', 'WINDOW', []), # header stuff (per region)
|
||||||
('Markers', 'EMPTY', 'WINDOW', []), # markers (per region)
|
|
||||||
('Animation', 'EMPTY', 'WINDOW', []), # frame change on click, preview range (per region)
|
|
||||||
('Grease Pencil', 'EMPTY', 'WINDOW', []), # grease pencil stuff (per region)
|
('Grease Pencil', 'EMPTY', 'WINDOW', []), # grease pencil stuff (per region)
|
||||||
|
|
||||||
('View2D Buttons List', 'EMPTY', 'WINDOW', []), # view 2d with buttons navigation
|
('3D View', 'VIEW_3D', 'WINDOW', [ # view 3d navigation and generic stuff (select, transform)
|
||||||
('Animation_Channels', 'EMPTY', 'WINDOW', []),
|
|
||||||
|
|
||||||
('Buttons Generic', 'PROPERTIES', 'WINDOW', []), # align context menu
|
|
||||||
('TimeLine', 'TIMELINE', 'WINDOW', []),
|
|
||||||
('Outliner', 'OUTLINER', 'WINDOW', []),
|
|
||||||
|
|
||||||
('View3D', 'VIEW_3D', 'WINDOW', [ # view 3d navigation and generic stuff (select, transform)
|
|
||||||
('Pose', 'EMPTY', 'WINDOW', []),
|
|
||||||
('Object Mode', 'EMPTY', 'WINDOW', []),
|
('Object Mode', 'EMPTY', 'WINDOW', []),
|
||||||
('Vertex Paint', 'EMPTY', 'WINDOW', []),
|
('Mesh', 'EMPTY', 'WINDOW', []),
|
||||||
('Weight Paint', 'EMPTY', 'WINDOW', []),
|
|
||||||
('Face Mask', 'EMPTY', 'WINDOW', []),
|
|
||||||
('Sculpt', 'EMPTY', 'WINDOW', []),
|
|
||||||
('EditMesh', 'EMPTY', 'WINDOW', []),
|
|
||||||
('Curve', 'EMPTY', 'WINDOW', []),
|
('Curve', 'EMPTY', 'WINDOW', []),
|
||||||
('Armature', 'EMPTY', 'WINDOW', []),
|
('Armature', 'EMPTY', 'WINDOW', []),
|
||||||
('Metaball', 'EMPTY', 'WINDOW', []),
|
('Metaball', 'EMPTY', 'WINDOW', []),
|
||||||
('Lattice', 'EMPTY', 'WINDOW', []),
|
('Lattice', 'EMPTY', 'WINDOW', []),
|
||||||
('Armature_Sketch', 'EMPTY', 'WINDOW', []),
|
|
||||||
('Particle', 'EMPTY', 'WINDOW', []),
|
|
||||||
('Font', 'EMPTY', 'WINDOW', []),
|
('Font', 'EMPTY', 'WINDOW', []),
|
||||||
('Object Non-modal', 'EMPTY', 'WINDOW', []), # mode change
|
|
||||||
|
('Pose', 'EMPTY', 'WINDOW', []),
|
||||||
|
|
||||||
|
('Vertex Paint', 'EMPTY', 'WINDOW', []),
|
||||||
|
('Weight Paint', 'EMPTY', 'WINDOW', []),
|
||||||
|
('Face Mask', 'EMPTY', 'WINDOW', []),
|
||||||
('Image Paint', 'EMPTY', 'WINDOW', []), # image and view3d
|
('Image Paint', 'EMPTY', 'WINDOW', []), # image and view3d
|
||||||
('View3D Generic', 'VIEW_3D', 'WINDOW', []) # toolbar and properties
|
('Sculpt', 'EMPTY', 'WINDOW', []),
|
||||||
|
|
||||||
|
('Armature Sketch', 'EMPTY', 'WINDOW', []),
|
||||||
|
('Particle', 'EMPTY', 'WINDOW', []),
|
||||||
|
|
||||||
|
('Object Non-modal', 'EMPTY', 'WINDOW', []), # mode change
|
||||||
|
|
||||||
|
('3D View Generic', 'VIEW_3D', 'WINDOW', []) # toolbar and properties
|
||||||
]),
|
]),
|
||||||
('GraphEdit Keys', 'GRAPH_EDITOR', 'WINDOW', [
|
|
||||||
('GraphEdit Generic', 'GRAPH_EDITOR', 'WINDOW', [])
|
('Frames', 'EMPTY', 'WINDOW', []), # frame navigation (per region)
|
||||||
|
('Markers', 'EMPTY', 'WINDOW', []), # markers (per region)
|
||||||
|
('Animation', 'EMPTY', 'WINDOW', []), # frame change on click, preview range (per region)
|
||||||
|
('Animation Channels', 'EMPTY', 'WINDOW', []),
|
||||||
|
('Graph Editor', 'GRAPH_EDITOR', 'WINDOW', [
|
||||||
|
('Graph Editor Generic', 'GRAPH_EDITOR', 'WINDOW', [])
|
||||||
|
]),
|
||||||
|
('Dopesheet', 'DOPESHEET_EDITOR', 'WINDOW', []),
|
||||||
|
('NLA Editor', 'NLA_EDITOR', 'WINDOW', [
|
||||||
|
('NLA Channels', 'NLA_EDITOR', 'WINDOW', []),
|
||||||
|
('NLA Generic', 'NLA_EDITOR', 'WINDOW', [])
|
||||||
]),
|
]),
|
||||||
|
|
||||||
('Image', 'IMAGE_EDITOR', 'WINDOW', [
|
('Image', 'IMAGE_EDITOR', 'WINDOW', [
|
||||||
('UVEdit', 'EMPTY', 'WINDOW', []), # image (reverse order, UVEdit before Image
|
('UV Editor', 'EMPTY', 'WINDOW', []), # image (reverse order, UVEdit before Image
|
||||||
('Image Paint', 'EMPTY', 'WINDOW', []), # image and view3d
|
('Image Paint', 'EMPTY', 'WINDOW', []), # image and view3d
|
||||||
('Image Generic', 'IMAGE_EDITOR', 'WINDOW', [])
|
('Image Generic', 'IMAGE_EDITOR', 'WINDOW', [])
|
||||||
]),
|
]),
|
||||||
|
|
||||||
('Node Generic', 'NODE_EDITOR', 'WINDOW', [
|
('Timeline', 'TIMELINE', 'WINDOW', []),
|
||||||
('Node', 'NODE_EDITOR', 'WINDOW', [])
|
('Outliner', 'OUTLINER', 'WINDOW', []),
|
||||||
|
|
||||||
|
('Node Editor', 'NODE_EDITOR', 'WINDOW', [
|
||||||
|
('Node Generic', 'NODE_EDITOR', 'WINDOW', [])
|
||||||
]),
|
]),
|
||||||
('File', 'FILE_BROWSER', 'WINDOW', [
|
('Sequencer', 'SEQUENCE_EDITOR', 'WINDOW', []),
|
||||||
('FileMain', 'FILE_BROWSER', 'WINDOW', []),
|
('Logic Editor', 'LOGIC_EDITOR', 'WINDOW', []),
|
||||||
('FileButtons', 'FILE_BROWSER', 'WINDOW', [])
|
|
||||||
]),
|
('File Browser', 'FILE_BROWSER', 'WINDOW', [
|
||||||
('Action_Keys', 'DOPESHEET_EDITOR', 'WINDOW', []),
|
('File Browser Main', 'FILE_BROWSER', 'WINDOW', []),
|
||||||
('NLA Generic', 'NLA_EDITOR', 'WINDOW', [
|
('File Browser Buttons', 'FILE_BROWSER', 'WINDOW', [])
|
||||||
('NLA Channels', 'NLA_EDITOR', 'WINDOW', []),
|
|
||||||
('NLA Data', 'NLA_EDITOR', 'WINDOW', [])
|
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
('Property Editor', 'PROPERTIES', 'WINDOW', []), # align context menu
|
||||||
|
|
||||||
('Script', 'SCRIPTS_WINDOW', 'WINDOW', []),
|
('Script', 'SCRIPTS_WINDOW', 'WINDOW', []),
|
||||||
('Text', 'TEXT_EDITOR', 'WINDOW', []),
|
('Text', 'TEXT_EDITOR', 'WINDOW', []),
|
||||||
('Sequencer', 'SEQUENCE_EDITOR', 'WINDOW', []),
|
|
||||||
('Logic Generic', 'LOGIC_EDITOR', 'WINDOW', []),
|
|
||||||
('Console', 'CONSOLE', 'WINDOW', []),
|
('Console', 'CONSOLE', 'WINDOW', []),
|
||||||
|
|
||||||
|
|
||||||
('View3D Gesture Circle', 'EMPTY', 'WINDOW', []),
|
('View3D Gesture Circle', 'EMPTY', 'WINDOW', []),
|
||||||
('Gesture Border', 'EMPTY', 'WINDOW', []),
|
('Gesture Border', 'EMPTY', 'WINDOW', []),
|
||||||
('Standard Modal Map', 'EMPTY', 'WINDOW', []),
|
('Standard Modal Map', 'EMPTY', 'WINDOW', []),
|
||||||
@@ -503,8 +511,6 @@ class USERPREF_PT_system(bpy.types.Panel):
|
|||||||
sub.template_color_ramp(system, "weight_color_range", expand=True)
|
sub.template_color_ramp(system, "weight_color_range", expand=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class USERPREF_PT_theme(bpy.types.Panel):
|
class USERPREF_PT_theme(bpy.types.Panel):
|
||||||
bl_space_type = 'USER_PREFERENCES'
|
bl_space_type = 'USER_PREFERENCES'
|
||||||
bl_label = "Themes"
|
bl_label = "Themes"
|
||||||
@@ -1254,10 +1260,10 @@ class USERPREF_PT_input(bpy.types.Panel):
|
|||||||
userpref = context.user_preferences
|
userpref = context.user_preferences
|
||||||
return (userpref.active_section == 'INPUT')
|
return (userpref.active_section == 'INPUT')
|
||||||
|
|
||||||
def draw_entry(self, kc, entry, col, level = 0):
|
def draw_entry(self, kc, entry, col, level=0):
|
||||||
idname, spaceid, regionid, children = entry
|
idname, spaceid, regionid, children = entry
|
||||||
|
|
||||||
km = kc.find_keymap(idname, space_type = spaceid, region_type = regionid)
|
km = kc.find_keymap(idname, space_type=spaceid, region_type=regionid)
|
||||||
|
|
||||||
if km:
|
if km:
|
||||||
self.draw_km(kc, km, children, col, level)
|
self.draw_km(kc, km, children, col, level)
|
||||||
@@ -1266,9 +1272,9 @@ class USERPREF_PT_input(bpy.types.Panel):
|
|||||||
indentpx = 16
|
indentpx = 16
|
||||||
if level == 0:
|
if level == 0:
|
||||||
level = 0.0001 # Tweak so that a percentage of 0 won't split by half
|
level = 0.0001 # Tweak so that a percentage of 0 won't split by half
|
||||||
indent = level*indentpx / bpy.context.region.width
|
indent = level * indentpx / bpy.context.region.width
|
||||||
|
|
||||||
split=layout.split(percentage=indent)
|
split = layout.split(percentage=indent)
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col = split.column()
|
col = split.column()
|
||||||
return col
|
return col
|
||||||
@@ -1309,7 +1315,7 @@ class USERPREF_PT_input(bpy.types.Panel):
|
|||||||
self.draw_kmi(kc, km, kmi, col, level + 1)
|
self.draw_kmi(kc, km, kmi, col, level + 1)
|
||||||
|
|
||||||
# "Add New" at end of keymap item list
|
# "Add New" at end of keymap item list
|
||||||
col = self.indented_layout(col, level+1)
|
col = self.indented_layout(col, level + 1)
|
||||||
subcol = col.split(percentage=0.2).column()
|
subcol = col.split(percentage=0.2).column()
|
||||||
subcol.active = km.user_defined
|
subcol.active = km.user_defined
|
||||||
subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
|
subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
|
||||||
@@ -1324,7 +1330,6 @@ class USERPREF_PT_input(bpy.types.Panel):
|
|||||||
for entry in children:
|
for entry in children:
|
||||||
self.draw_entry(kc, entry, col, level + 1)
|
self.draw_entry(kc, entry, col, level + 1)
|
||||||
|
|
||||||
|
|
||||||
def draw_kmi(self, kc, km, kmi, layout, level):
|
def draw_kmi(self, kc, km, kmi, layout, level):
|
||||||
layout.set_context_pointer("keyitem", kmi)
|
layout.set_context_pointer("keyitem", kmi)
|
||||||
|
|
||||||
@@ -1475,8 +1480,9 @@ class USERPREF_PT_input(bpy.types.Panel):
|
|||||||
if len(filtered_items) != 0:
|
if len(filtered_items) != 0:
|
||||||
km = km.active()
|
km = km.active()
|
||||||
|
|
||||||
|
layout.set_context_pointer("keymap", km)
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
col.set_context_pointer("keymap", km)
|
|
||||||
row = col.row()
|
row = col.row()
|
||||||
row.label(text=km.name, icon="DOT")
|
row.label(text=km.name, icon="DOT")
|
||||||
|
|
||||||
@@ -1491,6 +1497,12 @@ class USERPREF_PT_input(bpy.types.Panel):
|
|||||||
for kmi in filtered_items:
|
for kmi in filtered_items:
|
||||||
self.draw_kmi(kc, km, kmi, col, 1)
|
self.draw_kmi(kc, km, kmi, col, 1)
|
||||||
|
|
||||||
|
# "Add New" at end of keymap item list
|
||||||
|
col = self.indented_layout(layout, 1)
|
||||||
|
subcol = col.split(percentage=0.2).column()
|
||||||
|
subcol.active = km.user_defined
|
||||||
|
subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
|
||||||
|
|
||||||
def draw_hierarchy(self, defkc, layout):
|
def draw_hierarchy(self, defkc, layout):
|
||||||
for entry in KM_HIERARCHY:
|
for entry in KM_HIERARCHY:
|
||||||
self.draw_entry(defkc, entry, layout)
|
self.draw_entry(defkc, entry, layout)
|
||||||
@@ -1540,13 +1552,15 @@ bpy.types.register(USERPREF_PT_input)
|
|||||||
|
|
||||||
from bpy.props import *
|
from bpy.props import *
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_keyconfig_test(bpy.types.Operator):
|
class WM_OT_keyconfig_test(bpy.types.Operator):
|
||||||
"Test keyconfig for conflicts."
|
"Test keyconfig for conflicts."
|
||||||
bl_idname = "wm.keyconfig_test"
|
bl_idname = "wm.keyconfig_test"
|
||||||
bl_label = "Test Key Configuration for Conflicts"
|
bl_label = "Test Key Configuration for Conflicts"
|
||||||
|
|
||||||
def testEntry(self, kc, entry, src = None, parent = None):
|
def testEntry(self, kc, entry, src=None, parent=None):
|
||||||
result = False
|
result = False
|
||||||
|
|
||||||
def kmistr(kmi):
|
def kmistr(kmi):
|
||||||
if km.modal:
|
if km.modal:
|
||||||
s = ["kmi = km.add_modal_item(\'%s\', \'%s\', \'%s\'" % (kmi.propvalue, kmi.type, kmi.value)]
|
s = ["kmi = km.add_modal_item(\'%s\', \'%s\', \'%s\'" % (kmi.propvalue, kmi.type, kmi.value)]
|
||||||
@@ -1566,9 +1580,9 @@ class WM_OT_keyconfig_test(bpy.types.Operator):
|
|||||||
s.append(", oskey=True")
|
s.append(", oskey=True")
|
||||||
if kmi.key_modifier and kmi.key_modifier != 'NONE':
|
if kmi.key_modifier and kmi.key_modifier != 'NONE':
|
||||||
s.append(", key_modifier=\'%s\'" % kmi.key_modifier)
|
s.append(", key_modifier=\'%s\'" % kmi.key_modifier)
|
||||||
|
|
||||||
s.append(")\n")
|
s.append(")\n")
|
||||||
|
|
||||||
props = kmi.properties
|
props = kmi.properties
|
||||||
|
|
||||||
if props is not None:
|
if props is not None:
|
||||||
@@ -1578,16 +1592,16 @@ class WM_OT_keyconfig_test(bpy.types.Operator):
|
|||||||
value = _string_value(value)
|
value = _string_value(value)
|
||||||
if value != "":
|
if value != "":
|
||||||
s.append("kmi.properties.%s = %s\n" % (pname, value))
|
s.append("kmi.properties.%s = %s\n" % (pname, value))
|
||||||
|
|
||||||
return "".join(s).strip()
|
return "".join(s).strip()
|
||||||
|
|
||||||
idname, spaceid, regionid, children = entry
|
idname, spaceid, regionid, children = entry
|
||||||
|
|
||||||
km = kc.find_keymap(idname, space_type = spaceid, region_type = regionid)
|
km = kc.find_keymap(idname, space_type=spaceid, region_type=regionid)
|
||||||
|
|
||||||
if km:
|
if km:
|
||||||
km = km.active()
|
km = km.active()
|
||||||
|
|
||||||
if src:
|
if src:
|
||||||
for item in km.items:
|
for item in km.items:
|
||||||
if src.compare(item):
|
if src.compare(item):
|
||||||
@@ -1597,14 +1611,14 @@ class WM_OT_keyconfig_test(bpy.types.Operator):
|
|||||||
print(km.name)
|
print(km.name)
|
||||||
print(kmistr(item))
|
print(kmistr(item))
|
||||||
result = True
|
result = True
|
||||||
|
|
||||||
for child in children:
|
for child in children:
|
||||||
if self.testEntry(kc, child, src, parent):
|
if self.testEntry(kc, child, src, parent):
|
||||||
result = True
|
result = True
|
||||||
else:
|
else:
|
||||||
for i in range(len(km.items)):
|
for i in range(len(km.items)):
|
||||||
src = km.items[i]
|
src = km.items[i]
|
||||||
|
|
||||||
for child in children:
|
for child in children:
|
||||||
if self.testEntry(kc, child, src, km):
|
if self.testEntry(kc, child, src, km):
|
||||||
result = True
|
result = True
|
||||||
@@ -1617,28 +1631,29 @@ class WM_OT_keyconfig_test(bpy.types.Operator):
|
|||||||
print(kmistr(src))
|
print(kmistr(src))
|
||||||
print(kmistr(item))
|
print(kmistr(item))
|
||||||
result = True
|
result = True
|
||||||
|
|
||||||
for child in children:
|
for child in children:
|
||||||
if self.testEntry(kc, child):
|
if self.testEntry(kc, child):
|
||||||
result = True
|
result = True
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def testConfig(self, kc):
|
def testConfig(self, kc):
|
||||||
result = False
|
result = False
|
||||||
for entry in KM_HIERARCHY:
|
for entry in KM_HIERARCHY:
|
||||||
if self.testEntry(kc, entry):
|
if self.testEntry(kc, entry):
|
||||||
result = True
|
result = True
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
kc = wm.default_keyconfig
|
kc = wm.default_keyconfig
|
||||||
|
|
||||||
if self.testConfig(kc):
|
if self.testConfig(kc):
|
||||||
print("CONFLICT")
|
print("CONFLICT")
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
def _string_value(value):
|
def _string_value(value):
|
||||||
result = ""
|
result = ""
|
||||||
@@ -1666,7 +1681,8 @@ def _string_value(value):
|
|||||||
print("Export key configuration: can't write ", value)
|
print("Export key configuration: can't write ", value)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_keyconfig_export(bpy.types.Operator):
|
class WM_OT_keyconfig_export(bpy.types.Operator):
|
||||||
"Export key configuration to a python script."
|
"Export key configuration to a python script."
|
||||||
bl_idname = "wm.keyconfig_export"
|
bl_idname = "wm.keyconfig_export"
|
||||||
@@ -1728,12 +1744,12 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
|||||||
|
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
wm.add_fileselect(self)
|
wm.add_fileselect(self)
|
||||||
return ('RUNNING_MODAL',)
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_keymap_edit(bpy.types.Operator):
|
class WM_OT_keymap_edit(bpy.types.Operator):
|
||||||
@@ -1745,7 +1761,7 @@ class WM_OT_keymap_edit(bpy.types.Operator):
|
|||||||
wm = context.manager
|
wm = context.manager
|
||||||
km = context.keymap
|
km = context.keymap
|
||||||
km.copy_to_user()
|
km.copy_to_user()
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_keymap_restore(bpy.types.Operator):
|
class WM_OT_keymap_restore(bpy.types.Operator):
|
||||||
@@ -1765,7 +1781,8 @@ class WM_OT_keymap_restore(bpy.types.Operator):
|
|||||||
km = context.keymap
|
km = context.keymap
|
||||||
km.restore_to_default()
|
km.restore_to_default()
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_keyitem_restore(bpy.types.Operator):
|
class WM_OT_keyitem_restore(bpy.types.Operator):
|
||||||
"Restore key map item."
|
"Restore key map item."
|
||||||
@@ -1784,8 +1801,9 @@ class WM_OT_keyitem_restore(bpy.types.Operator):
|
|||||||
|
|
||||||
km.restore_item_to_default(kmi)
|
km.restore_item_to_default(kmi)
|
||||||
|
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_keyitem_add(bpy.types.Operator):
|
class WM_OT_keyitem_add(bpy.types.Operator):
|
||||||
"Add key map item."
|
"Add key map item."
|
||||||
bl_idname = "wm.keyitem_add"
|
bl_idname = "wm.keyitem_add"
|
||||||
@@ -1794,11 +1812,20 @@ class WM_OT_keyitem_add(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
wm = context.manager
|
wm = context.manager
|
||||||
km = context.keymap
|
km = context.keymap
|
||||||
|
kc = wm.default_keyconfig
|
||||||
|
|
||||||
if km.modal:
|
if km.modal:
|
||||||
km.add_modal_item("", 'A', 'PRESS') # kmi
|
km.add_modal_item("", 'A', 'PRESS') # kmi
|
||||||
else:
|
else:
|
||||||
km.add_item("", 'A', 'PRESS') # kmi
|
km.add_item("none", 'A', 'PRESS') # kmi
|
||||||
return ('FINISHED',)
|
|
||||||
|
# clear filter and expand keymap so we can see the newly added item
|
||||||
|
if kc.filter != '':
|
||||||
|
kc.filter = ''
|
||||||
|
km.items_expanded = True
|
||||||
|
km.children_expanded = True
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_keyitem_remove(bpy.types.Operator):
|
class WM_OT_keyitem_remove(bpy.types.Operator):
|
||||||
@@ -1811,12 +1838,12 @@ class WM_OT_keyitem_remove(bpy.types.Operator):
|
|||||||
kmi = context.keyitem
|
kmi = context.keyitem
|
||||||
km = context.keymap
|
km = context.keymap
|
||||||
km.remove_item(kmi)
|
km.remove_item(kmi)
|
||||||
return ('FINISHED',)
|
return {'FINISHED'}
|
||||||
|
|
||||||
bpy.ops.add(WM_OT_keyconfig_export)
|
bpy.types.register(WM_OT_keyconfig_export)
|
||||||
bpy.ops.add(WM_OT_keyconfig_test)
|
bpy.types.register(WM_OT_keyconfig_test)
|
||||||
bpy.ops.add(WM_OT_keymap_edit)
|
bpy.types.register(WM_OT_keymap_edit)
|
||||||
bpy.ops.add(WM_OT_keymap_restore)
|
bpy.types.register(WM_OT_keymap_restore)
|
||||||
bpy.ops.add(WM_OT_keyitem_add)
|
bpy.types.register(WM_OT_keyitem_add)
|
||||||
bpy.ops.add(WM_OT_keyitem_remove)
|
bpy.types.register(WM_OT_keyitem_remove)
|
||||||
bpy.ops.add(WM_OT_keyitem_restore)
|
bpy.types.register(WM_OT_keyitem_restore)
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
import bpy
|
import bpy
|
||||||
import dynamic_menu
|
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_HT_header(bpy.types.Header):
|
class VIEW3D_HT_header(bpy.types.Header):
|
||||||
@@ -205,7 +204,7 @@ class VIEW3D_MT_snap(bpy.types.Menu):
|
|||||||
layout.operator("view3d.snap_cursor_to_active", text="Cursor to Active")
|
layout.operator("view3d.snap_cursor_to_active", text="Cursor to Active")
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_MT_uv_map(dynamic_menu.DynMenu):
|
class VIEW3D_MT_uv_map(bpy.types.Menu):
|
||||||
bl_label = "UV Mapping"
|
bl_label = "UV Mapping"
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
@@ -456,6 +455,7 @@ class VIEW3D_MT_select_edit_mesh(bpy.types.Menu):
|
|||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
layout.operator("mesh.select_random", text="Random...")
|
layout.operator("mesh.select_random", text="Random...")
|
||||||
|
layout.operator("mesh.select_nth", text="Select Nth...")
|
||||||
layout.operator("mesh.edges_select_sharp", text="Sharp Edges")
|
layout.operator("mesh.edges_select_sharp", text="Sharp Edges")
|
||||||
layout.operator("mesh.faces_select_linked_flat", text="Linked Flat Faces")
|
layout.operator("mesh.faces_select_linked_flat", text="Linked Flat Faces")
|
||||||
layout.operator("mesh.faces_select_interior", text="Interior Faces")
|
layout.operator("mesh.faces_select_interior", text="Interior Faces")
|
||||||
@@ -902,6 +902,24 @@ class VIEW3D_MT_particle(bpy.types.Menu):
|
|||||||
layout.menu("VIEW3D_MT_particle_showhide")
|
layout.menu("VIEW3D_MT_particle_showhide")
|
||||||
|
|
||||||
|
|
||||||
|
class VIEW3D_MT_particle_specials(bpy.types.Menu):
|
||||||
|
bl_label = "Specials"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
particle_edit = context.tool_settings.particle_edit
|
||||||
|
|
||||||
|
layout.operator("particle.rekey")
|
||||||
|
|
||||||
|
layout.separator()
|
||||||
|
if particle_edit.selection_mode == 'POINT':
|
||||||
|
layout.operator("particle.subdivide")
|
||||||
|
layout.operator("particle.select_first")
|
||||||
|
layout.operator("particle.select_last")
|
||||||
|
|
||||||
|
layout.operator("particle.remove_doubles")
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_MT_particle_showhide(VIEW3D_MT_showhide):
|
class VIEW3D_MT_particle_showhide(VIEW3D_MT_showhide):
|
||||||
_operator_name = "particle"
|
_operator_name = "particle"
|
||||||
|
|
||||||
@@ -1121,6 +1139,27 @@ class VIEW3D_MT_edit_mesh_specials(bpy.types.Menu):
|
|||||||
layout.operator("mesh.select_vertex_path")
|
layout.operator("mesh.select_vertex_path")
|
||||||
|
|
||||||
|
|
||||||
|
class VIEW3D_MT_edit_mesh_selection_mode(bpy.types.Menu):
|
||||||
|
bl_label = "Mesh Select Mode"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||||
|
|
||||||
|
prop = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL')
|
||||||
|
prop.value = "(True, False, False)"
|
||||||
|
prop.path = "tool_settings.mesh_selection_mode"
|
||||||
|
|
||||||
|
prop = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL')
|
||||||
|
prop.value = "(False, True, False)"
|
||||||
|
prop.path = "tool_settings.mesh_selection_mode"
|
||||||
|
|
||||||
|
prop = layout.operator("wm.context_set_value", text="Face", icon='FACESEL')
|
||||||
|
prop.value = "(False, False, True)"
|
||||||
|
prop.path = "tool_settings.mesh_selection_mode"
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu):
|
class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu):
|
||||||
bl_label = "Vertices"
|
bl_label = "Vertices"
|
||||||
|
|
||||||
@@ -1190,7 +1229,7 @@ class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu):
|
|||||||
layout.operator("mesh.region_to_loop")
|
layout.operator("mesh.region_to_loop")
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_MT_edit_mesh_faces(dynamic_menu.DynMenu):
|
class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu):
|
||||||
bl_label = "Faces"
|
bl_label = "Faces"
|
||||||
bl_idname = "VIEW3D_MT_edit_mesh_faces"
|
bl_idname = "VIEW3D_MT_edit_mesh_faces"
|
||||||
|
|
||||||
@@ -1323,6 +1362,20 @@ class VIEW3D_MT_edit_curve_segments(bpy.types.Menu):
|
|||||||
layout.operator("curve.switch_direction")
|
layout.operator("curve.switch_direction")
|
||||||
|
|
||||||
|
|
||||||
|
class VIEW3D_MT_edit_curve_specials(bpy.types.Menu):
|
||||||
|
bl_label = "Specials"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
layout.operator("curve.subdivide")
|
||||||
|
layout.operator("curve.switch_direction")
|
||||||
|
layout.operator("curve.spline_weight_set")
|
||||||
|
layout.operator("curve.radius_set")
|
||||||
|
layout.operator("curve.smooth")
|
||||||
|
layout.operator("curve.smooth_radius")
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_MT_edit_curve_showhide(VIEW3D_MT_showhide):
|
class VIEW3D_MT_edit_curve_showhide(VIEW3D_MT_showhide):
|
||||||
_operator_name = "curve"
|
_operator_name = "curve"
|
||||||
|
|
||||||
@@ -1901,7 +1954,8 @@ bpy.types.register(VIEW3D_MT_sculpt) # Sculpt Menu
|
|||||||
|
|
||||||
bpy.types.register(VIEW3D_MT_paint_vertex)
|
bpy.types.register(VIEW3D_MT_paint_vertex)
|
||||||
|
|
||||||
bpy.types.register(VIEW3D_MT_particle) # Particle Menu
|
bpy.types.register(VIEW3D_MT_particle)# Particle Menu
|
||||||
|
bpy.types.register(VIEW3D_MT_particle_specials)
|
||||||
bpy.types.register(VIEW3D_MT_particle_showhide)
|
bpy.types.register(VIEW3D_MT_particle_showhide)
|
||||||
|
|
||||||
bpy.types.register(VIEW3D_MT_pose) # POSE Menu
|
bpy.types.register(VIEW3D_MT_pose) # POSE Menu
|
||||||
@@ -1915,6 +1969,7 @@ bpy.types.register(VIEW3D_MT_pose_showhide)
|
|||||||
|
|
||||||
bpy.types.register(VIEW3D_MT_edit_mesh)
|
bpy.types.register(VIEW3D_MT_edit_mesh)
|
||||||
bpy.types.register(VIEW3D_MT_edit_mesh_specials) # Only as a menu for keybindings
|
bpy.types.register(VIEW3D_MT_edit_mesh_specials) # Only as a menu for keybindings
|
||||||
|
bpy.types.register(VIEW3D_MT_edit_mesh_selection_mode) # Only as a menu for keybindings
|
||||||
bpy.types.register(VIEW3D_MT_edit_mesh_vertices)
|
bpy.types.register(VIEW3D_MT_edit_mesh_vertices)
|
||||||
bpy.types.register(VIEW3D_MT_edit_mesh_edges)
|
bpy.types.register(VIEW3D_MT_edit_mesh_edges)
|
||||||
bpy.types.register(VIEW3D_MT_edit_mesh_faces)
|
bpy.types.register(VIEW3D_MT_edit_mesh_faces)
|
||||||
@@ -1924,6 +1979,7 @@ bpy.types.register(VIEW3D_MT_edit_mesh_showhide)
|
|||||||
bpy.types.register(VIEW3D_MT_edit_curve)
|
bpy.types.register(VIEW3D_MT_edit_curve)
|
||||||
bpy.types.register(VIEW3D_MT_edit_curve_ctrlpoints)
|
bpy.types.register(VIEW3D_MT_edit_curve_ctrlpoints)
|
||||||
bpy.types.register(VIEW3D_MT_edit_curve_segments)
|
bpy.types.register(VIEW3D_MT_edit_curve_segments)
|
||||||
|
bpy.types.register(VIEW3D_MT_edit_curve_specials)
|
||||||
bpy.types.register(VIEW3D_MT_edit_curve_showhide)
|
bpy.types.register(VIEW3D_MT_edit_curve_showhide)
|
||||||
|
|
||||||
bpy.types.register(VIEW3D_MT_edit_surface)
|
bpy.types.register(VIEW3D_MT_edit_surface)
|
||||||
|
|||||||
@@ -498,7 +498,15 @@ class VIEW3D_PT_tools_brush(PaintPanel):
|
|||||||
if not context.particle_edit_object:
|
if not context.particle_edit_object:
|
||||||
col = layout.split().column()
|
col = layout.split().column()
|
||||||
row = col.row()
|
row = col.row()
|
||||||
row.template_list(settings, "brushes", settings, "active_brush_index", rows=2)
|
|
||||||
|
if context.sculpt_object and brush:
|
||||||
|
defaulttools = 8
|
||||||
|
elif context.texture_paint_object and brush:
|
||||||
|
defaulttools = 4
|
||||||
|
else:
|
||||||
|
defaulttools = 2
|
||||||
|
|
||||||
|
row.template_list(settings, "brushes", settings, "active_brush_index", rows=2, maxrows=defaulttools)
|
||||||
|
|
||||||
col.template_ID(settings, "brush", new="brush.add")
|
col.template_ID(settings, "brush", new="brush.add")
|
||||||
|
|
||||||
@@ -531,8 +539,6 @@ class VIEW3D_PT_tools_brush(PaintPanel):
|
|||||||
elif context.sculpt_object and brush:
|
elif context.sculpt_object and brush:
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
col.separator()
|
col.separator()
|
||||||
col.prop(brush, "sculpt_tool", expand=True)
|
|
||||||
col.separator()
|
|
||||||
|
|
||||||
row = col.row(align=True)
|
row = col.row(align=True)
|
||||||
row.prop(brush, "size", slider=True)
|
row.prop(brush, "size", slider=True)
|
||||||
@@ -563,12 +569,6 @@ class VIEW3D_PT_tools_brush(PaintPanel):
|
|||||||
# Texture Paint Mode #
|
# Texture Paint Mode #
|
||||||
|
|
||||||
elif context.texture_paint_object and brush:
|
elif context.texture_paint_object and brush:
|
||||||
col = layout.column(align=True)
|
|
||||||
col.prop_enum(settings, "tool", 'DRAW')
|
|
||||||
col.prop_enum(settings, "tool", 'SOFTEN')
|
|
||||||
col.prop_enum(settings, "tool", 'CLONE')
|
|
||||||
col.prop_enum(settings, "tool", 'SMEAR')
|
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
col.prop(brush, "color", text="")
|
col.prop(brush, "color", text="")
|
||||||
|
|
||||||
@@ -624,6 +624,33 @@ class VIEW3D_PT_tools_brush(PaintPanel):
|
|||||||
#row.prop(brush, "jitter", slider=True)
|
#row.prop(brush, "jitter", slider=True)
|
||||||
#row.prop(brush, "use_jitter_pressure", toggle=True, text="")
|
#row.prop(brush, "use_jitter_pressure", toggle=True, text="")
|
||||||
|
|
||||||
|
class VIEW3D_PT_tools_brush_tool(PaintPanel):
|
||||||
|
bl_label = "Tool"
|
||||||
|
bl_default_closed = True
|
||||||
|
|
||||||
|
def poll(self, context):
|
||||||
|
settings = self.paint_settings(context)
|
||||||
|
return (settings and settings.brush and (context.sculpt_object or
|
||||||
|
context.texture_paint_object))
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
settings = self.paint_settings(context)
|
||||||
|
brush = settings.brush
|
||||||
|
texture_paint = context.texture_paint_object
|
||||||
|
sculpt = context.sculpt_object
|
||||||
|
|
||||||
|
col = layout.column(align=True)
|
||||||
|
|
||||||
|
if context.sculpt_object:
|
||||||
|
col.prop(brush, "sculpt_tool", expand=True)
|
||||||
|
elif context.texture_paint_object:
|
||||||
|
col.prop_enum(settings, "tool", 'DRAW')
|
||||||
|
col.prop_enum(settings, "tool", 'SOFTEN')
|
||||||
|
col.prop_enum(settings, "tool", 'CLONE')
|
||||||
|
col.prop_enum(settings, "tool", 'SMEAR')
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_PT_tools_brush_stroke(PaintPanel):
|
class VIEW3D_PT_tools_brush_stroke(PaintPanel):
|
||||||
bl_label = "Stroke"
|
bl_label = "Stroke"
|
||||||
@@ -690,7 +717,7 @@ class VIEW3D_PT_sculpt_options(PaintPanel):
|
|||||||
bl_label = "Options"
|
bl_label = "Options"
|
||||||
|
|
||||||
def poll(self, context):
|
def poll(self, context):
|
||||||
return context.sculpt_object
|
return (context.sculpt_object and context.tool_settings.sculpt)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
@@ -826,24 +853,50 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel):
|
|||||||
col.active = (ipaint.use_normal_falloff and use_projection)
|
col.active = (ipaint.use_normal_falloff and use_projection)
|
||||||
col.prop(ipaint, "normal_angle", text="")
|
col.prop(ipaint, "normal_angle", text="")
|
||||||
|
|
||||||
split = layout.split(percentage=0.7)
|
col = layout.column(align=False)
|
||||||
|
row = col.row()
|
||||||
|
row.active = (use_projection)
|
||||||
|
row.prop(ipaint, "use_stencil_layer", text="Stencil")
|
||||||
|
|
||||||
col = split.column(align=False)
|
row2 = row.row(align=False)
|
||||||
col.active = (use_projection)
|
row2.active = (use_projection and ipaint.use_stencil_layer)
|
||||||
col.prop(ipaint, "use_stencil_layer")
|
row2.menu("VIEW3D_MT_tools_projectpaint_stencil", text=context.active_object.data.uv_texture_stencil.name)
|
||||||
|
row2.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA')
|
||||||
col = split.column(align=False)
|
|
||||||
col.active = (use_projection and ipaint.use_stencil_layer)
|
|
||||||
col.prop(ipaint, "invert_stencil", text="Inv")
|
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
sub = col.column()
|
sub = col.column()
|
||||||
sub.active = (settings.tool == 'CLONE')
|
row = sub.row()
|
||||||
sub.prop(ipaint, "use_clone_layer")
|
row.active = (settings.tool == 'CLONE')
|
||||||
|
|
||||||
|
row.prop(ipaint, "use_clone_layer", text="Clone")
|
||||||
|
row.menu("VIEW3D_MT_tools_projectpaint_clone", text=context.active_object.data.uv_texture_clone.name)
|
||||||
|
|
||||||
sub = col.column()
|
sub = col.column()
|
||||||
sub.prop(ipaint, "seam_bleed")
|
sub.prop(ipaint, "seam_bleed")
|
||||||
|
|
||||||
|
class VIEW3D_MT_tools_projectpaint_clone(bpy.types.Menu):
|
||||||
|
bl_label = "Clone Layer"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
for i, tex in enumerate(context.active_object.data.uv_textures):
|
||||||
|
prop = layout.operator("wm.context_set_int", text=tex.name)
|
||||||
|
prop.path = "active_object.data.uv_texture_clone_index"
|
||||||
|
prop.value = i
|
||||||
|
|
||||||
|
class VIEW3D_MT_tools_projectpaint_stencil(bpy.types.Menu):
|
||||||
|
bl_label = "Mask Layer"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
for i, tex in enumerate(context.active_object.data.uv_textures):
|
||||||
|
prop = layout.operator("wm.context_set_int", text=tex.name)
|
||||||
|
prop.path = "active_object.data.uv_texture_stencil_index"
|
||||||
|
prop.value = i
|
||||||
|
|
||||||
|
bpy.types.register(VIEW3D_MT_tools_projectpaint_clone)
|
||||||
|
bpy.types.register(VIEW3D_MT_tools_projectpaint_stencil)
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_PT_tools_particlemode(View3DPanel):
|
class VIEW3D_PT_tools_particlemode(View3DPanel):
|
||||||
'''default tools for particle mode'''
|
'''default tools for particle mode'''
|
||||||
@@ -922,6 +975,7 @@ bpy.types.register(VIEW3D_PT_tools_latticeedit)
|
|||||||
bpy.types.register(VIEW3D_PT_tools_posemode)
|
bpy.types.register(VIEW3D_PT_tools_posemode)
|
||||||
bpy.types.register(VIEW3D_PT_tools_posemode_options)
|
bpy.types.register(VIEW3D_PT_tools_posemode_options)
|
||||||
bpy.types.register(VIEW3D_PT_tools_brush)
|
bpy.types.register(VIEW3D_PT_tools_brush)
|
||||||
|
bpy.types.register(VIEW3D_PT_tools_brush_tool)
|
||||||
bpy.types.register(VIEW3D_PT_tools_brush_stroke)
|
bpy.types.register(VIEW3D_PT_tools_brush_stroke)
|
||||||
bpy.types.register(VIEW3D_PT_tools_brush_curve)
|
bpy.types.register(VIEW3D_PT_tools_brush_curve)
|
||||||
bpy.types.register(VIEW3D_PT_sculpt_options)
|
bpy.types.register(VIEW3D_PT_sculpt_options)
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
# <pep8 compliant>
|
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
|||||||
@@ -137,6 +137,10 @@ ifeq ($(WITH_SNDFILE),true)
|
|||||||
COMLIB += $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_sndfile.a
|
COMLIB += $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_sndfile.a
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(WITH_FFTW3),true)
|
||||||
|
COMLIB += $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_fftw.a
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(NAN_NO_KETSJI),true)
|
ifneq ($(NAN_NO_KETSJI),true)
|
||||||
COMLIB += $(OCGDIR)/gameengine/bloutines/$(DEBUG_DIR)libbloutines.a
|
COMLIB += $(OCGDIR)/gameengine/bloutines/$(DEBUG_DIR)libbloutines.a
|
||||||
COMLIB += $(OCGDIR)/gameengine/blconverter/$(DEBUG_DIR)libblconverter.a
|
COMLIB += $(OCGDIR)/gameengine/blconverter/$(DEBUG_DIR)libblconverter.a
|
||||||
|
|||||||
@@ -182,11 +182,11 @@ AviError AVI_print_error (AviError in_error) {
|
|||||||
|
|
||||||
return in_error;
|
return in_error;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
void AVI_set_debug (int mode) {
|
void AVI_set_debug (int mode) {
|
||||||
AVI_DEBUG= mode;
|
AVI_DEBUG= mode;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
int AVI_is_avi (char *name) {
|
int AVI_is_avi (char *name) {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|||||||
@@ -198,11 +198,11 @@ int CustomData_get_named_layer_index(const struct CustomData *data, int type, ch
|
|||||||
int CustomData_get_active_layer_index(const struct CustomData *data, int type);
|
int CustomData_get_active_layer_index(const struct CustomData *data, int type);
|
||||||
int CustomData_get_render_layer_index(const struct CustomData *data, int type);
|
int CustomData_get_render_layer_index(const struct CustomData *data, int type);
|
||||||
int CustomData_get_clone_layer_index(const struct CustomData *data, int type);
|
int CustomData_get_clone_layer_index(const struct CustomData *data, int type);
|
||||||
int CustomData_get_mask_layer_index(const struct CustomData *data, int type);
|
int CustomData_get_stencil_layer_index(const struct CustomData *data, int type);
|
||||||
int CustomData_get_active_layer(const struct CustomData *data, int type);
|
int CustomData_get_active_layer(const struct CustomData *data, int type);
|
||||||
int CustomData_get_render_layer(const struct CustomData *data, int type);
|
int CustomData_get_render_layer(const struct CustomData *data, int type);
|
||||||
int CustomData_get_clone_layer(const struct CustomData *data, int type);
|
int CustomData_get_clone_layer(const struct CustomData *data, int type);
|
||||||
int CustomData_get_mask_layer(const struct CustomData *data, int type);
|
int CustomData_get_stencil_layer(const struct CustomData *data, int type);
|
||||||
|
|
||||||
/* copies the data from source to the data element at index in the first
|
/* copies the data from source to the data element at index in the first
|
||||||
* layer of type
|
* layer of type
|
||||||
@@ -231,13 +231,13 @@ void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, voi
|
|||||||
void CustomData_set_layer_active(struct CustomData *data, int type, int n);
|
void CustomData_set_layer_active(struct CustomData *data, int type, int n);
|
||||||
void CustomData_set_layer_render(struct CustomData *data, int type, int n);
|
void CustomData_set_layer_render(struct CustomData *data, int type, int n);
|
||||||
void CustomData_set_layer_clone(struct CustomData *data, int type, int n);
|
void CustomData_set_layer_clone(struct CustomData *data, int type, int n);
|
||||||
void CustomData_set_layer_mask(struct CustomData *data, int type, int n);
|
void CustomData_set_layer_stencil(struct CustomData *data, int type, int n);
|
||||||
|
|
||||||
/* same as above but works with an index from CustomData_get_layer_index */
|
/* same as above but works with an index from CustomData_get_layer_index */
|
||||||
void CustomData_set_layer_active_index(struct CustomData *data, int type, int n);
|
void CustomData_set_layer_active_index(struct CustomData *data, int type, int n);
|
||||||
void CustomData_set_layer_render_index(struct CustomData *data, int type, int n);
|
void CustomData_set_layer_render_index(struct CustomData *data, int type, int n);
|
||||||
void CustomData_set_layer_clone_index(struct CustomData *data, int type, int n);
|
void CustomData_set_layer_clone_index(struct CustomData *data, int type, int n);
|
||||||
void CustomData_set_layer_mask_index(struct CustomData *data, int type, int n);
|
void CustomData_set_layer_stencil_index(struct CustomData *data, int type, int n);
|
||||||
|
|
||||||
/* adds flag to the layer flags */
|
/* adds flag to the layer flags */
|
||||||
void CustomData_set_layer_flag(struct CustomData *data, int type, int flag);
|
void CustomData_set_layer_flag(struct CustomData *data, int type, int flag);
|
||||||
|
|||||||
@@ -158,7 +158,12 @@ void copy_fcurves(ListBase *dst, ListBase *src);
|
|||||||
struct FCurve *list_find_fcurve(ListBase *list, const char rna_path[], const int array_index);
|
struct FCurve *list_find_fcurve(ListBase *list, const char rna_path[], const int array_index);
|
||||||
|
|
||||||
/* high level function to get an fcurve from C without having the rna */
|
/* high level function to get an fcurve from C without having the rna */
|
||||||
struct FCurve *id_data_find_fcurve(ID* id, void *data, struct StructRNA *type, char *prop_name, int index);
|
struct FCurve *id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, char *prop_name, int index);
|
||||||
|
|
||||||
|
/* Get list of LinkData's containing pointers to the F-Curves which control the types of data indicated
|
||||||
|
* e.g. numMatches = list_find_data_fcurves(matches, &act->curves, "pose.bones[", "MyFancyBone");
|
||||||
|
*/
|
||||||
|
int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName);
|
||||||
|
|
||||||
/* Binary search algorithm for finding where to 'insert' BezTriple with given frame number.
|
/* Binary search algorithm for finding where to 'insert' BezTriple with given frame number.
|
||||||
* Returns the index to insert at (data already at that index will be offset if replace is 0)
|
* Returns the index to insert at (data already at that index will be offset if replace is 0)
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ void key_curve_normal_weights(float t, float *data, int type);
|
|||||||
float *do_ob_key(struct Scene *scene, struct Object *ob);
|
float *do_ob_key(struct Scene *scene, struct Object *ob);
|
||||||
|
|
||||||
struct Key *ob_get_key(struct Object *ob);
|
struct Key *ob_get_key(struct Object *ob);
|
||||||
struct KeyBlock *add_keyblock(struct Scene *scene, struct Key *key);
|
struct KeyBlock *add_keyblock(struct Key *key, char *name);
|
||||||
struct KeyBlock *ob_get_keyblock(struct Object *ob);
|
struct KeyBlock *ob_get_keyblock(struct Object *ob);
|
||||||
struct KeyBlock *ob_get_reference_keyblock(struct Object *ob);
|
struct KeyBlock *ob_get_reference_keyblock(struct Object *ob);
|
||||||
struct KeyBlock *key_get_keyblock(struct Key *key, int index);
|
struct KeyBlock *key_get_keyblock(struct Key *key, int index);
|
||||||
@@ -68,6 +68,14 @@ char *key_get_curValue_rnaPath(struct Key *key, struct KeyBlock *kb);
|
|||||||
// needed for the GE
|
// needed for the GE
|
||||||
void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, struct KeyBlock *actkb, int mode);
|
void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, struct KeyBlock *actkb, int mode);
|
||||||
|
|
||||||
|
/* conversion functions */
|
||||||
|
void key_to_mesh(struct KeyBlock *kb, struct Mesh *me);
|
||||||
|
void mesh_to_key(struct Mesh *me, struct KeyBlock *kb);
|
||||||
|
void key_to_latt(struct KeyBlock *kb, struct Lattice *lt);
|
||||||
|
void latt_to_key(struct Lattice *lt, struct KeyBlock *kb);
|
||||||
|
void key_to_curve(struct KeyBlock *kb, struct Curve *cu, struct ListBase *nurb);
|
||||||
|
void curve_to_key(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ int give_obdata_texspace(struct Object *ob, short **texflag, float **loc, float
|
|||||||
|
|
||||||
int object_insert_ptcache(struct Object *ob);
|
int object_insert_ptcache(struct Object *ob);
|
||||||
// void object_delete_ptcache(struct Object *ob, int index);
|
// void object_delete_ptcache(struct Object *ob, int index);
|
||||||
|
struct KeyBlock *object_insert_shape_key(struct Scene *scene, struct Object *ob, char *name, int from_mix);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ struct uiMenuItem;
|
|||||||
ED_spacetypes_init() in editors/area/spacetypes.c */
|
ED_spacetypes_init() in editors/area/spacetypes.c */
|
||||||
/* an editor in Blender is a combined ScrArea + SpaceType + SpaceData */
|
/* an editor in Blender is a combined ScrArea + SpaceType + SpaceData */
|
||||||
|
|
||||||
#define BKE_ST_MAXNAME 32
|
#define BKE_ST_MAXNAME 64
|
||||||
|
|
||||||
typedef struct SpaceType {
|
typedef struct SpaceType {
|
||||||
struct SpaceType *next, *prev;
|
struct SpaceType *next, *prev;
|
||||||
@@ -220,8 +220,6 @@ const struct ListBase *BKE_spacetypes_list(void);
|
|||||||
void BKE_spacetype_register(struct SpaceType *st);
|
void BKE_spacetype_register(struct SpaceType *st);
|
||||||
void BKE_spacetypes_free(void); /* only for quitting blender */
|
void BKE_spacetypes_free(void); /* only for quitting blender */
|
||||||
|
|
||||||
// MenuType *BKE_spacemenu_find(const char *idname, int spacetype);
|
|
||||||
|
|
||||||
/* spacedata */
|
/* spacedata */
|
||||||
void BKE_spacedata_freelist(ListBase *lb);
|
void BKE_spacedata_freelist(ListBase *lb);
|
||||||
void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2);
|
void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2);
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ void free_imbuf_seq(struct Scene *scene, struct ListBase * seqbasep, int check_m
|
|||||||
|
|
||||||
void seq_update_sound(struct Sequence *seq);
|
void seq_update_sound(struct Sequence *seq);
|
||||||
void seq_update_muting(struct Editing *ed);
|
void seq_update_muting(struct Editing *ed);
|
||||||
|
void seqbase_sound_reload(Scene *scene, ListBase *seqbase);
|
||||||
void clear_scene_in_allseqs(struct Scene *sce);
|
void clear_scene_in_allseqs(struct Scene *sce);
|
||||||
|
|
||||||
struct Sequence *get_seq_by_name(struct ListBase *seqbase, const char *name, int recursive);
|
struct Sequence *get_seq_by_name(struct ListBase *seqbase, const char *name, int recursive);
|
||||||
|
|||||||
@@ -37,17 +37,19 @@ extern "C" {
|
|||||||
/* generic blender movie support, could move to own module */
|
/* generic blender movie support, could move to own module */
|
||||||
|
|
||||||
struct RenderData;
|
struct RenderData;
|
||||||
|
struct ReportList;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
void start_avi(struct Scene *scene, struct RenderData *rd, int rectx, int recty);
|
|
||||||
|
int start_avi(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports);
|
||||||
void end_avi(void);
|
void end_avi(void);
|
||||||
void append_avi(struct RenderData *rd, int frame, int *pixels, int rectx, int recty);
|
int append_avi(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports);
|
||||||
void makeavistring (struct RenderData *rd, char *string);
|
void makeavistring (struct RenderData *rd, char *string);
|
||||||
|
|
||||||
typedef struct bMovieHandle {
|
typedef struct bMovieHandle {
|
||||||
void (*start_movie)(struct Scene *scene, struct RenderData *rd, int rectx, int recty);
|
int (*start_movie)(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports);
|
||||||
void (*append_movie)(struct RenderData *rd, int frame, int *pixels, int rectx, int recty);
|
int (*append_movie)(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports);
|
||||||
void (*end_movie)(void);
|
void (*end_movie)(void);
|
||||||
int (*get_next_frame)(struct RenderData *rd); /* optional */
|
int (*get_next_frame)(struct RenderData *rd, struct ReportList *reports); /* optional */
|
||||||
} bMovieHandle;
|
} bMovieHandle;
|
||||||
|
|
||||||
bMovieHandle *BKE_get_movie_handle(int imtype);
|
bMovieHandle *BKE_get_movie_handle(int imtype);
|
||||||
|
|||||||
@@ -57,11 +57,12 @@ extern "C" {
|
|||||||
|
|
||||||
struct IDProperty;
|
struct IDProperty;
|
||||||
struct RenderData;
|
struct RenderData;
|
||||||
|
struct ReportList;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
|
|
||||||
extern void start_ffmpeg(struct Scene *scene, struct RenderData *rd, int rectx, int recty);
|
extern int start_ffmpeg(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports);
|
||||||
extern void end_ffmpeg(void);
|
extern void end_ffmpeg(void);
|
||||||
extern void append_ffmpeg(struct RenderData *rd, int frame, int *pixels, int rectx, int recty);
|
extern int append_ffmpeg(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports);
|
||||||
|
|
||||||
extern void ffmpeg_set_preset(struct RenderData *rd, int preset);
|
extern void ffmpeg_set_preset(struct RenderData *rd, int preset);
|
||||||
extern void ffmpeg_verify_image_type(struct RenderData *rd);
|
extern void ffmpeg_verify_image_type(struct RenderData *rd);
|
||||||
|
|||||||
@@ -33,12 +33,13 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct RenderData;
|
struct RenderData;
|
||||||
|
struct ReportList;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
|
|
||||||
extern void start_frameserver(struct Scene *scene, struct RenderData *rd, int rectx, int recty);
|
extern int start_frameserver(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports);
|
||||||
extern void end_frameserver(void);
|
extern void end_frameserver(void);
|
||||||
extern void append_frameserver(struct RenderData *rd, int frame, int *pixels, int rectx, int recty);
|
extern int append_frameserver(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports);
|
||||||
extern int frameserver_loop(struct RenderData *rd);
|
extern int frameserver_loop(struct RenderData *rd, struct ReportList *reports);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -379,19 +379,10 @@ bActionGroup *action_groups_find_named (bAction *act, const char name[])
|
|||||||
/* usually used within a loop, so we got a N^2 slowdown */
|
/* usually used within a loop, so we got a N^2 slowdown */
|
||||||
bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
|
bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
|
||||||
{
|
{
|
||||||
bPoseChannel *chan;
|
|
||||||
|
|
||||||
if (ELEM(NULL, pose, name) || (name[0] == 0))
|
if (ELEM(NULL, pose, name) || (name[0] == 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (chan=pose->chanbase.first; chan; chan=chan->next) {
|
return BLI_findstring(&pose->chanbase, name, offsetof(bPoseChannel, name));
|
||||||
if (chan->name[0] == name[0]) {
|
|
||||||
if (!strcmp (chan->name, name))
|
|
||||||
return chan;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use with care, not on Armature poses but for temporal ones */
|
/* Use with care, not on Armature poses but for temporal ones */
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ static short id_has_animdata (ID *id)
|
|||||||
switch (GS(id->name)) {
|
switch (GS(id->name)) {
|
||||||
/* has AnimData */
|
/* has AnimData */
|
||||||
case ID_OB:
|
case ID_OB:
|
||||||
case ID_MB: case ID_CU: case ID_AR:
|
case ID_ME: case ID_MB: case ID_CU: case ID_AR:
|
||||||
case ID_KE:
|
case ID_KE:
|
||||||
case ID_PA:
|
case ID_PA:
|
||||||
case ID_MA: case ID_TE: case ID_NT:
|
case ID_MA: case ID_TE: case ID_NT:
|
||||||
@@ -1774,7 +1774,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
|
|||||||
EVAL_ANIM_IDS(main->armature.first, ADT_RECALC_ANIM);
|
EVAL_ANIM_IDS(main->armature.first, ADT_RECALC_ANIM);
|
||||||
|
|
||||||
/* meshes */
|
/* meshes */
|
||||||
// TODO...
|
EVAL_ANIM_IDS(main->mesh.first, ADT_RECALC_ANIM);
|
||||||
|
|
||||||
/* particles */
|
/* particles */
|
||||||
EVAL_ANIM_IDS(main->particle.first, ADT_RECALC_ANIM);
|
EVAL_ANIM_IDS(main->particle.first, ADT_RECALC_ANIM);
|
||||||
|
|||||||
@@ -40,6 +40,8 @@
|
|||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
#include "DNA_windowmanager_types.h"
|
#include "DNA_windowmanager_types.h"
|
||||||
|
|
||||||
|
#include "WM_types.h"
|
||||||
|
|
||||||
#include "RNA_access.h"
|
#include "RNA_access.h"
|
||||||
|
|
||||||
#include "BLI_math.h"
|
#include "BLI_math.h"
|
||||||
@@ -56,6 +58,8 @@
|
|||||||
#include "BKE_texture.h"
|
#include "BKE_texture.h"
|
||||||
#include "BKE_utildefines.h"
|
#include "BKE_utildefines.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "IMB_imbuf.h"
|
#include "IMB_imbuf.h"
|
||||||
#include "IMB_imbuf_types.h"
|
#include "IMB_imbuf_types.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1006,7 +1006,7 @@ int CustomData_get_clone_layer_index(const CustomData *data, int type)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CustomData_get_mask_layer_index(const CustomData *data, int type)
|
int CustomData_get_stencil_layer_index(const CustomData *data, int type)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -1050,7 +1050,7 @@ int CustomData_get_clone_layer(const CustomData *data, int type)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CustomData_get_mask_layer(const CustomData *data, int type)
|
int CustomData_get_stencil_layer(const CustomData *data, int type)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -1088,7 +1088,7 @@ void CustomData_set_layer_clone(CustomData *data, int type, int n)
|
|||||||
data->layers[i].active_clone = n;
|
data->layers[i].active_clone = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomData_set_layer_mask(CustomData *data, int type, int n)
|
void CustomData_set_layer_stencil(CustomData *data, int type, int n)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -1125,7 +1125,7 @@ void CustomData_set_layer_clone_index(CustomData *data, int type, int n)
|
|||||||
data->layers[i].active_clone = n-i;
|
data->layers[i].active_clone = n-i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomData_set_layer_mask_index(CustomData *data, int type, int n)
|
void CustomData_set_layer_stencil_index(CustomData *data, int type, int n)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user