shapekeys are now stored as customdata in editmode, so edit operations like subdivide...
authorJoseph Eagar <joeedh@gmail.com>
Mon, 2 Nov 2009 06:33:16 +0000 (06:33 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Mon, 2 Nov 2009 06:33:16 +0000 (06:33 +0000)
112 files changed:
CMakeLists.txt
extern/Eigen2/Eigen/src/Array/Functors.h
extern/Eigen2/Eigen/src/Array/PartialRedux.h
extern/Eigen2/Eigen/src/Core/CommaInitializer.h
extern/Eigen2/Eigen/src/Core/Cwise.h
extern/Eigen2/Eigen/src/Core/Flagged.h
extern/Eigen2/Eigen/src/Core/Functors.h
extern/Eigen2/Eigen/src/Core/Matrix.h
extern/Eigen2/Eigen/src/Core/NestByValue.h
extern/Eigen2/Eigen/src/Core/Part.h
extern/Eigen2/Eigen/src/Core/Swap.h
extern/Eigen2/Eigen/src/Core/util/Memory.h
extern/Eigen2/Eigen/src/SVD/SVD.h
extern/Eigen2/Eigen/src/Sparse/AmbiVector.h
extern/Eigen2/Eigen/src/Sparse/DynamicSparseMatrix.h
extern/Eigen2/Eigen/src/Sparse/SparseBlock.h
extern/Eigen2/Eigen/src/Sparse/SparseCwise.h
extern/Eigen2/Eigen/src/Sparse/SparseCwiseBinaryOp.h
extern/Eigen2/Eigen/src/Sparse/SparseCwiseUnaryOp.h
extern/Eigen2/Eigen/src/Sparse/SparseDiagonalProduct.h
extern/Eigen2/Eigen/src/Sparse/SparseFlagged.h
extern/Eigen2/Eigen/src/Sparse/SparseMatrix.h
extern/Eigen2/Eigen/src/Sparse/SparseTranspose.h
extern/Eigen2/Eigen/src/Sparse/SparseVector.h
extern/Eigen2/eigen-update.sh
intern/ghost/GHOST_C-api.h
intern/ghost/GHOST_IWindow.h
intern/ghost/GHOST_Rect.h
intern/ghost/GHOST_Types.h
intern/ghost/intern/GHOST_C-api.cpp
intern/ghost/intern/GHOST_SystemCocoa.h
intern/ghost/intern/GHOST_SystemCocoa.mm
intern/ghost/intern/GHOST_SystemX11.cpp
intern/ghost/intern/GHOST_Window.cpp
intern/ghost/intern/GHOST_Window.h
intern/ghost/intern/GHOST_WindowCocoa.h
intern/ghost/intern/GHOST_WindowCocoa.mm
intern/ghost/intern/GHOST_WindowX11.cpp
intern/ghost/intern/GHOST_WindowX11.h
projectfiles_vc9/blender/editors/ED_editors.vcproj
projectfiles_vc9/blender/loader/BLO_loader.vcproj
release/environment-macosx [new file with mode: 0644]
release/environment-mswindows [new file with mode: 0644]
release/environment-unix [new file with mode: 0644]
release/scripts/io/engine_render_pov.py
release/scripts/io/export_3ds.py
release/scripts/io/export_fbx.py
release/scripts/io/export_obj.py
release/scripts/io/export_ply.py
release/scripts/io/export_x3d.py
release/scripts/io/import_3ds.py
release/scripts/io/import_obj.py
release/scripts/io/netrender/client.py
release/scripts/io/netrender/master.py
release/scripts/io/netrender/master_html.py
release/scripts/io/netrender/model.py
release/scripts/io/netrender/operators.py
release/scripts/io/netrender/slave.py
release/scripts/io/netrender/ui.py
release/scripts/io/netrender/utils.py
release/scripts/modules/bpy_ops.py
release/scripts/ui/buttons_data_armature.py
release/scripts/ui/buttons_data_bone.py
release/scripts/ui/buttons_data_empty.py
release/scripts/ui/buttons_data_lamp.py
release/scripts/ui/buttons_data_mesh.py
release/scripts/ui/buttons_game.py
release/scripts/ui/buttons_material.py
release/scripts/ui/buttons_object.py
release/scripts/ui/buttons_object_constraint.py
release/scripts/ui/buttons_particle.py
release/scripts/ui/buttons_physics_common.py
release/scripts/ui/buttons_physics_field.py
release/scripts/ui/buttons_physics_smoke.py
release/scripts/ui/buttons_scene.py
release/scripts/ui/buttons_texture.py
release/scripts/ui/buttons_world.py
release/scripts/ui/space_buttons.py
release/scripts/ui/space_console.py
release/scripts/ui/space_filebrowser.py
release/scripts/ui/space_image.py
release/scripts/ui/space_info.py
release/scripts/ui/space_node.py
release/scripts/ui/space_outliner.py
release/scripts/ui/space_sequencer.py
release/scripts/ui/space_text.py
release/scripts/ui/space_time.py
release/scripts/ui/space_userpref.py
release/scripts/ui/space_view3d.py
release/scripts/ui/space_view3d_toolbar.py
source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/BKE_tessmesh.h
source/blender/blenloader/intern/readfile.c
source/blender/bmesh/operators/mesh_conv.c
source/blender/editors/mesh/bmeshutils.c
source/blender/editors/object/object_shapekey.c
source/blender/makesdna/DNA_customdata_types.h
source/blender/makesdna/DNA_key_types.h
source/blender/render/intern/include/raycounter.h [new file with mode: 0644]
source/blender/render/intern/include/rayobject.h [new file with mode: 0644]
source/creator/CMakeLists.txt
source/creator/SConscript
source/creator/buildinfo.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/Converter/BL_ArmatureActuator.cpp
source/gameengine/Converter/BL_ShapeDeformer.cpp
source/gameengine/Converter/BL_SkinDeformer.cpp
source/gameengine/Converter/BL_SkinDeformer.h
source/gameengine/GamePlayer/ghost/GPG_Application.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/nan_compile.mk
tools/Blender.py

index d53f4ed99664361c3e302a5e00984e74ff3c2acd..ea62bbceb0e9d44f9c2390eec358c0bc16a7128e 100644 (file)
@@ -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.
 
index 0aae7fd2c40d33a6af750a22fb54e9c5c377ae3c..c2c325a788e35430e13ca07fc8ef649714f3dfed 100644 (file)
@@ -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> >
index b1e8fd4babdfa3e22fd443992cf309bb72e32951..3a052ca8a3d70e84312752073179ab739c44bbb6 100644 (file)
@@ -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
index ed28e0ca3713c9fc5b19719d6fe7bfdfbd2ae086..f66cbd6d5e1fc23015963d19adc74f464d2f6ceb 100644 (file)
@@ -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
index 0e92dce4e121c977a45a21251c156cb9b9f61302..4dc9d514b04935c73345c85e489db05e67c96843 100644 (file)
@@ -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
index ce50246cb678e628dd5c81a4ac35c13c50b0f7cc..e3d25341d9e840521d05b6767040b74f3943ab44 100644 (file)
@@ -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
index c8ca3dac1cfdc04f9bfec97946d87c46ea8daed4..969cad78d8f768fb9bcf1ffb23c74558309e48e8 100644 (file)
@@ -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> >
index ffd16d3760614ba0e25c19359b087a9576447e12..22090c777da8b6d40b860467f988b713f34c9fb3 100644 (file)
@@ -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;
     }
 
