diff options
author | Joseph Eagar <joeedh@gmail.com> | 2009-11-02 09:33:16 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2009-11-02 09:33:16 +0300 |
commit | e3a410d224380a82099cfd7e9f47074293df001b (patch) | |
tree | 7054dac876ffe8cb33cce426696c3b5373842608 | |
parent | 71d2ceb69147aeead0800cb3b66c37fd132e8c48 (diff) |
shapekeys are now stored as customdata in editmode, so edit operations like subdivide work (mostly) correctly. tesselated faces now store correct normals in more situations. and added more missing files from the last merge, there may be more though.
112 files changed, 3163 insertions, 1842 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index d53f4ed9966..ea62bbceb0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,8 @@ OPTION(WITH_BUILDINFO "Include extra build details" ON) OPTION(WITH_INSTALL "Install accompanying scripts and language files needed to run blender" ON) IF (APPLE) -OPTION(WITH_COCOA "Use Cocoa framework instead of deprecated Carbon" OFF) +OPTION(WITH_COCOA "Use Cocoa framework instead of deprecated Carbon" ON) +OPTION(WITH_LIBS10.5 "Use 10.5 libs (needed for 64bit builds)" OFF) ENDIF (APPLE) IF(NOT WITH_GAMEENGINE AND WITH_PLAYER) @@ -396,17 +397,22 @@ IF(WIN32) ENDIF(WIN32) IF(APPLE) - IF(CMAKE_OSX_ARCHITECTURES MATCHES i386) - SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-8.x.i386) - ELSE(CMAKE_OSX_ARCHITECTURES MATCHES i386) - SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-6.1-powerpc) - ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES i386) + IF(WITH_LIBS10.5) + SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-9.x.universal) + ELSE(WITH_LIBS10.5) + IF(CMAKE_OSX_ARCHITECTURES MATCHES i386) + SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-8.x.i386) + ELSE(CMAKE_OSX_ARCHITECTURES MATCHES i386) + SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-6.1-powerpc) + ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES i386) + ENDIF(WITH_LIBS10.5) + IF(WITH_OPENAL) FIND_PACKAGE(OpenAL) IF(OPENAL_FOUND) SET(WITH_OPENAL ON) - SET(OPENAL_INCLUDE_DIR "${OPENAL_INCLUDE_DIR};${LIBDIR}/openal/include") + SET(OPENAL_INCLUDE_DIR "${LIBDIR}/openal/include") ELSE(OPENAL_FOUND) SET(WITH_OPENAL OFF) ENDIF(OPENAL_FOUND) @@ -432,20 +438,20 @@ IF(APPLE) # we use precompiled libraries for py 3.1 and up by default SET(PYTHON ${LIBDIR}/python) - SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}" CACHE STRING "") - # SET(PYTHON_BINARY "${PYTHON}/bin/python${PYTHON_VERSION}" CACHE STRING "") # not used yet + SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}") + # SET(PYTHON_BINARY "${PYTHON}/bin/python${PYTHON_VERSION}") # not used yet SET(PYTHON_LIB python${PYTHON_VERSION}) - SET(PYTHON_LIBPATH "${PYTHON}/lib/python${PYTHON_VERSION}" CACHE STRING "") + SET(PYTHON_LIBPATH "${PYTHON}/lib/python${PYTHON_VERSION}") # SET(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled ELSE(PYTHON_VERSION MATCHES 3.1) # otherwise, use custom system framework SET(PYTHON /System/Library/Frameworks/Python.framework/Versions/) SET(PYTHON_VERSION 2.5) - SET(PYTHON_INC "${PYTHON}${PYTHON_VERSION}/include/python${PYTHON_VERSION}" CACHE STRING "") - # SET(PYTHON_BINARY ${PYTHON}${PYTHON_VERSION}/bin/python${PYTHON_VERSION} CACHE STRING "") # not used yet + SET(PYTHON_INC "${PYTHON}${PYTHON_VERSION}/include/python${PYTHON_VERSION}") + # SET(PYTHON_BINARY ${PYTHON}${PYTHON_VERSION}/bin/python${PYTHON_VERSION}) # not used yet SET(PYTHON_LIB "") - SET(PYTHON_LIBPATH ${PYTHON}${PYTHON_VERSION}/lib/python${PYTHON_VERSION}/config CACHE STRING "") + SET(PYTHON_LIBPATH ${PYTHON}${PYTHON_VERSION}/lib/python${PYTHON_VERSION}/config) SET(PYTHON_LINKFLAGS "-u _PyMac_Error -framework System -framework Python") ENDIF(PYTHON_VERSION MATCHES 3.1) @@ -457,7 +463,7 @@ IF(APPLE) IF(WITH_FFTW3) SET(FFTW3 ${LIBDIR}/fftw3) SET(FFTW3_INC ${FFTW3}/include) - SET(FFTW3_LIB libfftw) + SET(FFTW3_LIB fftw3) SET(FFTW3_LIBPATH ${FFTW3}/lib) ENDIF(WITH_FFTW3) @@ -529,15 +535,21 @@ ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") # buildinfo -IF(UNIX) - IF(WITH_BUILDINFO) +IF(WITH_BUILDINFO) + # BUILD_PLATFORM and BUILD_PLATFORM are taken from CMake + IF(UNIX) EXEC_PROGRAM("date \"+%Y-%m-%d\"" OUTPUT_VARIABLE BUILD_DATE) EXEC_PROGRAM("date \"+%H:%M:%S\"" OUTPUT_VARIABLE BUILD_TIME) EXEC_PROGRAM("svnversion ${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE BUILD_REV) - # BUILD_PLATFORM and BUILD_PLATFORM are taken from CMake - ENDIF(WITH_BUILDINFO) -ENDIF(UNIX) - + ENDIF(UNIX) + + IF(WIN32) + EXEC_PROGRAM("cmd /c date /t" OUTPUT_VARIABLE BUILD_DATE) + EXEC_PROGRAM("cmd /c time /t" OUTPUT_VARIABLE BUILD_TIME) + EXEC_PROGRAM("svnversion ${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE BUILD_REV) + ENDIF(WIN32) +ENDIF(WITH_BUILDINFO) + #----------------------------------------------------------------------------- # Common. diff --git a/extern/Eigen2/Eigen/src/Array/Functors.h b/extern/Eigen2/Eigen/src/Array/Functors.h index 0aae7fd2c40..c2c325a788e 100644 --- a/extern/Eigen2/Eigen/src/Array/Functors.h +++ b/extern/Eigen2/Eigen/src/Array/Functors.h @@ -43,6 +43,8 @@ struct ei_scalar_add_op { inline const PacketScalar packetOp(const PacketScalar& a) const { return ei_padd(a, ei_pset1(m_other)); } const Scalar m_other; +private: + ei_scalar_add_op& operator=(const ei_scalar_add_op&); }; template<typename Scalar> struct ei_functor_traits<ei_scalar_add_op<Scalar> > @@ -138,6 +140,8 @@ struct ei_scalar_pow_op { inline ei_scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {} inline Scalar operator() (const Scalar& a) const { return ei_pow(a, m_exponent); } const Scalar m_exponent; +private: + ei_scalar_pow_op& operator=(const ei_scalar_pow_op&); }; template<typename Scalar> struct ei_functor_traits<ei_scalar_pow_op<Scalar> > diff --git a/extern/Eigen2/Eigen/src/Array/PartialRedux.h b/extern/Eigen2/Eigen/src/Array/PartialRedux.h index b1e8fd4babd..3a052ca8a3d 100644 --- a/extern/Eigen2/Eigen/src/Array/PartialRedux.h +++ b/extern/Eigen2/Eigen/src/Array/PartialRedux.h @@ -133,6 +133,8 @@ struct ei_member_redux { inline result_type operator()(const MatrixBase<Derived>& mat) const { return mat.redux(m_functor); } const BinaryOp m_functor; +private: + ei_member_redux& operator=(const ei_member_redux&); }; /** \array_module \ingroup Array @@ -290,6 +292,9 @@ template<typename ExpressionType, int Direction> class PartialRedux protected: ExpressionTypeNested m_matrix; + + private: + PartialRedux& operator=(const PartialRedux&); }; /** \array_module diff --git a/extern/Eigen2/Eigen/src/Core/CommaInitializer.h b/extern/Eigen2/Eigen/src/Core/CommaInitializer.h index ed28e0ca371..f66cbd6d5e1 100644 --- a/extern/Eigen2/Eigen/src/Core/CommaInitializer.h +++ b/extern/Eigen2/Eigen/src/Core/CommaInitializer.h @@ -116,6 +116,9 @@ struct CommaInitializer int m_row; // current row id int m_col; // current col id int m_currentBlockRows; // current block height + +private: + CommaInitializer& operator=(const CommaInitializer&); }; /** \anchor MatrixBaseCommaInitRef diff --git a/extern/Eigen2/Eigen/src/Core/Cwise.h b/extern/Eigen2/Eigen/src/Core/Cwise.h index 0e92dce4e12..4dc9d514b04 100644 --- a/extern/Eigen2/Eigen/src/Core/Cwise.h +++ b/extern/Eigen2/Eigen/src/Core/Cwise.h @@ -178,6 +178,9 @@ template<typename ExpressionType> class Cwise protected: ExpressionTypeNested m_matrix; + + private: + Cwise& operator=(const Cwise&); }; /** \returns a Cwise wrapper of *this providing additional coefficient-wise operations diff --git a/extern/Eigen2/Eigen/src/Core/Flagged.h b/extern/Eigen2/Eigen/src/Core/Flagged.h index ce50246cb67..e3d25341d9e 100644 --- a/extern/Eigen2/Eigen/src/Core/Flagged.h +++ b/extern/Eigen2/Eigen/src/Core/Flagged.h @@ -109,6 +109,9 @@ template<typename ExpressionType, unsigned int Added, unsigned int Removed> clas protected: ExpressionTypeNested m_matrix; + +private: + Flagged& operator=(const Flagged&); }; /** \returns an expression of *this with added flags diff --git a/extern/Eigen2/Eigen/src/Core/Functors.h b/extern/Eigen2/Eigen/src/Core/Functors.h index c8ca3dac1cf..969cad78d8f 100644 --- a/extern/Eigen2/Eigen/src/Core/Functors.h +++ b/extern/Eigen2/Eigen/src/Core/Functors.h @@ -279,6 +279,8 @@ struct ei_scalar_multiple_op { EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return ei_pmul(a, ei_pset1(m_other)); } const Scalar m_other; +private: + ei_scalar_multiple_op& operator=(const ei_scalar_multiple_op&); }; template<typename Scalar> struct ei_functor_traits<ei_scalar_multiple_op<Scalar> > @@ -294,6 +296,8 @@ struct ei_scalar_quotient1_impl { EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return ei_pmul(a, ei_pset1(m_other)); } const Scalar m_other; +private: + ei_scalar_quotient1_impl& operator=(const ei_scalar_quotient1_impl&); }; template<typename Scalar> struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,true> > @@ -306,6 +310,8 @@ struct ei_scalar_quotient1_impl<Scalar,false> { EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const Scalar& other) : m_other(other) {} EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; } const Scalar m_other; +private: + ei_scalar_quotient1_impl& operator=(const ei_scalar_quotient1_impl&); }; template<typename Scalar> struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,false> > @@ -323,6 +329,8 @@ template<typename Scalar> struct ei_scalar_quotient1_op : ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint > { EIGEN_STRONG_INLINE ei_scalar_quotient1_op(const Scalar& other) : ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint >(other) {} +private: + ei_scalar_quotient1_op& operator=(const ei_scalar_quotient1_op&); }; // nullary functors @@ -335,6 +343,8 @@ struct ei_scalar_constant_op { EIGEN_STRONG_INLINE const Scalar operator() (int, int = 0) const { return m_other; } EIGEN_STRONG_INLINE const PacketScalar packetOp() const { return ei_pset1(m_other); } const Scalar m_other; +private: + ei_scalar_constant_op& operator=(const ei_scalar_constant_op&); }; template<typename Scalar> struct ei_functor_traits<ei_scalar_constant_op<Scalar> > diff --git a/extern/Eigen2/Eigen/src/Core/Matrix.h b/extern/Eigen2/Eigen/src/Core/Matrix.h index ffd16d37606..22090c777da 100644 --- a/extern/Eigen2/Eigen/src/Core/Matrix.h +++ b/extern/Eigen2/Eigen/src/Core/Matrix.h @@ -505,7 +505,9 @@ class Matrix template<typename OtherDerived> EIGEN_STRONG_INLINE Matrix& _set(const MatrixBase<OtherDerived>& other) { - _set_selector(other.derived(), typename ei_meta_if<bool(int(OtherDerived::Flags) & EvalBeforeAssigningBit), ei_meta_true, ei_meta_false>::ret()); + // this enum introduced to fix compilation with gcc 3.3 + enum { cond = int(OtherDerived::Flags) & EvalBeforeAssigningBit }; + _set_selector(other.derived(), typename ei_meta_if<bool(cond), ei_meta_true, ei_meta_false>::ret()); return *this; } diff --git a/extern/Eigen2/Eigen/src/Core/NestByValue.h b/extern/Eigen2/Eigen/src/Core/NestByValue.h index da79315bffe..2a14ab1f156 100644 --- a/extern/Eigen2/Eigen/src/Core/NestByValue.h +++ b/extern/Eigen2/Eigen/src/Core/NestByValue.h @@ -100,6 +100,9 @@ template<typename ExpressionType> class NestByValue protected: const ExpressionType m_expression; + + private: + NestByValue& operator=(const NestByValue&); }; /** \returns an expression of the temporary version of *this. diff --git a/extern/Eigen2/Eigen/src/Core/Part.h b/extern/Eigen2/Eigen/src/Core/Part.h index 9c273f249ec..96229f43b68 100644 --- a/extern/Eigen2/Eigen/src/Core/Part.h +++ b/extern/Eigen2/Eigen/src/Core/Part.h @@ -124,8 +124,10 @@ template<typename MatrixType, unsigned int Mode> class Part } protected: - const typename MatrixType::Nested m_matrix; + + private: + Part& operator=(const Part&); }; /** \nonstableyet diff --git a/extern/Eigen2/Eigen/src/Core/Swap.h b/extern/Eigen2/Eigen/src/Core/Swap.h index 77d562cd3ac..9aaac652fd8 100644 --- a/extern/Eigen2/Eigen/src/Core/Swap.h +++ b/extern/Eigen2/Eigen/src/Core/Swap.h @@ -117,6 +117,9 @@ template<typename ExpressionType> class SwapWrapper protected: ExpressionType& m_expression; + + private: + SwapWrapper& operator=(const SwapWrapper&); }; /** swaps *this with the expression \a other. diff --git a/extern/Eigen2/Eigen/src/Core/util/Memory.h b/extern/Eigen2/Eigen/src/Core/util/Memory.h index 09ad39d5be9..0a43e7f7bf2 100644 --- a/extern/Eigen2/Eigen/src/Core/util/Memory.h +++ b/extern/Eigen2/Eigen/src/Core/util/Memory.h @@ -1,5 +1,5 @@ // This file is part of Eigen, a lightweight C++ template library -// for linear algebra. Eigen itself is part of the KDE project. +// for linear algebra. // // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008-2009 Benoit Jacob <jacob.benoit.1@gmail.com> @@ -27,7 +27,17 @@ #ifndef EIGEN_MEMORY_H #define EIGEN_MEMORY_H -#if defined(__APPLE__) || defined(_WIN64) +// FreeBSD 6 seems to have 16-byte aligned malloc +// See http://svn.freebsd.org/viewvc/base/stable/6/lib/libc/stdlib/malloc.c?view=markup +// FreeBSD 7 seems to have 16-byte aligned malloc except on ARM and MIPS architectures +// See http://svn.freebsd.org/viewvc/base/stable/7/lib/libc/stdlib/malloc.c?view=markup +#if defined(__FreeBSD__) && !defined(__arm__) && !defined(__mips__) +#define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 1 +#else +#define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 0 +#endif + +#if defined(__APPLE__) || defined(_WIN64) || EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED #define EIGEN_MALLOC_ALREADY_ALIGNED 1 #else #define EIGEN_MALLOC_ALREADY_ALIGNED 0 @@ -65,7 +75,7 @@ inline void ei_handmade_aligned_free(void *ptr) } /** \internal allocates \a size bytes. The returned pointer is guaranteed to have 16 bytes alignment. - * On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown. + * On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown. */ inline void* ei_aligned_malloc(size_t size) { @@ -96,7 +106,7 @@ inline void* ei_aligned_malloc(size_t size) } /** allocates \a size bytes. If Align is true, then the returned ptr is 16-byte-aligned. - * On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown. + * On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown. */ template<bool Align> inline void* ei_conditional_aligned_malloc(size_t size) { @@ -116,20 +126,29 @@ template<> inline void* ei_conditional_aligned_malloc<false>(size_t size) return result; } +/** \internal construct the elements of an array. + * The \a size parameter tells on how many objects to call the constructor of T. + */ +template<typename T> inline T* ei_construct_elements_of_array(T *ptr, size_t size) +{ + for (size_t i=0; i < size; ++i) ::new (ptr + i) T; + return ptr; +} + /** allocates \a size objects of type T. The returned pointer is guaranteed to have 16 bytes alignment. * On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown. * The default constructor of T is called. */ template<typename T> inline T* ei_aligned_new(size_t size) { - void *void_result = ei_aligned_malloc(sizeof(T)*size); - return ::new(void_result) T[size]; + T *result = reinterpret_cast<T*>(ei_aligned_malloc(sizeof(T)*size)); + return ei_construct_elements_of_array(result, size); } template<typename T, bool Align> inline T* ei_conditional_aligned_new(size_t size) { - void *void_result = ei_conditional_aligned_malloc<Align>(sizeof(T)*size); - return ::new(void_result) T[size]; + T *result = reinterpret_cast<T*>(ei_conditional_aligned_malloc<Align>(sizeof(T)*size)); + return ei_construct_elements_of_array(result, size); } /** \internal free memory allocated with ei_aligned_malloc @@ -163,10 +182,10 @@ template<> inline void ei_conditional_aligned_free<false>(void *ptr) free(ptr); } -/** \internal delete the elements of an array. +/** \internal destruct the elements of an array. * The \a size parameters tells on how many objects to call the destructor of T. */ -template<typename T> inline void ei_delete_elements_of_array(T *ptr, size_t size) +template<typename T> inline void ei_destruct_elements_of_array(T *ptr, size_t size) { // always destruct an array starting from the end. while(size) ptr[--size].~T(); @@ -177,7 +196,7 @@ template<typename T> inline void ei_delete_elements_of_array(T *ptr, size_t size */ template<typename T> inline void ei_aligned_delete(T *ptr, size_t size) { - ei_delete_elements_of_array<T>(ptr, size); + ei_destruct_elements_of_array<T>(ptr, size); ei_aligned_free(ptr); } @@ -186,7 +205,7 @@ template<typename T> inline void ei_aligned_delete(T *ptr, size_t size) */ template<typename T, bool Align> inline void ei_conditional_aligned_delete(T *ptr, size_t size) { - ei_delete_elements_of_array<T>(ptr, size); + ei_destruct_elements_of_array<T>(ptr, size); ei_conditional_aligned_free<Align>(ptr); } @@ -225,8 +244,8 @@ inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset) #define ei_aligned_stack_free(PTR,SIZE) ei_aligned_free(PTR) #endif -#define ei_aligned_stack_new(TYPE,SIZE) ::new(ei_aligned_stack_alloc(sizeof(TYPE)*SIZE)) TYPE[SIZE] -#define ei_aligned_stack_delete(TYPE,PTR,SIZE) do {ei_delete_elements_of_array<TYPE>(PTR, SIZE); \ +#define ei_aligned_stack_new(TYPE,SIZE) ei_construct_elements_of_array(reinterpret_cast<TYPE*>(ei_aligned_stack_alloc(sizeof(TYPE)*SIZE)), SIZE) +#define ei_aligned_stack_delete(TYPE,PTR,SIZE) do {ei_destruct_elements_of_array<TYPE>(PTR, SIZE); \ ei_aligned_stack_free(PTR,sizeof(TYPE)*SIZE);} while(0) @@ -244,7 +263,7 @@ inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset) return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \ } #endif - + #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \ void *operator new(size_t size) { \ return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \ diff --git a/extern/Eigen2/Eigen/src/SVD/SVD.h b/extern/Eigen2/Eigen/src/SVD/SVD.h index 0a52acf3d5b..d117c158397 100644 --- a/extern/Eigen2/Eigen/src/SVD/SVD.h +++ b/extern/Eigen2/Eigen/src/SVD/SVD.h @@ -107,6 +107,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix) const int m = matrix.rows(); const int n = matrix.cols(); const int nu = std::min(m,n); + ei_assert(m>=n && "In Eigen 2.0, SVD only works for MxN matrices with M>=N. Sorry!"); m_matU.resize(m, nu); m_matU.setZero(); diff --git a/extern/Eigen2/Eigen/src/Sparse/AmbiVector.h b/extern/Eigen2/Eigen/src/Sparse/AmbiVector.h index 75001a2fa25..f279e80f00a 100644 --- a/extern/Eigen2/Eigen/src/Sparse/AmbiVector.h +++ b/extern/Eigen2/Eigen/src/Sparse/AmbiVector.h @@ -99,6 +99,8 @@ template<typename _Scalar> class AmbiVector allocSize = allocSize/sizeof(Scalar) + (allocSize%sizeof(Scalar)>0?1:0); Scalar* newBuffer = new Scalar[allocSize]; memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl)); + delete[] m_buffer; + m_buffer = newBuffer; } protected: @@ -238,8 +240,11 @@ Scalar& AmbiVector<Scalar>::coeffRef(int i) else { if (m_llSize>=m_allocatedElements) + { reallocateSparse(); - ei_internal_assert(m_llSize<m_size && "internal error: overflow in sparse mode"); + llElements = reinterpret_cast<ListEl*>(m_buffer); + } + ei_internal_assert(m_llSize<m_allocatedElements && "internal error: overflow in sparse mode"); // let's insert a new coefficient ListEl& el = llElements[m_llSize]; el.value = Scalar(0); @@ -365,6 +370,9 @@ class AmbiVector<_Scalar>::Iterator int m_cachedIndex; // current coordinate Scalar m_cachedValue; // current value bool m_isDense; // mode of the vector + + private: + Iterator& operator=(const Iterator&); }; diff --git a/extern/Eigen2/Eigen/src/Sparse/DynamicSparseMatrix.h b/extern/Eigen2/Eigen/src/Sparse/DynamicSparseMatrix.h index 7119a84bd51..01f97cd6d94 100644 --- a/extern/Eigen2/Eigen/src/Sparse/DynamicSparseMatrix.h +++ b/extern/Eigen2/Eigen/src/Sparse/DynamicSparseMatrix.h @@ -289,9 +289,11 @@ class DynamicSparseMatrix<Scalar,_Flags>::InnerIterator : public SparseVector<Sc inline int row() const { return IsRowMajor ? m_outer : Base::index(); } inline int col() const { return IsRowMajor ? Base::index() : m_outer; } - protected: const int m_outer; + + private: + InnerIterator& operator=(const InnerIterator&); }; #endif // EIGEN_DYNAMIC_SPARSEMATRIX_H diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseBlock.h b/extern/Eigen2/Eigen/src/Sparse/SparseBlock.h index c39066676b6..ae77a77879b 100644 --- a/extern/Eigen2/Eigen/src/Sparse/SparseBlock.h +++ b/extern/Eigen2/Eigen/src/Sparse/SparseBlock.h @@ -53,6 +53,9 @@ class SparseInnerVectorSet : ei_no_assignment_operator, inline InnerIterator(const SparseInnerVectorSet& xpr, int outer) : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer) {} + + private: + InnerIterator& operator=(const InnerIterator&); }; inline SparseInnerVectorSet(const MatrixType& matrix, int outerStart, int outerSize) @@ -110,6 +113,8 @@ class SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options>, Size> inline InnerIterator(const SparseInnerVectorSet& xpr, int outer) : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer) {} + private: + InnerIterator& operator=(const InnerIterator&); }; inline SparseInnerVectorSet(const MatrixType& matrix, int outerStart, int outerSize) diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseCwise.h b/extern/Eigen2/Eigen/src/Sparse/SparseCwise.h index 2206883cc76..ac285ec1aa3 100644 --- a/extern/Eigen2/Eigen/src/Sparse/SparseCwise.h +++ b/extern/Eigen2/Eigen/src/Sparse/SparseCwise.h @@ -156,6 +156,9 @@ template<typename ExpressionType> class SparseCwise protected: ExpressionTypeNested m_matrix; + + private: + SparseCwise& operator=(const SparseCwise&); }; template<typename Derived> diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseCwiseBinaryOp.h b/extern/Eigen2/Eigen/src/Sparse/SparseCwiseBinaryOp.h index d19970efcb1..da9746e2099 100644 --- a/extern/Eigen2/Eigen/src/Sparse/SparseCwiseBinaryOp.h +++ b/extern/Eigen2/Eigen/src/Sparse/SparseCwiseBinaryOp.h @@ -126,6 +126,8 @@ class SparseCwiseBinaryOp<BinaryOp,Lhs,Rhs>::InnerIterator EIGEN_STRONG_INLINE InnerIterator(const SparseCwiseBinaryOp& binOp, int outer) : Base(binOp,outer) {} + private: + InnerIterator& operator=(const InnerIterator&); }; /*************************************************************************** @@ -197,6 +199,9 @@ class ei_sparse_cwise_binary_op_inner_iterator_selector<BinaryOp, Lhs, Rhs, Deri const BinaryOp& m_functor; Scalar m_value; int m_id; + + private: + ei_sparse_cwise_binary_op_inner_iterator_selector& operator=(const ei_sparse_cwise_binary_op_inner_iterator_selector&); }; // sparse - sparse (product) @@ -250,6 +255,9 @@ class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, LhsIterator m_lhsIter; RhsIterator m_rhsIter; const BinaryFunc& m_functor; + + private: + ei_sparse_cwise_binary_op_inner_iterator_selector& operator=(const ei_sparse_cwise_binary_op_inner_iterator_selector&); }; // sparse - dense (product) @@ -290,6 +298,9 @@ class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, LhsIterator m_lhsIter; const BinaryFunc m_functor; const int m_outer; + + private: + ei_sparse_cwise_binary_op_inner_iterator_selector& operator=(const ei_sparse_cwise_binary_op_inner_iterator_selector&); }; // sparse - dense (product) diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseCwiseUnaryOp.h b/extern/Eigen2/Eigen/src/Sparse/SparseCwiseUnaryOp.h index b11c0f8a377..2ed7a15579f 100644 --- a/extern/Eigen2/Eigen/src/Sparse/SparseCwiseUnaryOp.h +++ b/extern/Eigen2/Eigen/src/Sparse/SparseCwiseUnaryOp.h @@ -90,6 +90,9 @@ class SparseCwiseUnaryOp<UnaryOp,MatrixType>::InnerIterator protected: MatrixTypeIterator m_iter; const UnaryOp m_functor; + + private: + InnerIterator& operator=(const InnerIterator&); }; template<typename Derived> diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseDiagonalProduct.h b/extern/Eigen2/Eigen/src/Sparse/SparseDiagonalProduct.h index 932daf220b9..9b7432a8216 100644 --- a/extern/Eigen2/Eigen/src/Sparse/SparseDiagonalProduct.h +++ b/extern/Eigen2/Eigen/src/Sparse/SparseDiagonalProduct.h @@ -120,6 +120,8 @@ class ei_sparse_diagonal_product_inner_iterator_selector const SparseDiagonalProductType& expr, int outer) : Base(expr.rhs().innerVector(outer) .cwise()* expr.lhs().diagonal(), 0) {} + private: + ei_sparse_diagonal_product_inner_iterator_selector& operator=(const ei_sparse_diagonal_product_inner_iterator_selector&); }; template<typename Lhs, typename Rhs, typename SparseDiagonalProductType> diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseFlagged.h b/extern/Eigen2/Eigen/src/Sparse/SparseFlagged.h index c47e162f538..315ec4af39f 100644 --- a/extern/Eigen2/Eigen/src/Sparse/SparseFlagged.h +++ b/extern/Eigen2/Eigen/src/Sparse/SparseFlagged.h @@ -64,16 +64,21 @@ template<typename ExpressionType, unsigned int Added, unsigned int Removed> clas protected: ExpressionTypeNested m_matrix; + + private: + SparseFlagged& operator=(const SparseFlagged&); }; template<typename ExpressionType, unsigned int Added, unsigned int Removed> class SparseFlagged<ExpressionType,Added,Removed>::InnerIterator : public ExpressionType::InnerIterator { public: - EIGEN_STRONG_INLINE InnerIterator(const SparseFlagged& xpr, int outer) : ExpressionType::InnerIterator(xpr.m_matrix, outer) {} + + private: + InnerIterator& operator=(const InnerIterator&); }; template<typename ExpressionType, unsigned int Added, unsigned int Removed> diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseMatrix.h b/extern/Eigen2/Eigen/src/Sparse/SparseMatrix.h index 3f09596bc64..65c609686d2 100644 --- a/extern/Eigen2/Eigen/src/Sparse/SparseMatrix.h +++ b/extern/Eigen2/Eigen/src/Sparse/SparseMatrix.h @@ -259,19 +259,21 @@ class SparseMatrix m_data.resize(k,0); } + /** Resizes the matrix to a \a rows x \a cols matrix and initializes it to zero + * \sa resizeNonZeros(int), reserve(), setZero() + */ void resize(int rows, int cols) { -// std::cerr << this << " resize " << rows << "x" << cols << "\n"; const int outerSize = IsRowMajor ? rows : cols; m_innerSize = IsRowMajor ? cols : rows; m_data.clear(); - if (m_outerSize != outerSize) + if (m_outerSize != outerSize || m_outerSize==0) { delete[] m_outerIndex; m_outerIndex = new int [outerSize+1]; m_outerSize = outerSize; - memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(int)); } + memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(int)); } void resizeNonZeros(int size) { @@ -442,6 +444,9 @@ class SparseMatrix<Scalar,_Flags>::InnerIterator int m_id; const int m_start; const int m_end; + + private: + InnerIterator& operator=(const InnerIterator&); }; #endif // EIGEN_SPARSEMATRIX_H diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseTranspose.h b/extern/Eigen2/Eigen/src/Sparse/SparseTranspose.h index 89a14d70707..7386294e4d4 100644 --- a/extern/Eigen2/Eigen/src/Sparse/SparseTranspose.h +++ b/extern/Eigen2/Eigen/src/Sparse/SparseTranspose.h @@ -62,15 +62,20 @@ template<typename MatrixType> class SparseTranspose protected: const typename MatrixType::Nested m_matrix; + + private: + SparseTranspose& operator=(const SparseTranspose&); }; template<typename MatrixType> class SparseTranspose<MatrixType>::InnerIterator : public MatrixType::InnerIterator { public: - EIGEN_STRONG_INLINE InnerIterator(const SparseTranspose& trans, int outer) : MatrixType::InnerIterator(trans.m_matrix, outer) {} + + private: + InnerIterator& operator=(const InnerIterator&); }; template<typename MatrixType> class SparseTranspose<MatrixType>::ReverseInnerIterator : public MatrixType::ReverseInnerIterator diff --git a/extern/Eigen2/Eigen/src/Sparse/SparseVector.h b/extern/Eigen2/Eigen/src/Sparse/SparseVector.h index 8e5a6efeda8..5d47209f790 100644 --- a/extern/Eigen2/Eigen/src/Sparse/SparseVector.h +++ b/extern/Eigen2/Eigen/src/Sparse/SparseVector.h @@ -360,6 +360,9 @@ class SparseVector<Scalar,_Flags>::InnerIterator const CompressedStorage<Scalar>& m_data; int m_id; const int m_end; + + private: + InnerIterator& operator=(const InnerIterator&); }; #endif // EIGEN_SPARSEVECTOR_H diff --git a/extern/Eigen2/eigen-update.sh b/extern/Eigen2/eigen-update.sh index 926a36ef120..797c710c196 100755 --- a/extern/Eigen2/eigen-update.sh +++ b/extern/Eigen2/eigen-update.sh @@ -17,7 +17,7 @@ if [ -d eigen2 ] then cd eigen2 # put here the version you want to use - hg up 2.0.6 + hg up 2.0 rm -f `find Eigen/ -type f -name "CMakeLists.txt"` cp -r Eigen .. cd .. diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 00d2cdb1e3b..bd812177f17 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -372,11 +372,13 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, * events when the mouse is outside the window. X11 only, others * do this automatically. * @param windowhandle The handle to the window - * @param grab The new grab state of the cursor. + * @param mode The new grab state of the cursor. + * @param bounds The grab ragion (optional) - left,top,right,bottom * @return Indication of success. */ extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, - int grab, int warp, int restore); + GHOST_TGrabCursorMode mode, + int* bounds); /*************************************************************************************** ** Access to mouse button and keyboard states. diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 993b41a4d4f..512fad877cb 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -271,7 +271,7 @@ public: * @param grab The new grab state of the cursor. * @return Indication of success. */ - virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp, bool restore) { return GHOST_kSuccess; }; + virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds) { return GHOST_kSuccess; }; }; diff --git a/intern/ghost/GHOST_Rect.h b/intern/ghost/GHOST_Rect.h index 6271ecad408..6a29b1ffc26 100644 --- a/intern/ghost/GHOST_Rect.h +++ b/intern/ghost/GHOST_Rect.h @@ -127,6 +127,13 @@ public: virtual inline void unionPoint(GHOST_TInt32 x, GHOST_TInt32 y); /** + * Grows the rectangle to included a point. + * @param x The x-coordinate of the point. + * @param y The y-coordinate of the point. + */ + virtual inline void wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs); + + /** * Returns whether the point is inside this rectangle. * Point on the boundary is considered inside. * @param x x-coordinate of point to test. @@ -221,6 +228,20 @@ inline void GHOST_Rect::unionPoint(GHOST_TInt32 x, GHOST_TInt32 y) if (y < m_t) m_t = y; if (y > m_b) m_b = y; } +#include <stdio.h> +inline void GHOST_Rect::wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs) +{ + GHOST_TInt32 w= getWidth(); + GHOST_TInt32 h= getHeight(); + + /* highly unlikely but avoid eternal loop */ + if(w-ofs*2 <= 0 || h-ofs*2 <= 0) + return; + while(x-ofs < m_l) x+= w-(ofs*2); + while(y-ofs < m_t) y+= h-(ofs*2); + while(x+ofs > m_r) x-= w-(ofs*2); + while(y+ofs > m_b) y-= h-(ofs*2); +} inline bool GHOST_Rect::isInside(GHOST_TInt32 x, GHOST_TInt32 y) const { diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 14e3c4bb5f7..e98e58740ad 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -341,6 +341,12 @@ typedef enum { GHOST_kKeyF24 } GHOST_TKey; +typedef enum { + GHOST_kGrabDisable = 0, /* grab not set */ + GHOST_kGrabNormal, /* no cursor adjustments */ + GHOST_kGrabWrap, /* wrap the mouse location to prevent limiting screen bounds */ + GHOST_kGrabHide, /* hide the mouse while grabbing and restore the original location on release (numbuts) */ +} GHOST_TGrabCursorMode; typedef void* GHOST_TEventDataPtr; diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index e225ad4fd90..0160df552cc 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -355,11 +355,21 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, - int grab, int warp, int restore) + GHOST_TGrabCursorMode mode, + int *bounds) { GHOST_IWindow* window = (GHOST_IWindow*) windowhandle; + GHOST_Rect bounds_rect, bounds_win; + + if(bounds) { + /* if this is X11 specific we need a function that converts */ + window->getClientBounds(bounds_win); + window->clientToScreen(bounds[0], bounds_win.getHeight() - bounds[1], bounds_rect.m_l, bounds_rect.m_t); + window->clientToScreen(bounds[2], bounds_win.getHeight() - bounds[3], bounds_rect.m_r, bounds_rect.m_b); + + } - return window->setCursorGrab(grab?true:false, warp?true:false, restore?true:false); + return window->setCursorGrab(mode, bounds ? &bounds_rect:NULL); } diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index 002089e4185..709625c5bef 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -228,34 +228,7 @@ protected: * @return Indication whether the event was handled. */ GHOST_TSuccess handleKeyEvent(void *eventPtr); - - /** - * Handles all basic Mac application stuff for a mouse down event. - * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++) - * @return Indication whether the event was handled. - */ - // bool handleMouseDown(void *eventPtr); - - /** - * Handles a Mac menu command. - * @param menuResult A Mac menu/item identifier. - * @return Indication whether the event was handled. - */ - // bool handleMenuCommand(GHOST_TInt32 menuResult); - /* callback for blender generated events */ -// static OSStatus blendEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData); - - - /** - * Callback for Mac Timer tasks that expire. - * @param tmTask Pointer to the timer task that expired. - */ - //static void s_timerCallback(TMTaskPtr tmTask); - - /** Event handler reference. */ - //EventHandlerRef m_handler; - /** Start time at initialization. */ GHOST_TUns64 m_start_time; @@ -266,7 +239,12 @@ protected: GHOST_TUns32 m_modifierMask; /** Ignores window size messages (when window is dragged). */ - bool m_ignoreWindowSizedMessages; + bool m_ignoreWindowSizedMessages; + + /** Stores the mouse cursor delta due to setting a new cursor position + * Needed because cocoa event delta cursor move takes setCursorPosition changes too. + */ + GHOST_TInt32 m_cursorDelta_x, m_cursorDelta_y; }; #endif // _GHOST_SYSTEM_COCOA_H_ diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index b924adeebde..b476ee8f0f2 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -525,7 +525,8 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) { @interface CocoaAppDelegate : NSObject {
GHOST_SystemCocoa *systemCocoa;
}
--(void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa;
+- (void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa; +- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename; - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
- (void)applicationWillTerminate:(NSNotification *)aNotification;
@end
@@ -536,6 +537,12 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) { systemCocoa = sysCocoa;
}
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename +{ + NSLog(@"\nGet open file event from cocoa : %@",filename); + return YES; +} + - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
//TODO: implement graceful termination through Cocoa mechanism to avoid session log off to be cancelled
@@ -565,6 +572,8 @@ GHOST_SystemCocoa::GHOST_SystemCocoa() {
m_modifierMask =0;
m_pressedMouseButtons =0;
+ m_cursorDelta_x=0; + m_cursorDelta_y=0; m_displayManager = new GHOST_DisplayManagerCocoa ();
GHOST_ASSERT(m_displayManager, "GHOST_SystemCocoa::GHOST_SystemCocoa(): m_displayManager==0\n");
m_displayManager->initialize();
@@ -656,13 +665,14 @@ GHOST_TSuccess GHOST_SystemCocoa::init() [NSApp setWindowsMenu:windowMenu];
[windowMenu release];
}
- [NSApp finishLaunching];
}
if ([NSApp delegate] == nil) {
CocoaAppDelegate *appDelegate = [[CocoaAppDelegate alloc] init];
[appDelegate setSystemCocoa:this];
[NSApp setDelegate:appDelegate];
}
+ + [NSApp finishLaunching]; [pool drain];
}
@@ -787,7 +797,9 @@ GHOST_TSuccess GHOST_SystemCocoa::endFullScreen(void) -
+/** + * @note : returns coordinates in Cocoa screen coordinates + */ GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const
{
NSPoint mouseLoc = [NSEvent mouseLocation];
@@ -798,18 +810,25 @@ GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt3 return GHOST_kSuccess;
}
-
+/** + * @note : expect Cocoa screen coordinates + */ GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const
{
float xf=(float)x, yf=(float)y;
+ GHOST_WindowCocoa* window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow(); + NSScreen *windowScreen = window->getScreen(); + NSRect screenRect = [windowScreen frame]; + //Set position relative to current screen + xf -= screenRect.origin.x; + yf -= screenRect.origin.y; + //Quartz Display Services uses the old coordinates (top left origin)
- yf = [[NSScreen mainScreen] frame].size.height -yf;
-
- //CGAssociateMouseAndMouseCursorPosition(false);
- CGWarpMouseCursorPosition(CGPointMake(xf, yf));
- //CGAssociateMouseAndMouseCursorPosition(true);
+ yf = screenRect.size.height -yf; + CGDisplayMoveCursorToPoint([[[windowScreen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue], CGPointMake(xf, yf)); + return GHOST_kSuccess;
}
@@ -873,15 +892,6 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) if (timerMgr->fireTimers(getMilliSeconds())) {
anyProcessed = true;
- }
-
- if (getFullScreen()) {
- // Check if the full-screen window is dirty
- GHOST_IWindow* window = m_windowManager->getFullScreenWindow();
- if (((GHOST_WindowCarbon*)window)->getFullScreenDirty()) {
- pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );
- anyProcessed = true;
- }
}*/
do {
@@ -999,6 +1009,12 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest()
{
+ GHOST_Window* window = (GHOST_Window*)m_windowManager->getActiveWindow(); + + //Discard quit event if we are in cursor grab sequence + if (window && (window->getCursorGrabMode() != GHOST_kGrabDisable) && (window->getCursorGrabMode() != GHOST_kGrabNormal)) + return GHOST_kExitCancel; + //Check open windows if some changes are not saved
if (m_windowManager->getAnyModifiedState())
{
@@ -1008,7 +1024,14 @@ GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest() {
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );
return GHOST_kExitNow;
+ } else { + //Give back focus to the blender window if user selected cancel quit + NSArray *windowsList = [NSApp orderedWindows]; + if ([windowsList count]) { + [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil]; + } }
+ }
else {
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );
@@ -1023,11 +1046,14 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventT {
NSEvent *event = (NSEvent *)eventPtr;
GHOST_IWindow* window = m_windowManager->getActiveWindow();
+ + if (!window) return GHOST_kFailure; + GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData();
switch (eventType) {
case NSTabletPoint:
- ct.Pressure = [event tangentialPressure];
+ ct.Pressure = [event pressure]; ct.Xtilt = [event tilt].x;
ct.Ytilt = [event tilt].y;
break;
@@ -1129,27 +1155,78 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) //No tablet event included : do nothing
break;
}
+ case NSMouseMoved:
- {
- if(window->getCursorWarp()) {
- GHOST_TInt32 x_warp, y_warp, x_accum, y_accum;
-
- window->getCursorWarpPos(x_warp, y_warp);
-
- window->getCursorWarpAccum(x_accum, y_accum);
- x_accum += [event deltaX];
- y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ...
- window->setCursorWarpAccum(x_accum, y_accum);
-
- pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum));
- }
- else { //Normal cursor operation: send mouse position in window
- NSPoint mousePos = [event locationInWindow];
- pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y));
- window->setCursorWarpAccum(0, 0); //Mouse motion occured between two cursor warps, so we can reset the delta counter
+ switch (window->getCursorGrabMode()) { + case GHOST_kGrabHide: //Cursor hidden grab operation : no cursor move + { + GHOST_TInt32 x_warp, y_warp, x_accum, y_accum; + + window->getCursorGrabInitPos(x_warp, y_warp); + + window->getCursorGrabAccum(x_accum, y_accum); + x_accum += [event deltaX]; + y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ... + window->setCursorGrabAccum(x_accum, y_accum); + + pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum)); + } + break; + case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries + { + NSPoint mousePos = [event locationInWindow]; + GHOST_TInt32 x_mouse= mousePos.x; + GHOST_TInt32 y_mouse= mousePos.y; + GHOST_TInt32 x_accum, y_accum, x_cur, y_cur; + GHOST_Rect bounds, windowBounds, correctedBounds; + + /* fallback to window bounds */ + if(window->getCursorGrabBounds(bounds)==GHOST_kFailure) + window->getClientBounds(bounds); + + //Switch back to Cocoa coordinates orientation (y=0 at botton,the same as blender internal btw!), and to client coordinates + window->getClientBounds(windowBounds); + window->screenToClient(bounds.m_l,bounds.m_b, correctedBounds.m_l, correctedBounds.m_t); + window->screenToClient(bounds.m_r, bounds.m_t, correctedBounds.m_r, correctedBounds.m_b); + correctedBounds.m_b = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_b; + correctedBounds.m_t = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_t; + + //Update accumulation counts + window->getCursorGrabAccum(x_accum, y_accum); + x_accum += [event deltaX]-m_cursorDelta_x; + y_accum += -[event deltaY]-m_cursorDelta_y; //Strange Apple implementation (inverted coordinates for the deltaY) ... + window->setCursorGrabAccum(x_accum, y_accum); + + + //Warp mouse cursor if needed + x_mouse += [event deltaX]-m_cursorDelta_x; + y_mouse += -[event deltaY]-m_cursorDelta_y; + correctedBounds.wrapPoint(x_mouse, y_mouse, 2); + + //Compensate for mouse moved event taking cursor position set into account + m_cursorDelta_x = x_mouse-mousePos.x; + m_cursorDelta_y = y_mouse-mousePos.y; + + //Set new cursor position + window->clientToScreen(x_mouse, y_mouse, x_cur, y_cur); + setCursorPosition(x_cur, y_cur); /* wrap */ + + //Post event + window->getCursorGrabInitPos(x_cur, y_cur); + pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_cur + x_accum, y_cur + y_accum)); + } + break; + default: + { + //Normal cursor operation: send mouse position in window + NSPoint mousePos = [event locationInWindow]; + pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y)); + m_cursorDelta_x=0; + m_cursorDelta_y=0; //Mouse motion occured between two cursor warps, so we can reset the delta counter + } + break; }
break;
- }
case NSScrollWheel:
{
@@ -1323,74 +1400,3 @@ void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const [pool drain];
}
-
-#pragma mark Carbon stuff to remove
-
-#ifdef WITH_CARBON
-
-
-OSErr GHOST_SystemCarbon::sAEHandlerLaunch(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
-{
- //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
-
- return noErr;
-}
-
-OSErr GHOST_SystemCarbon::sAEHandlerOpenDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
-{
- //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
- AEDescList docs;
- SInt32 ndocs;
- OSErr err;
-
- err = AEGetParamDesc(event, keyDirectObject, typeAEList, &docs);
- if (err != noErr) return err;
-
- err = AECountItems(&docs, &ndocs);
- if (err==noErr) {
- int i;
-
- for (i=0; i<ndocs; i++) {
- FSSpec fss;
- AEKeyword kwd;
- DescType actType;
- Size actSize;
-
- err = AEGetNthPtr(&docs, i+1, typeFSS, &kwd, &actType, &fss, sizeof(fss), &actSize);
- if (err!=noErr)
- break;
-
- if (i==0) {
- FSRef fsref;
-
- if (FSpMakeFSRef(&fss, &fsref)!=noErr)
- break;
- if (FSRefMakePath(&fsref, (UInt8*) g_firstFileBuf, sizeof(g_firstFileBuf))!=noErr)
- break;
-
- g_hasFirstFile = true;
- }
- }
- }
-
- AEDisposeDesc(&docs);
-
- return err;
-}
-
-OSErr GHOST_SystemCarbon::sAEHandlerPrintDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
-{
- //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
-
- return noErr;
-}
-
-OSErr GHOST_SystemCarbon::sAEHandlerQuit(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
-{
- GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
-
- sys->pushEvent( new GHOST_Event(sys->getMilliSeconds(), GHOST_kEventQuit, NULL) );
-
- return noErr;
-}
-#endif
\ No newline at end of file diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 8c87abf16bc..ff4a5956a12 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -388,30 +388,37 @@ GHOST_SystemX11::processEvent(XEvent *xe) { XMotionEvent &xme = xe->xmotion; - if(window->getCursorWarp()) { - /* Calculate offscreen location and re-center the mouse */ - GHOST_TInt32 x_warp, y_warp, x_new, y_new, x_accum, y_accum; - - window->getCursorWarpPos(x_warp, y_warp); - getCursorPosition(x_new, y_new); - - if(x_warp != x_new || y_warp != y_new) { - window->getCursorWarpAccum(x_accum, y_accum); - x_accum += x_new - x_warp; - y_accum += y_new - y_warp; - - window->setCursorWarpAccum(x_accum, y_accum); - setCursorPosition(x_warp, y_warp); /* reset */ - + if(window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal) + { + GHOST_TInt32 x_new= xme.x_root; + GHOST_TInt32 y_new= xme.y_root; + GHOST_TInt32 x_accum, y_accum; + GHOST_Rect bounds; + + /* fallback to window bounds */ + if(window->getCursorGrabBounds(bounds)==GHOST_kFailure) + window->getClientBounds(bounds); + + /* could also clamp to screen bounds + * wrap with a window outside the view will fail atm */ + bounds.wrapPoint(x_new, y_new, 2); /* offset of one incase blender is at screen bounds */ + window->getCursorGrabAccum(x_accum, y_accum); + + if(x_new != xme.x_root || y_new != xme.y_root) { + /* when wrapping we don't need to add an event because the + * setCursorPosition call will cause a new event after */ + setCursorPosition(x_new, y_new); /* wrap */ + window->setCursorGrabAccum(x_accum + (xme.x_root - x_new), y_accum + (xme.y_root - y_new)); + } + else { g_event = new GHOST_EventCursor( getMilliSeconds(), GHOST_kEventCursorMove, window, - x_warp + x_accum, - y_warp + y_accum + xme.x_root + x_accum, + xme.y_root + y_accum ); - } } else { diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index 94feb83e003..33484284d7c 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -48,15 +48,14 @@ GHOST_Window::GHOST_Window( : m_drawingContextType(type), m_cursorVisible(true), - m_cursorGrabbed(false), - m_cursorWarp(false), + m_cursorGrab(GHOST_kGrabDisable), m_cursorShape(GHOST_kStandardCursorDefault), m_stereoVisual(stereoVisual) { m_isUnsavedChanges = false; - m_cursorWarpAccumPos[0] = 0; - m_cursorWarpAccumPos[1] = 0; + m_cursorGrabAccumPos[0] = 0; + m_cursorGrabAccumPos[1] = 0; m_fullScreen = state == GHOST_kWindowStateFullScreen; if (m_fullScreen) { @@ -98,13 +97,19 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible) } } -GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab, bool warp, bool restore) +GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds) { - if(m_cursorGrabbed == grab) + if(m_cursorGrab == mode) return GHOST_kSuccess; - if (setWindowCursorGrab(grab, warp, restore)) { - m_cursorGrabbed = grab; + if (setWindowCursorGrab(mode)) { + + if(mode==GHOST_kGrabDisable) + m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; + else if (bounds) { + m_cursorGrabBounds= *bounds; + } + m_cursorGrab = mode; return GHOST_kSuccess; } else { @@ -112,6 +117,12 @@ GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab, bool warp, bool restore) } } +GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect& bounds) +{ + bounds= m_cursorGrabBounds; + return (bounds.m_l==-1 && bounds.m_r==-1) ? GHOST_kFailure : GHOST_kSuccess; +} + GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape) { if (setWindowCursorShape(cursorShape)) { diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index 786918716c5..86447a8623c 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -158,10 +158,10 @@ public: * @return The visibility state of the cursor. */ inline virtual bool getCursorVisibility() const; - inline virtual bool getCursorWarp() const; - inline virtual bool getCursorWarpPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const; - inline virtual bool getCursorWarpAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const; - inline virtual bool setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y); + inline virtual GHOST_TGrabCursorMode getCursorGrabMode() const; + inline virtual void getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const; + inline virtual void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const; + inline virtual void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y); /** * Shows or hides the cursor. @@ -172,10 +172,16 @@ public: /** * Sets the cursor grab. - * @param grab The new grab state of the cursor. + * @param mode The new grab state of the cursor. * @return Indication of success. */ - virtual GHOST_TSuccess setCursorGrab(bool grab, bool warp, bool restore); + virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds); + + /** + * Gets the cursor grab region, if unset the window is used. + * reset when grab is disabled. + */ + virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect& bounds); /** * Sets the window "modified" status, indicating unsaved changes @@ -247,7 +253,7 @@ protected: * Sets the cursor grab on the window using * native window system calls. */ - virtual GHOST_TSuccess setWindowCursorGrab(bool grab, bool warp, bool restore) { return GHOST_kSuccess; }; + virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode) { return GHOST_kSuccess; }; /** * Sets the cursor shape on the window using @@ -274,16 +280,16 @@ protected: bool m_cursorVisible; /** The current grabbed state of the cursor */ - bool m_cursorGrabbed; - - /** The current warped state of the cursor */ - bool m_cursorWarp; + GHOST_TGrabCursorMode m_cursorGrab; /** Initial grab location. */ - GHOST_TInt32 m_cursorWarpInitPos[2]; + GHOST_TInt32 m_cursorGrabInitPos[2]; + + /** Accumulated offset from m_cursorGrabInitPos. */ + GHOST_TInt32 m_cursorGrabAccumPos[2]; - /** Accumulated offset from m_cursorWarpInitPos. */ - GHOST_TInt32 m_cursorWarpAccumPos[2]; + /** Wrap the cursor within this region. */ + GHOST_Rect m_cursorGrabBounds; /** The current shape of the cursor */ GHOST_TStandardCursor m_cursorShape; @@ -317,40 +323,27 @@ inline bool GHOST_Window::getCursorVisibility() const return m_cursorVisible; } -inline bool GHOST_Window::getCursorWarp() const +inline GHOST_TGrabCursorMode GHOST_Window::getCursorGrabMode() const { - return m_cursorWarp; + return m_cursorGrab; } -inline bool GHOST_Window::getCursorWarpPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const +inline void GHOST_Window::getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const { - if(m_cursorWarp==false) - return GHOST_kFailure; - - x= m_cursorWarpInitPos[0]; - y= m_cursorWarpInitPos[1]; - return GHOST_kSuccess; + x = m_cursorGrabInitPos[0]; + y = m_cursorGrabInitPos[1]; } -inline bool GHOST_Window::getCursorWarpAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const +inline void GHOST_Window::getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const { - if(m_cursorWarp==false) - return GHOST_kFailure; - - x= m_cursorWarpAccumPos[0]; - y= m_cursorWarpAccumPos[1]; - return GHOST_kSuccess; + x= m_cursorGrabAccumPos[0]; + y= m_cursorGrabAccumPos[1]; } -inline bool GHOST_Window::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y) +inline void GHOST_Window::setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y) { - if(m_cursorWarp==false) - return GHOST_kFailure; - - m_cursorWarpAccumPos[0]= x; - m_cursorWarpAccumPos[1]= y; - - return GHOST_kSuccess; + m_cursorGrabAccumPos[0]= x; + m_cursorGrabAccumPos[1]= y; } inline GHOST_TStandardCursor GHOST_Window::getCursorShape() const diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index 4037ebafc64..c1fa147eee1 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -170,6 +170,12 @@ public: virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const; /** + * Gets the screen the window is displayed in + * @return The NSScreen object + */ + NSScreen* getScreen(); + + /** * Sets the state of the window (normal, minimized, maximized). * @param state The state of the window. * @return Indication of success. @@ -237,17 +243,11 @@ protected: virtual GHOST_TSuccess setWindowCursorVisibility(bool visible); /** - * Sets the cursor warp accumulator. Overriden for workaround due to Cocoa next event after cursor set giving delta values non zero - */ - inline virtual bool setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y); - - /** * Sets the cursor grab on the window using * native window system calls. - * @param warp Only used when grab is enabled, hides the mouse and allows gragging outside the screen. */ - virtual GHOST_TSuccess setWindowCursorGrab(bool grab, bool warp, bool restore); - + virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode); + /** * Sets the cursor shape on the window using * native window system calls. diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index a2b146c1e33..aac12e80893 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -34,6 +34,10 @@ #include <Carbon/Carbon.h>
#endif
+/***** Multithreaded opengl code : uncomment for enabling +#include <OpenGL/OpenGL.h> +*/ + #include "GHOST_WindowCocoa.h"
#include "GHOST_SystemCocoa.h"
#include "GHOST_Debug.h"
@@ -50,14 +54,27 @@ static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] = };
#pragma mark Cocoa window delegate object
-
+/* live resize ugly patch +extern "C" { + struct bContext; + typedef struct bContext bContext; + bContext* ghostC; + extern int wm_window_timer(const bContext *C); + extern void wm_window_process_events(const bContext *C); + extern void wm_event_do_handlers(bContext *C); + extern void wm_event_do_notifiers(bContext *C); + extern void wm_draw_update(bContext *C); +};*/ @interface CocoaWindowDelegate : NSObject
+#ifdef MAC_OS_X_VERSION_10_6 +<NSWindowDelegate> +#endif {
GHOST_SystemCocoa *systemCocoa;
GHOST_WindowCocoa *associatedWindow;
}
-- (void)setSystemAndWindowCocoa:(const GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;
+- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa; - (void)windowWillClose:(NSNotification *)notification;
- (void)windowDidBecomeKey:(NSNotification *)notification;
- (void)windowDidResignKey:(NSNotification *)notification;
@@ -97,7 +114,22 @@ static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] = - (void)windowDidResize:(NSNotification *)notification
{
- systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow);
+#ifdef MAC_OS_X_VERSION_10_6 + //if (![[notification object] inLiveResize]) { + //Send event only once, at end of resize operation (when user has released mouse button) +#endif + systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow); +#ifdef MAC_OS_X_VERSION_10_6 + //} +#endif + /* Live resize ugly patch. Needed because live resize runs in a modal loop, not letting main loop run + if ([[notification object] inLiveResize]) { + systemCocoa->dispatchEvents(); + wm_window_timer(ghostC); + wm_event_do_handlers(ghostC); + wm_event_do_notifiers(ghostC); + wm_draw_update(ghostC); + }*/ }
@end
@@ -107,8 +139,6 @@ static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] = {
}
--(BOOL)canBecomeKeyWindow;
-
@end
@implementation CocoaWindow
@@ -125,7 +155,6 @@ static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] = //We need to subclass it in order to give Cocoa the feeling key events are trapped
@interface CocoaOpenGLView : NSOpenGLView
{
-
}
@end
@implementation CocoaOpenGLView
@@ -173,6 +202,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( //Creates the window
NSRect rect;
+ NSSize minSize; rect.origin.x = left;
rect.origin.y = top;
@@ -187,6 +217,11 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( return;
}
+ //Forbid to resize the window below the blender defined minimum one + minSize.width = 320; + minSize.height = 240; + [m_window setContentMinSize:minSize]; + setTitle(title);
@@ -480,6 +515,13 @@ void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST outY = screenCoord.y;
}
+ +NSScreen* GHOST_WindowCocoa::getScreen() +{ + return [m_window screen]; +} + + /**
* @note Fullscreen switch is not actual fullscreen with display capture. As this capture removes all OS X window manager features.
* Instead, the menu bar and the dock are hidden, and the window is made borderless and enlarged.
@@ -515,6 +557,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) //Make window borderless and enlarge it
[m_window setStyleMask:NSBorderlessWindowMask];
[m_window setFrame:[[m_window screen] frame] display:YES];
+ [m_window makeFirstResponder:m_openGLView]; #else
//With 10.5, we need to create a new window to change its style to borderless
//Hide menu & dock if needed
@@ -572,6 +615,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) //Make window normal and resize it
[m_window setStyleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)];
[m_window setFrame:[[m_window screen] visibleFrame] display:YES];
+ [m_window makeFirstResponder:m_openGLView]; #else
//With 10.5, we need to create a new window to change its style to borderless
//Show menu & dock if needed
@@ -696,6 +740,10 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp NSOpenGLPixelFormat *pixelFormat;
NSOpenGLContext *tmpOpenGLContext;
+ /***** Multithreaded opengl code : uncomment for enabling + CGLContextObj cglCtx; + */ + switch (type) {
case GHOST_kDrawingContextTypeOpenGL:
if (!getValid()) break;
@@ -708,6 +756,13 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp break;
}
+ //Switch openGL to multhreaded mode + /******* Multithreaded opengl code : uncomment for enabling + cglCtx = (CGLContextObj)[tmpOpenGLContext CGLContextObj]; + if (CGLEnable(cglCtx, kCGLCEMPEngine) == kCGLNoError) + printf("\nSwitched openGL to multithreaded mode"); + */ + if (!s_firstOpenGLcontext) s_firstOpenGLcontext = tmpOpenGLContext;
#ifdef WAIT_FOR_VSYNC
/* wait for vsync, to avoid tearing artifacts */
@@ -849,73 +904,42 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible) }
-//Override this method to provide set feature even if not in warp
-inline bool GHOST_WindowCocoa::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y)
+GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode) {
- m_cursorWarpAccumPos[0]= x;
- m_cursorWarpAccumPos[1]= y;
+ GHOST_TSuccess err = GHOST_kSuccess; - return GHOST_kSuccess;
-}
-
-
-GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(bool grab, bool warp, bool restore)
-{
- if (grab)
+ if (mode != GHOST_kGrabDisable) {
//No need to perform grab without warp as it is always on in OS X
- if(warp) {
+ if(mode != GHOST_kGrabNormal) { GHOST_TInt32 x_old,y_old;
- m_cursorWarp= true;
m_systemCocoa->getCursorPosition(x_old,y_old);
- screenToClient(x_old, y_old, m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
+ screenToClient(x_old, y_old, m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); //Warp position is stored in client (window base) coordinates
- setWindowCursorVisibility(false);
- return CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
+ setCursorGrabAccum(0, 0); + + if(mode == GHOST_kGrabHide) { + setWindowCursorVisibility(false); + } + + //Dissociate cursor position even for warp mode, to allow mouse acceleration to work even when warping the cursor + err = CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure; }
}
else {
- if(m_cursorWarp)
- {/* are we exiting warp */
+ if(m_cursorGrab==GHOST_kGrabHide) + { + //No need to set again cursor position, as it has not changed for Cocoa setWindowCursorVisibility(true);
- /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
- if(restore) {
- GHOST_Rect bounds;
- GHOST_TInt32 x_new, y_new, x_cur, y_cur;
-
- getClientBounds(bounds);
- x_new= m_cursorWarpInitPos[0]+m_cursorWarpAccumPos[0];
- y_new= m_cursorWarpInitPos[1]+m_cursorWarpAccumPos[1];
-
- if(x_new < 0) x_new = 0;
- if(y_new < 0) y_new = 0;
- if(x_new > bounds.getWidth()) x_new = bounds.getWidth();
- if(y_new > bounds.getHeight()) y_new = bounds.getHeight();
-
- //get/set cursor position works in screen coordinates
- clientToScreen(x_new, y_new, x_cur, y_cur);
- m_systemCocoa->setCursorPosition(x_cur, y_cur);
-
- //As Cocoa will give as first deltaX,deltaY this change in cursor position, we need to compensate for it
- //Issue appearing in case of two transform operations conducted w/o mouse motion in between
- x_new=m_cursorWarpAccumPos[0];
- y_new=m_cursorWarpAccumPos[1];
- setCursorWarpAccum(-x_new, -y_new);
- }
- else {
- GHOST_TInt32 x_new, y_new;
- //get/set cursor position works in screen coordinates
- clientToScreen(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1], x_new, y_new);
- m_systemCocoa->setCursorPosition(x_new, y_new);
- setCursorWarpAccum(0, 0);
- }
-
- m_cursorWarp= false;
- return CGAssociateMouseAndMouseCursorPosition(true) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
}
+ + err = CGAssociateMouseAndMouseCursorPosition(true) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure; + /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ + setCursorGrabAccum(0, 0); + m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; /* disable */ }
- return GHOST_kSuccess;
+ return err; }
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)
@@ -979,7 +1003,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap samplesPerPixel:2
hasAlpha:YES
isPlanar:YES
- colorSpaceName:NSDeviceBlackColorSpace
+ colorSpaceName:NSDeviceWhiteColorSpace bytesPerRow:(sizex/8 + (sizex%8 >0 ?1:0))
bitsPerPixel:1];
@@ -989,10 +1013,10 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap for (y=0; y<nbUns16; y++) {
#if !defined(__LITTLE_ENDIAN__)
- cursorBitmap[y] = uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8));
+ cursorBitmap[y] = ~uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8)); cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y]<<0) | (mask[2*y+1]<<8));
#else
- cursorBitmap[y] = uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8));
+ cursorBitmap[y] = ~uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8)); cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y+1]<<0) | (mask[2*y]<<8));
#endif
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index d197b534352..d9c2654f446 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -297,11 +297,13 @@ GHOST_WindowX11( // we want this window treated. XSizeHints * xsizehints = XAllocSizeHints(); - xsizehints->flags = USPosition | USSize; + xsizehints->flags = PPosition | PSize | PMinSize; xsizehints->x = left; xsizehints->y = top; xsizehints->width = width; xsizehints->height = height; + xsizehints->min_width= 320; // size hints, could be made apart of the ghost api + xsizehints->min_height= 240; // limits are also arbitrary, but should not allow 1x1 window XSetWMNormalHints(m_display, m_window, xsizehints); XFree(xsizehints); @@ -382,7 +384,6 @@ GHOST_WindowX11( XSetWMHints(display, m_window, xwmhints ); XFree(xwmhints); // done setting the icon - setTitle(title); @@ -1400,47 +1401,35 @@ setWindowCursorVisibility( GHOST_TSuccess GHOST_WindowX11:: setWindowCursorGrab( - bool grab, bool warp, bool restore + GHOST_TGrabCursorMode mode ){ - if(grab) { - if(warp) { - m_system->getCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); + if(mode != GHOST_kGrabDisable) { + if(mode != GHOST_kGrabNormal) { + m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); + setCursorGrabAccum(0, 0); + + if(mode == GHOST_kGrabHide) + setWindowCursorVisibility(false); - setCursorWarpAccum(0, 0); - setWindowCursorVisibility(false); - m_cursorWarp= true; } XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); } else { - if(m_cursorWarp) { /* are we exiting warp */ + if (m_cursorGrab==GHOST_kGrabHide) { + m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); setWindowCursorVisibility(true); - /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ - if(restore) { - GHOST_Rect bounds; - GHOST_TInt32 x_new, y_new, x_rel, y_rel; - - getClientBounds(bounds); - - x_new= m_cursorWarpInitPos[0]+m_cursorWarpAccumPos[0]; - y_new= m_cursorWarpInitPos[1]+m_cursorWarpAccumPos[1]; - - screenToClient(x_new, y_new, x_rel, y_rel); - - if(x_rel < 0) x_new = (x_new-x_rel) + 2; - if(y_rel < 0) y_new = (y_new-y_rel) + 2; - if(x_rel > bounds.getWidth()) x_new -= (x_rel-bounds.getWidth()) + 2; - if(y_rel > bounds.getHeight()) y_new -= (y_rel-bounds.getHeight()) + 2; - m_system->setCursorPosition(x_new, y_new); - - } - else { - m_system->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]); - } + } - setCursorWarpAccum(0, 0); - m_cursorWarp= false; + if(m_cursorGrab != GHOST_kGrabNormal) { + /* use to generate a mouse move event, otherwise the last event + * blender gets can be outside the screen causing menus not to show + * properly unless the user moves the mouse */ + XWarpPointer(m_display,None,None,0,0,0,0,0,0); } + + /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ + setCursorGrabAccum(0, 0); + m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; /* disable */ XUngrabPointer(m_display, CurrentTime); } diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index eb0689ab410..0dba1776553 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -256,9 +256,12 @@ protected: */ GHOST_TSuccess setWindowCursorGrab( - bool grab, bool warp, bool restore + GHOST_TGrabCursorMode mode ); + GHOST_TGrabCursorMode + getWindowCursorGrab() const; + /** * Sets the cursor shape on the window using * native window system calls. diff --git a/projectfiles_vc9/blender/editors/ED_editors.vcproj b/projectfiles_vc9/blender/editors/ED_editors.vcproj index 593a84ccad6..c583c105a7a 100644 --- a/projectfiles_vc9/blender/editors/ED_editors.vcproj +++ b/projectfiles_vc9/blender/editors/ED_editors.vcproj @@ -540,10 +540,6 @@ >
</File>
<File
- RelativePath="..\..\..\source\blender\editors\space_outliner\outliner_header.c"
- >
- </File>
- <File
RelativePath="..\..\..\source\blender\editors\space_outliner\outliner_intern.h"
>
</File>
diff --git a/projectfiles_vc9/blender/loader/BLO_loader.vcproj b/projectfiles_vc9/blender/loader/BLO_loader.vcproj index 0ddb02afad1..1a14e987ed6 100644 --- a/projectfiles_vc9/blender/loader/BLO_loader.vcproj +++ b/projectfiles_vc9/blender/loader/BLO_loader.vcproj @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="9,00"
+ Version="9.00"
Name="BLO_loader"
ProjectGUID="{E5F2F004-C704-4DCC-A08F-6EB1E38EAB9F}"
RootNamespace="BLO_loader"
@@ -490,123 +490,123 @@ RelativePath="..\..\..\source\blender\blenloader\BLO_undofile.h"
>
</File>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="..\..\..\source\blender\blenloader\intern\readblenentry.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenloader\intern\readfile.c"
+ >
+ <FileConfiguration
+ Name="Blender Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="3D Plugin Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="3D Plugin Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Blender Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="BlenderPlayer Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="BlenderPlayer Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenloader\intern\undofile.c"
>
- <File
- RelativePath="..\..\..\source\blender\blenloader\intern\readblenentry.c"
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenloader\intern\writefile.c"
+ >
+ <FileConfiguration
+ Name="Blender Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="3D Plugin Debug|Win32"
>
- </File>
- <File
- RelativePath="..\..\..\source\blender\blenloader\intern\readfile.c"
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="3D Plugin Release|Win32"
>
- <FileConfiguration
- Name="Blender Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="3D Plugin Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="3D Plugin Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Blender Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="BlenderPlayer Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="BlenderPlayer Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\..\source\blender\blenloader\intern\undofile.c"
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Blender Release|Win32"
>
- </File>
- <File
- RelativePath="..\..\..\source\blender\blenloader\intern\writefile.c"
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="BlenderPlayer Debug|Win32"
>
- <FileConfiguration
- Name="Blender Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="3D Plugin Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="3D Plugin Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Blender Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="BlenderPlayer Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="BlenderPlayer Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- />
- </FileConfiguration>
- </File>
- </Filter>
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="BlenderPlayer Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ />
+ </FileConfiguration>
+ </File>
</Filter>
</Files>
<Globals>
diff --git a/release/environment-macosx b/release/environment-macosx new file mode 100644 index 00000000000..d41d5ec485f --- /dev/null +++ b/release/environment-macosx @@ -0,0 +1,18 @@ +# This is a Blender Environment Variable config file. +# +# Comment lines start with "#", other lines will be split at the "=" +# and the part before will be used as env var name and the part after +# as env var value. The value can make reference to previous or +# prelaunch variables with "${}" and the content will be replaced. +# Once set, values of variables will not be overwritten. +# +# BLENDER_SHARE should be /Library/Application Support/Blender for typical installs. +# BLENDER_VERSION will be set by the program before processing this file. +BLENDER_USER_BASE=${HOME}/Library/Application Support/Blender/${BLENDER_VERSION} +BLENDER_SYSTEM_BASE=${BLENDER_SHARE}/${BLENDER_VERSION} +BLENDER_USER_DATAFILES=${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}/datafiles +BLENDER_SYSTEM_DATAFILES=${BLENDER_SHARE}/${BLENDER_VERSION}/datafiles +BLENDER_USER_PY=${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}/py +BLENDER_SYSTEM_PY=${BLENDER_SHARE}/${BLENDER_VERSION}/py +BLENDER_USER_PLUGINS=${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}/plugins +BLENDER_SYSTEM_PLUGINS=${BLENDER_SHARE}/${BLENDER_VERSION}/plugins diff --git a/release/environment-mswindows b/release/environment-mswindows new file mode 100644 index 00000000000..f8890f89af8 --- /dev/null +++ b/release/environment-mswindows @@ -0,0 +1,18 @@ +# This is a Blender Environment Variable config file.
+#
+# Comment lines start with "#", other lines will be split at the "="
+# and the part before will be used as env var name and the part after
+# as env var value. The value can make reference to previous or
+# prelaunch variables with "%%" and the content will be replaced.
+# Once set, values of variables will not be overwritten.
+#
+# BLENDER_SHARE should be COMMON_APPDATA\\Blender Foundation\\Blender for typical installs.
+# BLENDER_VERSION will be set by the program before processing this file.
+BLENDER_USER_BASE=%USERPROFILE%\\Blender Foundation\\Blender\\%BLENDER_VERSION%
+BLENDER_SYSTEM_BASE=%BLENDER_SHARE%\\%BLENDER_VERSION%
+BLENDER_USER_DATAFILES=%USERPROFILE%\\Blender Foundation\\%BLENDER_VERSION%\\datafiles
+BLENDER_SYSTEM_DATAFILES=%BLENDER_SHARE%\\%BLENDER_VERSION%\\datafiles
+BLENDER_USER_PY=%USERPROFILE%\\Blender Foundation\\%BLENDER_VERSION%\\py
+BLENDER_SYSTEM_PY=%BLENDER_SHARE%\\%BLENDER_VERSION%\\py
+BLENDER_USER_PLUGINS=%USERPROFILE%\\Blender Foundation\\%BLENDER_VERSION%\\plugins
+BLENDER_SYSTEM_PLUGINS=%BLENDER_SHARE%\\%BLENDER_VERSION%\\plugins
diff --git a/release/environment-unix b/release/environment-unix new file mode 100644 index 00000000000..8a13c288306 --- /dev/null +++ b/release/environment-unix @@ -0,0 +1,18 @@ +# This is a Blender Environment Variable config file. +# +# Comment lines start with "#", other lines will be split at the "=" +# and the part before will be used as env var name and the part after +# as env var value. The value can make reference to previous or +# prelaunch variables with "${}" and the content will be replaced. +# Once set, values of variables will not be overwritten. +# +# BLENDER_SHARE should be /usr/share/blender for typical distro installs. +# BLENDER_VERSION will be set by the program before processing this file. +BLENDER_USER_BASE=${HOME}/.blender/${BLENDER_VERSION} +BLENDER_SYSTEM_BASE=${BLENDER_SHARE}/${BLENDER_VERSION} +BLENDER_USER_DATAFILES=${HOME}/.blender/${BLENDER_VERSION}/datafiles +BLENDER_SYSTEM_DATAFILES=${BLENDER_SHARE}/${BLENDER_VERSION}/datafiles +BLENDER_USER_PY=${HOME}/.blender/${BLENDER_VERSION}/py +BLENDER_SYSTEM_PY=${BLENDER_SHARE}/${BLENDER_VERSION}/py +BLENDER_USER_PLUGINS=${HOME}/.blender/${BLENDER_VERSION}/plugins +BLENDER_SYSTEM_PLUGINS=${BLENDER_SHARE}/${BLENDER_VERSION}/plugins diff --git a/release/scripts/io/engine_render_pov.py b/release/scripts/io/engine_render_pov.py index f0247ce532a..f69c8a267e0 100644 --- a/release/scripts/io/engine_render_pov.py +++ b/release/scripts/io/engine_render_pov.py @@ -826,12 +826,12 @@ class PovrayRender(bpy.types.RenderEngine): bpy.types.register(PovrayRender) # Use some of the existing buttons. -import buttons_scene -buttons_scene.SCENE_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER') -buttons_scene.SCENE_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER') -buttons_scene.SCENE_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER') -buttons_scene.SCENE_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER') -del buttons_scene +import buttons_render +buttons_render.RENDER_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER') +buttons_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER') +buttons_render.RENDER_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER') +buttons_render.RENDER_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER') +del buttons_render # Use only a subset of the world panels import buttons_world @@ -852,14 +852,14 @@ del buttons_material class RenderButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' - __context__ = "scene" + __context__ = "render" # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here def poll(self, context): rd = context.scene.render_data return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) -class SCENE_PT_povray_radiosity(RenderButtonsPanel): +class RENDER_PT_povray_radiosity(RenderButtonsPanel): __label__ = "Radiosity" COMPAT_ENGINES = set(['POVRAY_RENDER']) @@ -909,4 +909,4 @@ class SCENE_PT_povray_radiosity(RenderButtonsPanel): col = split.column() col.itemR(scene, "pov_radio_always_sample") -bpy.types.register(SCENE_PT_povray_radiosity) +bpy.types.register(RENDER_PT_povray_radiosity) diff --git a/release/scripts/io/export_3ds.py b/release/scripts/io/export_3ds.py index 2c1999c3d45..5ca7d5629d5 100644 --- a/release/scripts/io/export_3ds.py +++ b/release/scripts/io/export_3ds.py @@ -1,12 +1,4 @@ -#!BPY # coding: utf-8 -""" -Name: '3D Studio (.3ds)...' -Blender: 243 -Group: 'Export' -Tooltip: 'Export to 3DS file format (.3ds).' -""" - __author__ = ["Campbell Barton", "Bob Holcomb", "Richard Lärkäng", "Damien McGinnes", "Mark Stijnman"] __url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") __version__ = "0.90a" @@ -1100,9 +1092,7 @@ def save_3ds(filename, context): # # save_3ds('/test_b.3ds') class EXPORT_OT_3ds(bpy.types.Operator): - ''' - 3DS Exporter - ''' + '''Export to 3DS file format (.3ds).''' __idname__ = "export.3ds" __label__ = 'Export 3DS' @@ -1128,3 +1118,8 @@ class EXPORT_OT_3ds(bpy.types.Operator): return context.active_object != None bpy.ops.add(EXPORT_OT_3ds) + +# Add to a menu +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("export.3ds", text="Autodesk 3DS...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func) diff --git a/release/scripts/io/export_fbx.py b/release/scripts/io/export_fbx.py index 21b1388ebfe..d159c6588e5 100644 --- a/release/scripts/io/export_fbx.py +++ b/release/scripts/io/export_fbx.py @@ -1,10 +1,3 @@ -#!BPY -""" -Name: 'Autodesk FBX (.fbx)...' -Blender: 249 -Group: 'Export' -Tooltip: 'Selection to an ASCII Autodesk FBX ' -""" __author__ = "Campbell Barton" __url__ = ['www.blender.org', 'blenderartists.org'] __version__ = "1.2" @@ -3341,9 +3334,7 @@ def write_ui(): # GLOBALS.clear() class EXPORT_OT_fbx(bpy.types.Operator): - ''' - Operator documentation text, will be used for the operator tooltip and python docs. - ''' + '''Selection to an ASCII Autodesk FBX''' __idname__ = "export.fbx" __label__ = "Export FBX" @@ -3451,3 +3442,10 @@ bpy.ops.add(EXPORT_OT_fbx) # SMALL or COSMETICAL # - 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 +menu_func = lambda self, context: self.layout.itemO("export.fbx", text="Autodesk FBX...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func) + diff --git a/release/scripts/io/export_obj.py b/release/scripts/io/export_obj.py index 83b400816e3..1e8a152e91f 100644 --- a/release/scripts/io/export_obj.py +++ b/release/scripts/io/export_obj.py @@ -906,14 +906,16 @@ def do_export(filename, context, # orig_scene.makeCurrent() # Window.WaitCursor(0) - + +''' +Currently the exporter lacks these features: +* nurbs +* multiple scene export (only active scene is written) +* particles +''' class EXPORT_OT_obj(bpy.types.Operator): - ''' - Currently the exporter lacks these features: - * nurbs - * multiple scene export (only active scene is written) - * particles - ''' + '''Save a Wavefront OBJ File''' + __idname__ = "export.obj" __label__ = 'Export OBJ' @@ -984,6 +986,10 @@ class EXPORT_OT_obj(bpy.types.Operator): bpy.ops.add(EXPORT_OT_obj) +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("export.obj", text="Wavefront (.obj)...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func) + if __name__ == "__main__": bpy.ops.EXPORT_OT_obj(filename="/tmp/test.obj") diff --git a/release/scripts/io/export_ply.py b/release/scripts/io/export_ply.py index 8e79c3741bb..d74cc0e9d7e 100644 --- a/release/scripts/io/export_ply.py +++ b/release/scripts/io/export_ply.py @@ -273,7 +273,9 @@ class EXPORT_OT_ply(bpy.types.Operator): bpy.ops.add(EXPORT_OT_ply) +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("export.ply", text="Stanford (.ply)...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func) + if __name__ == "__main__": bpy.ops.EXPORT_OT_ply(path="/tmp/test.ply") - - diff --git a/release/scripts/io/export_x3d.py b/release/scripts/io/export_x3d.py index db29afc7d6d..2c6ca749757 100644 --- a/release/scripts/io/export_x3d.py +++ b/release/scripts/io/export_x3d.py @@ -1,10 +1,3 @@ -#!BPY -""" Registration info for Blender menus: -Name: 'X3D Extensible 3D (.x3d)...' -Blender: 245 -Group: 'Export' -Tooltip: 'Export selection to Extensible 3D file (.x3d)' -""" __author__ = ("Bart", "Campbell Barton") __email__ = ["Bart, bart:neeneenee*de"] @@ -1204,9 +1197,7 @@ def x3d_export_ui(filename): # Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d')) class EXPORT_OT_x3d(bpy.types.Operator): - ''' - X3D Exporter - ''' + '''Export selection to Extensible 3D file (.x3d)''' __idname__ = "export.x3d" __label__ = 'Export X3D' @@ -1229,12 +1220,12 @@ class EXPORT_OT_x3d(bpy.types.Operator): wm = context.manager wm.add_fileselect(self.__operator__) return ('RUNNING_MODAL',) - - def poll(self, context): # Poll isnt working yet - print("Poll") - return context.active_object != None bpy.ops.add(EXPORT_OT_x3d) +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("export.x3d", text="X3D Extensible 3D (.x3d)...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func) + # NOTES # - blender version is hardcoded diff --git a/release/scripts/io/import_3ds.py b/release/scripts/io/import_3ds.py index 339fac839ea..cbd9d8948ab 100644 --- a/release/scripts/io/import_3ds.py +++ b/release/scripts/io/import_3ds.py @@ -1,10 +1,3 @@ -#!BPY -""" -Name: '3D Studio (.3ds)...' -Blender: 244 -Group: 'Import' -Tooltip: 'Import from 3DS file format (.3ds)' -""" __author__= ['Bob Holcomb', 'Richard L?rk?ng', 'Damien McGinnes', 'Campbell Barton', 'Mario Lapin'] __url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") @@ -1130,9 +1123,7 @@ else: ''' class IMPORT_OT_3ds(bpy.types.Operator): - ''' - 3DS Importer - ''' + '''Import from 3DS file format (.3ds)''' __idname__ = "import.3ds" __label__ = 'Import 3DS' @@ -1155,13 +1146,13 @@ class IMPORT_OT_3ds(bpy.types.Operator): wm = context.manager wm.add_fileselect(self.__operator__) return ('RUNNING_MODAL',) - ''' - def poll(self, context): - print("Poll") - return context.active_object != None''' bpy.ops.add(IMPORT_OT_3ds) +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("import.3ds", text="3D Studio (.3ds)...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func) + # NOTES: # why add 1 extra vertex? and remove it when done? # disabled scaling to size, this requires exposing bb (easy) and understanding how it works (needs some time) diff --git a/release/scripts/io/import_obj.py b/release/scripts/io/import_obj.py index a762005ae7d..a557e4427d8 100644 --- a/release/scripts/io/import_obj.py +++ b/release/scripts/io/import_obj.py @@ -1,11 +1,3 @@ -#!BPY - -""" -Name: 'Wavefront (.obj)...' -Blender: 249 -Group: 'Import' -Tooltip: 'Load a Wavefront OBJ File, Shift: batch import all dir.' -""" __author__= "Campbell Barton", "Jiri Hnidek", "Paolo Ciccone" __url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org'] @@ -1560,15 +1552,9 @@ else: print 'TOTAL TIME: %.6f' % (sys.time() - TIME) ''' -#load_obj('/test.obj') -#load_obj('/fe/obj/mba1.obj') - - class IMPORT_OT_obj(bpy.types.Operator): - ''' - Operator documentation text, will be used for the operator tooltip and python docs. - ''' + '''Load a Wavefront OBJ File.''' __idname__ = "import.obj" __label__ = "Import OBJ" @@ -1593,10 +1579,6 @@ class IMPORT_OT_obj(bpy.types.Operator): bpy.props.BoolProperty(attr="IMAGE_SEARCH", name="Image Search", description="Search subdirs for any assosiated images (Warning, may be slow)", default= True), ] - ''' - def poll(self, context): - return True ''' - def execute(self, context): # print("Selected: " + context.active_object.name) @@ -1624,6 +1606,11 @@ class IMPORT_OT_obj(bpy.types.Operator): bpy.ops.add(IMPORT_OT_obj) +import dynamic_menu +menu_func = lambda self, context: self.layout.itemO("import.obj", text="Wavefront (.obj)...") +menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func) + + # NOTES (all line numbers refer to 2.4x import_obj.py, not this file) # check later: line 489 # can convert now: edge flags, edges: lines 508-528 diff --git a/release/scripts/io/netrender/client.py b/release/scripts/io/netrender/client.py index 65b2937867f..d4a7b242cab 100644 --- a/release/scripts/io/netrender/client.py +++ b/release/scripts/io/netrender/client.py @@ -3,12 +3,74 @@ import sys, os, re import http, http.client, http.server, urllib import subprocess, shutil, time, hashlib +import netrender.model import netrender.slave as slave import netrender.master as master from netrender.utils import * +def addFluidFiles(job, path): + if os.path.exists(path): + pattern = re.compile("fluidsurface_(final|preview)_([0-9]+)\.(bobj|bvel)\.gz") -def clientSendJob(conn, scene, anim = False, chunks = 5): + for fluid_file in sorted(os.listdir(path)): + match = pattern.match(fluid_file) + + if match: + current_frame = int(match.groups()[1]) + job.addFile(path + fluid_file, current_frame, current_frame) + +def addPointCache(job, ob, point_cache, default_path): + if not point_cache.disk_cache: + return + + + name = point_cache.name + if name == "": + name = "".join(["%02X" % ord(c) for c in ob.name]) + + cache_path = bpy.sys.expandpath(point_cache.filepath) if point_cache.external else default_path + + index = "%02i" % point_cache.index + + if os.path.exists(cache_path): + pattern = re.compile(name + "_([0-9]+)_" + index + "\.bphys") + + 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) + +def clientSendJob(conn, scene, anim = False): netsettings = scene.network_render job = netrender.model.RenderJob() @@ -23,6 +85,7 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): job_name = netsettings.job_name path, name = os.path.split(filename) + path += os.sep if job_name == "[default]": job_name = name @@ -30,67 +93,38 @@ def clientSendJob(conn, scene, anim = False, chunks = 5): # LIBRARIES ########################### for lib in bpy.data.libraries: - lib_path = lib.filename - - if lib_path.startswith("//"): - lib_path = path + os.sep + lib_path[2:] - - job.addFile(lib_path) - - ########################### - # POINT CACHES - ########################### - - root, ext = os.path.splitext(name) - cache_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that - - if os.path.exists(cache_path): - caches = {} - pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)_[0-9]+\.bphys") - for cache_file in sorted(os.listdir(cache_path)): - match = pattern.match(cache_file) - - if match: - cache_id = match.groups()[0] - cache_frame = int(match.groups()[1]) - - cache_files = caches.get(cache_id, []) - cache_files.append((cache_frame, cache_file)) - caches[cache_id] = cache_files - - for cache in caches.values(): - cache.sort() - - if len(cache) == 1: - cache_frame, cache_file = cache[0] - job.addFile(cache_path + cache_file, cache_frame, cache_frame) - else: - for i in range(len(cache)): - current_item = cache[i] - next_item = cache[i+1] if i + 1 < len(cache) else None - previous_item = cache[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) + job.addFile(bpy.sys.expandpath(lib_path)) ########################### # IMAGES ########################### for image in bpy.data.images: if image.source == "FILE" and not image.packed_file: - job.addFile(image.filename) + job.addFile(bpy.sys.expandpath(image.filename)) + + ########################### + # FLUID + POINT CACHE + ########################### + root, ext = os.path.splitext(name) + default_path = path + "blendcache_" + root + os.sep # need an API call for that + + for object in bpy.data.objects: + for modifier in object.modifiers: + if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN": + addFluidFiles(job, bpy.sys.expandpath(modifier.settings.path)) + elif modifier.type == "CLOTH": + 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) diff --git a/release/scripts/io/netrender/master.py b/release/scripts/io/netrender/master.py index a3e186a9cfd..1c83e758ce5 100644 --- a/release/scripts/io/netrender/master.py +++ b/release/scripts/io/netrender/master.py @@ -42,9 +42,10 @@ class MRenderSlave(netrender.model.RenderSlave): self.job = None class MRenderJob(netrender.model.RenderJob): - def __init__(self, job_id, name, files, chunks = 1, priority = 1, blacklist = []): + def __init__(self, job_id, job_type, name, files, chunks = 1, priority = 1, blacklist = []): super().__init__() self.id = job_id + self.type = job_type self.name = name self.files = files self.frames = [] @@ -53,6 +54,10 @@ class MRenderJob(netrender.model.RenderJob): self.usage = 0.0 self.blacklist = blacklist self.last_dispatched = time.time() + + # force one chunk for process jobs + if self.type == netrender.model.JOB_PROCESS: + self.chunks = 1 # special server properties self.last_update = 0 @@ -93,8 +98,8 @@ class MRenderJob(netrender.model.RenderJob): if frame: frame.log_path = log_path - def addFrame(self, frame_number): - frame = MRenderFrame(frame_number) + def addFrame(self, frame_number, command): + frame = MRenderFrame(frame_number, command) self.frames.append(frame) return frame @@ -114,12 +119,14 @@ class MRenderJob(netrender.model.RenderJob): return frames class MRenderFrame(netrender.model.RenderFrame): - def __init__(self, frame): + def __init__(self, frame, command): super().__init__() self.number = frame self.slave = None self.time = 0 self.status = QUEUED + self.command = command + self.log_path = None def reset(self, all): @@ -368,10 +375,10 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_id = self.server.nextJobID() - job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist) + job = MRenderJob(job_id, job_info.type, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist) for frame in job_info.frames: - frame = job.addFrame(frame.number) + frame = job.addFrame(frame.number, frame.command) self.server.addJob(job) @@ -538,17 +545,18 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): frame = job[job_frame] if frame: - if job_result == DONE: - length = int(self.headers['content-length']) - buf = self.rfile.read(length) - f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') - f.write(buf) - f.close() + if job.type == netrender.model.JOB_BLENDER: + if job_result == DONE: + length = int(self.headers['content-length']) + buf = self.rfile.read(length) + f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') + f.write(buf) + f.close() - del buf - elif job_result == ERROR: - # blacklist slave on this job on error - job.blacklist.append(slave.id) + del buf + elif job_result == ERROR: + # blacklist slave on this job on error + job.blacklist.append(slave.id) self.server.stats("", "Receiving result") @@ -736,7 +744,7 @@ def runMaster(address, broadcast, path, update_stats, test_break): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - start_time = time.time() + start_time = time.time() while not test_break(): httpd.handle_request() diff --git a/release/scripts/io/netrender/master_html.py b/release/scripts/io/netrender/master_html.py index 6a956a70e9f..545659e8dc4 100644 --- a/release/scripts/io/netrender/master_html.py +++ b/release/scripts/io/netrender/master_html.py @@ -32,9 +32,8 @@ def get(handler): def endTable(): output("</table>") - handler.send_head(content = "text/html") - if handler.path == "/html" or handler.path == "/": + handler.send_head(content = "text/html") output("<html><head><title>NetRender</title></head><body>") output("<h2>Master</h2>") @@ -86,6 +85,7 @@ def get(handler): output("</body></html>") elif handler.path.startswith("/html/job"): + handler.send_head(content = "text/html") job_id = handler.path[9:] output("<html><head><title>NetRender</title></head><body>") @@ -108,10 +108,9 @@ def get(handler): output("</body></html>") elif handler.path.startswith("/html/log"): + handler.send_head(content = "text/plain") pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)") - output("<html><head><title>NetRender</title></head><body>") - match = pattern.match(handler.path[9:]) if match: job_id = match.groups()[0] @@ -125,12 +124,8 @@ def get(handler): if frame: f = open(frame.log_path, 'rb') - output("<pre>") - shutil.copyfileobj(f, handler.wfile) - output("</pre>") - f.close() else: output("no such frame") @@ -138,5 +133,3 @@ def get(handler): output("no such job") else: output("malformed url") - - output("</body></html>") diff --git a/release/scripts/io/netrender/model.py b/release/scripts/io/netrender/model.py index be97f8d0a81..bef6f0e68af 100644 --- a/release/scripts/io/netrender/model.py +++ b/release/scripts/io/netrender/model.py @@ -72,9 +72,18 @@ class RenderSlave: return slave +JOB_BLENDER = 1 +JOB_PROCESS = 2 + +JOB_TYPES = { + JOB_BLENDER: "Blender", + JOB_PROCESS: "Process" + } + class RenderJob: def __init__(self): self.id = "" + self.type = JOB_BLENDER self.name = "" self.files = [] self.frames = [] @@ -87,8 +96,8 @@ class RenderJob: def addFile(self, file_path, start=-1, end=-1): self.files.append((file_path, start, end)) - def addFrame(self, frame_number): - frame = RenderFrame(frame_number) + def addFrame(self, frame_number, command = ""): + frame = RenderFrame(frame_number, command) self.frames.append(frame) return frame @@ -138,8 +147,9 @@ class RenderJob: max_frame = max((f.number for f in frames)) if frames else -1 return { "id": self.id, + "type": self.type, "name": self.name, - "files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= min_frame <= f[2] or f[1] <= max_frame <= f[2])], + "files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= max_frame and f[2] >= min_frame)], "frames": [f.serialize() for f in self.frames if not frames or f in frames], "chunks": self.chunks, "priority": self.priority, @@ -155,6 +165,7 @@ class RenderJob: job = RenderJob() job.id = data["id"] + job.type = data["type"] job.name = data["name"] job.files = data["files"] job.frames = [RenderFrame.materialize(f) for f in data["frames"]] @@ -167,11 +178,12 @@ class RenderJob: return job class RenderFrame: - def __init__(self, number = 0): + def __init__(self, number = 0, command = ""): self.number = number self.time = 0 self.status = QUEUED self.slave = None + self.command = command def statusText(self): return STATUS_TEXT[self.status] @@ -181,7 +193,8 @@ class RenderFrame: "number": self.number, "time": self.time, "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 } @staticmethod @@ -194,5 +207,6 @@ class RenderFrame: frame.time = data["time"] frame.status = data["status"] frame.slave = RenderSlave.materialize(data["slave"]) + frame.command = data["command"] return frame diff --git a/release/scripts/io/netrender/operators.py b/release/scripts/io/netrender/operators.py index 42d1f6a0b86..e46b0c7b888 100644 --- a/release/scripts/io/netrender/operators.py +++ b/release/scripts/io/netrender/operators.py @@ -9,11 +9,9 @@ import netrender.model @rnaOperator class RENDER_OT_netclientanim(bpy.types.Operator): - ''' - Operator documentation text, will be used for the operator tooltip and python docs. - ''' + '''Start rendering an animation on network''' __idname__ = "render.netclientanim" - __label__ = "Net Render Client Anim" + __label__ = "Animation on network" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -42,11 +40,9 @@ class RENDER_OT_netclientanim(bpy.types.Operator): @rnaOperator class RENDER_OT_netclientsend(bpy.types.Operator): - ''' - Operator documentation text, will be used for the operator tooltip and python docs. - ''' + '''Send Render Job to the Network''' __idname__ = "render.netclientsend" - __label__ = "Net Render Client Send" + __label__ = "Send job" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -73,9 +69,9 @@ class RENDER_OT_netclientsend(bpy.types.Operator): @rnaOperator class RENDER_OT_netclientstatus(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' + '''Refresh the status of the current jobs''' __idname__ = "render.netclientstatus" - __label__ = "Net Render Client Status" + __label__ = "Client Status" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -120,7 +116,7 @@ class RENDER_OT_netclientstatus(bpy.types.Operator): class RENDER_OT_netclientblacklistslave(bpy.types.Operator): '''Operator documentation text, will be used for the operator tooltip and python docs.''' __idname__ = "render.netclientblacklistslave" - __label__ = "Net Render Client Blacklist Slave" + __label__ = "Client Blacklist Slave" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -155,7 +151,7 @@ class RENDER_OT_netclientblacklistslave(bpy.types.Operator): class RENDER_OT_netclientwhitelistslave(bpy.types.Operator): '''Operator documentation text, will be used for the operator tooltip and python docs.''' __idname__ = "render.netclientwhitelistslave" - __label__ = "Net Render Client Whitelist Slave" + __label__ = "Client Whitelist Slave" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -189,9 +185,9 @@ class RENDER_OT_netclientwhitelistslave(bpy.types.Operator): @rnaOperator class RENDER_OT_netclientslaves(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' + '''Refresh status about available Render slaves''' __idname__ = "render.netclientslaves" - __label__ = "Net Render Client Slaves" + __label__ = "Client Slaves" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -239,9 +235,9 @@ class RENDER_OT_netclientslaves(bpy.types.Operator): @rnaOperator class RENDER_OT_netclientcancel(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' + '''Cancel the selected network rendering job.''' __idname__ = "render.netclientcancel" - __label__ = "Net Render Client Cancel" + __label__ = "Client Cancel" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -273,9 +269,9 @@ class RENDER_OT_netclientcancel(bpy.types.Operator): @rnaOperator class RENDER_OT_netclientcancelall(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' + '''Cancel all running network rendering jobs.''' __idname__ = "render.netclientcancelall" - __label__ = "Net Render Client Cancel All" + __label__ = "Client Cancel All" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -305,9 +301,9 @@ class RENDER_OT_netclientcancelall(bpy.types.Operator): @rnaOperator class netclientdownload(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' + '''Download render results from the network''' __idname__ = "render.netclientdownload" - __label__ = "Net Render Client Download" + __label__ = "Client Download" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -357,7 +353,7 @@ class netclientdownload(bpy.types.Operator): class netclientscan(bpy.types.Operator): '''Operator documentation text, will be used for the operator tooltip and python docs.''' __idname__ = "render.netclientscan" - __label__ = "Net Render Client Scan" + __label__ = "Client Scan" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. @@ -393,9 +389,9 @@ class netclientscan(bpy.types.Operator): @rnaOperator class netclientweb(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' + '''Open new window with information about running rendering jobs''' __idname__ = "render.netclientweb" - __label__ = "Net Render Client Web" + __label__ = "Open Master Monitor" # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. diff --git a/release/scripts/io/netrender/slave.py b/release/scripts/io/netrender/slave.py index 657e31001e0..15ca6faf297 100644 --- a/release/scripts/io/netrender/slave.py +++ b/release/scripts/io/netrender/slave.py @@ -99,37 +99,46 @@ def render_slave(engine, scene): if not os.path.exists(JOB_PREFIX): os.mkdir(JOB_PREFIX) - job_path = job.files[0][0] # data in files have format (path, start, end) - main_path, main_file = os.path.split(job_path) - - job_full_path = testFile(conn, job.id, slave_id, 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 file_path, start, end in job.files[1:]: - print("\t", file_path) - testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path) - - frame_args = [] - - for frame in job.frames: - print("frame", frame.number) - frame_args += ["-f", str(frame.number)] + if job.type == netrender.model.JOB_BLENDER: + job_path = job.files[0][0] # data in files have format (path, start, end) + main_path, main_file = os.path.split(job_path) + + job_full_path = testFile(conn, job.id, slave_id, 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 file_path, start, end in job.files[1:]: + print("\t", file_path) + testFile(conn, job.id, slave_id, JOB_PREFIX, file_path, main_path) + # announce log to master logfile = netrender.model.LogFile(job.id, [frame.number for frame in job.frames]) conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'), headers={"slave-id":slave_id}) response = conn.getresponse() - first_frame = job.frames[0].number + first_frame = job.frames[0].number + # start render start_t = time.time() - - val = SetErrorMode() - process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - RestoreErrorMode(val) + + if job.type == netrender.model.JOB_BLENDER: + frame_args = [] + + for frame in job.frames: + print("frame", frame.number) + frame_args += ["-f", str(frame.number)] + + val = SetErrorMode() + process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + RestoreErrorMode(val) + elif job.type == netrender.model.JOB_PROCESS: + command = job.frames[0].command + val = SetErrorMode() + process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + RestoreErrorMode(val) headers = {"job-id":job.id, "slave-id":slave_id} @@ -155,6 +164,9 @@ def render_slave(engine, scene): if testCancel(conn, job.id, first_frame): cancelled = True + # read leftovers if needed + stdout += process.stdout.read() + if cancelled: # kill process if needed if process.poll() == None: @@ -182,11 +194,16 @@ def render_slave(engine, scene): headers["job-result"] = str(DONE) for frame in job.frames: headers["job-frame"] = str(frame.number) - # send result back to server - f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb') - conn.request("PUT", "/render", f, headers=headers) - f.close() - response = conn.getresponse() + + 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() + response = conn.getresponse() + elif job.type == netrender.model.JOB_PROCESS: + conn.request("PUT", "/render", headers=headers) + response = conn.getresponse() else: headers["job-result"] = str(ERROR) for frame in job.frames: diff --git a/release/scripts/io/netrender/ui.py b/release/scripts/io/netrender/ui.py index 7681d4865e9..7d7f3c29630 100644 --- a/release/scripts/io/netrender/ui.py +++ b/release/scripts/io/netrender/ui.py @@ -20,7 +20,7 @@ ERROR = 3 class RenderButtonsPanel(bpy.types.Panel): __space_type__ = "PROPERTIES" __region_type__ = "WINDOW" - __context__ = "scene" + __context__ = "render" # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here def poll(self, context): @@ -29,14 +29,10 @@ class RenderButtonsPanel(bpy.types.Panel): # Setting panel, use in the scene for now. @rnaType -class SCENE_PT_network_settings(RenderButtonsPanel): +class RENDER_PT_network_settings(RenderButtonsPanel): __label__ = "Network Settings" COMPAT_ENGINES = set(['NET_RENDER']) - def draw_header(self, context): - layout = self.layout - scene = context.scene - def draw(self, context): layout = self.layout @@ -48,7 +44,6 @@ class SCENE_PT_network_settings(RenderButtonsPanel): split = layout.split() col = split.column() - col.itemR(scene.network_render, "mode") col.itemR(scene.network_render, "path") col.itemR(scene.network_render, "server_address") @@ -60,7 +55,7 @@ class SCENE_PT_network_settings(RenderButtonsPanel): col.itemO("render.netclientscan", icon="ICON_FILE_REFRESH", text="") @rnaType -class SCENE_PT_network_job(RenderButtonsPanel): +class RENDER_PT_network_job(RenderButtonsPanel): __label__ = "Job Settings" COMPAT_ENGINES = set(['NET_RENDER']) @@ -79,16 +74,16 @@ class SCENE_PT_network_job(RenderButtonsPanel): split = layout.split() col = split.column() - - col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION', text="Animaton on network") - col.itemO("render.netclientsend", icon="ICON_FILE_BLEND", text="Send job") - col.itemO("render.netclientweb", icon="ICON_QUESTION", text="Open Master Monitor") + col.itemO("render.netclientanim", icon='ICON_RENDER_ANIMATION') + col.itemO("render.netclientsend", icon="ICON_FILE_BLEND") + col.itemO("render.netclientweb", icon="ICON_QUESTION") col.itemR(scene.network_render, "job_name") - col.itemR(scene.network_render, "priority") - col.itemR(scene.network_render, "chunks") + row = col.row() + row.itemR(scene.network_render, "priority") + row.itemR(scene.network_render, "chunks") @rnaType -class SCENE_PT_network_slaves(RenderButtonsPanel): +class RENDER_PT_network_slaves(RenderButtonsPanel): __label__ = "Slaves Status" COMPAT_ENGINES = set(['NET_RENDER']) @@ -105,11 +100,9 @@ class SCENE_PT_network_slaves(RenderButtonsPanel): row = layout.row() row.template_list(netsettings, "slaves", netsettings, "active_slave_index", rows=2) - col = row.column() - - subcol = col.column(align=True) - subcol.itemO("render.netclientslaves", icon="ICON_FILE_REFRESH", text="") - subcol.itemO("render.netclientblacklistslave", icon="ICON_ZOOMOUT", text="") + sub = row.column(align=True) + sub.itemO("render.netclientslaves", icon="ICON_FILE_REFRESH", text="") + sub.itemO("render.netclientblacklistslave", icon="ICON_ZOOMOUT", text="") if len(bpy.data.netrender_slaves) == 0 and len(netsettings.slaves) > 0: while(len(netsettings.slaves) > 0): @@ -126,7 +119,7 @@ class SCENE_PT_network_slaves(RenderButtonsPanel): layout.itemL(text="Stats: " + slave.stats) @rnaType -class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel): +class RENDER_PT_network_slaves_blacklist(RenderButtonsPanel): __label__ = "Slaves Blacklist" COMPAT_ENGINES = set(['NET_RENDER']) @@ -143,10 +136,8 @@ class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel): row = layout.row() row.template_list(netsettings, "slaves_blacklist", netsettings, "active_blacklisted_slave_index", rows=2) - col = row.column() - - subcol = col.column(align=True) - subcol.itemO("render.netclientwhitelistslave", icon="ICON_ZOOMOUT", text="") + sub = row.column(align=True) + sub.itemO("render.netclientwhitelistslave", icon="ICON_ZOOMOUT", text="") if len(bpy.data.netrender_blacklist) == 0 and len(netsettings.slaves_blacklist) > 0: while(len(netsettings.slaves_blacklist) > 0): @@ -163,7 +154,7 @@ class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel): layout.itemL(text="Stats: " + time.ctime(slave.stats)) @rnaType -class SCENE_PT_network_jobs(RenderButtonsPanel): +class RENDER_PT_network_jobs(RenderButtonsPanel): __label__ = "Jobs" COMPAT_ENGINES = set(['NET_RENDER']) @@ -180,13 +171,11 @@ class SCENE_PT_network_jobs(RenderButtonsPanel): row = layout.row() row.template_list(netsettings, "jobs", netsettings, "active_job_index", rows=2) - col = row.column() - - subcol = col.column(align=True) - subcol.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="") - subcol.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="") - subcol.itemO("render.netclientcancelall", icon="ICON_PANEL_CLOSE", text="") - subcol.itemO("render.netclientdownload", icon='ICON_RENDER_ANIMATION', text="") + sub = row.column(align=True) + sub.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="") + sub.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="") + sub.itemO("render.netclientcancelall", icon="ICON_PANEL_CLOSE", text="") + sub.itemO("render.netclientdownload", icon='ICON_RENDER_ANIMATION', text="") if len(bpy.data.netrender_jobs) == 0 and len(netsettings.jobs) > 0: while(len(netsettings.jobs) > 0): @@ -234,18 +223,21 @@ NetRenderSettings.BoolProperty( attr="server_broadcast", description="broadcast server address on local network", default = True) -if os.name == 'nt': - NetRenderSettings.StringProperty( attr="path", - name="Path", - description="Path for temporary files", - maxlen = 128, - default = "C:/tmp/") -else: - NetRenderSettings.StringProperty( attr="path", - name="Path", - description="Path for temporary files", - maxlen = 128, - default = "/tmp/") +default_path = os.environ.get("TEMP", None) + +if not default_path: + if os.name == 'nt': + default_path = "c:/tmp/" + else: + default_path = "/tmp/" +elif not default_path.endswith(os.sep): + default_path += os.sep + +NetRenderSettings.StringProperty( attr="path", + name="Path", + description="Path for temporary files", + maxlen = 128, + default = default_path) NetRenderSettings.StringProperty( attr="job_name", name="Job name", @@ -300,8 +292,8 @@ NetRenderSettings.EnumProperty(attr="mode", ("RENDER_MASTER", "Master", "Act as render master"), ("RENDER_SLAVE", "Slave", "Act as render slave"), ), - name="network mode", - description="mode of operation of this instance", + name="Network mode", + description="Mode of operation of this instance", default="RENDER_CLIENT") NetRenderSettings.CollectionProperty(attr="slaves", type=NetRenderSlave, name="Slaves", description="") diff --git a/release/scripts/io/netrender/utils.py b/release/scripts/io/netrender/utils.py index 06393a738a0..b10648b8d62 100644 --- a/release/scripts/io/netrender/utils.py +++ b/release/scripts/io/netrender/utils.py @@ -75,7 +75,7 @@ def prefixPath(prefix_directory, file_path, prefix_path): if prefix_path and p.startswith(prefix_path): directory = prefix_directory + p[len(prefix_path):] - full_path = directory + n + full_path = directory + os.sep + n if not os.path.exists(directory): os.mkdir(directory) else: diff --git a/release/scripts/modules/bpy_ops.py b/release/scripts/modules/bpy_ops.py index 83c2e82bf6c..639b9836b0c 100644 --- a/release/scripts/modules/bpy_ops.py +++ b/release/scripts/modules/bpy_ops.py @@ -139,3 +139,188 @@ class bpy_ops_submodule_op(object): import bpy bpy.ops = bpy_ops() + +# TODO, C macro's cant define settings :| + +class MESH_OT_delete_edgeloop(bpy.types.Operator): + '''Export a single object as a stanford PLY with normals, colours and texture coordinates.''' + __idname__ = "mesh.delete_edgeloop" + __label__ = "Delete Edge Loop" + + def execute(self, context): + bpy.ops.tfm.edge_slide(value=1.0) + bpy.ops.mesh.select_more() + bpy.ops.mesh.remove_doubles() + return ('FINISHED',) + +rna_path_prop = bpy.props.StringProperty(attr="path", name="Context Attributes", description="rna context string", maxlen= 1024, default= "") +rna_reverse_prop = bpy.props.BoolProperty(attr="reverse", name="Reverse", description="Cycle backwards", default= False) + +class NullPathMember: + pass + +def context_path_validate(context, path): + import sys + try: + value = eval("context.%s" % path) + except AttributeError: + if "'NoneType'" in str(sys.exc_info()[1]): + # One of the items in the rna path is None, just ignore this + value = NullPathMember + else: + # We have a real error in the rna path, dont ignore that + raise + + return value + + + +def execute_context_assign(self, context): + if context_path_validate(context, self.path) == NullPathMember: + return ('PASS_THROUGH',) + + exec("context.%s=self.value" % self.path) + return ('FINISHED',) + +class WM_OT_context_set_boolean(bpy.types.Operator): + '''Set a context value.''' + __idname__ = "wm.context_set_boolean" + __label__ = "Context Set" + __props__ = [rna_path_prop, bpy.props.BoolProperty(attr="value", name="Value", description="Assignment value", default= True)] + execute = execute_context_assign + +class WM_OT_context_set_int(bpy.types.Operator): # same as enum + '''Set a context value.''' + __idname__ = "wm.context_set_int" + __label__ = "Context Set" + __props__ = [rna_path_prop, bpy.props.IntProperty(attr="value", name="Value", description="Assignment value", default= 0)] + execute = execute_context_assign + +class WM_OT_context_set_float(bpy.types.Operator): # same as enum + '''Set a context value.''' + __idname__ = "wm.context_set_int" + __label__ = "Context Set" + __props__ = [rna_path_prop, bpy.props.FloatProperty(attr="value", name="Value", description="Assignment value", default= 0.0)] + execute = execute_context_assign + +class WM_OT_context_set_string(bpy.types.Operator): # same as enum + '''Set a context value.''' + __idname__ = "wm.context_set_string" + __label__ = "Context Set" + __props__ = [rna_path_prop, bpy.props.StringProperty(attr="value", name="Value", description="Assignment value", maxlen= 1024, default= "")] + execute = execute_context_assign + +class WM_OT_context_set_enum(bpy.types.Operator): + '''Set a context value.''' + __idname__ = "wm.context_set_enum" + __label__ = "Context Set" + __props__ = [rna_path_prop, bpy.props.StringProperty(attr="value", name="Value", description="Assignment value (as a string)", maxlen= 1024, default= "")] + execute = execute_context_assign + +class WM_OT_context_toggle(bpy.types.Operator): + '''Toggle a context value.''' + __idname__ = "wm.context_toggle" + __label__ = "Context Toggle" + __props__ = [rna_path_prop] + def execute(self, context): + + if context_path_validate(context, self.path) == NullPathMember: + return ('PASS_THROUGH',) + + exec("context.%s=not (context.%s)" % (self.path, self.path)) # security nuts will complain. + return ('FINISHED',) + +class WM_OT_context_toggle_enum(bpy.types.Operator): + '''Toggle a context value.''' + __idname__ = "wm.context_toggle_enum" + __label__ = "Context Toggle Values" + __props__ = [ + rna_path_prop, + bpy.props.StringProperty(attr="value_1", name="Value", description="Toggle enum", maxlen= 1024, default= ""), + bpy.props.StringProperty(attr="value_2", name="Value", description="Toggle enum", maxlen= 1024, default= "") + ] + def execute(self, context): + + if context_path_validate(context, self.path) == NullPathMember: + return ('PASS_THROUGH',) + + exec("context.%s = ['%s', '%s'][context.%s!='%s']" % (self.path, self.value_1, self.value_2, self.path, self.value_2)) # security nuts will complain. + return ('FINISHED',) + +class WM_OT_context_cycle_int(bpy.types.Operator): + '''Set a context value. Useful for cycling active material, vertex keys, groups' etc.''' + __idname__ = "wm.context_cycle_int" + __label__ = "Context Int Cycle" + __props__ = [rna_path_prop, rna_reverse_prop] + def execute(self, context): + + value = context_path_validate(context, self.path) + if value == NullPathMember: + return ('PASS_THROUGH',) + + self.value = value + if self.reverse: self.value -= 1 + else: self.value += 1 + execute_context_assign(self, context) + + if self.value != eval("context.%s" % self.path): + # relies on rna clamping int's out of the range + if self.reverse: self.value = (1<<32) + else: self.value = -(1<<32) + execute_context_assign(self, context) + + return ('FINISHED',) + +class WM_OT_context_cycle_enum(bpy.types.Operator): + '''Toggle a context value.''' + __idname__ = "wm.context_cycle_enum" + __label__ = "Context Enum Cycle" + __props__ = [rna_path_prop, rna_reverse_prop] + def execute(self, context): + + value = context_path_validate(context, self.path) + if value == NullPathMember: + return ('PASS_THROUGH',) + + orig_value = value + + # Have to get rna enum values + rna_struct_str, rna_prop_str = self.path.rsplit('.', 1) + i = rna_prop_str.find('[') + if i != -1: rna_prop_str = rna_prop_str[0:i] # just incse we get "context.foo.bar[0]" + + rna_struct = eval("context.%s.rna_type" % rna_struct_str) + + rna_prop = rna_struct.properties[rna_prop_str] + + if type(rna_prop) != bpy.types.EnumProperty: + raise Exception("expected an enum property") + + enums = rna_struct.properties[rna_prop_str].items.keys() + orig_index = enums.index(orig_value) + + # Have the info we need, advance to the next item + if self.reverse: + if orig_index==0: advance_enum = enums[-1] + else: advance_enum = enums[orig_index-1] + else: + if orig_index==len(enums)-1: advance_enum = enums[0] + else: advance_enum = enums[orig_index+1] + + # set the new value + exec("context.%s=advance_enum" % self.path) + return ('FINISHED',) + + +bpy.ops.add(MESH_OT_delete_edgeloop) + +bpy.ops.add(WM_OT_context_set_boolean) +bpy.ops.add(WM_OT_context_set_int) +bpy.ops.add(WM_OT_context_set_float) +bpy.ops.add(WM_OT_context_set_string) +bpy.ops.add(WM_OT_context_set_enum) +bpy.ops.add(WM_OT_context_toggle) +bpy.ops.add(WM_OT_context_toggle_enum) +bpy.ops.add(WM_OT_context_cycle_enum) +bpy.ops.add(WM_OT_context_cycle_int) + diff --git a/release/scripts/ui/buttons_data_armature.py b/release/scripts/ui/buttons_data_armature.py index 9344294ff9e..0fb00b03961 100644 --- a/release/scripts/ui/buttons_data_armature.py +++ b/release/scripts/ui/buttons_data_armature.py @@ -47,9 +47,6 @@ class DATA_PT_skeleton(DataButtonsPanel): col.itemR(arm, "layer", text="") col.itemL(text="Protected Layers:") col.itemR(arm, "layer_protection", text="") - col.itemL(text="Edit Options:") - col.itemR(arm, "x_axis_mirror") - col.itemR(arm, "auto_ik") col = split.column() col.itemL(text="Deform:") @@ -88,7 +85,7 @@ class DATA_PT_bone_groups(DataButtonsPanel): pose = ob.pose row = layout.row() - row.template_list(pose, "bone_groups", pose, "active_bone_group_index") + row.template_list(pose, "bone_groups", pose, "active_bone_group_index", rows=2) col = row.column(align=True) col.active = (ob.proxy == None) diff --git a/release/scripts/ui/buttons_data_bone.py b/release/scripts/ui/buttons_data_bone.py index 5971e4492ce..e8041cc7393 100644 --- a/release/scripts/ui/buttons_data_bone.py +++ b/release/scripts/ui/buttons_data_bone.py @@ -48,7 +48,7 @@ class BONE_PT_transform(BoneButtonsPanel): else: pchan = ob.pose.pose_channels[context.bone.name] - layout.itemR(pchan, "rotation_mode") + row = layout.row() col = row.column() @@ -67,6 +67,8 @@ class BONE_PT_transform(BoneButtonsPanel): col.itemR(pchan, "rotation_euler", text="Rotation") row.column().itemR(pchan, "scale") + + layout.itemR(pchan, "rotation_mode") class BONE_PT_transform_locks(BoneButtonsPanel): __label__ = "Transform Locks" @@ -98,8 +100,8 @@ class BONE_PT_transform_locks(BoneButtonsPanel): row.column().itemR(pchan, "lock_scale") -class BONE_PT_bone(BoneButtonsPanel): - __label__ = "Bone" +class BONE_PT_relations(BoneButtonsPanel): + __label__ = "Relations" def draw(self, context): layout = self.layout @@ -115,7 +117,17 @@ class BONE_PT_bone(BoneButtonsPanel): pchan = ob.pose.pose_channels[context.bone.name] split = layout.split() - + + col = split.column() + col.itemL(text="Layers:") + col.itemR(bone, "layer", text="") + + col.itemS() + + if ob and pchan: + col.itemL(text="Bone Group:") + col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="") + col = split.column() col.itemL(text="Parent:") if context.bone: @@ -123,119 +135,46 @@ class BONE_PT_bone(BoneButtonsPanel): else: col.item_pointerR(bone, "parent", arm, "edit_bones", text="") - row = col.row() - row.active = bone.parent != None - row.itemR(bone, "connected") + sub = col.column() + sub.active = bone.parent != None + sub.itemR(bone, "connected") + sub.itemR(bone, "hinge", text="Inherit Rotation") + sub.itemR(bone, "inherit_scale", text="Inherit Scale") + + +class BONE_PT_display(BoneButtonsPanel): + __label__ = "Display" + + def poll(self, context): + return context.bone + + def draw(self, context): + layout = self.layout - col.itemL(text="Layers:") - col.itemR(bone, "layer", text="") + ob = context.object + bone = context.bone + arm = context.armature - col = split.column() - col.itemL(text="Inherit:") - col.itemR(bone, "hinge", text="Rotation") - col.itemR(bone, "inherit_scale", text="Scale") - col.itemL(text="Display:") - col.itemR(bone, "draw_wire", text="Wireframe") - col.itemR(bone, "hidden", text="Hide") + if not bone: + bone = context.edit_bone + pchan = None + else: + pchan = ob.pose.pose_channels[context.bone.name] if ob and pchan: - split = layout.split() + split = layout.split() + col = split.column() - col.itemL(text="Bone Group:") - col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="") + + col.itemR(bone, "draw_wire", text="Wireframe") + col.itemR(bone, "hidden", text="Hide") col = split.column() + col.itemL(text="Custom Shape:") col.itemR(pchan, "custom_shape", text="") -class BONE_PT_inverse_kinematics(BoneButtonsPanel): - __label__ = "Inverse Kinematics" - __default_closed__ = True - - def poll(self, context): - ob = context.object - bone = context.bone - - if ob and context.bone: - pchan = ob.pose.pose_channels[context.bone.name] - return pchan.has_ik - - return False - - def draw(self, context): - layout = self.layout - - ob = context.object - bone = context.bone - pchan = ob.pose.pose_channels[context.bone.name] - - row = layout.row() - row.itemR(ob.pose, "ik_solver") - - split = layout.split(percentage=0.25) - split.itemR(pchan, "ik_dof_x", text="X") - row = split.row() - row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True) - row.active = pchan.ik_dof_x - - split = layout.split(percentage=0.25) - row = split.row() - row.itemR(pchan, "ik_limit_x", text="Limit") - row.active = pchan.ik_dof_x - row = split.row(align=True) - row.itemR(pchan, "ik_min_x", text="") - row.itemR(pchan, "ik_max_x", text="") - row.active = pchan.ik_dof_x and pchan.ik_limit_x - - split = layout.split(percentage=0.25) - split.itemR(pchan, "ik_dof_y", text="Y") - row = split.row() - row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True) - row.active = pchan.ik_dof_y - - split = layout.split(percentage=0.25) - row = split.row() - row.itemR(pchan, "ik_limit_y", text="Limit") - row.active = pchan.ik_dof_y - row = split.row(align=True) - row.itemR(pchan, "ik_min_y", text="") - row.itemR(pchan, "ik_max_y", text="") - row.active = pchan.ik_dof_y and pchan.ik_limit_y - - split = layout.split(percentage=0.25) - split.itemR(pchan, "ik_dof_z", text="Z") - row = split.row() - row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True) - row.active = pchan.ik_dof_z - - split = layout.split(percentage=0.25) - row = split.row() - row.itemR(pchan, "ik_limit_z", text="Limit") - row.active = pchan.ik_dof_z - row = split.row(align=True) - row.itemR(pchan, "ik_min_z", text="") - row.itemR(pchan, "ik_max_z", text="") - row.active = pchan.ik_dof_z and pchan.ik_limit_z - split = layout.split() - split.itemR(pchan, "ik_stretch", text="Stretch", slider=True) - split.itemL() - - if ob.pose.ik_solver == "ITASC": - layout.itemL(text="Joint constraint:") - split = layout.split(percentage=0.3) - row = split.row() - row.itemR(pchan, "ik_rot_control", text="Rotation") - row = split.row() - row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True) - row.active = pchan.ik_rot_control - # not supported yet - #split = layout.split(percentage=0.3) - #row = split.row() - #row.itemR(pchan, "ik_lin_control", text="Size") - #row = split.row() - #row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True) - #row.active = pchan.ik_lin_control class BONE_PT_deform(BoneButtonsPanel): __label__ = "Deform" @@ -285,65 +224,10 @@ class BONE_PT_deform(BoneButtonsPanel): col.itemL(text="Offset:") col.itemR(bone, "cyclic_offset") -class BONE_PT_iksolver_itasc(BoneButtonsPanel): - __idname__ = "BONE_PT_iksolver_itasc" - __label__ = "iTaSC parameters" - __default_closed__ = True - - def poll(self, context): - ob = context.object - bone = context.bone - - if ob and context.bone: - pchan = ob.pose.pose_channels[context.bone.name] - return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param - - return False - - def draw(self, context): - layout = self.layout - - ob = context.object - itasc = ob.pose.ik_param - - layout.row().itemR(itasc, "simulation") - if itasc.simulation: - split = layout.split() - row = split.row() - row.itemR(itasc, "reiteration") - row = split.row() - if itasc.reiteration: - itasc.initial_reiteration = True - row.itemR(itasc, "initial_reiteration") - row.active = not itasc.reiteration - - flow = layout.column_flow() - flow.itemR(itasc, "precision") - flow.itemR(itasc, "num_iter") - flow.active = not itasc.simulation or itasc.initial_reiteration or itasc.reiteration - - if itasc.simulation: - layout.itemR(itasc, "auto_step") - row = layout.row() - if itasc.auto_step: - row.itemR(itasc, "min_step") - row.itemR(itasc, "max_step") - else: - row.itemR(itasc, "num_step") - - layout.itemR(itasc, "solver") - if itasc.simulation: - layout.itemR(itasc, "feedback") - layout.itemR(itasc, "max_velocity") - if itasc.solver == "DLS": - row = layout.row() - row.itemR(itasc, "dampmax") - row.itemR(itasc, "dampeps") bpy.types.register(BONE_PT_context_bone) bpy.types.register(BONE_PT_transform) bpy.types.register(BONE_PT_transform_locks) -bpy.types.register(BONE_PT_bone) +bpy.types.register(BONE_PT_relations) +bpy.types.register(BONE_PT_display) bpy.types.register(BONE_PT_deform) -bpy.types.register(BONE_PT_inverse_kinematics) -bpy.types.register(BONE_PT_iksolver_itasc) diff --git a/release/scripts/ui/buttons_data_empty.py b/release/scripts/ui/buttons_data_empty.py index c07f3136fae..eda6cced0ae 100644 --- a/release/scripts/ui/buttons_data_empty.py +++ b/release/scripts/ui/buttons_data_empty.py @@ -17,7 +17,7 @@ class DATA_PT_empty(DataButtonsPanel): ob = context.object - layout.itemR(ob, "empty_draw_type", text="Draw Type") - layout.itemR(ob, "empty_draw_size", text="Draw Size") + layout.itemR(ob, "empty_draw_type", text="Display") + layout.itemR(ob, "empty_draw_size", text="Size") bpy.types.register(DATA_PT_empty) diff --git a/release/scripts/ui/buttons_data_lamp.py b/release/scripts/ui/buttons_data_lamp.py index 86ca5beb9b5..4e495d158eb 100644 --- a/release/scripts/ui/buttons_data_lamp.py +++ b/release/scripts/ui/buttons_data_lamp.py @@ -202,7 +202,7 @@ class DATA_PT_shadow(DataButtonsPanel): col.itemL(text="Buffer Type:") col.row().itemR(lamp, "shadow_buffer_type", expand=True) - if lamp.shadow_buffer_type in ('REGULAR', 'HALFWAY'): + if lamp.shadow_buffer_type in ('REGULAR', 'HALFWAY', 'DEEP'): split = layout.split() col = split.column() @@ -218,6 +218,8 @@ class DATA_PT_shadow(DataButtonsPanel): sub = col.column(align=True) sub.itemR(lamp, "shadow_buffer_size", text="Size") sub.itemR(lamp, "shadow_buffer_samples", text="Samples") + if lamp.shadow_buffer_type == 'DEEP': + col.itemR(lamp, "compression_threshold") elif lamp.shadow_buffer_type == 'IRREGULAR': layout.itemR(lamp, "shadow_buffer_bias", text="Bias") @@ -249,7 +251,7 @@ class DATA_PT_area(DataButtonsPanel): split = layout.split() col = split.column() - col.itemR(lamp, "shape", text="") + col.row().itemR(lamp, "shape", expand=True) sub = col.column(align=True) if (lamp.shape == 'SQUARE'): @@ -273,9 +275,9 @@ class DATA_PT_spot(DataButtonsPanel): split = layout.split() col = split.column() - sub = col.column(align=True) + sub = col.column() sub.itemR(lamp, "spot_size", text="Size") - sub.itemR(lamp, "spot_blend", text="Blend") + sub.itemR(lamp, "spot_blend", text="Blend", slider=True) col.itemR(lamp, "square") col = split.column() diff --git a/release/scripts/ui/buttons_data_mesh.py b/release/scripts/ui/buttons_data_mesh.py index 780ae3ac8f9..77c6f834073 100644 --- a/release/scripts/ui/buttons_data_mesh.py +++ b/release/scripts/ui/buttons_data_mesh.py @@ -48,6 +48,19 @@ class DATA_PT_normals(DataButtonsPanel): col.itemR(mesh, "vertex_normal_flip") col.itemR(mesh, "double_sided") +class DATA_PT_settings(DataButtonsPanel): + __label__ = "Settings" + + def draw(self, context): + layout = self.layout + + mesh = context.mesh + + split = layout.split() + + col = split.column() + col.itemR(mesh, "texture_mesh") + class DATA_PT_vertex_groups(DataButtonsPanel): __label__ = "Vertex Groups" @@ -58,24 +71,28 @@ class DATA_PT_vertex_groups(DataButtonsPanel): layout = self.layout ob = context.object + group = ob.active_vertex_group + + rows = 2 + if group: + rows= 5 row = layout.row() - row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index", rows=2) + row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index", rows=rows) col = row.column(align=True) col.itemO("object.vertex_group_add", icon='ICON_ZOOMIN', text="") col.itemO("object.vertex_group_remove", icon='ICON_ZOOMOUT', text="") - col.itemO("object.vertex_group_copy", icon='ICON_COPYDOWN', text="") + col.itemO("object.vertex_group_copy", icon='ICON_COPY_ID', text="") if ob.data.users > 1: - col.itemO("object.vertex_group_copy_to_linked", icon='ICON_COPYDOWN', text="") + col.itemO("object.vertex_group_copy_to_linked", icon='ICON_LINK_AREA', text="") - group = ob.active_vertex_group if group: row = layout.row() row.itemR(group, "name") - if ob.mode == 'EDIT': + if ob.mode == 'EDIT' and len(ob.vertex_groups) > 0: row = layout.row() sub = row.row(align=True) @@ -92,7 +109,7 @@ class DATA_PT_shape_keys(DataButtonsPanel): __label__ = "Shape Keys" def poll(self, context): - return (context.object and context.object.type in ('MESH', 'LATTICE')) + return (context.object and context.object.type in ('MESH', 'LATTICE', 'CURVE', 'SURFACE')) def draw(self, context): layout = self.layout @@ -101,8 +118,19 @@ class DATA_PT_shape_keys(DataButtonsPanel): key = ob.data.shape_keys kb = ob.active_shape_key + enable_edit = ob.mode != 'EDIT' + enable_edit_value = False + + if ob.shape_key_lock == False: + if enable_edit or (ob.type == 'MESH' and ob.shape_key_edit_mode): + enable_edit_value = True + row = layout.row() - row.template_list(key, "keys", ob, "active_shape_key_index", rows=2) + + rows = 2 + if kb: + rows= 5 + row.template_list(key, "keys", ob, "active_shape_key_index", rows=rows) col = row.column() @@ -114,45 +142,54 @@ class DATA_PT_shape_keys(DataButtonsPanel): col.itemS() subcol = col.column(align=True) - subcol.itemR(ob, "shape_key_lock", icon='ICON_UNPINNED', text="") - subcol.itemR(kb, "mute", icon='ICON_MUTE_IPO_ON', text="") + subcol.item_enumO("object.shape_key_move", "type", 'UP', icon='ICON_TRIA_UP', text="") + subcol.item_enumO("object.shape_key_move", "type", 'DOWN', icon='ICON_TRIA_DOWN', text="") - if key.relative: - row = layout.row() - row.itemR(key, "relative") - row.itemL() + split = layout.split(percentage=0.4) + sub = split.row() + sub.enabled = enable_edit + sub.itemR(key, "relative") - row = layout.row() - row.itemR(kb, "name") + sub = split.row() + sub.alignment = 'RIGHT' + + subrow = sub.row(align=True) + subrow.active= enable_edit_value + subrow.itemR(ob, "shape_key_lock", icon='ICON_UNPINNED', text="") + subrow.itemR(kb, "mute", icon='ICON_MUTE_IPO_OFF', text="") + subrow.itemO("object.shape_key_clear", icon='ICON_X', text="") + + sub.itemO("object.shape_key_mirror", icon='ICON_MOD_MIRROR', text="") + + sub.itemR(ob, "shape_key_edit_mode", text="") + row = layout.row() + row.itemR(kb, "name") + + if key.relative: if ob.active_shape_key_index != 0: - row = layout.row() - row.enabled = ob.shape_key_lock == False - row.itemR(kb, "value", slider=True) + row.active = enable_edit_value + row.itemR(kb, "value") split = layout.split() sub = split.column(align=True) - sub.enabled = ob.shape_key_lock == False + sub.active = enable_edit_value sub.itemL(text="Range:") sub.itemR(kb, "slider_min", text="Min") sub.itemR(kb, "slider_max", text="Max") - sub = split.column() + sub = split.column(align=True) + sub.active = enable_edit_value sub.itemL(text="Blend:") sub.item_pointerR(kb, "vertex_group", ob, "vertex_groups", text="") sub.item_pointerR(kb, "relative_key", key, "keys", text="") else: row = layout.row() - row.itemR(key, "relative") + row.active = enable_edit_value row.itemR(key, "slurph") - layout.itemR(kb, "name") - - if ob.mode == 'EDIT': - layout.enabled = False - class DATA_PT_uv_texture(DataButtonsPanel): __label__ = "UV Texture" @@ -197,7 +234,9 @@ class DATA_PT_vertex_colors(DataButtonsPanel): bpy.types.register(DATA_PT_context_mesh) bpy.types.register(DATA_PT_normals) +bpy.types.register(DATA_PT_settings) bpy.types.register(DATA_PT_vertex_groups) bpy.types.register(DATA_PT_shape_keys) bpy.types.register(DATA_PT_uv_texture) bpy.types.register(DATA_PT_vertex_colors) + diff --git a/release/scripts/ui/buttons_game.py b/release/scripts/ui/buttons_game.py index 5f5d4f916d0..bf25289333f 100644 --- a/release/scripts/ui/buttons_game.py +++ b/release/scripts/ui/buttons_game.py @@ -158,16 +158,16 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel): bpy.types.register(PHYSICS_PT_game_physics) bpy.types.register(PHYSICS_PT_game_collision_bounds) -class SceneButtonsPanel(bpy.types.Panel): +class RenderButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' - __context__ = "scene" + __context__ = "render" def poll(self, context): rd = context.scene.render_data return (rd.engine == 'BLENDER_GAME') -class SCENE_PT_game(SceneButtonsPanel): +class RENDER_PT_game(RenderButtonsPanel): __label__ = "Game" def draw(self, context): @@ -177,7 +177,7 @@ class SCENE_PT_game(SceneButtonsPanel): row.itemO("view3d.game_start", text="Start") row.itemL() -class SCENE_PT_game_player(SceneButtonsPanel): +class RENDER_PT_game_player(RenderButtonsPanel): __label__ = "Standalone Player" def draw(self, context): @@ -208,7 +208,7 @@ class SCENE_PT_game_player(SceneButtonsPanel): if gs.framing_type == 'LETTERBOX': col.itemR(gs, "framing_color", text="") -class SCENE_PT_game_stereo(SceneButtonsPanel): +class RENDER_PT_game_stereo(RenderButtonsPanel): __label__ = "Stereo" def draw(self, context): @@ -257,7 +257,7 @@ class SCENE_PT_game_stereo(SceneButtonsPanel): layout.itemR(gs, "dome_text") -class SCENE_PT_game_shading(SceneButtonsPanel): +class RENDER_PT_game_shading(RenderButtonsPanel): __label__ = "Shading" def draw(self, context): @@ -279,7 +279,7 @@ class SCENE_PT_game_shading(SceneButtonsPanel): col.itemR(gs, "glsl_nodes", text="Nodes") col.itemR(gs, "glsl_extra_textures", text="Extra Textures") -class SCENE_PT_game_performance(SceneButtonsPanel): +class RENDER_PT_game_performance(RenderButtonsPanel): __label__ = "Performance" def draw(self, context): @@ -301,7 +301,7 @@ class SCENE_PT_game_performance(SceneButtonsPanel): col.itemR(gs, "all_frames") col.itemR(gs, "display_lists") -class SCENE_PT_game_sound(SceneButtonsPanel): +class RENDER_PT_game_sound(RenderButtonsPanel): __label__ = "Sound" def draw(self, context): @@ -313,12 +313,12 @@ class SCENE_PT_game_sound(SceneButtonsPanel): layout.itemR(scene, "speed_of_sound", text="Speed") layout.itemR(scene, "doppler_factor") -bpy.types.register(SCENE_PT_game) -bpy.types.register(SCENE_PT_game_player) -bpy.types.register(SCENE_PT_game_stereo) -bpy.types.register(SCENE_PT_game_shading) -bpy.types.register(SCENE_PT_game_performance) -bpy.types.register(SCENE_PT_game_sound) +bpy.types.register(RENDER_PT_game) +bpy.types.register(RENDER_PT_game_player) +bpy.types.register(RENDER_PT_game_stereo) +bpy.types.register(RENDER_PT_game_shading) +bpy.types.register(RENDER_PT_game_performance) +bpy.types.register(RENDER_PT_game_sound) class WorldButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' diff --git a/release/scripts/ui/buttons_material.py b/release/scripts/ui/buttons_material.py index ee7193da301..9499478a029 100644 --- a/release/scripts/ui/buttons_material.py +++ b/release/scripts/ui/buttons_material.py @@ -1,6 +1,19 @@ import bpy +def active_node_mat(mat): + # TODO, 2.4x has a pipeline section, for 2.5 we need to communicate + # which settings from node-materials are used + if mat: + mat_node = mat.active_node_material + if mat_node: + return mat_node + else: + return mat + + return None + + class MaterialButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' @@ -46,6 +59,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel): col = row.column(align=True) col.itemO("object.material_slot_add", icon='ICON_ZOOMIN', text="") col.itemO("object.material_slot_remove", icon='ICON_ZOOMOUT', text="") + col.itemO("object.material_slot_copy", icon='ICON_COPY_ID', text="") if ob.mode == 'EDIT': row = layout.row(align=True) @@ -74,14 +88,14 @@ class MATERIAL_PT_shading(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE', 'HALO')) and (engine in self.COMPAT_ENGINES) def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) if mat.type in ('SURFACE', 'WIRE'): split = layout.split() @@ -117,7 +131,7 @@ class MATERIAL_PT_strand(MaterialButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material + mat = context.material # dont use node material tan = mat.strand split = layout.split() @@ -136,7 +150,9 @@ class MATERIAL_PT_strand(MaterialButtonsPanel): col = split.column() col.itemL(text="Shading:") col.itemR(tan, "width_fade") - col.itemR(tan, "uv_layer") + ob = context.object + if ob and ob.type == 'MESH': col.item_pointerR(tan, "uv_layer", ob.data, "uv_textures", text="") + else: col.itemR(tan, "uv_layer", text="") col.itemS() sub = col.column() sub.active = (not mat.shadeless) @@ -152,7 +168,7 @@ class MATERIAL_PT_physics(MaterialButtonsPanel): def draw(self, context): layout = self.layout - phys = context.material.physics + phys = context.material.physics # dont use node material split = layout.split() @@ -171,14 +187,14 @@ class MATERIAL_PT_options(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE', 'HALO')) and (engine in self.COMPAT_ENGINES) def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) split = layout.split() @@ -188,6 +204,9 @@ class MATERIAL_PT_options(MaterialButtonsPanel): col.itemR(mat, "sky") col.itemR(mat, "exclude_mist") col.itemR(mat, "invert_z") + sub = col.row() + sub.itemR(mat, "z_offset") + sub.active = mat.transparency and mat.transparency_method == 'Z_TRANSPARENCY' sub = col.column(align=True) sub.itemL(text="Light Group:") sub.itemR(mat, "light_group", text="") @@ -211,14 +230,14 @@ class MATERIAL_PT_shadow(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) split = layout.split() @@ -244,14 +263,14 @@ class MATERIAL_PT_diffuse(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) split = layout.split() @@ -292,20 +311,22 @@ class MATERIAL_PT_diffuse(MaterialButtonsPanel): split = row.split(percentage=0.3) split.itemL(text="Blend:") split.itemR(mat, "diffuse_ramp_blend", text="") + row = layout.row() + row.itemR(mat, "diffuse_ramp_factor", text="Factor") class MATERIAL_PT_specular(MaterialButtonsPanel): __label__ = "Specular" COMPAT_ENGINES = set(['BLENDER_RENDER', 'BLENDER_GAME']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) layout.active = (not mat.shadeless) @@ -344,6 +365,8 @@ class MATERIAL_PT_specular(MaterialButtonsPanel): split = row.split(percentage=0.3) split.itemL(text="Blend:") split.itemR(mat, "specular_ramp_blend", text="") + row = layout.row() + row.itemR(mat, "specular_ramp_factor", text="Factor") class MATERIAL_PT_sss(MaterialButtonsPanel): __label__ = "Subsurface Scattering" @@ -351,12 +374,12 @@ class MATERIAL_PT_sss(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw_header(self, context): - mat = context.material + mat = active_node_mat(context.material) sss = mat.subsurface_scattering self.layout.active = (not mat.shadeless) @@ -365,7 +388,7 @@ class MATERIAL_PT_sss(MaterialButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) sss = mat.subsurface_scattering layout.active = sss.enabled @@ -396,19 +419,19 @@ class MATERIAL_PT_mirror(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw_header(self, context): - raym = context.material.raytrace_mirror + raym = active_node_mat(context.material).raytrace_mirror self.layout.itemR(raym, "enabled", text="") def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) raym = mat.raytrace_mirror layout.active = raym.enabled @@ -451,19 +474,19 @@ class MATERIAL_PT_transp(MaterialButtonsPanel): COMPAT_ENGINES = set(['BLENDER_RENDER']) def poll(self, context): - mat = context.material + mat = active_node_mat(context.material) engine = context.scene.render_data.engine return mat and (mat.type in ('SURFACE', 'WIRE')) and (engine in self.COMPAT_ENGINES) def draw_header(self, context): - mat = context.material + mat = active_node_mat(context.material) self.layout.itemR(mat, "transparency", text="") def draw(self, context): layout = self.layout - mat = context.material + mat = active_node_mat(context.material) rayt = mat.raytrace_transparency row = layout.row() @@ -517,7 +540,7 @@ class MATERIAL_PT_halo(MaterialButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material + mat = context.material # dont use node material halo = mat.halo split = layout.split() @@ -569,7 +592,7 @@ class MATERIAL_PT_flare(MaterialButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material + mat = context.material # dont use node material halo = mat.halo layout.active = halo.flare_mode @@ -618,8 +641,7 @@ class MATERIAL_PT_volume_density(VolumeButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material - vol = context.material.volume + vol = context.material.volume # dont use node material split = layout.split() row = split.row() @@ -635,7 +657,7 @@ class MATERIAL_PT_volume_shading(VolumeButtonsPanel): def draw(self, context): layout = self.layout - vol = context.material.volume + vol = context.material.volume # dont use node material split = layout.split() @@ -660,21 +682,22 @@ class MATERIAL_PT_volume_lighting(VolumeButtonsPanel): def draw(self, context): layout = self.layout - vol = context.material.volume + vol = context.material.volume # dont use node material split = layout.split() col = split.column() - col.itemR(vol, "scattering_mode", text="") + col.itemR(vol, "lighting_mode", text="") col = split.column() - if vol.scattering_mode == 'SINGLE_SCATTERING': + if vol.lighting_mode == 'SHADED': + col.itemR(vol, "external_shadows") col.itemR(vol, "light_cache") sub = col.column() sub.active = vol.light_cache sub.itemR(vol, "cache_resolution") - elif vol.scattering_mode in ('MULTIPLE_SCATTERING', 'SINGLE_PLUS_MULTIPLE_SCATTERING'): + elif vol.lighting_mode in ('MULTIPLE_SCATTERING', 'SHADED_PLUS_MULTIPLE_SCATTERING'): sub = col.column() sub.enabled = True sub.active = False @@ -694,7 +717,7 @@ class MATERIAL_PT_volume_transp(VolumeButtonsPanel): def draw(self, context): layout = self.layout - mat = context.material + mat = context.material # dont use node material layout.itemR(mat, "transparency_method", expand=True) @@ -706,7 +729,7 @@ class MATERIAL_PT_volume_integration(VolumeButtonsPanel): def draw(self, context): layout = self.layout - vol = context.material.volume + vol = context.material.volume # dont use node material split = layout.split() diff --git a/release/scripts/ui/buttons_object.py b/release/scripts/ui/buttons_object.py index c069572aa28..98ac462f2d4 100644 --- a/release/scripts/ui/buttons_object.py +++ b/release/scripts/ui/buttons_object.py @@ -26,8 +26,6 @@ class OBJECT_PT_transform(ObjectButtonsPanel): ob = context.object - layout.itemR(ob, "rotation_mode") - row = layout.row() row.column().itemR(ob, "location") @@ -43,6 +41,8 @@ class OBJECT_PT_transform(ObjectButtonsPanel): row.column().itemR(ob, "scale") + layout.itemR(ob, "rotation_mode") + class OBJECT_PT_transform_locks(ObjectButtonsPanel): __label__ = "Transform Locks" __default_closed__ = True diff --git a/release/scripts/ui/buttons_object_constraint.py b/release/scripts/ui/buttons_object_constraint.py index e089cff264f..63fe27f2e4b 100644 --- a/release/scripts/ui/buttons_object_constraint.py +++ b/release/scripts/ui/buttons_object_constraint.py @@ -50,6 +50,7 @@ class ConstraintButtonsPanel(bpy.types.Panel): layout.item_pointerR(con, "subtarget", con.target, "vertex_groups", text="Vertex Group") def ik_template(self, layout, con): + # only used for iTaSC layout.itemR(con, "pole_target") if con.pole_target and con.pole_target.type == 'ARMATURE': @@ -60,14 +61,14 @@ class ConstraintButtonsPanel(bpy.types.Panel): row.itemL() row.itemR(con, "pole_angle") - split = layout.split() + split = layout.split(percentage=0.33) col = split.column() col.itemR(con, "tail") col.itemR(con, "stretch") col = split.column() - col.itemR(con, "iterations") col.itemR(con, "chain_length") + col.itemR(con, "targetless") def CHILD_OF(self, context, layout, con): self.target_template(layout, con) @@ -115,24 +116,74 @@ class ConstraintButtonsPanel(bpy.types.Panel): layout.itemR(con, "ik_type") getattr(self, "IK_"+con.ik_type)(context, layout, con) else: - self.IK_COPY_POSE(context, layout, con) + # Legacy IK constraint + self.target_template(layout, con) + layout.itemR(con, "pole_target") + + if con.pole_target and con.pole_target.type == 'ARMATURE': + layout.item_pointerR(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone") + + if con.pole_target: + row = layout.row() + row.itemL() + row.itemR(con, "pole_angle") + + split = layout.split() + col = split.column() + col.itemR(con, "tail") + col.itemR(con, "stretch") + + col = split.column() + col.itemR(con, "iterations") + col.itemR(con, "chain_length") + + split = layout.split() + col = split.column() + col.itemL() + col.itemR(con, "targetless") + col.itemR(con, "rotation") + + col = split.column() + col.itemL(text="Weight:") + col.itemR(con, "weight", text="Position", slider=True) + sub = col.column() + sub.active = con.rotation + sub.itemR(con, "orient_weight", text="Rotation", slider=True) def IK_COPY_POSE(self, context, layout, con): self.target_template(layout, con) self.ik_template(layout, con) - - split = layout.split() - col = split.column() - col.itemL() - col.itemR(con, "targetless") - col.itemR(con, "rotation") - - col = split.column() - col.itemL(text="Weight:") - col.itemR(con, "weight", text="Position", slider=True) - sub = col.column() - sub.active = con.rotation - sub.itemR(con, "orient_weight", text="Rotation", slider=True) + + row = layout.row() + row.itemL(text="Axis Ref:") + row.itemR(con, "axis_reference", expand=True) + split = layout.split(percentage=0.33) + split.row().itemR(con, "position") + row = split.row() + row.itemR(con, "weight", text="Weight", slider=True) + row.active = con.position + split = layout.split(percentage=0.33) + row = split.row() + row.itemL(text="Lock:") + row = split.row() + row.itemR(con, "pos_lock_x", text="X") + row.itemR(con, "pos_lock_y", text="Y") + row.itemR(con, "pos_lock_z", text="Z") + split.active = con.position + + split = layout.split(percentage=0.33) + split.row().itemR(con, "rotation") + row = split.row() + row.itemR(con, "orient_weight", text="Weight", slider=True) + row.active = con.rotation + split = layout.split(percentage=0.33) + row = split.row() + row.itemL(text="Lock:") + row = split.row() + row.itemR(con, "rot_lock_x", text="X") + row.itemR(con, "rot_lock_y", text="Y") + row.itemR(con, "rot_lock_z", text="Z") + split.active = con.rotation def IK_DISTANCE(self, context, layout, con): self.target_template(layout, con) @@ -536,6 +587,138 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel): for con in ob.constraints: self.draw_constraint(context, con) +class BONE_PT_inverse_kinematics(ConstraintButtonsPanel): + __label__ = "Inverse Kinematics" + __default_closed__ = True + __context__ = "bone_constraint" + + def poll(self, context): + ob = context.object + bone = context.bone + + if ob and bone: + pchan = ob.pose.pose_channels[bone.name] + return pchan.has_ik + + return False + + def draw(self, context): + layout = self.layout + + ob = context.object + bone = context.bone + pchan = ob.pose.pose_channels[bone.name] + + row = layout.row() + row.itemR(ob.pose, "ik_solver") + + split = layout.split(percentage=0.25) + split.itemR(pchan, "ik_dof_x", text="X") + row = split.row() + row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True) + row.active = pchan.ik_dof_x + + split = layout.split(percentage=0.25) + row = split.row() + row.itemR(pchan, "ik_limit_x", text="Limit") + row.active = pchan.ik_dof_x + row = split.row(align=True) + row.itemR(pchan, "ik_min_x", text="") + row.itemR(pchan, "ik_max_x", text="") + row.active = pchan.ik_dof_x and pchan.ik_limit_x + + split = layout.split(percentage=0.25) + split.itemR(pchan, "ik_dof_y", text="Y") + row = split.row() + row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True) + row.active = pchan.ik_dof_y + + split = layout.split(percentage=0.25) + row = split.row() + row.itemR(pchan, "ik_limit_y", text="Limit") + row.active = pchan.ik_dof_y + row = split.row(align=True) + row.itemR(pchan, "ik_min_y", text="") + row.itemR(pchan, "ik_max_y", text="") + row.active = pchan.ik_dof_y and pchan.ik_limit_y + + split = layout.split(percentage=0.25) + split.itemR(pchan, "ik_dof_z", text="Z") + row = split.row() + row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True) + row.active = pchan.ik_dof_z + + split = layout.split(percentage=0.25) + row = split.row() + row.itemR(pchan, "ik_limit_z", text="Limit") + row.active = pchan.ik_dof_z + row = split.row(align=True) + row.itemR(pchan, "ik_min_z", text="") + row.itemR(pchan, "ik_max_z", text="") + row.active = pchan.ik_dof_z and pchan.ik_limit_z + split = layout.split() + split.itemR(pchan, "ik_stretch", text="Stretch", slider=True) + split.itemL() + + if ob.pose.ik_solver == "ITASC": + row = layout.row() + row.itemR(pchan, "ik_rot_control", text="Control Rotation") + row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True) + # not supported yet + #row = layout.row() + #row.itemR(pchan, "ik_lin_control", text="Joint Size") + #row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True) + +class BONE_PT_iksolver_itasc(ConstraintButtonsPanel): + __label__ = "iTaSC parameters" + __default_closed__ = True + __context__ = "bone_constraint" + + def poll(self, context): + ob = context.object + bone = context.bone + + if ob and bone: + pchan = ob.pose.pose_channels[bone.name] + return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param + + return False + + def draw(self, context): + layout = self.layout + + ob = context.object + itasc = ob.pose.ik_param + + layout.itemR(itasc, "mode", expand=True) + simulation = itasc.mode == "SIMULATION" + if simulation: + layout.itemL(text="Reiteration:") + layout.itemR(itasc, "reiteration", expand=True) + + flow = layout.column_flow() + flow.itemR(itasc, "precision", text="Prec") + flow.itemR(itasc, "num_iter", text="Iter") + flow.active = not simulation or itasc.reiteration != "NEVER" + + if simulation: + layout.itemR(itasc, "auto_step") + row = layout.row() + if itasc.auto_step: + row.itemR(itasc, "min_step", text="Min") + row.itemR(itasc, "max_step", text="Max") + else: + row.itemR(itasc, "num_step") + + layout.itemR(itasc, "solver") + if simulation: + layout.itemR(itasc, "feedback") + layout.itemR(itasc, "max_velocity") + if itasc.solver == "DLS": + row = layout.row() + row.itemR(itasc, "dampmax", text="Damp", slider=True) + row.itemR(itasc, "dampeps", text="Eps", slider=True) + class BONE_PT_constraints(ConstraintButtonsPanel): __label__ = "Constraints" __context__ = "bone_constraint" @@ -558,4 +741,6 @@ class BONE_PT_constraints(ConstraintButtonsPanel): self.draw_constraint(context, con) bpy.types.register(OBJECT_PT_constraints) +bpy.types.register(BONE_PT_iksolver_itasc) +bpy.types.register(BONE_PT_inverse_kinematics) bpy.types.register(BONE_PT_constraints) diff --git a/release/scripts/ui/buttons_particle.py b/release/scripts/ui/buttons_particle.py index 1a800fc4dfd..dcc93bd9c75 100644 --- a/release/scripts/ui/buttons_particle.py +++ b/release/scripts/ui/buttons_particle.py @@ -6,8 +6,8 @@ from buttons_physics_common import effector_weights_ui from buttons_physics_common import basic_force_field_settings_ui from buttons_physics_common import basic_force_field_falloff_ui -def particle_panel_enabled(psys): - return psys.point_cache.baked==False and psys.edited==False +def particle_panel_enabled(context, psys): + return psys.point_cache.baked==False and psys.edited==False and (not context.particle_system_editable) def particle_panel_poll(context): psys = context.particle_system @@ -78,7 +78,7 @@ class PARTICLE_PT_particles(ParticleButtonsPanel): return row=col.row() - row.enabled = particle_panel_enabled(psys) + row.enabled = particle_panel_enabled(context, psys) row.itemR(part, "type", text="") row.itemR(psys, "seed") @@ -89,7 +89,7 @@ class PARTICLE_PT_particles(ParticleButtonsPanel): else: split.itemL(text="") row = split.row() - row.enabled = particle_panel_enabled(psys) + row.enabled = particle_panel_enabled(context, psys) row.itemR(part, "hair_step") if psys.edited==True: if psys.global_hair: @@ -99,7 +99,7 @@ class PARTICLE_PT_particles(ParticleButtonsPanel): layout.itemO("particle.disconnect_hair") layout.itemL(text="") elif part.type=='REACTOR': - split.enabled = particle_panel_enabled(psys) + split.enabled = particle_panel_enabled(context, psys) split.itemR(psys, "reactor_target_object") split.itemR(psys, "reactor_target_particle_system", text="Particle System") @@ -118,20 +118,22 @@ class PARTICLE_PT_emission(ParticleButtonsPanel): psys = context.particle_system part = psys.settings - layout.enabled = particle_panel_enabled(psys) and not psys.multiple_caches + layout.enabled = particle_panel_enabled(context, psys) and not psys.multiple_caches row = layout.row() + row.active = part.distribution != 'GRID' row.itemR(part, "amount") - split = layout.split() - - col = split.column(align=True) - col.itemR(part, "start") - col.itemR(part, "end") + if part.type != 'HAIR': + split = layout.split() + + col = split.column(align=True) + col.itemR(part, "start") + col.itemR(part, "end") - col = split.column(align=True) - col.itemR(part, "lifetime") - col.itemR(part, "random_lifetime", slider=True) + col = split.column(align=True) + col.itemR(part, "lifetime") + col.itemR(part, "random_lifetime", slider=True) layout.row().itemL(text="Emit From:") @@ -219,9 +221,9 @@ class PARTICLE_PT_cache(ParticleButtonsPanel): psys = context.particle_system - point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), not psys.hair_dynamics, 0) + point_cache_ui(self, psys.point_cache, particle_panel_enabled(context, psys), not psys.hair_dynamics, 0) -class PARTICLE_PT_initial(ParticleButtonsPanel): +class PARTICLE_PT_velocity(ParticleButtonsPanel): __label__ = "Velocity" def poll(self, context): @@ -237,49 +239,67 @@ class PARTICLE_PT_initial(ParticleButtonsPanel): psys = context.particle_system part = psys.settings - layout.enabled = particle_panel_enabled(psys) - - layout.row().itemL(text="Direction:") + layout.enabled = particle_panel_enabled(context, psys) split = layout.split() sub = split.column() + sub.itemL(text="Emitter Geometry:") sub.itemR(part, "normal_factor") + subsub = sub.column(align=True) + subsub.itemR(part, "tangent_factor") + subsub.itemR(part, "tangent_phase", slider=True) + + sub = split.column() + sub.itemL(text="Emitter Object") + sub.itemR(part, "object_aligned_factor", text="") + + layout.row().itemL(text="Other:") + split = layout.split() + sub = split.column() if part.emit_from=='PARTICLE': sub.itemR(part, "particle_factor") else: sub.itemR(part, "object_factor", slider=True) + sub = split.column() sub.itemR(part, "random_factor") - sub.itemR(part, "tangent_factor") - sub.itemR(part, "tangent_phase", slider=True) - sub = split.column() - sub.itemL(text="TODO:") - sub.itemL(text="Object aligned") - sub.itemL(text="direction: X, Y, Z") + #if part.type=='REACTOR': + # sub.itemR(part, "reactor_factor") + # sub.itemR(part, "reaction_shape", slider=True) - if part.type=='REACTOR': - sub.itemR(part, "reactor_factor") - sub.itemR(part, "reaction_shape", slider=True) +class PARTICLE_PT_rotation(ParticleButtonsPanel): + __label__ = "Rotation" + + def poll(self, context): + if particle_panel_poll(context): + psys = context.particle_system + return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.external else: - sub.itemL(text="") + return False + + def draw(self, context): + layout = self.layout + + psys = context.particle_system + part = psys.settings - layout.row().itemL(text="Rotation:") - split = layout.split() - - sub = split.column() + layout.enabled = particle_panel_enabled(context, psys) - sub.itemR(part, "rotation_mode", text="Axis") + split = layout.split() + split.itemL(text="Initial Rotation:") + split.itemR(part, "rotation_dynamic") split = layout.split() - sub = split.column() - sub.itemR(part, "rotation_dynamic") - sub.itemR(part, "random_rotation_factor", slider=True) - sub = split.column() + sub = split.column(align=True) + sub.itemR(part, "rotation_mode", text="") + sub.itemR(part, "random_rotation_factor", slider=True, text="Random") + + sub = split.column(align=True) sub.itemR(part, "phase_factor", slider=True) sub.itemR(part, "random_phase_factor", text="Random", slider=True) - layout.row().itemL(text="Angular velocity:") + layout.row().itemL(text="Angular Velocity:") layout.row().itemR(part, "angular_velocity_mode", expand=True) split = layout.split() @@ -302,7 +322,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel): psys = context.particle_system part = psys.settings - layout.enabled = particle_panel_enabled(psys) + layout.enabled = particle_panel_enabled(context, psys) row = layout.row() row.itemR(part, "physics_type", expand=True) @@ -441,7 +461,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel): boids = context.particle_system.settings.boids layout = self.layout - layout.enabled = particle_panel_enabled(context.particle_system) + layout.enabled = particle_panel_enabled(context, context.particle_system) # Currently boids can only use the first state so these are commented out for now. #row = layout.row() @@ -607,16 +627,39 @@ class PARTICLE_PT_render(ParticleButtonsPanel): elif part.ren_as == 'OBJECT': sub.itemR(part, "dupli_object") + sub.itemR(part, "use_global_dupli") elif part.ren_as == 'GROUP': sub.itemR(part, "dupli_group") split = layout.split() sub = split.column() sub.itemR(part, "whole_group") + colsub = sub.column() + colsub.active = part.whole_group == False + colsub.itemR(part, "use_group_count") + sub = split.column() colsub = sub.column() colsub.active = part.whole_group == False + colsub.itemR(part, "use_global_dupli") colsub.itemR(part, "rand_group") + if part.use_group_count and not part.whole_group: + row = layout.row() + row.template_list(part, "dupliweights", part, "active_dupliweight_index") + + col = row.column() + subrow = col.row() + subcol = subrow.column(align=True) + subcol.itemO("particle.dupliob_copy", icon='ICON_ZOOMIN', text="") + subcol.itemO("particle.dupliob_remove", icon='ICON_ZOOMOUT', text="") + subcol.itemO("particle.dupliob_move_up", icon='VICON_MOVE_UP', text="") + subcol.itemO("particle.dupliob_move_down", icon='VICON_MOVE_DOWN', text="") + + weight = part.active_dupliweight + if weight: + row = layout.row() + row.itemR(weight, "count") + elif part.ren_as == 'BILLBOARD': sub.itemL(text="Align:") @@ -898,7 +941,8 @@ bpy.types.register(PARTICLE_PT_particles) bpy.types.register(PARTICLE_PT_hair_dynamics) bpy.types.register(PARTICLE_PT_cache) bpy.types.register(PARTICLE_PT_emission) -bpy.types.register(PARTICLE_PT_initial) +bpy.types.register(PARTICLE_PT_velocity) +bpy.types.register(PARTICLE_PT_rotation) bpy.types.register(PARTICLE_PT_physics) bpy.types.register(PARTICLE_PT_boidbrain) bpy.types.register(PARTICLE_PT_render) diff --git a/release/scripts/ui/buttons_physics_common.py b/release/scripts/ui/buttons_physics_common.py index b65d092fcfa..17ac1b2bbaa 100644 --- a/release/scripts/ui/buttons_physics_common.py +++ b/release/scripts/ui/buttons_physics_common.py @@ -78,7 +78,7 @@ def effector_weights_ui(self, weights): layout.itemS() flow = layout.column_flow() - flow.itemR(weights, "spherical", slider=True) + flow.itemR(weights, "force", slider=True) flow.itemR(weights, "vortex", slider=True) flow.itemR(weights, "magnetic", slider=True) flow.itemR(weights, "wind", slider=True) @@ -110,7 +110,7 @@ def basic_force_field_settings_ui(self, field): col.itemR(field, "flow") elif field.type == 'HARMONIC': col.itemR(field, "harmonic_damping", text="Damping") - elif field.type == 'VORTEX' and field.shape == 'PLANE': + elif field.type == 'VORTEX' and field.shape != 'POINT': col.itemR(field, "inflow") elif field.type == 'DRAG': col.itemR(field, "quadratic_drag", text="Quadratic") @@ -140,6 +140,7 @@ def basic_force_field_falloff_ui(self, field): col.itemR(field, "z_direction", text="") col.itemR(field, "use_min_distance", text="Use Minimum") col.itemR(field, "use_max_distance", text="Use Maximum") + col.itemR(field, "do_absorption") col = split.column() col.itemR(field, "falloff_power", text="Power") diff --git a/release/scripts/ui/buttons_physics_field.py b/release/scripts/ui/buttons_physics_field.py index 24740acc68f..9aec0404ab1 100644 --- a/release/scripts/ui/buttons_physics_field.py +++ b/release/scripts/ui/buttons_physics_field.py @@ -21,8 +21,6 @@ class PHYSICS_PT_field(PhysicButtonsPanel): ob = context.object field = ob.field - - #layout.active = field.enabled split = layout.split(percentage=0.2) split.itemL(text="Type:") @@ -39,7 +37,33 @@ class PHYSICS_PT_field(PhysicButtonsPanel): if field.type == 'NONE': return # nothing to draw elif field.type == 'GUIDE': - layout.itemR(field, "guide_path_add") + col = split.column() + col.itemR(field, "guide_minimum") + col.itemR(field, "guide_free") + col.itemR(field, "falloff_power") + col.itemR(field, "guide_path_add") + + col = split.column() + col.itemL(text="Clumping:") + col.itemR(field, "guide_clump_amount") + col.itemR(field, "guide_clump_shape") + + row = layout.row() + row.itemR(field, "use_max_distance") + sub = row.row() + sub.active = field.use_max_distance + sub.itemR(field, "maximum_distance") + + layout.itemS() + + layout.itemR(field, "guide_kink_type") + if (field.guide_kink_type != "NONE"): + layout.itemR(field, "guide_kink_axis") + + flow = layout.column_flow() + flow.itemR(field, "guide_kink_frequency") + flow.itemR(field, "guide_kink_shape") + flow.itemR(field, "guide_kink_amplitude") elif field.type == 'TEXTURE': col = split.column() col.itemR(field, "strength") @@ -102,17 +126,6 @@ class PHYSICS_PT_field(PhysicButtonsPanel): sub = col.column() sub.active = field.use_radial_max sub.itemR(field, "radial_maximum", text="Distance") - - #if ob.type in 'CURVE': - #if field.type == 'GUIDE': - #colsub = col.column(align=True) - - #if field.type != 'NONE': - #layout.itemR(field, "strength") - - #if field.type in ('HARMONIC', 'SPHERICAL', 'CHARGE', "LENNARDj"): - #if ob.type in ('MESH', 'SURFACE', 'FONT', 'CURVE'): - #layout.itemR(field, "surface") class PHYSICS_PT_collision(PhysicButtonsPanel): __label__ = "Collision" diff --git a/release/scripts/ui/buttons_physics_smoke.py b/release/scripts/ui/buttons_physics_smoke.py index 1541b0bae14..b1523148a30 100644 --- a/release/scripts/ui/buttons_physics_smoke.py +++ b/release/scripts/ui/buttons_physics_smoke.py @@ -1,7 +1,8 @@ import bpy -from buttons_particle import point_cache_ui +from buttons_physics_common import point_cache_ui +from buttons_physics_common import effector_weights_ui class PhysicButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' @@ -171,8 +172,21 @@ class PHYSICS_PT_smoke_cache_highres(PhysicButtonsPanel): cache = md.point_cache_high point_cache_ui(self, cache, cache.baked==False, 0, 1) + +class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel): + __label__ = "Smoke Field Weights" + __default_closed__ = True + + def poll(self, context): + smoke = context.smoke + return (smoke and smoke.smoke_type == 'TYPE_DOMAIN') + + def draw(self, context): + domain = context.smoke.domain_settings + effector_weights_ui(self, domain.effector_weights) bpy.types.register(PHYSICS_PT_smoke) +bpy.types.register(PHYSICS_PT_smoke_field_weights) bpy.types.register(PHYSICS_PT_smoke_cache) bpy.types.register(PHYSICS_PT_smoke_highres) bpy.types.register(PHYSICS_PT_smoke_groups) diff --git a/release/scripts/ui/buttons_scene.py b/release/scripts/ui/buttons_scene.py index 2fbd176e36a..54f47791d59 100644 --- a/release/scripts/ui/buttons_scene.py +++ b/release/scripts/ui/buttons_scene.py @@ -1,457 +1,120 @@ import bpy -class RenderButtonsPanel(bpy.types.Panel): +class SceneButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' __context__ = "scene" - # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here def poll(self, context): - rd = context.scene.render_data - return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) + return context.scene -class SCENE_PT_render(RenderButtonsPanel): - __label__ = "Render" +class SCENE_PT_scene(SceneButtonsPanel): + __label__ = "Scene" COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw(self, context): - layout = self.layout - - rd = context.scene.render_data - row = layout.row() - row.itemO("screen.render", text="Image", icon='ICON_RENDER_RESULT') - row.item_booleanO("screen.render", "animation", True, text="Animation", icon='ICON_RENDER_ANIMATION') - - layout.itemR(rd, "display_mode", text="Display") - -class SCENE_PT_layers(RenderButtonsPanel): - __label__ = "Layers" - __default_closed__ = True - COMPAT_ENGINES = set(['BLENDER_RENDER']) - def draw(self, context): layout = self.layout scene = context.scene - rd = scene.render_data - row = layout.row() - row.template_list(rd, "layers", rd, "active_layer_index", rows=2) - - col = row.column(align=True) - col.itemO("scene.render_layer_add", icon='ICON_ZOOMIN', text="") - col.itemO("scene.render_layer_remove", icon='ICON_ZOOMOUT', text="") - - rl = rd.layers[rd.active_layer_index] - - split = layout.split() - - col = split.column() - col.itemR(scene, "visible_layers", text="Scene") - col = split.column() - col.itemR(rl, "visible_layers", text="Layer") - - layout.itemR(rl, "light_override", text="Light") - layout.itemR(rl, "material_override", text="Material") - - layout.itemS() - layout.itemL(text="Include:") - - split = layout.split() + layout.itemR(scene, "camera") + layout.itemR(scene, "set", text="Background") - col = split.column() - col.itemR(rl, "zmask") - row = col.row() - row.itemR(rl, "zmask_negate", text="Negate") - row.active = rl.zmask - col.itemR(rl, "all_z") - - col = split.column() - col.itemR(rl, "solid") - col.itemR(rl, "halo") - col.itemR(rl, "ztransp") - - col = split.column() - col.itemR(rl, "sky") - col.itemR(rl, "edge") - col.itemR(rl, "strand") - - if rl.zmask: - split = layout.split() - split.itemL(text="Zmask Layers:") - split.column().itemR(rl, "zmask_layers", text="") - - layout.itemS() - - split = layout.split() - - col = split.column() - col.itemL(text="Passes:") - col.itemR(rl, "pass_combined") - col.itemR(rl, "pass_z") - col.itemR(rl, "pass_vector") - col.itemR(rl, "pass_normal") - col.itemR(rl, "pass_uv") - col.itemR(rl, "pass_mist") - col.itemR(rl, "pass_object_index") - - col = split.column() - col.itemL() - col.itemR(rl, "pass_color") - col.itemR(rl, "pass_diffuse") - row = col.row() - row.itemR(rl, "pass_specular") - row.itemR(rl, "pass_specular_exclude", text="", icon='ICON_X') - row = col.row() - row.itemR(rl, "pass_shadow") - row.itemR(rl, "pass_shadow_exclude", text="", icon='ICON_X') - row = col.row() - row.itemR(rl, "pass_ao") - row.itemR(rl, "pass_ao_exclude", text="", icon='ICON_X') - row = col.row() - row.itemR(rl, "pass_reflection") - row.itemR(rl, "pass_reflection_exclude", text="", icon='ICON_X') - row = col.row() - row.itemR(rl, "pass_refraction") - row.itemR(rl, "pass_refraction_exclude", text="", icon='ICON_X') - -class SCENE_PT_shading(RenderButtonsPanel): - __label__ = "Shading" +class SCENE_PT_unit(SceneButtonsPanel): + __label__ = "Units" COMPAT_ENGINES = set(['BLENDER_RENDER']) def draw(self, context): layout = self.layout - rd = context.scene.render_data - - split = layout.split() - - col = split.column() - col.itemR(rd, "render_textures", text="Textures") - col.itemR(rd, "render_shadows", text="Shadows") - col.itemR(rd, "render_sss", text="Subsurface Scattering") - col.itemR(rd, "render_envmaps", text="Environment Map") + unit = context.scene.unit_settings - col = split.column() - col.itemR(rd, "render_raytracing", text="Ray Tracing") - col.itemR(rd, "color_management") - col.itemR(rd, "alpha_mode", text="Alpha") - -class SCENE_PT_performance(RenderButtonsPanel): - __label__ = "Performance" - __default_closed__ = True - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw(self, context): - layout = self.layout + col = layout.column() + col.row().itemR(unit, "system", expand=True) - rd = context.scene.render_data - - split = layout.split() + row = layout.row() + row.active = (unit.system != 'NONE') + row.itemR(unit, "scale_length", text="Scale") + row.itemR(unit, "use_separate") - col = split.column(align=True) - col.itemL(text="Threads:") - col.row().itemR(rd, "threads_mode", expand=True) - sub = col.column() - sub.enabled = rd.threads_mode == 'THREADS_FIXED' - sub.itemR(rd, "threads") - col.itemL(text="Tiles:") - col.itemR(rd, "parts_x", text="X") - col.itemR(rd, "parts_y", text="Y") - - col = split.column() - col.itemL(text="Memory:") - sub = col.column() - sub.itemR(rd, "save_buffers") - sub.enabled = not rd.full_sample - sub = col.column() - sub.active = rd.use_compositing - sub.itemR(rd, "free_image_textures") - sub = col.column() - sub.active = rd.render_raytracing - sub.itemL(text="Ray Tracing Octree:") - sub.itemR(rd, "octree_resolution", text="") - -class SCENE_PT_post_processing(RenderButtonsPanel): - __label__ = "Post Processing" - __default_closed__ = True - COMPAT_ENGINES = set(['BLENDER_RENDER']) - +class SCENE_PT_keying_sets(SceneButtonsPanel): + __label__ = "Keying Sets" + def draw(self, context): layout = self.layout - rd = context.scene.render_data - - split = layout.split() - - col = split.column() - col.itemR(rd, "use_compositing") - col.itemR(rd, "use_sequencer") - - col = split.column() - col.itemR(rd, "dither_intensity", text="Dither", slider=True) - - layout.itemS() - - split = layout.split() - - col = split.column() - col.itemR(rd, "fields", text="Fields") - sub = col.column() - sub.active = rd.fields - sub.row().itemR(rd, "field_order", expand=True) - sub.itemR(rd, "fields_still", text="Still") + scene = context.scene - col = split.column() - col.itemR(rd, "edge") - sub = col.column() - sub.active = rd.edge - sub.itemR(rd, "edge_threshold", text="Threshold", slider=True) - sub.itemR(rd, "edge_color", text="") + row = layout.row() -class SCENE_PT_output(RenderButtonsPanel): - __label__ = "Output" - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw(self, context): - layout = self.layout + col = row.column() + col.template_list(scene, "keying_sets", scene, "active_keying_set_index", rows=2) - rd = context.scene.render_data + col = row.column(align=True) + col.itemO("anim.keying_set_add", icon='ICON_ZOOMIN', text="") + col.itemO("anim.keying_set_remove", icon='ICON_ZOOMOUT', text="") - layout.itemR(rd, "output_path", text="") - - split = layout.split() - col = split.column() - col.itemR(rd, "file_format", text="") - col.row().itemR(rd, "color_mode", text="Color", expand=True) - - col = split.column() - col.itemR(rd, "file_extensions") - col.itemR(rd, "use_overwrite") - col.itemR(rd, "use_placeholder") - - if rd.file_format in ('AVIJPEG', 'JPEG'): - split = layout.split() - split.itemR(rd, "quality", slider=True) - - elif rd.file_format == 'OPENEXR': - split = layout.split() + ks = scene.active_keying_set + if ks: + row = layout.row() - col = split.column() - col.itemL(text="Codec:") - col.itemR(rd, "exr_codec", text="") - - subsplit = split.split() - col = subsplit.column() - col.itemR(rd, "exr_half") - col.itemR(rd, "exr_zbuf") - col = subsplit.column() - col.itemR(rd, "exr_preview") - - elif rd.file_format == 'JPEG2000': - split = layout.split() - col = split.column() - col.itemL(text="Depth:") - col.row().itemR(rd, "jpeg2k_depth", expand=True) - - col = split.column() - col.itemR(rd, "jpeg2k_preset", text="") - col.itemR(rd, "jpeg2k_ycc") + col = row.column() + col.itemR(ks, "name") + col.itemR(ks, "absolute") - elif rd.file_format in ('CINEON', 'DPX'): - split = layout.split() - col = split.column() - col.itemR(rd, "cineon_log", text="Convert to Log") - - col = split.column(align=True) - col.active = rd.cineon_log - col.itemR(rd, "cineon_black", text="Black") - col.itemR(rd, "cineon_white", text="White") - col.itemR(rd, "cineon_gamma", text="Gamma") + col = row.column() + col.itemL(text="Keyframing Settings:") + col.itemR(ks, "insertkey_needed", text="Needed") + col.itemR(ks, "insertkey_visual", text="Visual") - elif rd.file_format == 'TIFF': - split = layout.split() - split.itemR(rd, "tiff_bit") - -class SCENE_PT_encoding(RenderButtonsPanel): - __label__ = "Encoding" - __default_closed__ = True - COMPAT_ENGINES = set(['BLENDER_RENDER']) +class SCENE_PT_keying_set_paths(SceneButtonsPanel): + __label__ = "Active Keying Set" def poll(self, context): - rd = context.scene.render_data - return rd.file_format in ('FFMPEG', 'XVID', 'H264', 'THEORA') - - def draw(self, context): - layout = self.layout - - rd = context.scene.render_data - - split = layout.split() - - split.itemR(rd, "ffmpeg_format") - if rd.ffmpeg_format in ('AVI', 'QUICKTIME', 'MKV', 'OGG'): - split.itemR(rd, "ffmpeg_codec") - else: - split.itemL() - - split = layout.split() + return (context.scene != None) and (context.scene.active_keying_set != None) - col = split.column() - col.itemR(rd, "ffmpeg_video_bitrate") - col.itemL(text="Rate:") - col.itemR(rd, "ffmpeg_minrate", text="Minimum") - col.itemR(rd, "ffmpeg_maxrate", text="Maximum") - col.itemR(rd, "ffmpeg_buffersize", text="Buffer") - - col = split.column() - col.itemR(rd, "ffmpeg_gopsize") - col.itemR(rd, "ffmpeg_autosplit") - col.itemL(text="Mux:") - col.itemR(rd, "ffmpeg_muxrate", text="Rate") - col.itemR(rd, "ffmpeg_packetsize", text="Packet Size") - - row = layout.row() - row.itemL(text="Audio:") - row = layout.row() - row.itemR(rd, "ffmpeg_audio_codec") - - split = layout.split() - - col = split.column() - col.itemR(rd, "ffmpeg_audio_bitrate") - col.itemR(rd, "ffmpeg_audio_mixrate") - col = split.column() - col.itemR(rd, "ffmpeg_multiplex_audio") - col.itemR(rd, "ffmpeg_audio_volume") - -class SCENE_PT_antialiasing(RenderButtonsPanel): - __label__ = "Anti-Aliasing" - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw_header(self, context): - rd = context.scene.render_data - - self.layout.itemR(rd, "antialiasing", text="") - - def draw(self, context): - layout = self.layout - - rd = context.scene.render_data - - layout.active = rd.antialiasing - - split = layout.split() - - col = split.column() - col.row().itemR(rd, "antialiasing_samples", expand=True) - col.itemR(rd, "full_sample") - - col = split.column() - col.itemR(rd, "pixel_filter", text="") - col.itemR(rd, "filter_size", text="Size", slider=True) - -class SCENE_PT_dimensions(RenderButtonsPanel): - __label__ = "Dimensions" - COMPAT_ENGINES = set(['BLENDER_RENDER']) - def draw(self, context): layout = self.layout scene = context.scene - rd = scene.render_data - - split = layout.split() - - col = split.column() - sub = col.column(align=True) - sub.itemL(text="Resolution:") - sub.itemR(rd, "resolution_x", text="X") - sub.itemR(rd, "resolution_y", text="Y") - sub.itemR(rd, "resolution_percentage", text="") + ks = scene.active_keying_set - sub.itemL(text="Aspect Ratio:") - sub.itemR(rd, "pixel_aspect_x", text="X") - sub.itemR(rd, "pixel_aspect_y", text="Y") - - row = col.row() - row.itemR(rd, "use_border", text="Border") - rowsub = row.row() - rowsub.active = rd.use_border - rowsub.itemR(rd, "crop_to_border", text="Crop") - - col = split.column(align=True) - col.itemL(text="Frame Range:") - col.itemR(scene, "start_frame", text="Start") - col.itemR(scene, "end_frame", text="End") - col.itemR(scene, "frame_step", text="Step") - - col.itemL(text="Frame Rate:") - col.itemR(rd, "fps") - col.itemR(rd, "fps_base",text="/") - -class SCENE_PT_stamp(RenderButtonsPanel): - __label__ = "Stamp" - __default_closed__ = True - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw_header(self, context): - rd = context.scene.render_data - - self.layout.itemR(rd, "render_stamp", text="") - - def draw(self, context): - layout = self.layout - - rd = context.scene.render_data - - layout.active = rd.render_stamp - - split = layout.split() - - col = split.column() - col.itemR(rd, "stamp_time", text="Time") - col.itemR(rd, "stamp_date", text="Date") - col.itemR(rd, "stamp_frame", text="Frame") - col.itemR(rd, "stamp_scene", text="Scene") - col.itemR(rd, "stamp_camera", text="Camera") - col.itemR(rd, "stamp_filename", text="Filename") - col.itemR(rd, "stamp_marker", text="Marker") - col.itemR(rd, "stamp_sequence_strip", text="Seq. Strip") - - col = split.column() - col.active = rd.render_stamp - col.itemR(rd, "stamp_foreground", slider=True) - col.itemR(rd, "stamp_background", slider=True) - col.itemR(rd, "stamp_font_size", text="Font Size") - - row = layout.split(percentage=0.2) - row.itemR(rd, "stamp_note", text="Note") - sub = row.row() - sub.active = rd.stamp_note - sub.itemR(rd, "stamp_note_text", text="") - -class SCENE_PT_unit(RenderButtonsPanel): - __label__ = "Units" - __default_closed__ = True - COMPAT_ENGINES = set(['BLENDER_RENDER']) - - def draw(self, context): - layout = self.layout + row = layout.row() + row.itemL(text="Paths:") - unit = context.scene.unit_settings + row = layout.row() - col = layout.column() - col.row().itemR(unit, "system", expand=True) + col = row.column() + col.template_list(ks, "paths", ks, "active_path_index", rows=2) - row = layout.row() - row.active = (unit.system != 'NONE') - row.itemR(unit, "scale_length", text="Scale") - row.itemR(unit, "use_separate") + col = row.column(align=True) + col.itemO("anim.keying_set_path_add", icon='ICON_ZOOMIN', text="") + col.itemO("anim.keying_set_path_remove", icon='ICON_ZOOMOUT', text="") + + ksp = ks.active_path + if ksp: + col = layout.column() + col.itemL(text="Target:") + col.template_any_ID(ksp, "id", "id_type") + col.template_path_builder(ksp, "rna_path", ksp.id) + + + row = layout.row() + + col = row.column() + col.itemL(text="Array Target:") + col.itemR(ksp, "entire_array") + if ksp.entire_array == False: + col.itemR(ksp, "array_index") + + col = row.column() + col.itemL(text="F-Curve Grouping:") + col.itemR(ksp, "grouping") + if ksp.grouping == 'NAMED': + col.itemR(ksp, "group") -class SCENE_PT_physics(RenderButtonsPanel): +class SCENE_PT_physics(SceneButtonsPanel): __label__ = "Gravity" COMPAT_ENGINES = set(['BLENDER_RENDER']) @@ -467,16 +130,8 @@ class SCENE_PT_physics(RenderButtonsPanel): layout.itemR(scene, "gravity", text="") - -bpy.types.register(SCENE_PT_render) -bpy.types.register(SCENE_PT_layers) -bpy.types.register(SCENE_PT_dimensions) -bpy.types.register(SCENE_PT_antialiasing) -bpy.types.register(SCENE_PT_shading) -bpy.types.register(SCENE_PT_output) -bpy.types.register(SCENE_PT_encoding) -bpy.types.register(SCENE_PT_performance) -bpy.types.register(SCENE_PT_post_processing) -bpy.types.register(SCENE_PT_stamp) +bpy.types.register(SCENE_PT_scene) bpy.types.register(SCENE_PT_unit) +bpy.types.register(SCENE_PT_keying_sets) +bpy.types.register(SCENE_PT_keying_set_paths) bpy.types.register(SCENE_PT_physics) diff --git a/release/scripts/ui/buttons_texture.py b/release/scripts/ui/buttons_texture.py index 9765aa93ca4..1680a80bb6c 100644 --- a/release/scripts/ui/buttons_texture.py +++ b/release/scripts/ui/buttons_texture.py @@ -1,6 +1,30 @@ import bpy +def active_node_mat(mat): + if mat: + mat_node = mat.active_node_material + if mat_node: + return mat_node + else: + return mat + + return None + +def context_tex_datablock(context): + + idblock = active_node_mat(context.material) + if idblock: return idblock + + idblock = context.lamp + if idblock: return idblock + + idblock = context.world + if idblock: return idblock + + idblock = context.brush + return idblock + class TextureButtonsPanel(bpy.types.Panel): __space_type__ = 'PROPERTIES' __region_type__ = 'WINDOW' @@ -18,19 +42,11 @@ class TEXTURE_PT_preview(TextureButtonsPanel): tex = context.texture slot = context.texture_slot - ma = context.material - la = context.lamp - wo = context.world - br = context.brush - - if ma: - layout.template_preview(tex, parent=ma, slot=slot) - elif la: - layout.template_preview(tex, parent=la, slot=slot) - elif wo: - layout.template_preview(tex, parent=wo, slot=slot) - elif br: - layout.template_preview(tex, parent=br, slot=slot) + + idblock = context_tex_datablock(context) + + if idblock: + layout.template_preview(tex, parent=idblock, slot=slot) else: layout.template_preview(tex, slot=slot) @@ -44,22 +60,25 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel): layout = self.layout tex = context.texture - - id = context.material - if not id: id = context.lamp - if not id: id = context.world - if not id: id = context.brush + + idblock = context_tex_datablock(context) space = context.space_data - if id: + if idblock: row = layout.row() - row.template_list(id, "textures", id, "active_texture_index", rows=2) + + row.template_list(idblock, "textures", idblock, "active_texture_index", rows=2) + + col = row.column(align=True) + col.item_enumO("texture.slot_move", "type", 'UP', text="", icon='ICON_TRIA_UP') + col.item_enumO("texture.slot_move", "type", 'DOWN', text="", icon='ICON_TRIA_DOWN') + split = layout.split(percentage=0.65) - if id: - split.template_ID(id, "active_texture", new="texture.new") + if idblock: + split.template_ID(idblock, "active_texture", new="texture.new") elif tex: split.template_ID(space, "pin_id") @@ -75,11 +94,13 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel): layout.itemR(tex, "use_nodes") split = layout.split(percentage=0.2) - + if tex.use_nodes: slot = context.texture_slot - split.itemL(text="Output:") - split.itemR(slot, "output_node", text="") + + if slot: + split.itemL(text="Output:") + split.itemR(slot, "output_node", text="") else: split.itemL(text="Type:") @@ -99,8 +120,13 @@ class TEXTURE_PT_colors(TextureButtonsPanel): layout.template_color_ramp(tex, "color_ramp", expand=True) split = layout.split() - - split.itemR(tex, "rgb_factor", text="Multiply RGB") + + col = split.column() + col.itemL(text="RGB Multiply:") + sub = col.column(align=True) + sub.itemR(tex, "factor_red", text="R") + sub.itemR(tex, "factor_green", text="G") + sub.itemR(tex, "factor_blue", text="B") col = split.column() col.itemL(text="Adjust:") @@ -122,14 +148,12 @@ class TEXTURE_PT_mapping(TextureSlotPanel): def draw(self, context): layout = self.layout - ma = context.material - la = context.lamp - wo = context.world - br = context.brush + idblock = context_tex_datablock(context) + tex = context.texture_slot textype = context.texture - if not br: + if type(idblock) != bpy.types.Brush: split = layout.split(percentage=0.3) col = split.column() col.itemL(text="Coordinates:") @@ -147,58 +171,64 @@ class TEXTURE_PT_mapping(TextureSlotPanel): elif tex.texture_coordinates == 'UV': split = layout.split(percentage=0.3) split.itemL(text="Layer:") - split.itemR(tex, "uv_layer", text="") + ob = context.object + if ob and ob.type == 'MESH': split.item_pointerR(tex, "uv_layer", ob.data, "uv_textures", text="") + else: split.itemR(tex, "uv_layer", text="") elif tex.texture_coordinates == 'OBJECT': split = layout.split(percentage=0.3) split.itemL(text="Object:") split.itemR(tex, "object", text="") - if ma: - split = layout.split(percentage=0.3) - split.itemL(text="Projection:") - split.itemR(tex, "mapping", text="") - - split = layout.split() - - col = split.column() - if tex.texture_coordinates in ('ORCO', 'UV'): - col.itemR(tex, "from_dupli") - elif tex.texture_coordinates == 'OBJECT': - col.itemR(tex, "from_original") - else: - col.itemL() - - col = split.column() - row = col.row() - row.itemR(tex, "x_mapping", text="") - row.itemR(tex, "y_mapping", text="") - row.itemR(tex, "z_mapping", text="") - - if br: - layout.itemR(tex, "brush_map_mode", expand=True) + if type(idblock) == bpy.types.Brush: + layout.itemR(tex, "map_mode", expand=True) row = layout.row() - row.active = tex.brush_map_mode in ('FIXED', 'TILED') + row.active = tex.map_mode in ('FIXED', 'TILED') row.itemR(tex, "angle") row = layout.row() - row.active = tex.brush_map_mode in ('TILED', '3D') + row.active = tex.map_mode in ('TILED', '3D') row.column().itemR(tex, "size") else: + if type(idblock) == bpy.types.Material: + split = layout.split(percentage=0.3) + split.itemL(text="Projection:") + split.itemR(tex, "mapping", text="") + + split = layout.split() + + col = split.column() + if tex.texture_coordinates in ('ORCO', 'UV'): + col.itemR(tex, "from_dupli") + elif tex.texture_coordinates == 'OBJECT': + col.itemR(tex, "from_original") + else: + col.itemL() + + col = split.column() + row = col.row() + row.itemR(tex, "x_mapping", text="") + row.itemR(tex, "y_mapping", text="") + row.itemR(tex, "z_mapping", text="") + + # any non brush row = layout.row() row.column().itemR(tex, "offset") row.column().itemR(tex, "size") + class TEXTURE_PT_influence(TextureSlotPanel): __label__ = "Influence" + def poll(self, context): + return context.texture_slot + def draw(self, context): + layout = self.layout - ma = context.material - la = context.lamp - wo = context.world - br = context.brush + idblock = context_tex_datablock(context) + textype = context.texture tex = context.texture_slot @@ -209,8 +239,8 @@ class TEXTURE_PT_influence(TextureSlotPanel): sub.active = active sub.itemR(tex, factor, text=name, slider=True) - if ma: - if ma.type in ['SURFACE', 'HALO', 'WIRE']: + if type(idblock) == bpy.types.Material: + if idblock.type in ('SURFACE', 'HALO', 'WIRE'): split = layout.split() col = split.column() @@ -240,7 +270,7 @@ class TEXTURE_PT_influence(TextureSlotPanel): #sub = col.column() #sub.active = tex.map_translucency or tex.map_emit or tex.map_alpha or tex.map_raymir or tex.map_hardness or tex.map_ambient or tex.map_specularity or tex.map_reflection or tex.map_mirror #sub.itemR(tex, "default_value", text="Amount", slider=True) - elif ma.type == 'VOLUME': + elif idblock.type == 'VOLUME': split = layout.split() col = split.column() @@ -255,11 +285,12 @@ class TEXTURE_PT_influence(TextureSlotPanel): factor_but(col, tex.map_colortransmission, "map_colortransmission", "colortransmission_factor", "Transmission Color") factor_but(col, tex.map_colorreflection, "map_colorreflection", "colorreflection_factor", "Reflection Color") - elif la: + elif type(idblock) == bpy.types.Lamp: row = layout.row() factor_but(row, tex.map_color, "map_color", "color_factor", "Color") factor_but(row, tex.map_shadow, "map_shadow", "shadow_factor", "Shadow") - elif wo: + + elif type(idblock) == bpy.types.World: split = layout.split() col = split.column() @@ -284,7 +315,8 @@ class TEXTURE_PT_influence(TextureSlotPanel): col = split.column() col.itemR(tex, "negate", text="Negative") col.itemR(tex, "stencil") - if ma or wo: + + if type(idblock) in (bpy.types.Material, bpy.types.World): col.itemR(tex, "default_value", text="DVar", slider=True) # Texture Type Panels # @@ -758,3 +790,4 @@ bpy.types.register(TEXTURE_PT_pointdensity_turbulence) bpy.types.register(TEXTURE_PT_colors) bpy.types.register(TEXTURE_PT_mapping) bpy.types.register(TEXTURE_PT_influence) + diff --git a/release/scripts/ui/buttons_world.py b/release/scripts/ui/buttons_world.py index 3134c0ce46b..b64efc1048d 100644 --- a/release/scripts/ui/buttons_world.py +++ b/release/scripts/ui/buttons_world.py @@ -129,7 +129,8 @@ class WORLD_PT_ambient_occlusion(WorldButtonsPanel): col = split.column() col.itemL(text="Attenuation:") - col.itemR(ao, "distance") + if ao.gather_method == 'RAYTRACE': + col.itemR(ao, "distance") col.itemR(ao, "falloff") sub = col.row() sub.active = ao.falloff diff --git a/release/scripts/ui/space_buttons.py b/release/scripts/ui/space_buttons.py index aa89c06ea08..299e8bc9dae 100644 --- a/release/scripts/ui/space_buttons.py +++ b/release/scripts/ui/space_buttons.py @@ -22,7 +22,6 @@ class Buttons_HT_header(bpy.types.Header): row.itemR(scene, "current_frame") class Buttons_MT_view(bpy.types.Menu): - __space_type__ = 'PROPERTIES' __label__ = "View" def draw(self, context): diff --git a/release/scripts/ui/space_console.py b/release/scripts/ui/space_console.py index a65d7577c7a..5bb211f7d98 100644 --- a/release/scripts/ui/space_console.py +++ b/release/scripts/ui/space_console.py @@ -38,7 +38,6 @@ class CONSOLE_HT_header(bpy.types.Header): row.itemO("console.autocomplete", text="Autocomplete") class CONSOLE_MT_console(bpy.types.Menu): - __space_type__ = 'CONSOLE' __label__ = "Console" def draw(self, context): @@ -51,7 +50,6 @@ class CONSOLE_MT_console(bpy.types.Menu): layout.itemO("console.paste") class CONSOLE_MT_report(bpy.types.Menu): - __space_type__ = 'CONSOLE' __label__ = "Report" def draw(self, context): diff --git a/release/scripts/ui/space_filebrowser.py b/release/scripts/ui/space_filebrowser.py index f1ea5555787..5b0c189464f 100644 --- a/release/scripts/ui/space_filebrowser.py +++ b/release/scripts/ui/space_filebrowser.py @@ -12,11 +12,17 @@ class FILEBROWSER_HT_header(bpy.types.Header): layout.template_header(menus=False) + row = layout.row() + row.itemS() + row = layout.row(align=True) + row.itemO("file.previous", text="", icon='ICON_BACK') + row.itemO("file.next", text="", icon='ICON_FORWARD') row.itemO("file.parent", text="", icon='ICON_FILE_PARENT') row.itemO("file.refresh", text="", icon='ICON_FILE_REFRESH') - row.itemO("file.previous", text="", icon='ICON_PREV_KEYFRAME') - row.itemO("file.next", text="", icon='ICON_NEXT_KEYFRAME') + + row = layout.row() + row.itemS() row = layout.row(align=True) row.itemO("file.directory_new", text="", icon='ICON_NEWFOLDER') @@ -24,8 +30,8 @@ class FILEBROWSER_HT_header(bpy.types.Header): layout.itemR(params, "display", expand=True, text="") layout.itemR(params, "sort", expand=True, text="") - layout.itemR(params, "hide_dot") - layout.itemR(params, "do_filter") + layout.itemR(params, "hide_dot", text="Hide Invisible") + layout.itemR(params, "do_filter", text="", icon='ICON_FILTER') row = layout.row(align=True) row.itemR(params, "filter_folder", text=""); diff --git a/release/scripts/ui/space_image.py b/release/scripts/ui/space_image.py index b14bec0e40e..93d8043b61f 100644 --- a/release/scripts/ui/space_image.py +++ b/release/scripts/ui/space_image.py @@ -2,7 +2,6 @@ import bpy class IMAGE_MT_view(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "View" def draw(self, context): @@ -33,7 +32,7 @@ class IMAGE_MT_view(bpy.types.Menu): for a, b in ratios: text = "Zoom %d:%d" % (a, b) - layout.item_floatO("image.view_zoom_ratio", "ratio", a/float(b), text=text) + layout.item_floatO("image.view_zoom_ratio", "ratio", a/b, text=text) layout.itemS() @@ -44,7 +43,6 @@ class IMAGE_MT_view(bpy.types.Menu): layout.itemO("screen.screen_full_area") class IMAGE_MT_select(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "Select" def draw(self, context): @@ -65,7 +63,6 @@ class IMAGE_MT_select(bpy.types.Menu): layout.itemO("uv.select_linked") class IMAGE_MT_image(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "Image" def draw(self, context): @@ -109,7 +106,6 @@ class IMAGE_MT_image(bpy.types.Menu): layout.itemR(sima, "image_painting") class IMAGE_MT_uvs_showhide(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "Show/Hide Faces" def draw(self, context): @@ -120,7 +116,6 @@ class IMAGE_MT_uvs_showhide(bpy.types.Menu): layout.item_booleanO("uv.hide", "unselected", True) class IMAGE_MT_uvs_transform(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "Transform" def draw(self, context): @@ -131,7 +126,6 @@ class IMAGE_MT_uvs_transform(bpy.types.Menu): layout.itemO("tfm.resize") class IMAGE_MT_uvs_mirror(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "Mirror" def draw(self, context): @@ -145,7 +139,6 @@ class IMAGE_MT_uvs_mirror(bpy.types.Menu): props.constraint_axis[1]= True class IMAGE_MT_uvs_weldalign(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "Weld/Align" def draw(self, context): @@ -155,7 +148,6 @@ class IMAGE_MT_uvs_weldalign(bpy.types.Menu): layout.items_enumO("uv.align", "axis") # W, 2/3/4 class IMAGE_MT_uvs(bpy.types.Menu): - __space_type__ = 'IMAGE_EDITOR' __label__ = "UVs" def draw(self, context): diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py index c1a2b1f4275..d1e4ac13ab7 100644 --- a/release/scripts/ui/space_info.py +++ b/release/scripts/ui/space_info.py @@ -1,6 +1,9 @@ import bpy +import dynamic_menu +# reload(dynamic_menu) + class INFO_HT_header(bpy.types.Header): __space_type__ = 'INFO' @@ -36,28 +39,30 @@ class INFO_HT_header(bpy.types.Header): layout.template_running_jobs() layout.itemL(text=scene.statistics()) - + + layout.itemO("wm.window_fullscreen_toggle", icon='ICON_ARROW_LEFTRIGHT', text="") + class INFO_MT_file(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "File" def draw(self, context): layout = self.layout layout.operator_context = "EXEC_AREA" - layout.itemO("wm.read_homefile", text="New") + layout.itemO("wm.read_homefile", text="New", icon='ICON_NEW') layout.operator_context = "INVOKE_AREA" - layout.itemO("wm.open_mainfile", text="Open...") + layout.itemO("wm.open_mainfile", text="Open...", icon='ICON_FILE_FOLDER') layout.item_menu_enumO("wm.open_recentfile", "file", text="Open Recent") layout.itemO("wm.recover_last_session") + layout.itemO("wm.recover_auto_save", text="Recover Auto Save...") layout.itemS() layout.operator_context = "EXEC_AREA" - layout.itemO("wm.save_mainfile", text="Save") + layout.itemO("wm.save_mainfile", text="Save", icon='ICON_FILE_TICK') layout.operator_context = "INVOKE_AREA" layout.itemO("wm.save_as_mainfile", text="Save As...") - layout.itemO("screen.userpref_show", text="User Preferences...") + layout.itemO("screen.userpref_show", text="User Preferences...", icon='ICON_PREFERENCES') layout.itemS() layout.operator_context = "INVOKE_AREA" @@ -75,35 +80,35 @@ class INFO_MT_file(bpy.types.Menu): layout.itemS() layout.operator_context = "EXEC_AREA" - layout.itemO("wm.exit_blender", text="Quit") + layout.itemO("wm.exit_blender", text="Quit", icon='ICON_QUIT') -class INFO_MT_file_import(bpy.types.Menu): - __space_type__ = 'INFO' - __label__ = "Import" + +# test for expanding menus +''' +class INFO_MT_file_more(INFO_MT_file): + __label__ = "File" def draw(self, context): layout = self.layout - - layout.itemO("import.3ds", text="3DS") - layout.itemO("import.obj", text="OBJ") + layout.itemO("wm.read_homefile", text="TESTING ") -class INFO_MT_file_export(bpy.types.Menu): - __space_type__ = 'INFO' - __label__ = "Export" +dynamic_menu.setup(INFO_MT_file_more) +''' + +class INFO_MT_file_import(dynamic_menu.DynMenu): + __label__ = "Import" def draw(self, context): - layout = self.layout + pass # dynamic menu - layout.itemO("export.3ds", text="3DS") - layout.itemO("export.fbx", text="FBX") - layout.itemO("export.obj", text="OBJ") - layout.itemO("export.ply", text="PLY") - layout.itemO("export.x3d", text="X3D") +class INFO_MT_file_export(dynamic_menu.DynMenu): + __label__ = "Export" + def draw(self, context): + pass # dynamic menu class INFO_MT_file_external_data(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "External Data" def draw(self, context): @@ -119,8 +124,24 @@ class INFO_MT_file_external_data(bpy.types.Menu): layout.itemO("file.report_missing_files") layout.itemO("file.find_missing_files") + +class INFO_MT_mesh_add(dynamic_menu.DynMenu): + __label__ = "Mesh" + def draw(self, context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' + layout.itemO("mesh.primitive_plane_add", icon='ICON_MESH_PLANE', text="Plane") + layout.itemO("mesh.primitive_cube_add", icon='ICON_MESH_CUBE', text="Cube") + layout.itemO("mesh.primitive_circle_add", icon='ICON_MESH_CIRCLE', text="Circle") + layout.itemO("mesh.primitive_uv_sphere_add", icon='ICON_MESH_UVSPHERE', text="UV Sphere") + layout.itemO("mesh.primitive_ico_sphere_add", icon='ICON_MESH_ICOSPHERE', text="Icosphere") + layout.itemO("mesh.primitive_tube_add", icon='ICON_MESH_TUBE', text="Tube") + layout.itemO("mesh.primitive_cone_add", icon='ICON_MESH_CONE', text="Cone") + layout.itemS() + layout.itemO("mesh.primitive_grid_add", icon='ICON_MESH_GRID', text="Grid") + layout.itemO("mesh.primitive_monkey_add", icon='ICON_MESH_MONKEY', text="Monkey") + class INFO_MT_add(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "Add" def draw(self, context): @@ -128,7 +149,9 @@ class INFO_MT_add(bpy.types.Menu): layout.operator_context = "EXEC_SCREEN" - layout.item_menu_enumO("object.mesh_add", "type", text="Mesh", icon='ICON_OUTLINER_OB_MESH') + # layout.item_menu_enumO("object.mesh_add", "type", text="Mesh", icon='ICON_OUTLINER_OB_MESH') + layout.itemM("INFO_MT_mesh_add", icon='ICON_OUTLINER_OB_MESH') + layout.item_menu_enumO("object.curve_add", "type", text="Curve", icon='ICON_OUTLINER_OB_CURVE') layout.item_menu_enumO("object.surface_add", "type", text="Surface", icon='ICON_OUTLINER_OB_SURFACE') layout.item_menu_enumO("object.metaball_add", "type", 'META', text="Metaball", icon='ICON_OUTLINER_OB_META') @@ -144,9 +167,16 @@ class INFO_MT_add(bpy.types.Menu): layout.item_enumO("object.add", "type", 'CAMERA', icon='ICON_OUTLINER_OB_CAMERA') layout.item_menu_enumO("object.lamp_add", "type", 'LAMP', text="Lamp", icon='ICON_OUTLINER_OB_LAMP') + + layout.itemS() + + layout.item_menu_enumO("object.effector_add", "type", 'EMPTY', text="Force Field", icon='ICON_OUTLINER_OB_EMPTY') + + layout.itemS() + + layout.item_menu_enumO("object.group_instance_add", "type", text="Group Instance", icon='ICON_OUTLINER_OB_EMPTY') class INFO_MT_game(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "Game" def draw(self, context): @@ -164,7 +194,6 @@ class INFO_MT_game(bpy.types.Menu): layout.itemR(gs, "deprecation_warnings") class INFO_MT_render(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "Render" def draw(self, context): @@ -172,32 +201,30 @@ class INFO_MT_render(bpy.types.Menu): rd = context.scene.render_data - layout.itemO("screen.render", text="Render Image") - layout.item_booleanO("screen.render", "animation", True, text="Render Animation") + layout.itemO("screen.render", text="Render Image", icon='ICON_RENDER_STILL') + layout.item_booleanO("screen.render", "animation", True, text="Render Animation", icon='ICON_RENDER_ANIMATION') layout.itemS() layout.itemO("screen.render_view_show") class INFO_MT_help(bpy.types.Menu): - __space_type__ = 'INFO' __label__ = "Help" def draw(self, context): layout = self.layout - layout.itemO("help.manual") - layout.itemO("help.release_logs") + layout.itemO("help.manual", icon='ICON_HELP') + layout.itemO("help.release_logs", icon='ICON_URL') layout.itemS() - layout.itemO("help.blender_website") - layout.itemO("help.blender_eshop") - layout.itemO("help.developer_community") - layout.itemO("help.user_community") + layout.itemO("help.blender_website", icon='ICON_URL') + layout.itemO("help.blender_eshop", icon='ICON_URL') + layout.itemO("help.developer_community", icon='ICON_URL') + layout.itemO("help.user_community", icon='ICON_URL') layout.itemS() layout.itemO("help.operator_cheat_sheet") - bpy.types.register(INFO_HT_header) bpy.types.register(INFO_MT_file) @@ -205,6 +232,7 @@ bpy.types.register(INFO_MT_file_import) bpy.types.register(INFO_MT_file_export) bpy.types.register(INFO_MT_file_external_data) bpy.types.register(INFO_MT_add) +bpy.types.register(INFO_MT_mesh_add) bpy.types.register(INFO_MT_game) bpy.types.register(INFO_MT_render) bpy.types.register(INFO_MT_help) @@ -224,38 +252,44 @@ class HelpOperator(bpy.types.Operator): return ('FINISHED',) class HELP_OT_manual(HelpOperator): + '''The Blender Wiki manual''' __idname__ = "help.manual" __label__ = "Manual" __URL__ = 'http://wiki.blender.org/index.php/Manual' class HELP_OT_release_logs(HelpOperator): + '''Information about the changes in this version of Blender''' __idname__ = "help.release_logs" __label__ = "Release Logs" __URL__ = 'http://www.blender.org/development/release-logs/' class HELP_OT_blender_website(HelpOperator): + '''The official Blender website''' __idname__ = "help.blender_website" __label__ = "Blender Website" __URL__ = 'http://www.blender.org/' class HELP_OT_blender_eshop(HelpOperator): + '''Buy official Blender resources and merchandise online''' __idname__ = "help.blender_eshop" __label__ = "Blender e-Shop" __URL__ = 'http://www.blender3d.org/e-shop' class HELP_OT_developer_community(HelpOperator): + '''Get involved with Blender development''' __idname__ = "help.developer_community" __label__ = "Developer Community" __URL__ = 'http://www.blender.org/community/get-involved/' class HELP_OT_user_community(HelpOperator): + '''Get involved with other Blender users''' __idname__ = "help.user_community" __label__ = "User Community" __URL__ = 'http://www.blender.org/community/user-community/' class HELP_OT_operator_cheat_sheet(bpy.types.Operator): __idname__ = "help.operator_cheat_sheet" - __label__ = "Operator Cheet Sheet (new textblock)" + __label__ = "Operator Cheat Sheet (new textblock)" def execute(self, context): op_strings = [] tot = 0 @@ -278,7 +312,6 @@ class HELP_OT_operator_cheat_sheet(bpy.types.Operator): print("See OperatorList.txt textblock") return ('FINISHED',) - bpy.ops.add(HELP_OT_manual) bpy.ops.add(HELP_OT_release_logs) bpy.ops.add(HELP_OT_blender_website) @@ -286,4 +319,3 @@ bpy.ops.add(HELP_OT_blender_eshop) bpy.ops.add(HELP_OT_developer_community) bpy.ops.add(HELP_OT_user_community) bpy.ops.add(HELP_OT_operator_cheat_sheet) - diff --git a/release/scripts/ui/space_node.py b/release/scripts/ui/space_node.py index b32e6a9f61a..5c5c49afbc7 100644 --- a/release/scripts/ui/space_node.py +++ b/release/scripts/ui/space_node.py @@ -48,7 +48,6 @@ class NODE_HT_header(bpy.types.Header): layout.itemR(snode, "backdrop") class NODE_MT_view(bpy.types.Menu): - __space_type__ = 'NODE_EDITOR' __label__ = "View" def draw(self, context): @@ -66,7 +65,6 @@ class NODE_MT_view(bpy.types.Menu): layout.itemO("screen.screen_full_area") class NODE_MT_select(bpy.types.Menu): - __space_type__ = 'NODE_EDITOR' __label__ = "Select" def draw(self, context): @@ -80,7 +78,6 @@ class NODE_MT_select(bpy.types.Menu): layout.itemO("node.select_linked_to") class NODE_MT_node(bpy.types.Menu): - __space_type__ = 'NODE_EDITOR' __label__ = "Node" def draw(self, context): diff --git a/release/scripts/ui/space_outliner.py b/release/scripts/ui/space_outliner.py index 522b620e29d..40816309e7e 100644 --- a/release/scripts/ui/space_outliner.py +++ b/release/scripts/ui/space_outliner.py @@ -5,9 +5,11 @@ class OUTLINER_HT_header(bpy.types.Header): __space_type__ = 'OUTLINER' def draw(self, context): - so = context.space_data - sce = context.scene layout = self.layout + + space = context.space_data + scene = context.scene + ks = context.scene.active_keying_set row = layout.row(align=True) row.template_header() @@ -15,38 +17,62 @@ class OUTLINER_HT_header(bpy.types.Header): if context.area.show_menus: sub = row.row(align=True) sub.itemM("OUTLINER_MT_view") - - row = layout.row() - row.itemR(so, "display_mode", text="") + if space.display_mode == 'DATABLOCKS': + sub.itemM("OUTLINER_MT_edit_datablocks") + + layout.itemR(space, "display_mode", text="") - if so.display_mode == 'DATABLOCKS': + layout.itemS() + + if space.display_mode == 'DATABLOCKS': row = layout.row(align=True) - row.itemO("anim.keyingset_add_new", text="", icon=31) - # row.itemR(sce, "active_keyingset", text="KS: ") - # ks = sce.keyingsets[sce.active_keyingset - 1] - # row.itemR(ks, "name", text="") - ## row.itemR(sce, "keyingsets") - - row = layout.row() - row.itemO("outliner.keyingset_add_selected", text="", icon=31) - row.itemO("outliner.keyingset_remove_selected", text="", icon=32) + row.itemO("outliner.keyingset_add_selected", icon='ICON_ZOOMIN', text="") + row.itemO("outliner.keyingset_remove_selected", icon='ICON_ZOOMOUT', text="") - row.itemO("anim.insert_keyframe", text="", icon=514) - row.itemO("anim.delete_keyframe", text="", icon=513) - + if ks: + row = layout.row(align=False) + row.item_pointerR(scene, "active_keying_set", scene, "keying_sets", text="") + + row = layout.row(align=True) + row.itemO("anim.insert_keyframe", text="", icon='ICON_KEY_HLT') + row.itemO("anim.delete_keyframe", text="", icon='ICON_KEY_DEHLT') + else: + row = layout.row(align=False) + row.itemL(text="No Keying Set active") class OUTLINER_MT_view(bpy.types.Menu): - __space_type__ = 'OUTLINER' __label__ = "View" def draw(self, context): layout = self.layout - so = context.space_data + + space = context.space_data + + col = layout.column() + if space.display_mode not in ('DATABLOCKS', 'USER_PREFERENCES', 'KEYMAPS'): + col.itemR(space, "show_restriction_columns") + col.itemS() + col.itemO("outliner.show_active") + col.itemO("outliner.show_one_level") + col.itemO("outliner.show_hierarchy") + +class OUTLINER_MT_edit_datablocks(bpy.types.Menu): + __label__ = "Edit" + + def draw(self, context): + layout = self.layout + col = layout.column() - col.itemR(so, "show_restriction_columns") - #layout.itemO("text.new") + + col.itemO("outliner.keyingset_add_selected") + col.itemO("outliner.keyingset_remove_selected") + + col.itemS() + + col.itemO("outliner.drivers_add_selected") + col.itemO("outliner.drivers_delete_selected") bpy.types.register(OUTLINER_HT_header) bpy.types.register(OUTLINER_MT_view) - +bpy.types.register(OUTLINER_MT_edit_datablocks) diff --git a/release/scripts/ui/space_sequencer.py b/release/scripts/ui/space_sequencer.py index a804998cdaa..ca84e345885 100644 --- a/release/scripts/ui/space_sequencer.py +++ b/release/scripts/ui/space_sequencer.py @@ -38,7 +38,6 @@ class SEQUENCER_HT_header(bpy.types.Header): layout.itemR(st, "display_channel", text="Channel") class SEQUENCER_MT_view(bpy.types.Menu): - __space_type__ = 'SEQUENCE_EDITOR' __label__ = "View" def draw(self, context): @@ -106,7 +105,6 @@ class SEQUENCER_MT_view(bpy.types.Menu): """ class SEQUENCER_MT_select(bpy.types.Menu): - __space_type__ = 'SEQUENCE_EDITOR' __label__ = "Select" def draw(self, context): @@ -127,7 +125,6 @@ class SEQUENCER_MT_select(bpy.types.Menu): layout.itemO("sequencer.select_inverse") class SEQUENCER_MT_marker(bpy.types.Menu): - __space_type__ = 'SEQUENCE_EDITOR' __label__ = "Marker (TODO)" def draw(self, context): @@ -146,11 +143,11 @@ class SEQUENCER_MT_marker(bpy.types.Menu): #layout.itemO("sequencer.sound_strip_add", text="Transform Markers") # toggle, will be rna - (sseq->flag & SEQ_MARKER_TRANS) class SEQUENCER_MT_add(bpy.types.Menu): - __space_type__ = 'SEQUENCE_EDITOR' __label__ = "Add" def draw(self, context): layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' st = context.space_data @@ -163,12 +160,11 @@ class SEQUENCER_MT_add(bpy.types.Menu): layout.itemM("SEQUENCER_MT_add_effect") class SEQUENCER_MT_add_effect(bpy.types.Menu): - __space_type__ = 'SEQUENCE_EDITOR' __label__ = "Effect Strip..." def draw(self, context): layout = self.layout - + layout.operator_context = 'INVOKE_REGION_WIN' st = context.space_data layout.column() @@ -187,7 +183,6 @@ class SEQUENCER_MT_add_effect(bpy.types.Menu): layout.item_enumO("sequencer.effect_strip_add", 'type', 'SPEED') class SEQUENCER_MT_strip(bpy.types.Menu): - __space_type__ = 'SEQUENCE_EDITOR' __label__ = "Strip" def draw(self, context): diff --git a/release/scripts/ui/space_text.py b/release/scripts/ui/space_text.py index 117033c50a1..4860767d69d 100644 --- a/release/scripts/ui/space_text.py +++ b/release/scripts/ui/space_text.py @@ -98,7 +98,6 @@ class TEXT_PT_find(bpy.types.Panel): row.itemR(st, "find_all", text="All") class TEXT_MT_text(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "Text" def draw(self, context): @@ -140,7 +139,6 @@ class TEXT_MT_text(bpy.types.Menu): #endif class TEXT_MT_edit_view(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "View" def draw(self, context): @@ -150,7 +148,6 @@ class TEXT_MT_edit_view(bpy.types.Menu): layout.item_enumO("text.move", "type", 'FILE_BOTTOM', text="Bottom of File") class TEXT_MT_edit_select(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "Select" def draw(self, context): @@ -160,7 +157,6 @@ class TEXT_MT_edit_select(bpy.types.Menu): layout.itemO("text.select_line") class TEXT_MT_edit_markers(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "Markers" def draw(self, context): @@ -171,7 +167,6 @@ class TEXT_MT_edit_markers(bpy.types.Menu): layout.itemO("text.previous_marker") class TEXT_MT_format(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "Format" def draw(self, context): @@ -190,7 +185,6 @@ class TEXT_MT_format(bpy.types.Menu): layout.item_menu_enumO("text.convert_whitespace", "type") class TEXT_MT_edit_to3d(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "Text To 3D Object" def draw(self, context): @@ -200,7 +194,6 @@ class TEXT_MT_edit_to3d(bpy.types.Menu): layout.item_booleanO("text.to_3d_object", "split_lines", True, text="One Object Per Line"); class TEXT_MT_edit(bpy.types.Menu): - __space_type__ = 'TEXT_EDITOR' __label__ = "Edit" def poll(self, context): diff --git a/release/scripts/ui/space_time.py b/release/scripts/ui/space_time.py index 696dcf18623..2ead4305960 100644 --- a/release/scripts/ui/space_time.py +++ b/release/scripts/ui/space_time.py @@ -64,7 +64,6 @@ class TIME_HT_header(bpy.types.Header): row.itemO("anim.delete_keyframe", text="", icon='ICON_KEY_DEHLT') class TIME_MT_view(bpy.types.Menu): - __space_type__ = 'TIMELINE' __label__ = "View" def draw(self, context): @@ -79,7 +78,6 @@ class TIME_MT_view(bpy.types.Menu): layout.itemR(st, "only_selected") class TIME_MT_frame(bpy.types.Menu): - __space_type__ = 'TIMELINE' __label__ = "Frame" def draw(self, context): @@ -100,11 +98,10 @@ class TIME_MT_frame(bpy.types.Menu): layout.itemS() sub = layout.row() - sub.active = tools.enable_auto_key + #sub.active = tools.enable_auto_key sub.itemM("TIME_MT_autokey") class TIME_MT_playback(bpy.types.Menu): - __space_type__ = 'TIMELINE' __label__ = "Playback" def draw(self, context): @@ -132,7 +129,6 @@ class TIME_MT_playback(bpy.types.Menu): layout.itemR(scene, "scrub_audio") class TIME_MT_autokey(bpy.types.Menu): - __space_type__ = 'TIMELINE' __label__ = "Auto-Keyframing Mode" def draw(self, context): diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py index 9798e0ccab6..c887289e45d 100644 --- a/release/scripts/ui/space_userpref.py +++ b/release/scripts/ui/space_userpref.py @@ -12,9 +12,12 @@ class USERPREF_HT_header(bpy.types.Header): layout.operator_context = "EXEC_AREA" layout.itemO("wm.save_homefile", text="Save As Default") + + if userpref.active_section == 'INPUT': + layout.operator_context = "INVOKE_DEFAULT" + layout.itemO("wm.keyconfig_export", "Export Key Configuration...") class USERPREF_MT_view(bpy.types.Menu): - __space_type__ = 'USER_PREFERENCES' __label__ = "View" def draw(self, context): @@ -31,14 +34,14 @@ class USERPREF_PT_tabs(bpy.types.Panel): layout.itemR(userpref, "active_section", expand=True) -class USERPREF_PT_view(bpy.types.Panel): +class USERPREF_PT_interface(bpy.types.Panel): __space_type__ = 'USER_PREFERENCES' - __label__ = "View" + __label__ = "Interface" __show_header__ = False def poll(self, context): userpref = context.user_preferences - return (userpref.active_section == 'VIEW_CONTROLS') + return (userpref.active_section == 'INTERFACE') def draw(self, context): layout = self.layout @@ -87,37 +90,27 @@ class USERPREF_PT_view(bpy.types.Panel): sub1.itemR(view, "perspective_orthographic_switch") sub1.itemR(view, "smooth_view") sub1.itemR(view, "rotation_angle") - sub1.itemS() - sub1.itemL(text="NDOF Device:") - sub1.itemR(view, "ndof_pan_speed", text="Pan Speed") - sub1.itemR(view, "ndof_rotate_speed", text="Orbit Speed") col = split.column() sub = col.split(percentage=0.85) sub1 = sub.column() - sub1.itemL(text="Mouse Buttons:") - - sub2 = sub1.column() - sub2.enabled = (view.select_mouse == 'RIGHT') - sub2.itemR(view, "emulate_3_button_mouse") - sub1.itemL(text="Select With:") - sub1.row().itemR(view, "select_mouse", expand=True) - sub1.itemL(text="Middle Mouse:") - sub1.row().itemR(view, "middle_mouse", expand=True) - sub1.itemR(view, "use_middle_mouse_paste") - sub1.itemL(text="Mouse Wheel:") - sub1.itemR(view, "wheel_invert_zoom", text="Invert Zoom") - sub1.itemR(view, "wheel_scroll_lines", text="Scroll Lines") - sub1.itemS() - sub1.itemS() - sub1.itemS() sub1.itemL(text="Menus:") sub1.itemR(view, "open_mouse_over") sub1.itemL(text="Menu Open Delay:") sub1.itemR(view, "open_toplevel_delay", text="Top Level") sub1.itemR(view, "open_sublevel_delay", text="Sub Level") + sub1.itemS() + sub1.itemS() + sub1.itemS() + + sub1.itemL(text="Toolbox:") + sub1.itemR(view, "use_column_layout") + sub1.itemL(text="Open Toolbox Delay:") + sub1.itemR(view, "open_left_mouse_delay", text="Hold LMB") + sub1.itemR(view, "open_right_mouse_delay", text="Hold RMB") + col = split.column() sub = col.split(percentage=0.85) @@ -129,14 +122,6 @@ class USERPREF_PT_view(bpy.types.Panel): sub2.itemR(view, "manipulator_size", text="Size") sub2.itemR(view, "manipulator_handle_size", text="Handle Size") sub2.itemR(view, "manipulator_hotspot", text="Hotspot") - sub1.itemS() - sub1.itemS() - sub1.itemS() - sub1.itemL(text="Toolbox:") - sub1.itemR(view, "use_column_layout") - sub1.itemL(text="Open Toolbox Delay:") - sub1.itemR(view, "open_left_mouse_delay", text="Hold LMB") - sub1.itemR(view, "open_right_mouse_delay", text="Hold RMB") class USERPREF_PT_edit(bpy.types.Panel): __space_type__ = 'USER_PREFERENCES' @@ -145,7 +130,7 @@ class USERPREF_PT_edit(bpy.types.Panel): def poll(self, context): userpref = context.user_preferences - return (userpref.active_section == 'EDIT_METHODS') + return (userpref.active_section == 'EDITING') def draw(self, context): layout = self.layout @@ -199,14 +184,16 @@ class USERPREF_PT_edit(bpy.types.Panel): sub1 = sub.column() sub1.itemL(text="Keyframing:") sub1.itemR(edit, "use_visual_keying") - sub1.itemR(edit, "new_interpolation_type", text="New F-Curves") + sub1.itemR(edit, "keyframe_insert_needed", text="Only Insert Needed") + sub1.itemS() + sub1.itemL(text="New F-Curve Defaults:") + sub1.itemR(edit, "new_interpolation_type", text="Interpolation") sub1.itemS() - sub1.itemR(edit, "auto_keying_enable", text="Auto Keyframing") + sub1.itemR(edit, "auto_keying_enable", text="Auto Keyframing:") sub2 = sub1.column() - sub2.enabled = edit.auto_keying_enable - sub2.row().itemR(edit, "auto_keying_mode", expand=True) + sub2.active = edit.auto_keying_enable + sub2.itemR(edit, "auto_keyframe_insert_keyingset", text="Only Insert for Keying Set") sub2.itemR(edit, "auto_keyframe_insert_available", text="Only Insert Available") - sub2.itemR(edit, "auto_keyframe_insert_needed", text="Only Insert Needed") sub1.itemS() sub1.itemS() @@ -246,7 +233,7 @@ class USERPREF_PT_system(bpy.types.Panel): def poll(self, context): userpref = context.user_preferences - return (userpref.active_section == 'SYSTEM_OPENGL') + return (userpref.active_section == 'SYSTEM') def draw(self, context): layout = self.layout @@ -274,7 +261,7 @@ class USERPREF_PT_system(bpy.types.Panel): sub1.itemL(text="Sound:") sub1.row().itemR(system, "audio_device", expand=True) sub2 = sub1.column() - sub2.active = system.audio_device != 'AUDIO_DEVICE_NULL' + sub2.active = system.audio_device != 'NONE' sub2.itemR(system, "enable_all_codecs") sub2.itemR(system, "game_sound") sub2.itemR(system, "audio_channels", text="Channels") @@ -314,6 +301,7 @@ class USERPREF_PT_system(bpy.types.Panel): sub1.itemL(text="OpenGL:") sub1.itemR(system, "clip_alpha", slider=True) sub1.itemR(system, "use_mipmaps") + sub1.itemR(system, "use_vbos") sub1.itemL(text="Window Draw Method:") sub1.row().itemR(system, "window_draw_method", expand=True) sub1.itemL(text="Textures:") @@ -329,14 +317,14 @@ class USERPREF_PT_system(bpy.types.Panel): sub1.itemR(system, "prefetch_frames") sub1.itemR(system, "memory_cache_limit") -class USERPREF_PT_filepaths(bpy.types.Panel): +class USERPREF_PT_file(bpy.types.Panel): __space_type__ = 'USER_PREFERENCES' - __label__ = "File Paths" + __label__ = "Files" __show_header__ = False def poll(self, context): userpref = context.user_preferences - return (userpref.active_section == 'FILE_PATHS') + return (userpref.active_section == 'FILES') def draw(self, context): layout = self.layout @@ -395,11 +383,314 @@ class USERPREF_PT_filepaths(bpy.types.Panel): sub3.enabled = paths.auto_save_temporary_files sub3.itemR(paths, "auto_save_time", text="Timer (mins)") +class USERPREF_PT_input(bpy.types.Panel): + __space_type__ = 'USER_PREFERENCES' + __label__ = "Input" + __show_header__ = False + + def poll(self, context): + userpref = context.user_preferences + return (userpref.active_section == 'INPUT') + + def draw(self, context): + layout = self.layout + + userpref = context.user_preferences + wm = context.manager + #input = userpref.input + input = userpref + view = userpref.view + + split = layout.split(percentage=0.25) + + # General settings + row = split.row() + col = row.column() + + sub = col.column() + sub.itemL(text="Configuration:") + sub.item_pointerR(wm, "active_keyconfig", wm, "keyconfigs", text="") + + col.itemS() + + sub = col.column() + sub.itemL(text="Mouse:") + sub1 = sub.column() + sub1.enabled = (view.select_mouse == 'RIGHT') + sub1.itemR(view, "emulate_3_button_mouse") + sub.itemR(view, "continuous_mouse") + + sub.itemL(text="Select With:") + sub.row().itemR(view, "select_mouse", expand=True) + #sub.itemL(text="Middle Mouse:") + #sub.row().itemR(view, "middle_mouse", expand=True) + #sub.itemR(view, "use_middle_mouse_paste") + + #col.itemS() + + #sub = col.column() + #sub.itemL(text="Mouse Wheel:") + #sub.itemR(view, "wheel_invert_zoom", text="Invert Zoom") + #sub.itemR(view, "wheel_scroll_lines", text="Scroll Lines") + + col.itemS() + + sub = col.column() + sub.itemL(text="NDOF Device:") + sub.itemR(view, "ndof_pan_speed", text="Pan Speed") + sub.itemR(view, "ndof_rotate_speed", text="Orbit Speed") + + row.itemS() + + # Keymap Settings + col = split.column() + + kc = wm.active_keyconfig + defkc = wm.default_keyconfig + km = wm.active_keymap + + subsplit = col.split() + subsplit.item_pointerR(wm, "active_keymap", defkc, "keymaps", text="Map:") + if km.user_defined: + row = subsplit.row() + row.itemO("WM_OT_keymap_restore", text="Restore") + row.item_booleanO("WM_OT_keymap_restore", "all", True, text="Restore All") + else: + row = subsplit.row() + row.itemO("WM_OT_keymap_edit", text="Edit") + row.itemL() + + col.itemS() + + for kmi in km.items: + subcol = col.column() + subcol.set_context_pointer("keyitem", kmi) + + row = subcol.row() + + if kmi.expanded: + row.itemR(kmi, "expanded", text="", icon="ICON_TRIA_RIGHT") + else: + row.itemR(kmi, "expanded", text="", icon="ICON_TRIA_RIGHT") + + itemrow = row.row() + itemrow.enabled = km.user_defined + itemrow.itemR(kmi, "active", text="", icon="ICON_CHECKBOX_DEHLT") + + itemcol = itemrow.column() + itemcol.active = kmi.active + row = itemcol.row() + row.itemR(kmi, "idname", text="") + + sub = row.row() + sub.scale_x = 0.6 + sub.itemR(kmi, "map_type", text="") + + sub = row.row(align=True) + if kmi.map_type == 'KEYBOARD': + sub.itemR(kmi, "type", text="", full_event=True) + elif kmi.map_type == 'MOUSE': + sub.itemR(kmi, "type", text="", full_event=True) + elif kmi.map_type == 'TWEAK': + sub.scale_x = 0.5 + sub.itemR(kmi, "type", text="") + sub.itemR(kmi, "value", text="") + elif kmi.map_type == 'TIMER': + sub.itemR(kmi, "type", text="") + else: + sub.itemL() + + if kmi.expanded: + if kmi.map_type not in ('TEXTINPUT', 'TIMER'): + sub = itemcol.row(align=True) + + if kmi.map_type == 'KEYBOARD': + sub.itemR(kmi, "type", text="", event=True) + sub.itemR(kmi, "value", text="") + elif kmi.map_type == 'MOUSE': + sub.itemR(kmi, "type", text="") + sub.itemR(kmi, "value", text="") + else: + sub.itemL() + sub.itemL() + + subrow = sub.row() + subrow.scale_x = 0.75 + subrow.itemR(kmi, "shift") + subrow.itemR(kmi, "ctrl") + subrow.itemR(kmi, "alt") + subrow.itemR(kmi, "oskey", text="Cmd") + sub.itemR(kmi, "key_modifier", text="", event=True) + + flow = itemcol.column_flow(columns=2) + props = kmi.properties + + if props != None: + for pname in dir(props): + if not props.is_property_hidden(pname): + flow.itemR(props, pname) + + itemcol.itemS() + + itemrow.itemO("wm.keyitem_remove", text="", icon="ICON_ZOOMOUT") + + itemrow = col.row() + itemrow.itemL() + itemrow.itemO("wm.keyitem_add", text="", icon="ICON_ZOOMIN") + itemrow.enabled = km.user_defined + bpy.types.register(USERPREF_HT_header) bpy.types.register(USERPREF_MT_view) bpy.types.register(USERPREF_PT_tabs) -bpy.types.register(USERPREF_PT_view) +bpy.types.register(USERPREF_PT_interface) bpy.types.register(USERPREF_PT_edit) bpy.types.register(USERPREF_PT_system) -bpy.types.register(USERPREF_PT_filepaths) +bpy.types.register(USERPREF_PT_file) +bpy.types.register(USERPREF_PT_input) + +class WM_OT_keyconfig_export(bpy.types.Operator): + "Export key configuration to a python script." + __idname__ = "wm.keyconfig_export" + __label__ = "Export Key Configuration..." + __props__ = [ + bpy.props.StringProperty(attr="path", name="File Path", description="File path to write file to.")] + + def _string_value(self, value): + result = "" + if isinstance(value, str): + if value != "": + result = "\'%s\'" % value + elif isinstance(value, bool): + if value: + result = "True" + else: + result = "False" + elif isinstance(value, float): + result = "%.10f" % value + elif isinstance(value, int): + result = "%d" % value + elif getattr(value, '__len__', False): + if len(value): + result = "[" + for i in range(0, len(value)): + result += self._string_value(value[i]) + if i != len(value)-1: + result += ", " + result += "]" + else: + print("Export key configuration: can't write ", value) + + return result + + def execute(self, context): + if not self.path: + raise Exception("File path not set.") + + f = open(self.path, "w") + if not f: + raise Exception("Could not open file.") + + wm = context.manager + kc = wm.active_keyconfig + + f.write('# Configuration %s\n' % kc.name) + + f.write("wm = bpy.data.windowmanagers[0]\n"); + f.write("kc = wm.add_keyconfig(\'%s\')\n\n" % kc.name) + + for km in kc.keymaps: + f.write("# Map %s\n" % km.name) + f.write("km = kc.add_keymap(\'%s\', space_type=\'%s\', region_type=\'%s\')\n\n" % (km.name, km.space_type, km.region_type)) + for kmi in km.items: + f.write("kmi = km.add_item(\'%s\', \'%s\', \'%s\'" % (kmi.idname, kmi.type, kmi.value)) + if kmi.shift: + f.write(", shift=True") + if kmi.ctrl: + f.write(", ctrl=True") + if kmi.alt: + f.write(", alt=True") + if kmi.oskey: + f.write(", oskey=True") + if kmi.key_modifier and kmi.key_modifier != 'NONE': + f.write(", key_modifier=\'%s\'" % kmi.key_modifier) + f.write(")\n") + + props = kmi.properties + + if props != None: + for pname in dir(props): + if props.is_property_set(pname) and not props.is_property_hidden(pname): + value = eval("props.%s" % pname) + value = self._string_value(value) + if value != "": + f.write("kmi.properties.%s = %s\n" % (pname, value)) + + f.write("\n") + + f.close() + + return ('FINISHED',) + + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + +class WM_OT_keymap_edit(bpy.types.Operator): + "Edit key map." + __idname__ = "wm.keymap_edit" + __label__ = "Edit Key Map" + + def execute(self, context): + wm = context.manager + km = wm.active_keymap + km.copy_to_user() + return ('FINISHED',) + +class WM_OT_keymap_restore(bpy.types.Operator): + "Restore key map" + __idname__ = "wm.keymap_restore" + __label__ = "Restore Key Map" + __props__ = [bpy.props.BoolProperty(attr="all", name="All Keymaps", description="Restore all keymaps to default.")] + + def execute(self, context): + wm = context.manager + + if self.all: + for km in wm.default_keyconfig.keymaps: + km.restore_to_default() + else: + km = wm.active_keymap + km.restore_to_default() + + return ('FINISHED',) + +class WM_OT_keyitem_add(bpy.types.Operator): + "Add key map item." + __idname__ = "wm.keyitem_add" + __label__ = "Add Key Map Item" + + def execute(self, context): + wm = context.manager + km = wm.active_keymap + kmi = km.add_item("", "A", "PRESS") + return ('FINISHED',) + +class WM_OT_keyitem_remove(bpy.types.Operator): + "Remove key map item." + __idname__ = "wm.keyitem_remove" + __label__ = "Remove Key Map Item" + + def execute(self, context): + wm = context.manager + kmi = context.keyitem + km = wm.active_keymap + km.remove_item(kmi) + return ('FINISHED',) + +bpy.ops.add(WM_OT_keyconfig_export) +bpy.ops.add(WM_OT_keymap_edit) +bpy.ops.add(WM_OT_keymap_restore) +bpy.ops.add(WM_OT_keyitem_add) +bpy.ops.add(WM_OT_keyitem_remove) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index a270e053126..ad2597d6c24 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -1,6 +1,8 @@ import bpy +import dynamic_menu + # ********** Header ********** class VIEW3D_HT_header(bpy.types.Header): @@ -44,7 +46,6 @@ class VIEW3D_HT_header(bpy.types.Header): # ********** Utilities ********** class VIEW3D_MT_showhide(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Show/Hide" _operator_name = "" @@ -56,7 +57,6 @@ class VIEW3D_MT_showhide(bpy.types.Menu): layout.item_booleanO("%s.hide" % self._operator_name, "unselected", True, text="Hide Unselected") class VIEW3D_MT_snap(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Snap" def draw(self, context): @@ -75,7 +75,6 @@ class VIEW3D_MT_snap(bpy.types.Menu): # ********** View menus ********** class VIEW3D_MT_view(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "View" def draw(self, context): @@ -111,6 +110,7 @@ class VIEW3D_MT_view(bpy.types.Menu): layout.itemS() + layout.itemO("view3d.localview", text="View Global/Local") layout.itemO("view3d.view_center") layout.itemO("view3d.view_all") @@ -120,7 +120,6 @@ class VIEW3D_MT_view(bpy.types.Menu): layout.itemO("screen.screen_full_area", text="Toggle Full Screen") class VIEW3D_MT_view_navigation(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Navigation" def draw(self, context): @@ -142,7 +141,6 @@ class VIEW3D_MT_view_navigation(bpy.types.Menu): layout.itemO("view3d.fly") class VIEW3D_MT_view_align(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Align View" def draw(self, context): @@ -151,16 +149,16 @@ class VIEW3D_MT_view_align(bpy.types.Menu): layout.itemO("view3d.view_center") class VIEW3D_MT_view_cameras(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Cameras" def draw(self, context): layout = self.layout + + layout.itemO("view3d.object_as_camera") # ********** Select menus, suffix from context.mode ********** class VIEW3D_MT_select_object(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -175,11 +173,11 @@ class VIEW3D_MT_select_object(bpy.types.Menu): layout.itemO("object.select_random", text="Random") layout.itemO("object.select_mirror", text="Mirror") layout.itemO("object.select_by_layer", text="Select All by Layer") - layout.item_enumO("object.select_by_type", "type", "", text="Select All by Type...") - layout.itemO("object.select_grouped", text="Select Grouped...") + layout.item_menu_enumO("object.select_by_type", "type", "", text="Select All by Type...") + layout.item_menu_enumO("object.select_grouped", "type", text="Select Grouped...") + layout.itemO("object.select_pattern", text="Select Pattern...") class VIEW3D_MT_select_pose(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -210,7 +208,6 @@ class VIEW3D_MT_select_pose(bpy.types.Menu): props.direction = 'CHILD' class VIEW3D_MT_select_particle(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -229,7 +226,6 @@ class VIEW3D_MT_select_particle(bpy.types.Menu): layout.itemO("particle.select_less") class VIEW3D_MT_select_edit_mesh(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -261,6 +257,8 @@ class VIEW3D_MT_select_edit_mesh(bpy.types.Menu): layout.itemO("mesh.select_more", text="More") layout.itemS() + + layout.itemO("mesh.select_mirror", text="Mirror") layout.itemO("mesh.select_linked", text="Linked") layout.itemO("mesh.select_vertex_path", text="Vertex Path") @@ -273,7 +271,6 @@ class VIEW3D_MT_select_edit_mesh(bpy.types.Menu): layout.itemO("mesh.region_to_loop") class VIEW3D_MT_select_edit_curve(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -302,7 +299,6 @@ class VIEW3D_MT_select_edit_curve(bpy.types.Menu): layout.itemO("curve.select_less") class VIEW3D_MT_select_edit_surface(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -328,7 +324,6 @@ class VIEW3D_MT_select_edit_surface(bpy.types.Menu): layout.itemO("curve.select_less") class VIEW3D_MT_select_edit_metaball(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -346,7 +341,6 @@ class VIEW3D_MT_select_edit_metaball(bpy.types.Menu): layout.itemO("mball.select_random_metaelems") class VIEW3D_MT_select_edit_lattice(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -359,7 +353,6 @@ class VIEW3D_MT_select_edit_lattice(bpy.types.Menu): layout.itemO("lattice.select_all_toggle", text="Select/Deselect All") class VIEW3D_MT_select_edit_armature(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -388,7 +381,6 @@ class VIEW3D_MT_select_edit_armature(bpy.types.Menu): props.direction = 'CHILD' class VIEW3D_MT_select_face(bpy.types.Menu):# XXX no matching enum - __space_type__ = 'VIEW_3D' __label__ = "Select" def draw(self, context): @@ -399,7 +391,6 @@ class VIEW3D_MT_select_face(bpy.types.Menu):# XXX no matching enum # ********** Object menu ********** class VIEW3D_MT_object(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __context__ = "objectmode" __label__ = "Object" @@ -407,6 +398,7 @@ class VIEW3D_MT_object(bpy.types.Menu): layout = self.layout layout.itemM("VIEW3D_MT_object_clear") + layout.itemM("VIEW3D_MT_object_apply") layout.itemM("VIEW3D_MT_snap") layout.itemS() @@ -420,6 +412,8 @@ class VIEW3D_MT_object(bpy.types.Menu): layout.item_booleanO("object.duplicate", "linked", True, text="Duplicate Linked") layout.itemO("object.delete", text="Delete...") layout.itemO("object.proxy_make", text="Make Proxy...") + layout.item_menu_enumO("object.make_local", "type", text="Make Local...") + layout.itemM("VIEW3D_MT_make_single_user") layout.itemS() @@ -434,10 +428,12 @@ class VIEW3D_MT_object(bpy.types.Menu): layout.itemS() + layout.itemO("object.move_to_layer", text="Move to Layer...") layout.itemM("VIEW3D_MT_object_showhide") + layout.item_menu_enumO("object.convert", "target") + class VIEW3D_MT_object_clear(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Clear" def draw(self, context): @@ -448,8 +444,21 @@ class VIEW3D_MT_object_clear(bpy.types.Menu): layout.itemO("object.scale_clear", text="Scale") layout.itemO("object.origin_clear", text="Origin") +class VIEW3D_MT_object_apply(bpy.types.Menu): + __label__ = "Apply" + + def draw(self, context): + layout = self.layout + + layout.itemO("object.location_apply", text="Location") + layout.itemO("object.rotation_apply", text="Rotation") + layout.itemO("object.scale_apply", text="Scale") + layout.itemS() + layout.itemO("object.visual_transform_apply", text="Visual Transform") + layout.itemO("object.duplicates_make_real") + + class VIEW3D_MT_object_parent(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Parent" def draw(self, context): @@ -459,7 +468,6 @@ class VIEW3D_MT_object_parent(bpy.types.Menu): layout.itemO("object.parent_clear", text="Clear") class VIEW3D_MT_object_track(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Track" def draw(self, context): @@ -469,7 +477,6 @@ class VIEW3D_MT_object_track(bpy.types.Menu): layout.itemO("object.track_clear", text="Clear") class VIEW3D_MT_object_group(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Group" def draw(self, context): @@ -484,7 +491,6 @@ class VIEW3D_MT_object_group(bpy.types.Menu): layout.itemO("group.objects_remove_active") class VIEW3D_MT_object_constraints(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Constraints" def draw(self, context): @@ -494,7 +500,6 @@ class VIEW3D_MT_object_constraints(bpy.types.Menu): layout.itemO("object.constraints_clear") class VIEW3D_MT_object_showhide(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Show/Hide" def draw(self, context): @@ -504,10 +509,30 @@ class VIEW3D_MT_object_showhide(bpy.types.Menu): layout.itemO("object.restrictview_set", text="Hide Selected") layout.item_booleanO("object.restrictview_set", "unselected", True, text="Hide Unselected") +class VIEW3D_MT_make_single_user(bpy.types.Menu): + __label__ = "Make Single User" + + def draw(self, context): + layout = self.layout + + props = layout.itemO("object.make_single_user", properties=True, text="Object") + props.object = True + + props = layout.itemO("object.make_single_user", properties=True, text="Object & ObData") + props.object = props.obdata = True + + props = layout.itemO("object.make_single_user", properties=True, text="Object & ObData & Materials+Tex") + props.object = props.obdata = props.material = props.texture = True + + props = layout.itemO("object.make_single_user", properties=True, text="Materials+Tex") + props.material = props.texture = True + + props = layout.itemO("object.make_single_user", properties=True, text="Animation") + props.animation = True + # ********** Vertex paint menu ********** class VIEW3D_MT_paint_vertex(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Paint" def draw(self, context): @@ -522,7 +547,6 @@ class VIEW3D_MT_paint_vertex(bpy.types.Menu): # ********** Sculpt menu ********** class VIEW3D_MT_sculpt(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Sculpt" def draw(self, context): @@ -558,7 +582,6 @@ class VIEW3D_MT_sculpt(bpy.types.Menu): # ********** Particle menu ********** class VIEW3D_MT_particle(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Particle" def draw(self, context): @@ -588,7 +611,6 @@ class VIEW3D_MT_particle_showhide(VIEW3D_MT_showhide): # ********** Pose Menu ********** class VIEW3D_MT_pose(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Pose" def draw(self, context): @@ -648,7 +670,6 @@ class VIEW3D_MT_pose(bpy.types.Menu): layout.item_menu_enumO("pose.flags_set", 'mode', text="Bone Settings") class VIEW3D_MT_pose_transform(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Clear Transform" def draw(self, context): @@ -663,7 +684,6 @@ class VIEW3D_MT_pose_transform(bpy.types.Menu): layout.itemL(text="Origin") class VIEW3D_MT_pose_pose(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Pose Library" def draw(self, context): @@ -678,7 +698,6 @@ class VIEW3D_MT_pose_pose(bpy.types.Menu): layout.itemO("poselib.pose_remove", text="Remove Pose...") class VIEW3D_MT_pose_motion(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Motion Paths" def draw(self, context): @@ -688,7 +707,6 @@ class VIEW3D_MT_pose_motion(bpy.types.Menu): layout.itemO("pose.paths_clear", text="Clear") class VIEW3D_MT_pose_group(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Bone Groups" def draw(self, context): @@ -703,7 +721,6 @@ class VIEW3D_MT_pose_group(bpy.types.Menu): class VIEW3D_MT_pose_ik(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Inverse Kinematics" def draw(self, context): @@ -713,7 +730,6 @@ class VIEW3D_MT_pose_ik(bpy.types.Menu): layout.itemO("pose.ik_clear") class VIEW3D_MT_pose_constraints(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Constraints" def draw(self, context): @@ -729,7 +745,6 @@ class VIEW3D_MT_pose_showhide(VIEW3D_MT_showhide): # Edit MESH class VIEW3D_MT_edit_mesh(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Mesh" def draw(self, context): @@ -764,19 +779,44 @@ class VIEW3D_MT_edit_mesh(bpy.types.Menu): layout.itemS() layout.itemR(settings, "automerge_editing") - layout.itemR(settings, "proportional_editing") + layout.item_menu_enumR(settings, "proportional_editing") layout.item_menu_enumR(settings, "proportional_editing_falloff") layout.itemS() layout.itemM("VIEW3D_MT_edit_mesh_showhide") +# Only used by the menu +class VIEW3D_MT_edit_mesh_specials(bpy.types.Menu): + __label__ = "Specials" + + def draw(self, context): + layout = self.layout + + layout.operator_context = 'INVOKE_REGION_WIN' + + layout.itemO("mesh.subdivide", text="Subdivide") + layout.item_floatO("mesh.subdivide", "smoothness", 1.0, text="Subdivide Smooth") + layout.itemO("mesh.merge", text="Merge...") + layout.itemO("mesh.remove_doubles") + layout.itemO("mesh.hide", text="Hide") + layout.itemO("mesh.reveal", text="Reveal") + layout.itemO("mesh.select_inverse") + layout.itemO("mesh.flip_normals") + layout.itemO("mesh.vertices_smooth", text="Smooth") + # layout.itemO("mesh.bevel", text="Bevel") + layout.itemO("mesh.faces_shade_smooth") + layout.itemO("mesh.faces_shade_flat") + layout.itemO("mesh.blend_from_shape") + # layout.itemO("mesh.shape_propagate_to_all") + layout.itemO("mesh.select_vertex_path") + class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Vertices" def draw(self, context): layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' layout.itemO("mesh.merge") layout.itemO("mesh.rip") @@ -787,14 +827,21 @@ class VIEW3D_MT_edit_mesh_vertices(bpy.types.Menu): layout.itemO("mesh.vertices_smooth") layout.itemO("mesh.remove_doubles") + + layout.itemO("mesh.select_vertex_path") + + layout.itemO("mesh.blend_from_shape") + + layout.itemO("object.vertex_group_blend") + # uiItemO(layout, "Propagate to All Shapes", 0, "mesh.shape_propagate_to_all"); class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Edges" def draw(self, context): layout = self.layout - + layout.operator_context = 'INVOKE_REGION_WIN' + layout.itemO("mesh.edge_face_add") layout.itemO("mesh.subdivide") @@ -813,13 +860,30 @@ class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu): layout.item_enumO("mesh.edge_rotate", "direction", 'CW', text="Rotate Edge CW") layout.item_enumO("mesh.edge_rotate", "direction", 'CCW', text="Rotate Edge CCW") -class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu): - __space_type__ = 'VIEW_3D' + layout.itemS() + + layout.itemO("TFM_OT_edge_slide", text="Edge Slide") + layout.itemO("mesh.loop_multi_select", text="Edge Loop") + + # uiItemO(layout, "Loopcut", 0, "mesh.loop_cut"); // CutEdgeloop(em, 1); + # uiItemO(layout, "Edge Slide", 0, "mesh.edge_slide"); // EdgeSlide(em, 0,0.0); + + layout.item_booleanO("mesh.loop_multi_select", "ring", True, text="Edge Ring") + + layout.itemO("mesh.loop_to_region") + layout.itemO("mesh.region_to_loop") + + +class VIEW3D_MT_edit_mesh_faces(dynamic_menu.DynMenu): __label__ = "Faces" def draw(self, context): layout = self.layout - + layout.operator_context = 'INVOKE_REGION_WIN' + + layout.itemO("mesh.flip_normals") + # layout.itemO("mesh.bevel") + # layout.itemO("mesh.bevel") layout.itemO("mesh.edge_face_add") layout.itemO("mesh.fill") layout.itemO("mesh.beauty_fill") @@ -834,9 +898,23 @@ class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu): layout.itemO("mesh.faces_shade_smooth") layout.itemO("mesh.faces_shade_flat") + + layout.itemS() + + # uiItemO(layout, NULL, 0, "mesh.face_mode"); // mesh_set_face_flags(em, 1); + # uiItemBooleanO(layout, NULL, 0, "mesh.face_mode", "clear", 1); // mesh_set_face_flags(em, 0); + + layout.item_enumO("mesh.edge_rotate", "direction", 'CW', text="Rotate Edge CW") + + layout.itemS() + + layout.item_menu_enumO("mesh.uvs_rotate", "direction") + layout.item_menu_enumO("mesh.uvs_mirror", "axis") + layout.item_menu_enumO("mesh.colors_rotate", "direction") + layout.item_menu_enumO("mesh.colors_mirror", "axis") + class VIEW3D_MT_edit_mesh_normals(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Normals" def draw(self, context): @@ -886,13 +964,11 @@ def draw_curve(self, context): layout.itemM("VIEW3D_MT_edit_curve_showhide") class VIEW3D_MT_edit_curve(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Curve" draw = draw_curve class VIEW3D_MT_edit_curve_ctrlpoints(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Control Points" def draw(self, context): @@ -910,7 +986,6 @@ class VIEW3D_MT_edit_curve_ctrlpoints(bpy.types.Menu): layout.item_menu_enumO("curve.handle_type_set", "type") class VIEW3D_MT_edit_curve_segments(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Segments" def draw(self, context): @@ -924,14 +999,12 @@ class VIEW3D_MT_edit_curve_showhide(VIEW3D_MT_showhide): # Edit SURFACE class VIEW3D_MT_edit_surface(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Surface" draw = draw_curve # Edit TEXT class VIEW3D_MT_edit_text(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Text" def draw(self, context): @@ -944,7 +1017,6 @@ class VIEW3D_MT_edit_text(bpy.types.Menu): layout.itemm("view3d_mt_edit_text_chars") class VIEW3D_MT_edit_text_chars(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Special Characters" def draw(self, context): @@ -979,7 +1051,6 @@ class VIEW3D_MT_edit_text_chars(bpy.types.Menu): # Edit META class VIEW3D_MT_edit_meta(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Metaball" def draw(self, context): @@ -1009,7 +1080,6 @@ class VIEW3D_MT_edit_meta(bpy.types.Menu): layout.itemM("VIEW3D_MT_edit_meta_showhide") class VIEW3D_MT_edit_meta_showhide(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Show/Hide" def draw(self, context): @@ -1021,7 +1091,6 @@ class VIEW3D_MT_edit_meta_showhide(bpy.types.Menu): # Edit LATTICE class VIEW3D_MT_edit_lattice(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Lattice" def draw(self, context): @@ -1042,7 +1111,6 @@ class VIEW3D_MT_edit_lattice(bpy.types.Menu): # Edit ARMATURE class VIEW3D_MT_edit_armature(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Armature" def draw(self, context): @@ -1099,7 +1167,6 @@ class VIEW3D_MT_edit_armature(bpy.types.Menu): layout.item_menu_enumO("armature.flags_set", "mode", text="Bone Settings") class VIEW3D_MT_edit_armature_parent(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Parent" def draw(self, context): @@ -1109,7 +1176,6 @@ class VIEW3D_MT_edit_armature_parent(bpy.types.Menu): layout.itemO("armature.parent_clear", text="Clear") class VIEW3D_MT_edit_armature_roll(bpy.types.Menu): - __space_type__ = 'VIEW_3D' __label__ = "Bone Roll" def draw(self, context): @@ -1169,7 +1235,10 @@ class VIEW3D_PT_3dview_display(bpy.types.Panel): def draw(self, context): layout = self.layout + view = context.space_data + gs = context.scene.game_data + ob = context.object col = layout.column() col.itemR(view, "display_floor", text="Grid Floor") @@ -1179,16 +1248,23 @@ class VIEW3D_PT_3dview_display(bpy.types.Panel): col.itemR(view, "outline_selected") col.itemR(view, "all_object_centers") col.itemR(view, "relationship_lines") - col.itemR(view, "textured_solid") - - layout.itemS() - - layout.itemO("screen.region_foursplit", text="Toggle Quad View") + if ob and ob.type =='MESH': + mesh = context.active_object.data + col.itemR(mesh, "all_edges") col = layout.column() - col.itemR(view, "lock_rotation") - col.itemR(view, "box_preview") - col.itemR(view, "box_clip") + col.itemL(text="Shading:") + col.itemR(gs, "material_mode", text="") + col.itemR(view, "textured_solid") + +# XXX - the Quad View options don't work yet +# layout.itemS() +# +# layout.itemO("screen.region_foursplit", text="Toggle Quad View") +# col = layout.column() +# col.itemR(view, "lock_rotation") +# col.itemR(view, "box_preview") +# col.itemR(view, "box_clip") class VIEW3D_PT_3dview_meshdisplay(bpy.types.Panel): __space_type__ = 'VIEW_3D' @@ -1225,7 +1301,6 @@ class VIEW3D_PT_3dview_meshdisplay(bpy.types.Panel): col.itemR(mesh, "draw_edge_angle") col.itemR(mesh, "draw_face_area") - class VIEW3D_PT_3dview_curvedisplay(bpy.types.Panel): __space_type__ = 'VIEW_3D' __region_type__ = 'UI' @@ -1245,8 +1320,7 @@ class VIEW3D_PT_3dview_curvedisplay(bpy.types.Panel): col.itemR(curve, "draw_handles", text="Handles") col.itemR(curve, "draw_normals", text="Normals") col.itemR(context.scene.tool_settings, "normal_size", text="Normal Size") - - + class VIEW3D_PT_background_image(bpy.types.Panel): __space_type__ = 'VIEW_3D' __region_type__ = 'UI' @@ -1301,10 +1375,96 @@ class VIEW3D_PT_transform_orientations(bpy.types.Panel): view = context.space_data col = layout.column() - col.itemO("TFM_OT_select_orientation", text="Select") - col.itemO("TFM_OT_create_orientation", text="Create") - col.itemO("TFM_OT_delete_orientation", text="Delete") - + + col.itemR(view, "transform_orientation") + col.itemO("tfm.create_orientation", text="Create") + + orientation = view.current_orientation + + if orientation: + col.itemR(orientation, "name") + col.itemO("tfm.delete_orientation", text="Delete") + +class VIEW3D_PT_etch_a_ton(bpy.types.Panel): + __space_type__ = 'VIEW_3D' + __region_type__ = 'UI' + __label__ = "Skeleton Sketching" + __default_closed__ = True + + def poll(self, context): + scene = context.space_data + ob = context.active_object + return scene and ob and ob.type == 'ARMATURE' and ob.mode == 'EDIT' + + def draw_header(self, context): + layout = self.layout + toolsettings = context.scene.tool_settings + + layout.itemR(toolsettings, "bone_sketching", text="") + + def draw(self, context): + layout = self.layout + toolsettings = context.scene.tool_settings + + col = layout.column() + + col.itemR(toolsettings, "etch_quick") + col.itemR(toolsettings, "etch_overdraw") + + col.itemR(toolsettings, "etch_convert_mode") + + if toolsettings.etch_convert_mode == "LENGTH": + col.itemR(toolsettings, "etch_length_limit") + elif toolsettings.etch_convert_mode == "ADAPTIVE": + col.itemR(toolsettings, "etch_adaptive_limit") + elif toolsettings.etch_convert_mode == "FIXED": + col.itemR(toolsettings, "etch_subdivision_number") + elif toolsettings.etch_convert_mode == "RETARGET": + col.itemR(toolsettings, "etch_template") + col.itemR(toolsettings, "etch_roll_mode") + col.itemR(toolsettings, "etch_autoname") + col.itemR(toolsettings, "etch_number") + col.itemR(toolsettings, "etch_side") + + +# Operators + +class OBJECT_OT_select_pattern(bpy.types.Operator): + '''Select object matching a naming pattern.''' + __idname__ = "object.select_pattern" + __label__ = "Select Pattern" + __register__ = True + __undo__ = True + __props__ = [ + bpy.props.StringProperty(attr="pattern", name="Pattern", description="Name filter using '*' and '?' wildcard chars", maxlen= 32, default= "*"), + bpy.props.BoolProperty(attr="case_sensitive", name="Case Sensitive", description="Do a case sensitive compare", default= False), + bpy.props.BoolProperty(attr="extend", name="Extend", description="Extend the existing selection", default= True), + ] + + def execute(self, context): + + import fnmatch + if self.case_sensitive: pattern_match = fnmatch.fnmatchcase + else: pattern_match = lambda a, b: fnmatch.fnmatchcase(a.upper(), b.upper()) + + for ob in context.visible_objects: + if pattern_match(ob.name, self.pattern): + ob.selected = True + elif not self.extend: + ob.selected = False + + return ('FINISHED',) + + # TODO - python cant do popups yet + ''' + def invoke(self, context, event): + wm = context.manager + wm.add_fileselect(self.__operator__) + return ('RUNNING_MODAL',) + ''' + + + bpy.types.register(VIEW3D_HT_header) # Header bpy.types.register(VIEW3D_MT_view) #View Menus @@ -1324,12 +1484,15 @@ bpy.types.register(VIEW3D_MT_select_edit_armature) bpy.types.register(VIEW3D_MT_select_face) # XXX todo bpy.types.register(VIEW3D_MT_object) # Object Menu +bpy.types.register(VIEW3D_MT_object_apply) bpy.types.register(VIEW3D_MT_object_clear) bpy.types.register(VIEW3D_MT_object_parent) bpy.types.register(VIEW3D_MT_object_track) bpy.types.register(VIEW3D_MT_object_group) bpy.types.register(VIEW3D_MT_object_constraints) bpy.types.register(VIEW3D_MT_object_showhide) +bpy.types.register(VIEW3D_MT_make_single_user) + bpy.types.register(VIEW3D_MT_sculpt) # Sculpt Menu @@ -1350,6 +1513,7 @@ bpy.types.register(VIEW3D_MT_pose_showhide) bpy.types.register(VIEW3D_MT_snap) # Edit Menus 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_vertices) bpy.types.register(VIEW3D_MT_edit_mesh_edges) bpy.types.register(VIEW3D_MT_edit_mesh_faces) @@ -1380,4 +1544,8 @@ bpy.types.register(VIEW3D_PT_3dview_display) bpy.types.register(VIEW3D_PT_3dview_meshdisplay) bpy.types.register(VIEW3D_PT_3dview_curvedisplay) bpy.types.register(VIEW3D_PT_background_image) -bpy.types.register(VIEW3D_PT_transform_orientations)
\ No newline at end of file +bpy.types.register(VIEW3D_PT_transform_orientations) +bpy.types.register(VIEW3D_PT_etch_a_ton) + +bpy.ops.add(OBJECT_OT_select_pattern) + diff --git a/release/scripts/ui/space_view3d_toolbar.py b/release/scripts/ui/space_view3d_toolbar.py index 4c1b54ea8e6..a552bb7de14 100644 --- a/release/scripts/ui/space_view3d_toolbar.py +++ b/release/scripts/ui/space_view3d_toolbar.py @@ -38,6 +38,12 @@ class VIEW3D_PT_tools_objectmode(View3DPanel): col.itemO("anim.insert_keyframe_menu", text="Insert") col.itemO("anim.delete_keyframe_v3d", text="Remove") +# col = layout.column(align=True) +# col.itemL(text="Grease Pencil:") +# col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") +# col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") +# col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") @@ -85,11 +91,29 @@ class VIEW3D_PT_tools_meshedit(View3DPanel): col.itemO("mesh.uvs_rotate") col.itemO("mesh.uvs_mirror") +# col = layout.column(align=True) +# col.itemL(text="Grease Pencil:") +# col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") +# col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") +# col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") col.itemO("screen.repeat_history", text="History...") col.itemO("screen.redo_last", text="Tweak...") + +class VIEW3D_PT_tools_meshedit_options(View3DPanel): + __context__ = "mesh_edit" + __label__ = "Mesh Options" + + def draw(self, context): + layout = self.layout + + mesh = context.active_object.data + + col = layout.column(align=True) + col.itemR(mesh, "use_mirror_x") # ********** default tools for editmode_curve **************** @@ -126,6 +150,12 @@ class VIEW3D_PT_tools_curveedit(View3DPanel): col.itemO("curve.extrude") col.itemO("curve.subdivide") +# col = layout.column(align=True) +# col.itemL(text="Grease Pencil:") +# col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") +# col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") +# col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") @@ -159,6 +189,12 @@ class VIEW3D_PT_tools_surfaceedit(View3DPanel): col.itemO("curve.extrude") col.itemO("curve.subdivide") +# col = layout.column(align=True) +# col.itemL(text="Grease Pencil:") +# col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") +# col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") +# col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") @@ -216,11 +252,20 @@ class VIEW3D_PT_tools_armatureedit(View3DPanel): col.itemL(text="Modeling:") col.itemO("armature.extrude") +# col = layout.column(align=True) +# col.itemL(text="Grease Pencil:") +# col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") +# col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") +# col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") col.itemO("screen.repeat_history", text="History...") col.itemO("screen.redo_last", text="Tweak...") + + + # ********** default tools for editmode_mball **************** @@ -237,6 +282,12 @@ class VIEW3D_PT_tools_mballedit(View3DPanel): col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") +# col = layout.column(align=True) +# col.itemL(text="Grease Pencil:") +# col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") +# col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") +# col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") @@ -258,6 +309,12 @@ class VIEW3D_PT_tools_latticeedit(View3DPanel): col.itemO("tfm.rotate") col.itemO("tfm.resize", text="Scale") +# col = layout.column(align=True) +# col.itemL(text="Grease Pencil:") +# col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") +# col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") +# col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") @@ -302,11 +359,30 @@ class VIEW3D_PT_tools_posemode(View3DPanel): col.itemO("pose.push", text="Push") col.itemO("pose.breakdown", text="Breakdowner") +# col = layout.column(align=True) +# col.itemL(text="Grease Pencil:") +# col.item_enumO("gpencil.draw", "mode", 'DRAW', text="Draw Freehand") +# col.item_enumO("gpencil.draw", "mode", 'DRAW_STRAIGHT', text="Straight Line") +# col.item_enumO("gpencil.draw", "mode", 'ERASER', text="Eraser") + col = layout.column(align=True) col.itemL(text="Repeat:") col.itemO("screen.repeat_last") col.itemO("screen.repeat_history", text="History...") col.itemO("screen.redo_last", text="Tweak...") + +class VIEW3D_PT_tools_posemode_options(View3DPanel): + __context__ = "posemode" + __label__ = "Pose Options" + + def draw(self, context): + layout = self.layout + + arm = context.active_object.data + + col = layout.column(align=True) + col.itemR(arm, "x_axis_mirror") + col.itemR(arm, "auto_ik") # ********** default tools for paint modes **************** @@ -560,6 +636,22 @@ class VIEW3D_PT_sculpt_options(PaintPanel): class VIEW3D_PT_tools_weightpaint(View3DPanel): __context__ = "weightpaint" + __label__ = "Weight Tools" + + def draw(self, context): + layout = self.layout + + wpaint = context.tool_settings.weight_paint + + col = layout.column() + # col.itemL(text="Blend:") + col.itemO("object.vertex_group_normalize_all", text="Normalize All") + col.itemO("object.vertex_group_normalize", text="Normalize") + col.itemO("object.vertex_group_invert", text="Invert") + col.itemO("object.vertex_group_clean", text="Clean") + +class VIEW3D_PT_tools_weightpaint_options(View3DPanel): + __context__ = "weightpaint" __label__ = "Options" def draw(self, context): @@ -574,6 +666,11 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel): col.itemR(wpaint, "normals") col.itemR(wpaint, "spray") col.itemR(wpaint, "vertex_dist", text="Distance") + + + data = context.weight_paint_object.data + if type(data) == bpy.types.Mesh: + col.itemR(data, "use_mirror_x") # Commented out because the Apply button isn't an operator yet, making these settings useless # col.itemL(text="Gamma:") @@ -676,9 +773,7 @@ class VIEW3D_PT_tools_particlemode(View3DPanel): pe = context.tool_settings.particle_edit ob = pe.object - row = layout.row() - row.itemL(text="Edit:") - row.itemR(pe, "type", text="") + layout.itemR(pe, "type", text="") if pe.type == 'PARTICLES': if ob.particle_systems: @@ -727,8 +822,10 @@ class VIEW3D_PT_tools_particlemode(View3DPanel): sub.active = pe.fade_time sub.itemR(pe, "fade_frames", slider=True) +bpy.types.register(VIEW3D_PT_tools_weightpaint) bpy.types.register(VIEW3D_PT_tools_objectmode) bpy.types.register(VIEW3D_PT_tools_meshedit) +bpy.types.register(VIEW3D_PT_tools_meshedit_options) bpy.types.register(VIEW3D_PT_tools_curveedit) bpy.types.register(VIEW3D_PT_tools_surfaceedit) bpy.types.register(VIEW3D_PT_tools_textedit) @@ -736,11 +833,12 @@ bpy.types.register(VIEW3D_PT_tools_armatureedit) bpy.types.register(VIEW3D_PT_tools_mballedit) bpy.types.register(VIEW3D_PT_tools_latticeedit) bpy.types.register(VIEW3D_PT_tools_posemode) +bpy.types.register(VIEW3D_PT_tools_posemode_options) bpy.types.register(VIEW3D_PT_tools_brush) bpy.types.register(VIEW3D_PT_tools_brush_stroke) bpy.types.register(VIEW3D_PT_tools_brush_curve) bpy.types.register(VIEW3D_PT_sculpt_options) bpy.types.register(VIEW3D_PT_tools_vertexpaint) -bpy.types.register(VIEW3D_PT_tools_weightpaint) +bpy.types.register(VIEW3D_PT_tools_weightpaint_options) bpy.types.register(VIEW3D_PT_tools_projectpaint) bpy.types.register(VIEW3D_PT_tools_particlemode) diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 17513b1b7c3..a253d18486f 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -227,6 +227,7 @@ void *CustomData_get_layer_n(const struct CustomData *data, int type, int n); void *CustomData_get_layer_named(const struct CustomData *data, int type, char *name); int CustomData_get_layer_index(const struct CustomData *data, int type); +int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n); int CustomData_get_named_layer_index(const struct CustomData *data, int type, char *name); int CustomData_get_active_layer_index(const struct CustomData *data, int type); int CustomData_get_render_layer_index(const struct CustomData *data, int type); diff --git a/source/blender/blenkernel/BKE_tessmesh.h b/source/blender/blenkernel/BKE_tessmesh.h index daad8665d1a..1045295ae92 100644 --- a/source/blender/blenkernel/BKE_tessmesh.h +++ b/source/blender/blenkernel/BKE_tessmesh.h @@ -2,8 +2,9 @@ struct BMesh; struct BMLoop; -struct DerivedMesh; struct BMFace; +struct Mesh; +struct DerivedMesh; /* ok: the EDBM module is for editmode bmesh stuff. in contrast, the @@ -49,6 +50,10 @@ typedef struct BMEditMesh { int selectmode; int mat_nr; + + /*Mesh structure this editmesh came from, if it came from one*/ + struct Mesh *me; + struct Object *ob; } BMEditMesh; void BMEdit_RecalcTesselation(BMEditMesh *tm); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index fa1a7da669a..d6cc785b146 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2453,6 +2453,16 @@ static void lib_link_key(FileData *fd, Main *main) key= main->key.first; while(key) { + /*check if we need to generate unique ids for the shapekeys*/ + if (!key->uidgen) { + KeyBlock *block; + + key->uidgen = 1; + for (block=key->block.first; block; block=block->next) { + block->uid = key->uidgen++; + } + } + if(key->id.flag & LIB_NEEDLINK) { if(key->adt) lib_link_animdata(fd, &key->id, key->adt); diff --git a/source/blender/bmesh/operators/mesh_conv.c b/source/blender/bmesh/operators/mesh_conv.c index d9c8bd63c5c..53a358a824c 100644 --- a/source/blender/bmesh/operators/mesh_conv.c +++ b/source/blender/bmesh/operators/mesh_conv.c @@ -56,7 +56,7 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) { MEdge *medge; MLoop *ml; MPoly *mpoly; - KeyBlock *actkey; + KeyBlock *actkey, *block; BMVert *v, **vt=NULL; BMEdge *e, **fedges=NULL, **et = NULL; BMFace *f; @@ -77,19 +77,37 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) { CustomData_add_layer(&bm->vdata, CD_SHAPE_KEYINDEX, CD_ASSIGN, NULL, 0); - CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]); - CustomData_bmesh_init_pool(&bm->edata, allocsize[1]); - CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]); - CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]); - actkey = ob_get_keyblock(ob); if(actkey && actkey->totelem == me->totvert) { + /*check if we need to generate unique ids for the shapekeys. + this also exists in the file reading code, but is here for + a sanity check*/ + if (!me->key->uidgen) { + printf("yeek! had to generate shape key uid's in a situation we shouldn't need to!\n"); + me->key->uidgen = 1; + for (block=me->key->block.first; block; block=block->next) { + block->uid = me->key->uidgen++; + } + } + keyco= actkey->data; bm->shapenr= ob->shapenr; + for (i=0, block=me->key->block.first; block; block=block->next, i++) { + CustomData_add_layer_named(&bm->vdata, CD_SHAPEKEY, + CD_ASSIGN, NULL, 0, block->name); + + j = CustomData_get_layer_index_n(&bm->vdata, CD_SHAPEKEY, i); + bm->vdata.layers[j].uid = block->uid; + } } else if (actkey) { printf("shapekey<->mesh mismatch!\n"); } + CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]); + CustomData_bmesh_init_pool(&bm->edata, allocsize[1]); + CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]); + CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]); + for (i=0; i<me->totvert; i++, mvert++) { v = BM_Make_Vert(bm, keyco ? keyco[i] : mvert->co, NULL); VECCOPY(v->no, mvert->no); @@ -110,6 +128,15 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) { /*set shape key original index*/ keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX); *keyi = i; + + /*set shapekey data*/ + if (me->key) { + for (block=me->key->block.first, j=0; block; block=block->next, j++) { + float *co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, + CD_SHAPEKEY, j); + VECCOPY(co, ((float*)block->data)+3*i); + } + } } if (!me->totedge) { @@ -262,6 +289,7 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { Mesh *me = BMO_Get_Pnt(op, "mesh"); Object *ob = BMO_Get_Pnt(op, "object"); MLoop *mloop; + KeyBlock *block; MPoly *mpoly; MVert *mvert, *oldverts; MEdge *medge; @@ -271,6 +299,7 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { BMLoop *l; BMFace *f; BMIter iter, liter; + float *facenors = NULL; int i, j, *keyi, ototvert, totloop, totface, numTex, numCol; int dotess = !BMO_Get_Int(op, "notesselation"); @@ -328,7 +357,7 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge); CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop); CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly); - + i = 0; BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) { VECCOPY(mvert->co, v->co); @@ -402,9 +431,13 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { /* new tess face block */ if(totface==0) mface= NULL; - else mface= MEM_callocN(totface*sizeof(MFace), "loadeditbMesh face"); + else { + mface= MEM_callocN(totface*sizeof(MFace), "loadeditbMesh face"); + facenors = MEM_callocN(totface*sizeof(float)*3, "facenors"); + } CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface); + CustomData_add_layer(&me->fdata, CD_NORMAL, CD_ASSIGN, facenors, me->totface); CustomData_from_bmeshpoly(&me->fdata, &bm->pdata, &bm->ldata, totface); mesh_update_customdata_pointers(me); @@ -457,7 +490,10 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { test_index_face(mface, &me->fdata, i, 1); loops_to_corners(bm, me, i, f, ls, numTex, numCol); + VECCOPY(facenors, ls[0]->f->no); + mface++; + facenors += 3; i++; } BLI_end_edgefill(); @@ -561,7 +597,73 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { mesh_update_customdata_pointers(me); - /* are there keys? */ + if (me->key) { + KeyBlock *actkey= BLI_findlink(&me->key->block, bm->shapenr-1); + + /*go through and find any shapekey customdata layers + that might not have corrusponding KeyBlocks, and add them if + necassary.*/ + j = 0; + for (i=0; i<bm->vdata.totlayer; i++) { + if (bm->vdata.layers[i].type != CD_SHAPEKEY) + continue; + + for (block=me->key->block.first; block; block=block->next) { + if (block->uid == bm->vdata.layers[i].uid) + break; + } + + if (!block) { + block = MEM_callocN(sizeof(KeyBlock), "KeyBlock mesh_conv.c"); + block->type = KEY_LINEAR; + block->slidermin = 0.0f; + block->slidermax = 1.0f; + + BLI_addtail(&me->key->block, block); + me->key->totkey++; + } + + j++; + } + + for (block=me->key->block.first; block; block=block->next) { + j = 0; + + for (i=0; i<bm->vdata.totlayer; i++) { + if (bm->vdata.layers[i].type != CD_SHAPEKEY) + continue; + + if (block->uid == bm->vdata.layers[i].uid) { + float *fp, *co; + + if (block->data) + MEM_freeN(block->data); + block->data = fp = MEM_mallocN(sizeof(float)*3*bm->totvert, "shape key data"); + block->totelem = bm->totvert; + + BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) { + co = block==actkey ? eve->co : CustomData_bmesh_get_n(&bm->vdata, eve->head.data, CD_SHAPEKEY, j); + + VECCOPY(fp, co); + fp += 3; + } + break; + } + + j++; + } + + /*if we didn't find a shapekey, tag the block to be reconstructed + via the old method below*/ + if (j == CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY)) { + block->flag |= KEYBLOCK_MISSING; + } + } + } + + /* old method of reconstructing keys via vertice's original key indices, + currently used if the new method above fails (which is theoretically + possible in certain cases of undo).*/ if(me->key) { float *fp, *newkey, *oldkey; KeyBlock *currkey; @@ -571,6 +673,16 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { * with the way things were before editmode */ currkey = me->key->block.first; while(currkey) { + if (!(currkey->flag & KEYBLOCK_MISSING)) { + currkey = currkey->next; + continue; + } + + printf("warning: had to hackishly reconstruct shape key \"%s\"," + " it may not be correct anymore.\n", currkey->name); + + currkey->flag &= ~KEYBLOCK_MISSING; + fp= newkey= MEM_callocN(me->key->elemsize*bm->totvert, "currkey->data"); oldkey = currkey->data; diff --git a/source/blender/editors/mesh/bmeshutils.c b/source/blender/editors/mesh/bmeshutils.c index 984c93a3a79..beac07b6415 100644 --- a/source/blender/editors/mesh/bmeshutils.c +++ b/source/blender/editors/mesh/bmeshutils.c @@ -267,6 +267,8 @@ void EDBM_MakeEditBMesh(ToolSettings *ts, Scene *scene, Object *ob) me->edit_btmesh = BMEdit_Create(bm); me->edit_btmesh->selectmode = ts->selectmode; + me->edit_btmesh->me = me; + me->edit_btmesh->ob = ob; } void EDBM_LoadEditBMesh(Scene *scene, Object *ob) @@ -557,6 +559,9 @@ static void *editbtMesh_to_undoMesh(void *emv) { BMEditMesh *em = emv; undomesh *me = MEM_callocN(sizeof(undomesh), "undo Mesh"); + + /*make sure shape keys work*/ + me->me.key = em->me->key; /*we recalc the tesselation here, to avoid seeding calls to BMEdit_RecalcTesselation throughout the code.*/ @@ -578,7 +583,7 @@ static void undoMesh_to_editbtMesh(void *umv, void *emv) BMEdit_Free(em); bm = BM_Make_Mesh(allocsize); - BMO_CallOpf(bm, "mesh_to_bmesh mesh=%p", me); + BMO_CallOpf(bm, "mesh_to_bmesh mesh=%p object=%p", me, em->ob); em2 = BMEdit_Create(bm); *em = *em2; diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index c9fb3351af9..eb27486b93c 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -139,9 +139,11 @@ static KeyBlock *add_keyblock(Scene *scene, Key *key) // XXX this is old anim system stuff? (i.e. the 'index' of the shapekey) kb->adrcode= tot-1; + kb->uid = key->uidgen++; + key->totkey++; if(key->totkey==1) key->refkey= kb; - + kb->slidermin= 0.0f; kb->slidermax= 1.0f; @@ -241,7 +243,8 @@ static void insert_lattkey(Scene *scene, Object *ob) } kb= add_keyblock(scene, key); - + kb->uid = key->uidgen++; + if(newkey) { /* create from lattice */ latt_to_key(lt, kb); @@ -372,6 +375,7 @@ static void insert_curvekey(Scene *scene, Object *ob) } kb= add_keyblock(scene, key); + kb->uid = key->uidgen++; if(newkey) { /* create from curve */ diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index dbaa6f40cbf..b4feb3c4d16 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -39,7 +39,7 @@ typedef struct CustomDataLayer { int active_rnd; /* number of the layer to render*/ int active_clone; /* number of the layer to render*/ int active_mask; /* number of the layer to render*/ - char pad[4]; + int uid; /*shape keyblock unique id reference*/ char name[32]; /* layer name */ void *data; /* layer data */ } CustomDataLayer; diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h index e86abf12424..02d3e8efb00 100644 --- a/source/blender/makesdna/DNA_key_types.h +++ b/source/blender/makesdna/DNA_key_types.h @@ -43,7 +43,7 @@ typedef struct KeyBlock { float pos; float curval; short type, adrcode, relative, flag; /* relative == 0 means first key is reference */ - int totelem, pad2; + int totelem, pad; void *data; float *weights; @@ -52,6 +52,8 @@ typedef struct KeyBlock { float slidermin; float slidermax; + + int uid, pad2; } KeyBlock; @@ -71,6 +73,9 @@ typedef struct Key { short type, totkey; short slurph, flag; + + /*can never be 0, this is used for detecting old data*/ + int uidgen, pad; /*current free uid for keyblocks*/ } Key; /* **************** KEY ********************* */ @@ -91,6 +96,6 @@ typedef struct Key { #define KEYBLOCK_MUTE (1<<0) #define KEYBLOCK_SEL (1<<1) #define KEYBLOCK_LOCKED (1<<2) - +#define KEYBLOCK_MISSING (1<<3) /*temporary flag*/ #endif diff --git a/source/blender/render/intern/include/raycounter.h b/source/blender/render/intern/include/raycounter.h new file mode 100644 index 00000000000..5f721a596c0 --- /dev/null +++ b/source/blender/render/intern/include/raycounter.h @@ -0,0 +1,55 @@ +/** + * $Id: raycounter.h 23649 2009-10-06 02:56:11Z jaguarandi $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef RE_RAYCOUNTER_H +#define RE_RAYCOUNTER_H + +#include "RE_raytrace.h" + + +#ifdef RE_RAYCOUNTER + +/* #define RE_RC_INIT(isec, shi) (isec).count = re_rc_counter+(shi).thread */ +#define RE_RC_INIT(isec, shi) (isec).raycounter = &((shi).raycounter) +void RE_RC_INFO (RayCounter *rc); +void RE_RC_MERGE(RayCounter *rc, RayCounter *tmp); +#define RE_RC_COUNT(var) (var)++ + +extern RayCounter re_rc_counter[]; + +#else + +# define RE_RC_INIT(isec,shi) +# define RE_RC_INFO(rc) +# define RE_RC_MERGE(dest,src) +# define RE_RC_COUNT(var) + +#endif + + +#endif diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h new file mode 100644 index 00000000000..8dc2281bd3b --- /dev/null +++ b/source/blender/render/intern/include/rayobject.h @@ -0,0 +1,208 @@ +/** + * $Id: rayobject.h 23651 2009-10-06 03:40:50Z aligorith $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): André Pinto. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef RE_RAYOBJECT_H +#define RE_RAYOBJECT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "RE_raytrace.h" +#include "render_types.h" +#include <stdio.h> +#include <float.h> + + +/* RayObject + + A ray object is everything where we can cast rays like: + * a face/triangle + * an octree + * a bvh tree + * an octree of bvh's + * a bvh of bvh's + + + All types of RayObjects can be created by implementing the + callbacks of the RayObject. + + Due to high computing time evolved with casting on faces + there is a special type of RayObject (named RayFace) + which won't use callbacks like other generic nodes. + + In order to allow a mixture of RayFace+RayObjects, + all RayObjects must be 4byte aligned, allowing us to use the + 2 least significant bits (with the mask 0x03) to define the + type of RayObject. + + This leads to 4 possible types of RayObject: + + addr&3 - type of object + 0 Self (reserved for each structure) + 1 RayFace (tri/quad primitive) + 2 RayObject (generic with API callbacks) + 3 VlakPrimitive + (vlak primitive - to be used when we have a vlak describing the data + eg.: on render code) + + 0 means it's reserved and has it own meaning inside each ray acceleration structure + (this way each structure can use the allign offset to determine if a node represents a + RayObject primitive, which can be used to save memory) + + You actually don't need to care about this if you are only using the API + described on RE_raytrace.h + */ + +/* used to align a given ray object */ +#define RE_rayobject_align(o) ((RayObject*)(((intptr_t)o)&(~3))) + +/* used to unalign a given ray object */ +#define RE_rayobject_unalignRayFace(o) ((RayObject*)(((intptr_t)o)|1)) +#define RE_rayobject_unalignRayAPI(o) ((RayObject*)(((intptr_t)o)|2)) +#define RE_rayobject_unalignVlakPrimitive(o) ((RayObject*)(((intptr_t)o)|3)) + +/* used to test the type of ray object */ +#define RE_rayobject_isAligned(o) ((((intptr_t)o)&3) == 0) +#define RE_rayobject_isRayFace(o) ((((intptr_t)o)&3) == 1) +#define RE_rayobject_isRayAPI(o) ((((intptr_t)o)&3) == 2) +#define RE_rayobject_isVlakPrimitive(o) ((((intptr_t)o)&3) == 3) + + + +/* + * This class is intended as a place holder for control, configuration of the rayobject like: + * - stop building (TODO maybe when porting build to threads this could be implemented with some thread_cancel function) + * - max number of threads and threads callback to use during build + * ... + */ +typedef int (*RE_rayobjectcontrol_test_break_callback)(void *data); +typedef struct RayObjectControl RayObjectControl; +struct RayObjectControl +{ + void *data; + RE_rayobjectcontrol_test_break_callback test_break; +}; + +/* + * This rayobject represents a generic object. With it's own callbacks for raytrace operations. + * It's suitable to implement things like LOD. + */ +struct RayObject +{ + struct RayObjectAPI *api; + + struct RayObjectControl control; +}; + + + + +typedef int (*RE_rayobject_raycast_callback)(RayObject *, Isect *); +typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject); +typedef void (*RE_rayobject_done_callback)(RayObject *); +typedef void (*RE_rayobject_free_callback)(RayObject *); +typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max); +typedef float (*RE_rayobject_cost_callback)(RayObject *); +typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, RayHint *, float *, float *); + +typedef struct RayObjectAPI +{ + RE_rayobject_raycast_callback raycast; + RE_rayobject_add_callback add; + RE_rayobject_done_callback done; + RE_rayobject_free_callback free; + RE_rayobject_merge_bb_callback bb; + RE_rayobject_cost_callback cost; + RE_rayobject_hint_bb_callback hint_bb; + +} RayObjectAPI; + + +/* + * This function differs from RE_rayobject_raycast + * RE_rayobject_intersect does NOT perform last-hit optimization + * So this is probably a function to call inside raytrace structures + */ +int RE_rayobject_intersect(RayObject *r, Isect *i); + +/* + * Returns distance ray must travel to hit the given bounding box + * BB should be in format [2][3] + */ +/* float RE_rayobject_bb_intersect(const Isect *i, const float *bb); */ +int RE_rayobject_bb_intersect_test(const Isect *i, const float *bb); /* same as bb_intersect but doens't calculates distance */ + +/* + * Returns the expected cost of raycast on this node, primitives have a cost of 1 + */ +float RE_rayobject_cost(RayObject *r); + + +/* + * Returns true if for some reason a heavy processing function should stop + * (eg.: user asked to stop during a tree a build) + */ +int RE_rayobjectcontrol_test_break(RayObjectControl *c); + + +#define ISECT_EPSILON ((float)FLT_EPSILON) + + + +#if !defined(_WIN32) && !defined(_WIN64) + +#include <sys/time.h> +#include <time.h> + +#define BENCH(a,name) \ + do { \ + double _t1, _t2; \ + struct timeval _tstart, _tend; \ + clock_t _clock_init = clock(); \ + gettimeofday ( &_tstart, NULL); \ + (a); \ + gettimeofday ( &_tend, NULL); \ + _t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 ); \ + _t2 = ( double ) _tend.tv_sec + ( double ) _tend.tv_usec/ ( 1000*1000 ); \ + printf("BENCH:%s: %fs (real) %fs (cpu)\n", #name, _t2-_t1, (float)(clock()-_clock_init)/CLOCKS_PER_SEC);\ + } while(0) +#else + +#define BENCH(a,name) (a) + +#endif + + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 1a91e4cf8f3..5f352e1d67b 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -207,6 +207,7 @@ IF(APPLE) ADD_CUSTOM_COMMAND( TARGET blender POST_BUILD MAIN_DEPENDENCY blender COMMAND find ${TARGETDIR} -name .svn -prune -exec rm -rf {} "\;" + COMMAND find ${TARGETDIR} -name __MACOSX -prune -exec rm -rf {} "\;" ) @@ -325,11 +326,16 @@ IF(WIN32) ENDIF(WITH_INTERNATIONAL) IF(WITH_PYTHON) + IF(WITH_LIBS10.5) + SET(PYTHON_ZIP "python_${CMAKE_OSX_ARCHITECTURES}.zip") + ELSE(WITH_LIBS10.5) + SET(PYTHON_ZIP "python.zip") + ENDIF(WITH_LIBS10.5) ADD_CUSTOM_COMMAND( TARGET blender POST_BUILD MAIN_DEPENDENCY blender COMMAND cp -Rf ${CMAKE_SOURCE_DIR}/release/scripts ${TARGETDIR}/blender.app/Contents/MacOS/.blender/ COMMAND mkdir ${TARGETDIR}/blender.app/Contents/MacOS/.blender/python/ - COMMAND unzip -q ${LIBDIR}/release/python.zip -d ${TARGETDIR}/blender.app/Contents/MacOS/.blender/python/ + COMMAND unzip -q ${LIBDIR}/release/${PYTHON_ZIP} -d ${TARGETDIR}/blender.app/Contents/MacOS/.blender/python/ COMMAND find ${TARGETDIR}/blender.app -name "*.py?" -prune -exec rm -rf {} "\;" ) ENDIF(WITH_PYTHON) diff --git a/source/creator/SConscript b/source/creator/SConscript index 7b3d1493ed2..6c95f25a0b2 100644 --- a/source/creator/SConscript +++ b/source/creator/SConscript @@ -36,5 +36,7 @@ else: if env['WITH_BF_FHS']: # /usr -> /usr/share/blender/2.5 defs.append('BLENDERPATH=\\"' + os.path.join(env['BF_INSTALLDIR'], 'share', 'blender', env['BF_VERSION']) + '\\"') +if env['BF_BUILDINFO']: + defs.append('BUILD_DATE') env.BlenderLib ( libname = 'bf_creator', sources = Split(sources), includes = Split(incs), defines = defs, libtype='core', priority = 0 ) diff --git a/source/creator/buildinfo.c b/source/creator/buildinfo.c index cef98915d79..db24b50b82d 100644 --- a/source/creator/buildinfo.c +++ b/source/creator/buildinfo.c @@ -31,14 +31,13 @@ #include <config.h> #endif +#define STRINGIFY(x) XSTRINGIFY(x) +#define XSTRINGIFY(x) #x + #ifdef BUILD_DATE -#ifndef WIN32 -const char * build_date=BUILD_DATE; -const char * build_time=BUILD_TIME; -const char * build_rev=BUILD_REV; -const char * build_platform=BUILD_PLATFORM; -const char * build_type=BUILD_TYPE; -#else -#include "winbuildinfo.h" -#endif +const char * build_date=STRINGIFY(BUILD_DATE); +const char * build_time=STRINGIFY(BUILD_TIME); +const char * build_rev=STRINGIFY(BUILD_REV); +const char * build_platform=STRINGIFY(BUILD_PLATFORM); +const char * build_type=STRINGIFY(BUILD_TYPE); #endif diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index df7f35d7773..ca5faf00bb6 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -356,7 +356,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, int alw if(GLEW_ARB_multitexture && GLEW_VERSION_1_1) usemat = true; - if(GPU_extensions_minimum_support()) + if(GPU_glsl_support()) useglslmat = true; else if(blscene->gm.matmode == GAME_MAT_GLSL) usemat = false; diff --git a/source/gameengine/Converter/BL_ArmatureActuator.cpp b/source/gameengine/Converter/BL_ArmatureActuator.cpp index 4105eb57d5f..46c63f5e9a9 100644 --- a/source/gameengine/Converter/BL_ArmatureActuator.cpp +++ b/source/gameengine/Converter/BL_ArmatureActuator.cpp @@ -31,9 +31,9 @@ #include "DNA_constraint_types.h" #include "DNA_actuator_types.h" #include "BKE_constraint.h" -#include "BLI_arithb.h" #include "BL_ArmatureActuator.h" #include "BL_ArmatureObject.h" +#include "BLI_arithb.h" /** * This class is the conversion of the Pose channel constraint. diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index 20ca7f07f2b..125e91e0e0a 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -148,10 +148,13 @@ bool BL_ShapeDeformer::Update(void) // make sure the vertex weight cache is in line with this object m_pMeshObject->CheckWeightCache(blendobj); - /* we will blend the key directly in mvert array: it is used by armature as the start position */ + /* we will blend the key directly in m_transverts array: it is used by armature as the start position */ /* m_bmesh->key can be NULL in case of Modifier deformer */ if (m_bmesh->key) { - do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)m_bmesh->mvert->co, m_bmesh->key, 0); + /* store verts locally */ + VerifyStorage(); + + do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)(float *)m_transverts, m_bmesh->key, NULL, 0); m_bDynamic = true; } @@ -167,18 +170,12 @@ bool BL_ShapeDeformer::Update(void) bShapeUpdate = true; } // check for armature deform - bSkinUpdate = BL_SkinDeformer::Update(); + bSkinUpdate = BL_SkinDeformer::UpdateInternal(bShapeUpdate && m_bDynamic); // non dynamic deformer = Modifer without armature and shape keys, no need to create storage if (!bSkinUpdate && bShapeUpdate && m_bDynamic) { - // this means that there is no armature, we still need to copy the vertex to m_transverts - // and update the normal (was not done after shape key calculation) - - /* store verts locally */ - VerifyStorage(); - - for (int v =0; v<m_bmesh->totvert; v++) - VECCOPY(m_transverts[v], m_bmesh->mvert[v].co); + // this means that there is no armature, we still need to + // update the normal (was not done after shape key calculation) #ifdef __NLA_DEFNORMALS if (m_recalcNormal) diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index a13f78e1b27..f166a7252ad 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -172,7 +172,7 @@ void BL_SkinDeformer::ProcessReplica() //void where_is_pose (Object *ob); //void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts, int deformflag); -bool BL_SkinDeformer::Update(void) +bool BL_SkinDeformer::UpdateInternal(bool shape_applied) { /* See if the armature has been updated for this frame */ if (PoseUpdated()){ @@ -182,12 +182,14 @@ bool BL_SkinDeformer::Update(void) /* but it requires the blender object pointer... */ Object* par_arma = m_armobj->GetArmatureObject(); - /* store verts locally */ - VerifyStorage(); - - /* duplicate */ - for (int v =0; v<m_bmesh->totvert; v++) - VECCOPY(m_transverts[v], m_bmesh->mvert[v].co); + if(!shape_applied) { + /* store verts locally */ + VerifyStorage(); + + /* duplicate */ + for (int v =0; v<m_bmesh->totvert; v++) + VECCOPY(m_transverts[v], m_bmesh->mvert[v].co); + } m_armobj->ApplyPose(); @@ -219,6 +221,11 @@ bool BL_SkinDeformer::Update(void) return false; } +bool BL_SkinDeformer::Update(void) +{ + return UpdateInternal(false); +} + /* XXX note: I propose to drop this function */ void BL_SkinDeformer::SetArmature(BL_ArmatureObject *armobj) { diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index b83895d5609..9c6f5db2b95 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -72,6 +72,7 @@ public: virtual ~BL_SkinDeformer(); bool Update (void); + bool UpdateInternal (bool shape_applied); bool Apply (class RAS_IPolyMaterial *polymat); bool UpdateBuckets(void) { diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 3c989293c94..e771d12988c 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -539,7 +539,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) if(GLEW_ARB_multitexture && GLEW_VERSION_1_1) m_blendermat = (SYS_GetCommandLineInt(syshandle, "blender_material", 1) != 0); - if(GPU_extensions_minimum_support()) + if(GPU_glsl_support()) m_blenderglslmat = (SYS_GetCommandLineInt(syshandle, "blender_glsl_material", 1) != 0); else if(gm->matmode == GAME_MAT_GLSL) m_blendermat = false; diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 9bb261fcba9..d516d3e03ff 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -46,7 +46,6 @@ typedef unsigned long uint_ptr; #define KX_INERTIA_INFINITE 10000 -#include "BLI_arithb.h" #include "RAS_IPolygonMaterial.h" #include "KX_BlenderMaterial.h" #include "KX_GameObject.h" @@ -80,6 +79,8 @@ typedef unsigned long uint_ptr; #include "KX_SG_NodeRelationships.h" +#include "BLI_arithb.h" + static MT_Point3 dummy_point= MT_Point3(0.0, 0.0, 0.0); static MT_Vector3 dummy_scaling = MT_Vector3(1.0, 1.0, 1.0); static MT_Matrix3x3 dummy_orientation = MT_Matrix3x3( 1.0, 0.0, 0.0, diff --git a/source/nan_compile.mk b/source/nan_compile.mk index 8d4da1e2790..6a1263e286c 100644 --- a/source/nan_compile.mk +++ b/source/nan_compile.mk @@ -73,8 +73,8 @@ ifeq ($(OS),darwin) CC ?= gcc CCC ?= g++ ifeq ($(CPU),powerpc) - CFLAGS += -pipe -fPIC -ffast-math -mcpu=7450 -mtune=G5 -funsigned-char -fno-strict-aliasing - CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing + CFLAGS += -pipe -fPIC -ffast-math -mcpu=7450 -mtune=G5 -funsigned-char -fno-strict-aliasing -Wno-long-double + CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing -Wno-long-double else CFLAGS += -pipe -fPIC -ffast-math -march=pentium-m -funsigned-char -fno-strict-aliasing CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing diff --git a/tools/Blender.py b/tools/Blender.py index 92894c19884..4a8e8d9bb30 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -244,22 +244,12 @@ def buildinfo(lenv, build_type): obj = [] if lenv['BF_BUILDINFO']: - if sys.platform=='win32': - build_info_file = open("source/creator/winbuildinfo.h", 'w') - build_info_file.write("char *build_date=\"%s\";\n"%build_date) - build_info_file.write("char *build_time=\"%s\";\n"%build_time) - build_info_file.write("char *build_rev=\"%s\";\n"%build_rev) - build_info_file.write("char *build_platform=\"win32\";\n") - build_info_file.write("char *build_type=\"dynamic\";\n") - build_info_file.close() - lenv.Append (CPPDEFINES = ['NAN_BUILDINFO', 'BUILD_DATE']) - else: - lenv.Append (CPPDEFINES = ['BUILD_TIME=\'"%s"\''%(build_time), - 'BUILD_DATE=\'"%s"\''%(build_date), - 'BUILD_TYPE=\'"dynamic"\'', - 'BUILD_REV=\'"%s"\''%(build_rev), - 'NAN_BUILDINFO', - 'BUILD_PLATFORM=\'"%s"\''%(sys.platform)]) + lenv.Append (CPPDEFINES = ['BUILD_TIME=\'"%s"\''%(build_time), + 'BUILD_DATE=\'"%s"\''%(build_date), + 'BUILD_TYPE=\'"dynamic"\'', + 'BUILD_REV=\'"%s"\''%(build_rev), + 'NAN_BUILDINFO', + 'BUILD_PLATFORM=\'"%s"\''%(sys.platform)]) obj = [lenv.Object (root_build_dir+'source/creator/%s_buildinfo'%build_type, [root_build_dir+'source/creator/buildinfo.c'])] return obj |