index da79315bffe1753eeb59558de39c1c25411c54cd..2a14ab1f1562f2d6641838bab3a9c8db135a5134 100644 (file)
@@ -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.
index 9c273f249ecd1aeda4027be62b4a72763b93ab15..96229f43b68be6dfcf0f887ab2027790bf9065c3 100644 (file)
@@ -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
index 77d562cd3ace59fdab03d48311f6657eedcb1a9e..9aaac652fd830087dac8190acc15047aad8dffb4 100644 (file)
@@ -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.
index 09ad39d5be97de102ebbc45f743d76c5df3493e4..0a43e7f7bf2c0d58b4f2f73930853a5e81705fc3 100644 (file)
@@ -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>
 #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); \
index 0a52acf3d5b91a1ab54c251158dd7fe12106976b..d117c158397aa61574b498f8402398afa65f6f11 100644 (file)
@@ -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();
index 75001a2fa25321b174e7f03cfe30ab09140e5b41..f279e80f00a160fea6c52a649ac53c99b7099f8b 100644 (file)
@@ -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&);
 };
 
 
index 7119a84bd51479b2070a51a732454a33a61017d2..01f97cd6d9478a96a7f09ed41ec61fc544921837 100644 (file)
@@ -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
index c39066676b6159094dede01e6e4c3529189bdbbf..ae77a77879b936e6d1f6254b83fbee758ad93e40 100644 (file)
@@ -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)
index 2206883cc764d154757483b4ba620cda723fd222..ac285ec1aa3d9b4d4bae81d1a958b846d5600dee 100644 (file)
@@ -156,6 +156,9 @@ template<typename ExpressionType> class SparseCwise
 
   protected:
     ExpressionTypeNested m_matrix;
+
+  private:
+    SparseCwise& operator=(const SparseCwise&);
 };
 
 template<typename Derived>
index d19970efcb1a2860fe7c874dc2b7b8c8e8c71e32..da9746e2099d1d3554004bfe9a3ee168e97f2893 100644 (file)
@@ -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)
index b11c0f8a3773522a5f58a255ad983cf76e0aaf14..2ed7a15579f08b3f5d3ee4700a3768128689451a 100644 (file)
@@ -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>
index 932daf220b9f9110bc4633c4bff2447c3e348b8c..9b7432a82164a7e27b497a86855113b42d614737 100644 (file)
@@ -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>
index c47e162f538f4107ed4e00cc4543db3a5e073443..315ec4af39ff978ffce3485bec473043da8be1c3 100644 (file)
@@ -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>
index 3f09596bc6481213accce58faff634a34d23abf1..65c609686d2a4f16579a35b62603a00678ac8bea 100644 (file)
@@ -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
index 89a14d70707326c47a8d20496bc99d32bffbf05b..7386294e4d465af619a6a6d54785962c62bae471 100644 (file)
@@ -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
index 8e5a6efeda8b44064afab68aa791b578e72bee78..5d47209f790dc8e12cf3da3cbaaceae626b8d736 100644 (file)
@@ -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
index 926a36ef1207572c45891141eae0efdf0a958b2d..797c710c196156e42ec53426533b5e6fb327c4ca 100755 (executable)
@@ -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 ..
index 00d2cdb1e3b62d75f754346a47a11715da01e245..bd812177f17d6633a028dc3b21fc36c1e59d6c94 100644 (file)
@@ -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.
index 993b41a4d4fd282c398b367fb148fe3926ecd451..512fad877cb1d2cc6a3842537cddcf70236d9f95 100644 (file)
@@ -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; };
 
 };
 
index 6271ecad408ebbac5d4aafebeda7d553b51ebef7..6a29b1ffc262e494be83d9529b6173517ee7ea61 100644 (file)
@@ -126,6 +126,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.
@@ -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
 {
index 14e3c4bb5f7bb0fcda55842fa402b9aae783a8b0..e98e58740ada8a723cea9c6d561be4e42b540efa 100644 (file)
@@ -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;
 
index e225ad4fd90a719c4efb9d13469f1d159395f5f5..0160df552cc10df5f04bf3b841ab383bc2a5d057 100644 (file)
@@ -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);
 }
 
 
index 002089e418586cd981e4005b054ca34d6552022e..709625c5bef0c487517b46e6cbee3bd6c9ac41b3 100644 (file)
@@ -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_
index b924adeebdeff4929330e243317d2e5be3cce516..b476ee8f0f2bc175509800af45796e8c8f744a78 100644 (file)
@@ -525,7 +525,8 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) {
 @interface CocoaAppDelegate : NSObject {\r
        GHOST_SystemCocoa *systemCocoa;\r
 }\r
--(void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa;\r
+- (void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa;
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;\r
 - (void)applicationWillTerminate:(NSNotification *)aNotification;\r
 @end\r
@@ -536,6 +537,12 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) {
        systemCocoa = sysCocoa;\r
 }\r
 \r
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
+{
+       NSLog(@"\nGet open file event from cocoa : %@",filename);
+       return YES;
+}
+
 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender\r
 {\r
        //TODO: implement graceful termination through Cocoa mechanism to avoid session log off to be cancelled\r
@@ -565,6 +572,8 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
 {\r
        m_modifierMask =0;\r
        m_pressedMouseButtons =0;\r
+       m_cursorDelta_x=0;
+       m_cursorDelta_y=0;
        m_displayManager = new GHOST_DisplayManagerCocoa ();\r
        GHOST_ASSERT(m_displayManager, "GHOST_SystemCocoa::GHOST_SystemCocoa(): m_displayManager==0\n");\r
        m_displayManager->initialize();\r
@@ -656,13 +665,14 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
                                [NSApp setWindowsMenu:windowMenu];\r
                                [windowMenu release];\r
                        }\r
-                       [NSApp finishLaunching];\r
                }\r
                if ([NSApp delegate] == nil) {\r
                        CocoaAppDelegate *appDelegate = [[CocoaAppDelegate alloc] init];\r
                        [appDelegate setSystemCocoa:this];\r
                        [NSApp setDelegate:appDelegate];\r
                }\r
+               
+               [NSApp finishLaunching];
                                \r
                [pool drain];\r
     }\r
@@ -787,7 +797,9 @@ GHOST_TSuccess GHOST_SystemCocoa::endFullScreen(void)
 \r
 \r
        \r
-\r
+/**
+ * @note : returns coordinates in Cocoa screen coordinates
+ */
 GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const\r
 {\r
     NSPoint mouseLoc = [NSEvent mouseLocation];\r
@@ -798,18 +810,25 @@ GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt3
     return GHOST_kSuccess;\r
 }\r
 \r
-\r
+/**
+ * @note : expect Cocoa screen coordinates
+ */
 GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const\r
 {\r
        float xf=(float)x, yf=(float)y;\r
+       GHOST_WindowCocoa* window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow();
+       NSScreen *windowScreen = window->getScreen();
+       NSRect screenRect = [windowScreen frame];
        \r
+       //Set position relative to current screen
+       xf -= screenRect.origin.x;
+       yf -= screenRect.origin.y;
+       
        //Quartz Display Services uses the old coordinates (top left origin)\r
-       yf = [[NSScreen mainScreen] frame].size.height -yf;\r
-       \r
-       //CGAssociateMouseAndMouseCursorPosition(false);\r
-       CGWarpMouseCursorPosition(CGPointMake(xf, yf));\r
-       //CGAssociateMouseAndMouseCursorPosition(true);\r
+       yf = screenRect.size.height -yf;
 \r
+       CGDisplayMoveCursorToPoint([[[windowScreen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue], CGPointMake(xf, yf));
+
     return GHOST_kSuccess;\r
 }\r
 \r
@@ -873,15 +892,6 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
                 \r
                 if (timerMgr->fireTimers(getMilliSeconds())) {\r
                 anyProcessed = true;\r
-                }\r
-                \r
-                        if (getFullScreen()) {\r
-                // Check if the full-screen window is dirty\r
-                GHOST_IWindow* window = m_windowManager->getFullScreenWindow();\r
-                if (((GHOST_WindowCarbon*)window)->getFullScreenDirty()) {\r
-                pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );\r
-                anyProcessed = true;\r
-                }\r
                 }*/\r
                \r
                do {\r
@@ -999,6 +1009,12 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
 \r
 GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest()\r
 {\r
+       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\r
        if (m_windowManager->getAnyModifiedState())\r
        {\r
@@ -1008,7 +1024,14 @@ GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest()
                {\r
                        pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );\r
                        return GHOST_kExitNow;\r
+               } 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];
+                       }
                }\r
+
        }\r
        else {\r
                pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL) );\r
@@ -1023,11 +1046,14 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventT
 {\r
        NSEvent *event = (NSEvent *)eventPtr;\r
        GHOST_IWindow* window = m_windowManager->getActiveWindow();\r
+       
+       if (!window) return GHOST_kFailure;
+       
        GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData();\r
        \r
        switch (eventType) {\r
                case NSTabletPoint:\r
-                       ct.Pressure = [event tangentialPressure];\r
+                       ct.Pressure = [event pressure];
                        ct.Xtilt = [event tilt].x;\r
                        ct.Ytilt = [event tilt].y;\r
                        break;\r
@@ -1129,27 +1155,78 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                                        //No tablet event included : do nothing\r
                                        break;\r
                        }\r
+                       
                case NSMouseMoved:\r
-                       {\r
-                               if(window->getCursorWarp()) {\r
-                                       GHOST_TInt32 x_warp, y_warp, x_accum, y_accum;\r
-                                       \r
-                                       window->getCursorWarpPos(x_warp, y_warp);\r
-                                       \r
-                                       window->getCursorWarpAccum(x_accum, y_accum);\r
-                                       x_accum += [event deltaX];\r
-                                       y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ...\r
-                                       window->setCursorWarpAccum(x_accum, y_accum);\r
-                                       \r
-                                       pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum));\r
-                               } \r
-                               else { //Normal cursor operation: send mouse position in window\r
-                                       NSPoint mousePos = [event locationInWindow];\r
-                                       pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y));\r
-                                       window->setCursorWarpAccum(0, 0); //Mouse motion occured between two cursor warps, so we can reset the delta counter\r
+                               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;
                                }\r
                                break;\r
-                       }\r
                        \r
                case NSScrollWheel:\r
                        {\r
@@ -1323,74 +1400,3 @@ void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const
        \r
        [pool drain];\r
 }\r
-\r
-#pragma mark Carbon stuff to remove\r
-\r
-#ifdef WITH_CARBON\r
-\r
-\r
-OSErr GHOST_SystemCarbon::sAEHandlerLaunch(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)\r
-{\r
-       //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;\r
-       \r
-       return noErr;\r
-}\r
-\r
-OSErr GHOST_SystemCarbon::sAEHandlerOpenDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)\r
-{\r
-       //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;\r
-       AEDescList docs;\r
-       SInt32 ndocs;\r
-       OSErr err;\r
-       \r
-       err = AEGetParamDesc(event, keyDirectObject, typeAEList, &docs);\r
-       if (err != noErr)  return err;\r
-       \r
-       err = AECountItems(&docs, &ndocs);\r
-       if (err==noErr) {\r
-               int i;\r
-               \r
-               for (i=0; i<ndocs; i++) {\r
-                       FSSpec fss;\r
-                       AEKeyword kwd;\r
-                       DescType actType;\r
-                       Size actSize;\r
-                       \r
-                       err = AEGetNthPtr(&docs, i+1, typeFSS, &kwd, &actType, &fss, sizeof(fss), &actSize);\r
-                       if (err!=noErr)\r
-                               break;\r
-                       \r
-                       if (i==0) {\r
-                               FSRef fsref;\r
-                               \r
-                               if (FSpMakeFSRef(&fss, &fsref)!=noErr)\r
-                                       break;\r
-                               if (FSRefMakePath(&fsref, (UInt8*) g_firstFileBuf, sizeof(g_firstFileBuf))!=noErr)\r
-                                       break;\r
-                               \r
-                               g_hasFirstFile = true;\r
-                       }\r
-               }\r
-       }\r
-       \r
-       AEDisposeDesc(&docs);\r
-       \r
-       return err;\r
-}\r
-\r
-OSErr GHOST_SystemCarbon::sAEHandlerPrintDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)\r
-{\r
-       //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;\r
-       \r
-       return noErr;\r
-}\r
-\r
-OSErr GHOST_SystemCarbon::sAEHandlerQuit(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)\r
-{\r
-       GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;\r
-       \r
-       sys->pushEvent( new GHOST_Event(sys->getMilliSeconds(), GHOST_kEventQuit, NULL) );\r
-       \r
-       return noErr;\r
-}\r
-#endif
\ No newline at end of file
index 8c87abf16bc2e34d5897c7b6f24d0b3e25ec3468..ff4a5956a1287243a4d998171ff8841c84cbf35b 100644 (file)
@@ -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 {
index 94feb83e003b6d4a54d5386ceb4387ad10e3f1c1..33484284d7c64d1314fa2b62074b2b90566ba3c9 100644 (file)
@@ -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)) {
index 786918716c51ce57cf69dcc74861cce248dd45d6..86447a8623c533fe50c04f0e7022f56c7d00206f 100644 (file)
@@ -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
index 4037ebafc6460f945dd37c4a47250d1f4c764532..c1fa147eee16e7635cc156bc41b7a9247cbec92c 100644 (file)
@@ -169,6 +169,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.
@@ -236,18 +242,12 @@ 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.
index a2b146c1e33e4ae7866af1a181f50e48cc5ee0ee..aac12e80893c0c97bade3d86d10e5d29724dfb8c 100644 (file)
 #include <Carbon/Carbon.h>\r
 #endif\r
 \r
+/***** Multithreaded opengl code : uncomment for enabling
+#include <OpenGL/OpenGL.h>
+*/
 #include "GHOST_WindowCocoa.h"\r
 #include "GHOST_SystemCocoa.h"\r
 #include "GHOST_Debug.h"\r
@@ -50,14 +54,27 @@ static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] =
 };\r
 \r
 #pragma mark Cocoa window delegate object\r
-\r
+/* 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\r
+#ifdef MAC_OS_X_VERSION_10_6
+<NSWindowDelegate>
+#endif
 {\r
        GHOST_SystemCocoa *systemCocoa;\r
        GHOST_WindowCocoa *associatedWindow;\r
 }\r
 \r
-- (void)setSystemAndWindowCocoa:(const GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;\r
+- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;
 - (void)windowWillClose:(NSNotification *)notification;\r
 - (void)windowDidBecomeKey:(NSNotification *)notification;\r
 - (void)windowDidResignKey:(NSNotification *)notification;\r
@@ -97,7 +114,22 @@ static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] =
 \r
 - (void)windowDidResize:(NSNotification *)notification\r
 {\r
-       systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow);\r
+#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);
+       }*/
 }\r
 @end\r
 \r
@@ -107,8 +139,6 @@ static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] =
 {\r
 \r
 }\r
--(BOOL)canBecomeKeyWindow;\r
-\r
 @end\r
 @implementation CocoaWindow\r
 \r
@@ -125,7 +155,6 @@ static NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] =
 //We need to subclass it in order to give Cocoa the feeling key events are trapped\r
 @interface CocoaOpenGLView : NSOpenGLView\r
 {\r
-       \r
 }\r
 @end\r
 @implementation CocoaOpenGLView\r
@@ -173,6 +202,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
 \r
        //Creates the window\r
        NSRect rect;\r
+       NSSize  minSize;
        \r
        rect.origin.x = left;\r
        rect.origin.y = top;\r
@@ -187,6 +217,11 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
                return;\r
        }\r
        \r
+       //Forbid to resize the window below the blender defined minimum one
+       minSize.width = 320;
+       minSize.height = 240;
+       [m_window setContentMinSize:minSize];
+       
        setTitle(title);\r
        \r
                        \r
@@ -480,6 +515,13 @@ void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST
        outY = screenCoord.y;\r
 }\r
 \r
+
+NSScreen* GHOST_WindowCocoa::getScreen()
+{
+       return [m_window screen];
+}
+
+
 /**\r
  * @note Fullscreen switch is not actual fullscreen with display capture. As this capture removes all OS X window manager features.\r
  * Instead, the menu bar and the dock are hidden, and the window is made borderless and enlarged.\r
@@ -515,6 +557,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
                                //Make window borderless and enlarge it\r
                                [m_window setStyleMask:NSBorderlessWindowMask];\r
                                [m_window setFrame:[[m_window screen] frame] display:YES];\r
+                               [m_window makeFirstResponder:m_openGLView];
 #else\r
                                //With 10.5, we need to create a new window to change its style to borderless\r
                                //Hide menu & dock if needed\r
@@ -572,6 +615,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
                                //Make window normal and resize it\r
                                [m_window setStyleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)];\r
                                [m_window setFrame:[[m_window screen] visibleFrame] display:YES];\r
+                               [m_window makeFirstResponder:m_openGLView];
 #else\r
                                //With 10.5, we need to create a new window to change its style to borderless\r
                                //Show menu & dock if needed\r
@@ -696,6 +740,10 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp
        NSOpenGLPixelFormat *pixelFormat;\r
        NSOpenGLContext *tmpOpenGLContext;\r
        \r
+       /***** Multithreaded opengl code : uncomment for enabling
+       CGLContextObj cglCtx;
+       */
+        
        switch (type) {\r
                case GHOST_kDrawingContextTypeOpenGL:\r
                        if (!getValid()) break;\r
@@ -708,6 +756,13 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp
                                break;\r
                        }\r
                        \r
+                       //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;\r
 #ifdef WAIT_FOR_VSYNC\r
                                /* wait for vsync, to avoid tearing artifacts */\r
@@ -849,73 +904,42 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
 }\r
 \r
 \r
-//Override this method to provide set feature even if not in warp\r
-inline bool GHOST_WindowCocoa::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y)\r
+GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
 {\r
-       m_cursorWarpAccumPos[0]= x;\r
-       m_cursorWarpAccumPos[1]= y;\r
+       GHOST_TSuccess err = GHOST_kSuccess;
        \r
-       return GHOST_kSuccess;\r
-}\r
-\r
-\r
-GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(bool grab, bool warp, bool restore)\r
-{\r
-       if (grab)\r
+       if (mode != GHOST_kGrabDisable)
        {\r
                //No need to perform grab without warp as it is always on in OS X\r
-               if(warp) {\r
+               if(mode != GHOST_kGrabNormal) {
                        GHOST_TInt32 x_old,y_old;\r
 \r
-                       m_cursorWarp= true;\r
                        m_systemCocoa->getCursorPosition(x_old,y_old);\r
-                       screenToClient(x_old, y_old, m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);\r
+                       screenToClient(x_old, y_old, m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
                        //Warp position is stored in client (window base) coordinates\r
-                       setWindowCursorVisibility(false);\r
-                       return CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;\r
+                       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;
                }\r
        }\r
        else {\r
-               if(m_cursorWarp)\r
-               {/* are we exiting warp */\r
+               if(m_cursorGrab==GHOST_kGrabHide)
+               {
+                       //No need to set again cursor position, as it has not changed for Cocoa
                        setWindowCursorVisibility(true);\r
-                       /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */\r
-                       if(restore) {\r
-                               GHOST_Rect bounds;\r
-                               GHOST_TInt32 x_new, y_new, x_cur, y_cur;\r
-                               \r
-                               getClientBounds(bounds);\r
-                               x_new= m_cursorWarpInitPos[0]+m_cursorWarpAccumPos[0];\r
-                               y_new= m_cursorWarpInitPos[1]+m_cursorWarpAccumPos[1];\r
-                               \r
-                               if(x_new < 0)           x_new = 0;\r
-                               if(y_new < 0)           y_new = 0;\r
-                               if(x_new > bounds.getWidth())   x_new = bounds.getWidth();\r
-                               if(y_new > bounds.getHeight())  y_new = bounds.getHeight();\r
-                               \r
-                               //get/set cursor position works in screen coordinates\r
-                               clientToScreen(x_new, y_new, x_cur, y_cur);\r
-                               m_systemCocoa->setCursorPosition(x_cur, y_cur);\r
-                               \r
-                               //As Cocoa will give as first deltaX,deltaY this change in cursor position, we need to compensate for it\r
-                               //Issue appearing in case of two transform operations conducted w/o mouse motion in between\r
-                               x_new=m_cursorWarpAccumPos[0];\r
-                               y_new=m_cursorWarpAccumPos[1];\r
-                               setCursorWarpAccum(-x_new, -y_new);\r
-                       }\r
-                       else {\r
-                               GHOST_TInt32 x_new, y_new;\r
-                               //get/set cursor position works in screen coordinates\r
-                               clientToScreen(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1], x_new, y_new);\r
-                               m_systemCocoa->setCursorPosition(x_new, y_new);\r
-                               setCursorWarpAccum(0, 0);\r
-                       }\r
-                       \r
-                       m_cursorWarp= false;\r
-                       return CGAssociateMouseAndMouseCursorPosition(true) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;\r
                }\r
+               
+               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 */
        }\r
-       return GHOST_kSuccess;\r
+       return err;
 }\r
        \r
 GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)\r
@@ -979,7 +1003,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap
                                                                                                                samplesPerPixel:2\r
                                                                                                                           hasAlpha:YES\r
                                                                                                                           isPlanar:YES\r
-                                                                                                                colorSpaceName:NSDeviceBlackColorSpace\r
+                                                                                                                colorSpaceName:NSDeviceWhiteColorSpace
                                                                                                                        bytesPerRow:(sizex/8 + (sizex%8 >0 ?1:0))\r
                                                                                                                   bitsPerPixel:1];\r
        \r
@@ -989,10 +1013,10 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap
        \r
        for (y=0; y<nbUns16; y++) {\r
 #if !defined(__LITTLE_ENDIAN__)\r
-               cursorBitmap[y] = uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8));\r
+               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));\r
 #else\r
-               cursorBitmap[y] = uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8));\r
+               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));\r
 #endif\r
                \r
index d197b5343526f08961d7b5fa3aa970937824daea..d9c2654f446f86960d133aceaf5fac38f51fa942 100644 (file)
@@ -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);
        }
 
index eb0689ab4105c9b99abe401cd56e800183c8339f..0dba1776553a30311671be88574ee1ff57c7f192 100644 (file)
@@ -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.
index 593a84ccad6bd687fe025e538c1e9be9c2c411da..c583c105a7a36a4acee8eeba411cfe47e585502a 100644 (file)
                                RelativePath="..\..\..\source\blender\editors\space_outliner\outliner.c"\r
                                >\r
                        </File>\r
-                       <File\r
-                               RelativePath="..\..\..\source\blender\editors\space_outliner\outliner_header.c"\r
-                               >\r
-                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\blender\editors\space_outliner\outliner_intern.h"\r
                                >\r
index 0ddb02afad1f975488f87eec3d7b6d8d11472b37..1a14e987ed6b7b654a0b6778d168edbd64d02db3 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>\r
 <VisualStudioProject\r
        ProjectType="Visual C++"\r
-       Version="9,00"\r
+       Version="9.00"\r
        Name="BLO_loader"\r
        ProjectGUID="{E5F2F004-C704-4DCC-A08F-6EB1E38EAB9F}"\r
        RootNamespace="BLO_loader"\r
                                RelativePath="..\..\..\source\blender\blenloader\BLO_undofile.h"\r
                                >\r
                        </File>\r
-                       <Filter\r
-                               Name="Source Files"\r
-                               Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+               </Filter>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+                       >\r
+                       <File\r
+                               RelativePath="..\..\..\source\blender\blenloader\intern\readblenentry.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\blender\blenloader\intern\readfile.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Blender Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="3D Plugin Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="3D Plugin Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Blender Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="BlenderPlayer Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="BlenderPlayer Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\blender\blenloader\intern\undofile.c"\r
                                >\r
-                               <File\r
-                                       RelativePath="..\..\..\source\blender\blenloader\intern\readblenentry.c"\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\blender\blenloader\intern\writefile.c"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Blender Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="3D Plugin Debug|Win32"\r
                                        >\r
-                               </File>\r
-                               <File\r
-                                       RelativePath="..\..\..\source\blender\blenloader\intern\readfile.c"\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="3D Plugin Release|Win32"\r
                                        >\r
-                                       <FileConfiguration\r
-                                               Name="Blender Debug|Win32"\r
-                                               >\r
-                                               <Tool\r
-                                                       Name="VCCLCompilerTool"\r
-                                                       AdditionalIncludeDirectories=""\r
-                                               />\r
-                                       </FileConfiguration>\r
-                                       <FileConfiguration\r
-                                               Name="3D Plugin Debug|Win32"\r
-                                               >\r
-                                               <Tool\r
-                                                       Name="VCCLCompilerTool"\r
-                                                       AdditionalIncludeDirectories=""\r
-                                               />\r
-                                       </FileConfiguration>\r
-                                       <FileConfiguration\r
-                                               Name="3D Plugin Release|Win32"\r
-                                               >\r
-                                               <Tool\r
-                                                       Name="VCCLCompilerTool"\r
-                                                       AdditionalIncludeDirectories=""\r
-                                               />\r
-                                       </FileConfiguration>\r
-                                       <FileConfiguration\r
-                                               Name="Blender Release|Win32"\r
-                                               >\r
-                                               <Tool\r
-                                                       Name="VCCLCompilerTool"\r
-                                                       AdditionalIncludeDirectories=""\r
-                                               />\r
-                                       </FileConfiguration>\r
-                                       <FileConfiguration\r
-                                               Name="BlenderPlayer Debug|Win32"\r
-                                               >\r
-                                               <Tool\r
-                                                       Name="VCCLCompilerTool"\r
-                                                       AdditionalIncludeDirectories=""\r
-                                               />\r
-                                       </FileConfiguration>\r
-                                       <FileConfiguration\r
-                                               Name="BlenderPlayer Release|Win32"\r
-                                               >\r
-                                               <Tool\r
-                                                       Name="VCCLCompilerTool"\r
-                                                       AdditionalIncludeDirectories=""\r
-                                               />\r
-                                       </FileConfiguration>\r
-                               </File>\r
-                               <File\r
-                                       RelativePath="..\..\..\source\blender\blenloader\intern\undofile.c"\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Blender Release|Win32"\r
                                        >\r
-                               </File>\r
-                               <File\r
-                                       RelativePath="..\..\..\source\blender\blenloader\intern\writefile.c"\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="BlenderPlayer Debug|Win32"\r
                                        >\r
-                                       <FileConfiguration\r
-                                               Name="Blender Debug|Win32"\r
-                                               >\r
-                                               <Tool\r
-                                                       Name="VCCLCompilerTool"\r
-                                                       AdditionalIncludeDirectories=""\r
-                                               />\r
-                                       </FileConfiguration>\r
-                                       <FileConfiguration\r
-                                               Name="3D Plugin Debug|Win32"\r
-                                               >\r
-                                               <Tool\r
-                                                       Name="VCCLCompilerTool"\r
-                                                       AdditionalIncludeDirectories=""\r
-                                               />\r
-                                       </FileConfiguration>\r
-                                       <FileConfiguration\r
-                                               Name="3D Plugin Release|Win32"\r
-                                               >\r
-                                               <Tool\r
-                                                       Name="VCCLCompilerTool"\r
-                                                       AdditionalIncludeDirectories=""\r
-                                               />\r
-                                       </FileConfiguration>\r
-                                       <FileConfiguration\r
-                                               Name="Blender Release|Win32"\r
-                                               >\r
-                                               <Tool\r
-                                                       Name="VCCLCompilerTool"\r
-                                                       AdditionalIncludeDirectories=""\r
-                                               />\r
-                                       </FileConfiguration>\r
-                                       <FileConfiguration\r
-                                               Name="BlenderPlayer Debug|Win32"\r
-                                               >\r
-                                               <Tool\r
-                                                       Name="VCCLCompilerTool"\r
-                                                       AdditionalIncludeDirectories=""\r
-                                               />\r
-                                       </FileConfiguration>\r
-                                       <FileConfiguration\r
-                                               Name="BlenderPlayer Release|Win32"\r
-                                               >\r
-                                               <Tool\r
-                                                       Name="VCCLCompilerTool"\r
-                                                       AdditionalIncludeDirectories=""\r
-                                               />\r
-                                       </FileConfiguration>\r
-                               </File>\r
-                       </Filter>\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="BlenderPlayer Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               AdditionalIncludeDirectories=""\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
                </Filter>\r
        </Files>\r
        <Globals>\r
diff --git a/release/environment-macosx b/release/environment-macosx
new file mode 100644 (file)
index 0000000..d41d5ec
--- /dev/null
@@ -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 (file)
index 0000000..f8890f8
--- /dev/null
@@ -0,0 +1,18 @@
+# This is a Blender Environment Variable config file.\r
+#\r
+# Comment lines start with "#", other lines will be split at the "="\r
+# and the part before will be used as env var name and the part after\r
+# as env var value. The value can make reference to previous or\r
+# prelaunch variables with "%%" and the content will be replaced.\r
+# Once set, values of variables will not be overwritten.\r
+#\r
+# BLENDER_SHARE should be COMMON_APPDATA\\Blender Foundation\\Blender for typical installs.\r
+# BLENDER_VERSION will be set by the program before processing this file.\r
+BLENDER_USER_BASE=%USERPROFILE%\\Blender Foundation\\Blender\\%BLENDER_VERSION%\r
+BLENDER_SYSTEM_BASE=%BLENDER_SHARE%\\%BLENDER_VERSION%\r
+BLENDER_USER_DATAFILES=%USERPROFILE%\\Blender Foundation\\%BLENDER_VERSION%\\datafiles\r
+BLENDER_SYSTEM_DATAFILES=%BLENDER_SHARE%\\%BLENDER_VERSION%\\datafiles\r
+BLENDER_USER_PY=%USERPROFILE%\\Blender Foundation\\%BLENDER_VERSION%\\py\r
+BLENDER_SYSTEM_PY=%BLENDER_SHARE%\\%BLENDER_VERSION%\\py\r
+BLENDER_USER_PLUGINS=%USERPROFILE%\\Blender Foundation\\%BLENDER_VERSION%\\plugins\r
+BLENDER_SYSTEM_PLUGINS=%BLENDER_SHARE%\\%BLENDER_VERSION%\\plugins\r
diff --git a/release/environment-unix b/release/environment-unix
new file mode 100644 (file)
index 0000000..8a13c28
--- /dev/null
@@ -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
index f0247ce532a8981761338d26c107cb69d5e574f0..f69c8a267e0ea6f621190e0fa67744456da03ac7 100644 (file)
@@ -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)
index 2c1999c3d45d94326065963c8051caa9c3b5cb3a..5ca7d5629d582ab09cef6bda14dfad6b72dea41d 100644 (file)
@@ -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)
index 21b1388ebfe622c53550762e7de4fdc556f41475..d159c6588e573565d305b1bef1a4f144a4a282eb 100644 (file)
@@ -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)
+
index 83b400816e35d2a8026b33a1eeb1724b76886bb3..1e8a152e91f8f14748cd3e87b3d93167929eb71a 100644 (file)
@@ -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")
 
index 8e79c3741bb5717dbcfa08c9dc34be1cd7515ef6..d74cc0e9d7ef082832140da1f3874e133155759f 100644 (file)
@@ -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")
-
-
index db29afc7d6dfb40274dfde4bc92712dcb59133c3..2c6ca7497574f44d8bbaf68166babfc0e26a1eea 100644 (file)
@@ -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 
index 339fac839ea4086d13521ad4433b9786b006cf7b..cbd9d8948abcccefe149992803c9694a1dcfb846 100644 (file)
@@ -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)
index a762005ae7dde7e36116013aca88e19bf67acb57..a557e4427d853cabbb6456c1adaa2e6c9e526f95 100644 (file)
@@ -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
index 65b2937867f0df95a9f2cc368a5b3bffeddff996..d4a7b242cab6a3fa93d8b7d3df6a2f03d32fb97c 100644 (file)
@@ -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)
        
index a3e186a9cfde328390fcad1e4cf4284a9ced6323..1c83e758ce5383a67a2ece5625e7ba62cd1c5b90 100644 (file)
@@ -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()
index 6a956a70e9fe36c59597893be93b2526750c50ba..545659e8dc4f704de1db6a2faf781721c50385f6 100644 (file)
@@ -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>")
index be97f8d0a81d0ee6072986854380bdfc1215e922..bef6f0e68af4d8f0b0f0cb98bd7662364b2fd5ec 100644 (file)
@@ -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
index 42d1f6a0b860e894fe738254760070cfec7bfeea..e46b0c7b88862071f1b092011b301fa68cf091d6 100644 (file)
@@ -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.
index 657e31001e0da2a770b000fe1231088eb7746e08..15ca6faf29730304ffa6c14fab4486a046b44515 100644 (file)
@@ -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:
index 7681d4865e9508e57af0c66e246e22fbb773d9fb..7d7f3c29630f6b9c15621c777cb2f01321adecc0 100644 (file)
@@ -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="")
index 06393a738a0f41b5eb0522f978df7a0089d283e7..b10648b8d621ab546c453f33b582e455e1363419 100644 (file)
@@ -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:
index 83c2e82bf6cc31e462c58ecc9e03f0f9aecc2ff6..639b9836b0c65cc78f82edefec715297ec27997d 100644 (file)
@@ -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)
+
index 9344294ff9e185d56cb6e8e99f64d0980f0928f8..0fb00b03961db534831d6c85b386f1141830c69b 100644 (file)
@@ -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)
index 5971e4492cebf7ae08e30df179ebedae573eca99..e8041cc7393b3c52de88be4da29f5db692d8050c 100644 (file)
@@ -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)
index c07f3136fae274b31b3b4b1fde07af37c7623f98..eda6cced0ae47a8d86d940cac5a54101511b7d5d 100644 (file)
@@ -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)
index 86ca5beb9b5d28ec0d5bb03d57c6c6c1ba82df8b..4e495d158ebeaa97ec613dcff0b7ba09cb150ce9 100644 (file)
@@ -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()
index 780ae3ac8f97ebff5a8002a80aff188ebfedc79a..77c6f83407313d4caad586f8a341a3559cbaaf7f 100644 (file)
@@ -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)
+
index 5f5d4f916d0ca39021a33b3c62f2b758188a5912..bf25289333ff1a60774b172980291ed16b4f7934 100644 (file)
@@ -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'
index ee7193da30135565122c7c1172d39f3ee49d26d8..9499478a029dcb4fcedf6e1ee6f420ee52520f74 100644 (file)
@@ -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()
                
index c069572aa2807d518daa72135ffb3c40382271f5..98ac462f2d43a2aa71c14972262bfe3470a9d343 100644 (file)
@@ -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
index e089cff264fe86dc459223c5ef421712fc7e9deb..63fe27f2e4b5b50da573ad494e7f9e6308062b23 100644 (file)
@@ -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)
index 1a800fc4dfd2b441020a6e1a73f7fc2f1cff3e02..dcc93bd9c75ccf40b5b94ac90f36249c31268833 100644 (file)
@@ -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)
index b65d092fcfa3de5d3bb4bf66bcbe71d022b45bf4..17ac1b2bbaa1157a91ae95bba49fafbd02587e93 100644 (file)
@@ -78,7 +78,7 @@ def effector_weights_ui(self, weights):
                layout.itemS()
                
                flow = layout.column_flow()
-           &