Merging r39998 through r40043 from trunk into soc-2011-tomato
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 8 Sep 2011 18:59:35 +0000 (18:59 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 8 Sep 2011 18:59:35 +0000 (18:59 +0000)
58 files changed:
CMakeLists.txt
build_files/cmake/Modules/FindOpenCOLLADA.cmake
build_files/cmake/Modules/FindPCRE.cmake [new file with mode: 0644]
build_files/cmake/Modules/FindXML2.cmake [new file with mode: 0644]
build_files/scons/config/darwin-config.py
doc/python_api/examples/bge.texture.1.py
doc/python_api/examples/bpy.types.Operator.py
doc/python_api/rst/info_tips_and_tricks.rst
doc/python_api/sphinx_doc_gen.py
release/datafiles/blenderbuttons
release/scripts/modules/bpy_types.py
release/scripts/startup/bl_operators/animsys_update.py
release/scripts/startup/bl_operators/nla.py
release/scripts/startup/bl_ui/properties_data_armature.py
release/scripts/startup/bl_ui/properties_data_modifier.py
release/scripts/startup/bl_ui/properties_data_speaker.py
release/scripts/startup/bl_ui/properties_game.py
release/scripts/startup/bl_ui/space_userpref.py
source/blender/blenkernel/intern/node.c
source/blender/collada/ArmatureExporter.cpp
source/blender/collada/ArmatureExporter.h
source/blender/collada/CMakeLists.txt
source/blender/collada/CameraExporter.cpp
source/blender/collada/CameraExporter.h
source/blender/collada/DocumentExporter.cpp
source/blender/collada/DocumentExporter.h
source/blender/collada/EffectExporter.cpp
source/blender/collada/EffectExporter.h
source/blender/collada/ExportSettings.cpp [new file with mode: 0644]
source/blender/collada/ExportSettings.h [new file with mode: 0644]
source/blender/collada/GeometryExporter.cpp
source/blender/collada/GeometryExporter.h
source/blender/collada/ImageExporter.cpp
source/blender/collada/ImageExporter.h
source/blender/collada/LightExporter.cpp
source/blender/collada/LightExporter.h
source/blender/collada/MaterialExporter.cpp
source/blender/collada/MaterialExporter.h
source/blender/collada/SceneExporter.cpp
source/blender/collada/SceneExporter.h
source/blender/collada/collada.cpp
source/blender/editors/datafiles/blenderbuttons.c
source/blender/editors/mesh/editmesh_mods.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_draw.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_modifier.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/modifiers/intern/MOD_weightvgproximity.c
source/blender/nodes/composite/node_composite_tree.c
source/blender/nodes/intern/node_common.c
source/blender/nodes/shader/node_shader_tree.c
source/blender/python/generic/py_capi_utils.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_keymap.c

index 42e4559cfb01f1f3af088de965488f6ee47af260..bea6f655235eeece9a0efd863fb71da6bc34c061 100644 (file)
@@ -455,15 +455,8 @@ if(UNIX AND NOT APPLE)
        if(WITH_OPENCOLLADA)
                find_package(OpenCOLLADA)
                if(OPENCOLLADA_FOUND)
-                       set(PCRE /usr CACHE PATH "PCRE Directory")
-                       mark_as_advanced(PCRE)
-                       set(PCRE_LIBPATH ${PCRE}/lib)
-                       set(PCRE_LIB pcre)
-
-                       set(EXPAT /usr CACHE PATH "Expat Directory")
-                       mark_as_advanced(EXPAT)
-                       set(EXPAT_LIBPATH ${EXPAT}/lib)
-                       set(EXPAT_LIB expat)
+                       find_package(XML2)
+                       find_package(PCRE)
                else()
                        set(WITH_OPENCOLLADA OFF)
                endif()
index c7637283514df29d32bed5f36862dd2e8d28a6ad..a9a1d54450741331da0968f8a67eb80be1ba46d9 100644 (file)
@@ -49,12 +49,14 @@ SET(_opencollada_FIND_COMPONENTS
   OpenCOLLADAFramework
   OpenCOLLADABaseUtils
   GeneratedSaxParser
-  UTF
   MathMLSolver
-  pcre
+)
+
+# Fedora openCOLLADA package links these statically
+SET(_opencollada_FIND_STATIC_COMPONENTS
+  UTF
   ftoa
   buffer
-  xml2
 )
 
 SET(_opencollada_SEARCH_DIRS
@@ -104,6 +106,25 @@ FOREACH(COMPONENT ${_opencollada_FIND_COMPONENTS})
   LIST(APPEND _opencollada_LIBRARIES "${OPENCOLLADA_${UPPERCOMPONENT}_LIBRARY}")
 ENDFOREACH()
 
+FOREACH(COMPONENT ${_opencollada_FIND_STATIC_COMPONENTS})
+  STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
+
+  FIND_LIBRARY(OPENCOLLADA_${UPPERCOMPONENT}_LIBRARY
+    NAMES
+      ${COMPONENT}
+    HINTS
+      ${_opencollada_SEARCH_DIRS}
+    PATH_SUFFIXES
+      lib64 lib
+      # Ubuntu ppa needs this.
+      lib64/opencollada lib/opencollada
+    )
+  IF(OPENCOLLADA_${UPPERCOMPONENT}_LIBRARY)
+    MARK_AS_ADVANCED(OPENCOLLADA_${UPPERCOMPONENT}_LIBRARY)
+    LIST(APPEND _opencollada_LIBRARIES "${OPENCOLLADA_${UPPERCOMPONENT}_LIBRARY}")
+  ENDIF()
+ENDFOREACH()
+
 
 # handle the QUIETLY and REQUIRED arguments and set OPENCOLLADA_FOUND to TRUE if 
 # all listed variables are TRUE
diff --git a/build_files/cmake/Modules/FindPCRE.cmake b/build_files/cmake/Modules/FindPCRE.cmake
new file mode 100644 (file)
index 0000000..a093752
--- /dev/null
@@ -0,0 +1,43 @@
+# - Try to find the PCRE regular expression library
+# Once done this will define
+#
+#  PCRE_FOUND - system has the PCRE library
+#  PCRE_INCLUDE_DIR - the PCRE include directory
+#  PCRE_LIBRARIES - The libraries needed to use PCRE
+
+# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+
+if (PCRE_INCLUDE_DIR AND PCRE_PCREPOSIX_LIBRARY AND PCRE_PCRE_LIBRARY)
+  # Already in cache, be silent
+  set(PCRE_FIND_QUIETLY TRUE)
+endif (PCRE_INCLUDE_DIR AND PCRE_PCREPOSIX_LIBRARY AND PCRE_PCRE_LIBRARY)
+       
+if (NOT WIN32)
+  # use pkg-config to get the directories and then use these values
+  # in the FIND_PATH() and FIND_LIBRARY() calls
+  find_package(PkgConfig)
+  pkg_check_modules(PC_PCRE QUIET libpcre)
+  set(PCRE_DEFINITIONS ${PC_PCRE_CFLAGS_OTHER})
+endif (NOT WIN32)
+
+find_path(PCRE_INCLUDE_DIR pcre.h
+          HINTS ${PC_PCRE_INCLUDEDIR} ${PC_PCRE_INCLUDE_DIRS}
+          PATH_SUFFIXES pcre)
+
+find_library(PCRE_PCRE_LIBRARY NAMES pcre HINTS ${PC_PCRE_LIBDIR} ${PC_PCRE_LIBRARY_DIRS})
+
+find_library(PCRE_PCREPOSIX_LIBRARY NAMES pcreposix HINTS ${PC_PCRE_LIBDIR} ${PC_PCRE_LIBRARY_DIRS})
+
+include(FindPackageHandleStandardArgs)
+
+IF(NOT WIN32)
+        find_package_handle_standard_args(PCRE DEFAULT_MSG PCRE_INCLUDE_DIR PCRE_PCRE_LIBRARY PCRE_PCREPOSIX_LIBRARY )
+        mark_as_advanced(PCRE_INCLUDE_DIR PCRE_LIBRARIES PCRE_PCREPOSIX_LIBRARY PCRE_PCRE_LIBRARY)
+        set(PCRE_LIBRARIES ${PCRE_PCRE_LIBRARY} ${PCRE_PCREPOSIX_LIBRARY})
+ELSE()
+        find_package_handle_standard_args(PCRE DEFAULT_MSG PCRE_INCLUDE_DIR PCRE_PCRE_LIBRARY  )
+        set(PCRE_LIBRARIES ${PCRE_PCRE_LIBRARY} )
+        mark_as_advanced(PCRE_INCLUDE_DIR PCRE_LIBRARIES PCRE_PCRE_LIBRARY)
+ENDIF()
diff --git a/build_files/cmake/Modules/FindXML2.cmake b/build_files/cmake/Modules/FindXML2.cmake
new file mode 100644 (file)
index 0000000..e9f9fb3
--- /dev/null
@@ -0,0 +1,88 @@
+# - Try to find XML2
+# Once done this will define
+#
+#  XML2_FOUND - system has XML2
+#  XML2_INCLUDE_DIRS - the XML2 include directory
+#  XML2_LIBRARIES - Link these to use XML2
+#  XML2_DEFINITIONS - Compiler switches required for using XML2
+#
+#  Copyright (c) 2008 Andreas Schneider <mail@cynapses.org>
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#
+
+
+if (XML2_LIBRARIES AND XML2_INCLUDE_DIRS)
+  # in cache already
+  set(XML2_FOUND TRUE)
+else (XML2_LIBRARIES AND XML2_INCLUDE_DIRS)
+  # use pkg-config to get the directories and then use these values
+  # in the FIND_PATH() and FIND_LIBRARY() calls
+  if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
+    include(UsePkgConfig)
+    pkgconfig(libxml-2.0 _XML2_INCLUDEDIR _XML2_LIBDIR _XML2_LDFLAGS _XML2_CFLAGS)
+  else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
+    find_package(PkgConfig)
+    if (PKG_CONFIG_FOUND)
+      pkg_check_modules(_XML2 libxml-2.0)
+    endif (PKG_CONFIG_FOUND)
+  endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
+  find_path(XML2_INCLUDE_DIR
+    NAMES
+      libxml/xpath.h
+    PATHS
+      ${_XML2_INCLUDEDIR}
+      /usr/include
+      /usr/local/include
+      /opt/local/include
+      /sw/include
+    PATH_SUFFIXES
+      libxml2
+  )
+
+  find_library(XML2_LIBRARY
+    NAMES
+      xml2
+    PATHS
+      ${_XML2_LIBDIR}
+      /usr/lib
+      /usr/local/lib
+      /opt/local/lib
+      /sw/lib
+  )
+
+  if (XML2_LIBRARY)
+    set(XML2_FOUND TRUE)
+  endif (XML2_LIBRARY)
+
+  set(XML2_INCLUDE_DIRS
+    ${XML2_INCLUDE_DIR}
+  )
+
+  if (XML2_FOUND)
+    set(XML2_LIBRARIES
+      ${XML2_LIBRARIES}
+      ${XML2_LIBRARY}
+    )
+  endif (XML2_FOUND)
+
+  if (XML2_INCLUDE_DIRS AND XML2_LIBRARIES)
+     set(XML2_FOUND TRUE)
+  endif (XML2_INCLUDE_DIRS AND XML2_LIBRARIES)
+
+  if (XML2_FOUND)
+    if (NOT XML2_FIND_QUIETLY)
+      message(STATUS "Found XML2: ${XML2_LIBRARIES}")
+    endif (NOT XML2_FIND_QUIETLY)
+  else (XML2_FOUND)
+    if (XML2_FIND_REQUIRED)
+      message(FATAL_ERROR "Could not find XML2")
+    endif (XML2_FIND_REQUIRED)
+  endif (XML2_FOUND)
+
+  # show the XML2_INCLUDE_DIRS and XML2_LIBRARIES variables only in the advanced view
+  mark_as_advanced(XML2_INCLUDE_DIRS XML2_LIBRARIES)
+
+endif (XML2_LIBRARIES AND XML2_INCLUDE_DIRS)
+
index 102ec73a4e309439232208a9d0f460492c54ae28..29d2b39323ec117a9e83f2530ccab99ea0f470fc 100644 (file)
@@ -14,7 +14,7 @@ USE_SDK=True
 ###################     Cocoa & architecture settings      ##################
 #############################################################################
 WITH_GHOST_COCOA=True
-MACOSX_ARCHITECTURE = 'x86_64' # valid archs: ppc, i386, ppc64, x86_64
+MACOSX_ARCHITECTURE = 'i386' # valid archs: ppc, i386, ppc64, x86_64
 
 
 cmd = 'uname -p'
index faa0ae736e83eefc4e0ff3ec166f93d3820f0254..4be6f51de67cf2aefed4333f3f15e7bdcfe891ec 100644 (file)
@@ -14,7 +14,7 @@ def createTexture(cont):
     object = cont.owner
 
     # get the reference pointer (ID) of the internal texture
-    ID = texture.materialID(obj, 'IMoriginal.png')
+    ID = texture.materialID(object, 'IMoriginal.png')
 
     # create a texture object
     object_texture = texture.Texture(object, ID)
index 52edfa0a61b93a59e906a0a40170e4a433d1d191..0981712e1ff07291d5d0d81cc0ecf25d4e64e43b 100644 (file)
@@ -21,7 +21,7 @@ class HelloWorldOperator(bpy.types.Operator):
         print("Hello World")
         return {'FINISHED'}
 
-bpy.utils.register_class(SimpleOperator)
+bpy.utils.register_class(HelloWorldOperator)
 
 # test call to the newly defined operator
 bpy.ops.wm.hello_world()
index 3ce2cfd48ad67316fd41441bfb87091072740ea3..bd3ed196193d36898a9ff675a260d6cb57fe6b02 100644 (file)
@@ -2,7 +2,9 @@
 Tips and Tricks
 ***************
 
-Some of these are just python features that scripters may not have thaught to use with blender.
+Here are various suggestions that you might find useful when writing scripts.
+
+Some of these are just python features that scripters may not have thought to use with blender, others are blender specific.
 
 
 Use The Terminal
@@ -14,44 +16,37 @@ There are 3 main uses for the terminal, these are:
 
 * You can see the output of `print()` as you're script runs, which is useful to view debug info.
 
-* The error tracebacks are printed in full to the terminal which wont always generate an error popup in blenders user interface (depending on how the script is executed).
+* The error trace-back is printed in full to the terminal which wont always generate an error popup in blenders user interface (depending on how the script is executed).
 
-* If the script runs for too long or you accidentally enter an infinate loop, Ctrl+C in the terminal (Ctrl+Break on Windows) will quit the script early.
+* If the script runs for too long or you accidentally enter an infinite loop, Ctrl+C in the terminal (Ctrl+Break on Windows) will quit the script early.
 
 .. note::
    For Linux and OSX users this means starting the terminal first, then running blender from within it. On Windows the terminal can be enabled from the help menu.
 
 
-Run External Scripts
-====================
+Use an External Editor
+======================
 
-Blenders text editor is fine for edits and writing small tests but it is not a full featured editor so for larger projects you'll probably want to use an external editor.
+Blenders text editor is fine for small changes and writing tests but its not full featured, for larger projects you'll probably want to use a standalone editor or python IDE.
 
 Editing a text file externally and having the same text open in blender does work but isn't that optimal so here are 2 ways you can easily use an external file from blender.
 
+Using the following examples you'll still need textblock in blender to execute, but reference an external file rather then including it directly.
 
 Executing External Scripts
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+--------------------------
 
-This is the equivilent to running the script directly, referencing a scripts path from a 2 line textblock.
+This is the equivalent to running the script directly, referencing a scripts path from a 2 line textblock.
 
-.. code-block::
+.. code-block:: python
 
    filename = "/full/path/to/myscript.py"
    exec(compile(open(filename).read(), filename, 'exec'))
 
 
-You might also want to reference the file relative to the blend file.
-
-.. code-block::
-
-   filename = "/full/path/to/script.py"
-   exec(compile(open(filename).read(), filename, 'exec'))
+You might want to reference a script relative to the blend file.
 
-
-You might want to reference a script thats at the same location as the blend file.
-
-.. code-block::
+.. code-block:: python
 
    import bpy
    import os
@@ -61,11 +56,11 @@ You might want to reference a script thats at the same location as the blend fil
 
 
 Executing Modules
-^^^^^^^^^^^^^^^^^
+-----------------
 
 This example shows loading a script in as a module and executing a module function.
 
-.. code-block::
+.. code-block:: python
 
    import myscript
    import imp
@@ -74,18 +69,18 @@ This example shows loading a script in as a module and executing a module functi
    myscript.main()
 
 
-Notice that the script is reloaded every time, this forces an update, normally the module stays cached in `sys.modules`.
+Notice that the script is reloaded every time, this forces use of the modified version otherwise the cached one in `sys.modules` would be used until blender was restarted.
 
-The main difference between this and executing the script directly is it has to call a function in the module, in this case `main()` but it can be any function, an advantage with this is you can pass argumnents to the function from this small script which is often useful for testing differnt settings quickly.
+The important difference between this and executing the script directly is it has to call a function in the module, in this case `main()` but it can be any function, an advantage with this is you can pass arguments to the function from this small script which is often useful for testing different settings quickly.
 
 The other issue with this is the script has to be in pythons module search path.
 While this is not best practice - for testing you can extend the search path, this example adds the current blend files directory to the search path, then loads the script as a module.
 
-.. code-block::
+.. code-block:: python
 
    import sys
    import os
-   impory bpy
+   import bpy
 
    blend_dir = os.path.basename(bpy.data.filepath)
    if blend_dir not in sys.path:
@@ -100,37 +95,103 @@ While this is not best practice - for testing you can extend the search path, th
 Don't Use Blender!
 ==================
 
-While developing your own scripts blenders interface can get in the way, manually reloading, running the scripts, opening file import etc is just overhead.
+While developing your own scripts blenders interface can get in the way, manually reloading, running the scripts, opening file import etc. adds overhead.
+
+For scripts that are not interactive it can end up being more efficient not to use blenders interface at all and instead execute the script on the command line.
+
+.. code-block:: python
+
+   blender --background --python myscript.py
+
+
+You might want to run this with a blend file so the script has some data to operate on.
+
+.. code-block:: python
 
-For scripts that are not interactive it can end up being easier not to use blender at all and run blender from a terminal, without opening a window and execute the script on the command line.
+   blender myscene.blend --background --python myscript.py
 
-.. code-block::
 
-   blender --backgruond --python myscript.py
+.. note::
+
+   Depending on you're setup you might have to enter the full path to the blender executable.
+
+
+Once the script is running properly in background mode, you'll want to check the output of the script, this depends completely on the task at hand however here are some suggestions.
 
+* render the output to an image, use an image viewer and keep writing over the same image each time.
 
-You might want to run this with a blend file too.
+* save a new blend file, or export the file using one of blenders exporters.
 
-.. code-block::
+* if the results can be displayed as text - print them or write them to a file.
 
-   blender myscene.blend --backgruond --python myscript.py
 
+This can take a little time to setup, but it can be well worth the effort to reduce the time it takes to test changes - you can even have blender running the script ever few seconds with a viewer updating the results, so no need to leave you're text editor to see changes.
 
 
 Use External Tools
 ==================
 
+When there are no readily available python modules to perform specific tasks its worth keeping in mind you may be able to have python execute an external command on you're data and read the result back in.
+
+Using external programs adds an extra dependency and may limit who can use the script but to quickly setup you're own custom pipeline or writing one-off scripts this can be handy.
+
+Examples include:
+
+* Run The Gimp in batch mode to execute custom scripts for advanced image processing.
 
-Bundled Python
-==============
+* Write out 3D models to use external mesh manipulation tools and read back in the results.
 
-Blender from blender.org includes a compleate python installation on all platforms, this has the disadvantage that any extensions you have installed in you're systems python wont be found by blender.
+* Convert files into recognizable formats before reading.
+
+
+Bundled Python & Extensions
+===========================
+
+The Blender releases distributed from blender.org include a complete python installation on all platforms, this has the disadvantage that any extensions you have installed in you're systems python wont be found by blender.
 
 There are 2 ways around this:
 
-* remove blender python subdirectory, blender will then look for the systems python and use that instead **python version must match the one that blender comes with**.
+* remove blender python sub-directory, blender will then fallback on the systems python and use that instead **python version must match the one that blender comes with**.
+
+* copy the extensions into blender's python sub-directory so blender can access them, you could also copy the entire python installation into blenders sub-directory, replacing the one blender comes with. This works as long as the python versions match and the paths are created in the same relative locations. Doing this has the advantage that you can redistribute this bundle to others with blender and/or the game player, including any extensions you rely on.
+
+
+Drop Into a Python Interpreter in You're Script
+===============================================
+
+In the middle of a script you may want to inspect some variables, run some function and generally dig about to see whats going on.
 
-* copy the extensions into blender's python subdirectry so blender can access them, you could also copy the entire python installation into blenders subdirectory, replacing the one blender comes with. This works as long as the python versions match and the paths are created in the same location relative locations. Doing this has the advantage that you can redistribute this bundle to others with blender and/or the game player, including any extensions you rely on.
+.. code-block:: python
+
+   import code
+   code.interact(local=locals())
+
+
+If you want to access both global and local variables do this...
+
+.. code-block:: python
+
+   import code
+   namespace = globals().copy()
+   namespace.update(locals())
+   code.interact(local=namespace)
+
+
+The next example is an equivalent single line version of the script above which is easier to paste into you're code:
+
+.. code-block:: python
+
+   __import__('code').interact(local={k: v for ns in (globals(), locals()) for k, v in ns.items()})
+
+
+`code.interact` can be added at any line in the script and will pause the script an launch an interactive interpreter in the terminal, when you're done you can quit the interpreter and the script will continue execution.
+
+
+Admittedly this highlights the lack of any python debugging support built into blender, but its still handy to know.
+
+.. note::
+
+   This works in the game engine as well, it can be handy to inspect the state of a running game.
 
 
 Advanced
@@ -140,10 +201,28 @@ Advanced
 Blender as a module
 -------------------
 
+From a python perspective its nicer to have everything as an extension which lets the python script combine many components.
+
+Advantages include:
+
+* you can use external editors/IDE's with blenders python API and execute scripts within the IDE (step over code, inspect variables as the script runs).
+
+* editors/IDE's can auto complete blender modules & variables.
+
+* existing scripts can import blender API's without having to run inside blender.
+
+
+This is marked advanced because to run blender as a python module requires a special build option.
+
+For instructions on building see `Building blender as a python module <http://wiki.blender.org/index.php/User:Ideasman42/BlenderAsPyModule>`_
+
 
 Python Safety (Build Option)
 ----------------------------
 
+Since its possible to accessed data which has been removed (see Gotcha's), this can be a hard to track down the cause of crashes.
+
+To raise python exceptions on accessing freed data (rather then crashing), enable the CMake build option WITH_PYTHON_SAFETY.
+
+This enables data tracking which makes data access about 2x slower which is why the option is not enabled in release builds.
 
-CTypes in Blender
------------------
index 661d41af4ef77a8aecbb71798a06e933a442129c..a7657fad4322f3ee58ab345bb099744b103fc921 100644 (file)
@@ -103,6 +103,7 @@ sphinx-build doc/python_api/sphinx-in doc/python_api/sphinx-out
 INFO_DOCS = (
     ("info_quickstart.rst", "Blender/Python Quickstart: new to blender/scripting and want to get you're feet wet?"),
     ("info_overview.rst", "Blender/Python API Overview: a more complete explanation of python integration"),
+    ("info_tips_and_tricks.rst", "Tips and Tricks: Hints to help you while writeing scripts for blender"),
     ("info_gotcha.rst", "Gotcha's: some of the problems you may come up against when writing scripts"),
     )
 
index 5e6f1a9de879facf4503dd62b3dcc6ecbc058e0c..c309ad11da2eed0a4134f9a429e0d391b203eea0 100644 (file)
Binary files a/release/datafiles/blenderbuttons and b/release/datafiles/blenderbuttons differ
index 101416f49430971d8c6fe6fa343c506b42d8aa37..b3127733c1eb8d8da655f510b31722a139c0a96a 100644 (file)
@@ -356,7 +356,7 @@ class Mesh(bpy_types.ID):
 
     @property
     def edge_keys(self):
-        return [edge_key for face in self.faces for edge_key in face.edge_keys]
+        return [ed.key for ed in self.edges]
 
 
 class MeshEdge(StructRNA):
@@ -376,17 +376,31 @@ class MeshFace(StructRNA):
         face_verts = self.vertices[:]
         mesh_verts = self.id_data.vertices
         if len(face_verts) == 3:
-            return (mesh_verts[face_verts[0]].co + mesh_verts[face_verts[1]].co + mesh_verts[face_verts[2]].co) / 3.0
+            return (mesh_verts[face_verts[0]].co +
+                    mesh_verts[face_verts[1]].co +
+                    mesh_verts[face_verts[2]].co
+                    ) / 3.0
         else:
-            return (mesh_verts[face_verts[0]].co + mesh_verts[face_verts[1]].co + mesh_verts[face_verts[2]].co + mesh_verts[face_verts[3]].co) / 4.0
+            return (mesh_verts[face_verts[0]].co +
+                    mesh_verts[face_verts[1]].co +
+                    mesh_verts[face_verts[2]].co +
+                    mesh_verts[face_verts[3]].co
+                    ) / 4.0
 
     @property
     def edge_keys(self):
         verts = self.vertices[:]
         if len(verts) == 3:
-            return ord_ind(verts[0], verts[1]), ord_ind(verts[1], verts[2]), ord_ind(verts[2], verts[0])
-
-        return ord_ind(verts[0], verts[1]), ord_ind(verts[1], verts[2]), ord_ind(verts[2], verts[3]), ord_ind(verts[3], verts[0])
+            return (ord_ind(verts[0], verts[1]),
+                    ord_ind(verts[1], verts[2]),
+                    ord_ind(verts[2], verts[0]),
+                    )
+        else:
+            return (ord_ind(verts[0], verts[1]),
+                    ord_ind(verts[1], verts[2]),
+                    ord_ind(verts[2], verts[3]),
+                    ord_ind(verts[3], verts[0]),
+                    )
 
 
 class Text(bpy_types.ID):
index 3710c57ac167e74ac175984757324f87d1702ed2..23b9cf13f07296e296574ed58eb5be19c3e4af87 100644 (file)
@@ -685,7 +685,6 @@ data_path_update = [
     ]
 
 
-import bpy
 from bpy.types import Operator
 
 
index c764f7d62f1d73e2da946c6645e0e91cd0847a0a..feb0016b1c72fab39515c3ca9c4180e9116cf953 100644 (file)
@@ -271,7 +271,8 @@ class BakeAction(Operator):
 
 
 class ClearUselessActions(Operator):
-    '''Mark actions with no F-Curves for deletion after save+reload of file preserving "action libraries"'''
+    '''Mark actions with no F-Curves for deletion after save+reload of ''' \
+    '''file preserving "action libraries"'''
     bl_idname = "anim.clear_useless_actions"
     bl_label = "Clear Useless Actions"
     bl_options = {'REGISTER', 'UNDO'}
@@ -292,12 +293,14 @@ class ClearUselessActions(Operator):
             if ((self.only_unused is False) or
                 (action.use_fake_user and action.users == 1)):
 
-                # if it has F-Curves, then it's a "action library" (i.e. walk, wave, jump, etc.)
+                # if it has F-Curves, then it's a "action library"
+                # (i.e. walk, wave, jump, etc.)
                 # and should be left alone as that's what fake users are for!
                 if not action.fcurves:
                     # mark action for deletion
                     action.user_clear()
                     removed += 1
 
-        self.report({'INFO'}, "Removed %d empty and/or fake-user only Actions" % (removed))
+        self.report({'INFO'}, "Removed %d empty and/or fake-user only Actions"
+                              % removed)
         return {'FINISHED'}
index 463ba84470f9445635d90bc41e11d4a8fce58b38..61093abe81400d4985907652124b40ad4495eac5 100644 (file)
@@ -74,6 +74,7 @@ class DATA_PT_skeleton(ArmatureButtonsPanel, Panel):
         if context.scene.render.engine == "BLENDER_GAME":
             layout.row().prop(arm, "vert_deformer", expand=True)
 
+
 class DATA_PT_display(ArmatureButtonsPanel, Panel):
     bl_label = "Display"
 
@@ -185,11 +186,10 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel):
         layout.template_ID(ob, "pose_library", new="poselib.new", unlink="poselib.unlink")
 
         if poselib:
-            
-            # list of poses in pose library 
+            # list of poses in pose library
             row = layout.row()
             row.template_list(poselib, "pose_markers", poselib.pose_markers, "active_index", rows=5)
-            
+
             # column of operators for active pose
             # - goes beside list
             col = row.column(align=True)
@@ -206,9 +206,9 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel):
             if pose_marker_active is not None:
                 col.operator("poselib.pose_remove", icon='ZOOMOUT', text="").pose = pose_marker_active.name
                 col.operator("poselib.apply_pose", icon='ZOOM_SELECTED', text="").pose_index = poselib.pose_markers.active_index
-            
-            col.operator("poselib.action_sanitise", icon='HELP', text="") # XXX: put in menu?
-            
+
+            col.operator("poselib.action_sanitise", icon='HELP', text="")  # XXX: put in menu?
+
             # properties for active marker
             if pose_marker_active is not None:
                 layout.prop(pose_marker_active, "name")
index 058e8161fe6e3529f1d0f128f4c5b3092193cca2..8d4e3f153b1f4abc36ac93a9fc781230cddddb95 100644 (file)
@@ -608,32 +608,31 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         layout.label(text="Settings can be found inside the Physics context")
 
     def UV_PROJECT(self, layout, ob, md):
-        if ob.type == 'MESH':
-            split = layout.split()
+        split = layout.split()
 
-            col = split.column()
-            col.label(text="Image:")
-            col.prop(md, "image", text="")
+        col = split.column()
+        col.label(text="Image:")
+        col.prop(md, "image", text="")
 
-            col = split.column()
-            col.label(text="UV Layer:")
-            col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
+        col = split.column()
+        col.label(text="UV Layer:")
+        col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="")
 
-            split = layout.split()
-            col = split.column()
-            col.prop(md, "use_image_override")
-            col.prop(md, "projector_count", text="Projectors")
-            for proj in md.projectors:
-                col.prop(proj, "object", text="")
+        split = layout.split()
+        col = split.column()
+        col.prop(md, "use_image_override")
+        col.prop(md, "projector_count", text="Projectors")
+        for proj in md.projectors:
+            col.prop(proj, "object", text="")
 
-            col = split.column()
-            sub = col.column(align=True)
-            sub.prop(md, "aspect_x", text="Aspect X")
-            sub.prop(md, "aspect_y", text="Aspect Y")
+        col = split.column()
+        sub = col.column(align=True)
+        sub.prop(md, "aspect_x", text="Aspect X")
+        sub.prop(md, "aspect_y", text="Aspect Y")
 
-            sub = col.column(align=True)
-            sub.prop(md, "scale_x", text="Scale X")
-            sub.prop(md, "scale_y", text="Scale Y")
+        sub = col.column(align=True)
+        sub.prop(md, "scale_x", text="Scale X")
+        sub.prop(md, "scale_y", text="Scale Y")
 
     def WARP(self, layout, ob, md):
         use_falloff = (md.falloff_type != 'NONE')
@@ -738,27 +737,29 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         col.prop(md, "narrowness", slider=True)
 
     @staticmethod
-    def weight_vg_mask(layout, ob, md):
+    def vertex_weight_mask(layout, ob, md):
         layout.label(text="Influence/Mask Options:")
-        split = layout.split()
-        col1 = split.column()
-        col2 = split.column()
 
-        col1.label(text="Global Influence:")
-        col2.prop(md, "mask_constant", text="")
+        split = layout.split(percentage=0.4)
+        split.label(text="Global Influence:")
+        split.prop(md, "mask_constant", text="")
 
         if not md.mask_texture:
-            col1.label(text="Vertex Group Mask:")
-            col2.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="")
+            split = layout.split(percentage=0.4)
+            split.label(text="Vertex Group Mask:")
+            split.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="")
 
         if not md.mask_vertex_group:
-            col1.label(text="Texture Mask:")
-            col2.template_ID(md, "mask_texture", new="texture.new")
+            split = layout.split(percentage=0.4)
+            split.label(text="Texture Mask:")
+            split.template_ID(md, "mask_texture", new="texture.new")
             if md.mask_texture:
                 split = layout.split()
+                
                 col = split.column()
                 col.label(text="Texture Coordinates:")
                 col.prop(md, "mask_tex_mapping", text="")
+                
                 col = split.column()
                 col.label(text="Use Channel:")
                 col.prop(md, "mask_tex_use_channel", text="")
@@ -769,88 +770,85 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
                     layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_textures")
 
     def VERTEX_WEIGHT_EDIT(self, layout, ob, md):
-        if ob.type == 'MESH':
-            split = layout.split()
-            col = split.column()
-            col.label(text="Vertex Group:")
-            col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+        split = layout.split()
+        col = split.column()
+        col.label(text="Vertex Group:")
+        col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
 
-            col = split.column()
-            col.label(text="Default Weight:")
-            col.prop(md, "default_weight", text="")
+        col = split.column()
+        col.label(text="Default Weight:")
+        col.prop(md, "default_weight", text="")
 
-            layout.prop(md, "falloff_type")
-            if md.falloff_type == 'CURVE':
-                col = layout.column()
-                col.template_curve_mapping(md, "map_curve")
+        layout.prop(md, "falloff_type")
+        if md.falloff_type == 'CURVE':
+            col = layout.column()
+            col.template_curve_mapping(md, "map_curve")
 
-            split = layout.split(percentage=0.4)
-            split.prop(md, "use_add")
-            row = split.row()
-            row.active = md.use_add
-            row.prop(md, "add_threshold")
+        split = layout.split(percentage=0.4)
+        split.prop(md, "use_add")
+        row = split.row()
+        row.active = md.use_add
+        row.prop(md, "add_threshold")
 
-            split = layout.split(percentage=0.4)
-            split.prop(md, "use_remove")
-            row = split.row()
-            row.active = md.use_remove
-            row.prop(md, "remove_threshold")
+        split = layout.split(percentage=0.4)
+        split.prop(md, "use_remove")
+        row = split.row()
+        row.active = md.use_remove
+        row.prop(md, "remove_threshold")
 
-            # Common mask options…
-            layout.separator()
-            self.weight_vg_mask(layout, ob, md)
+        # Common mask options
+        layout.separator()
+        self.vertex_weight_mask(layout, ob, md)
 
     def VERTEX_WEIGHT_MIX(self, layout, ob, md):
-        if ob.type == 'MESH':
-            split = layout.split()
-            col = split.column()
-            col.label(text="Vertex Group A:")
-            col.prop_search(md, "vertex_group_a", ob, "vertex_groups", text="")
-            col.label(text="Default Weight A:")
-            col.prop(md, "default_weight_a", text="")
+        split = layout.split()
+        
+        col = split.column()
+        col.label(text="Vertex Group A:")
+        col.prop_search(md, "vertex_group_a", ob, "vertex_groups", text="")
+        col.label(text="Default Weight A:")
+        col.prop(md, "default_weight_a", text="")
 
-            col.label(text="Mix Mode:")
-            col.prop(md, "mix_mode", text="")
+        col.label(text="Mix Mode:")
+        col.prop(md, "mix_mode", text="")
 
-            col = split.column()
-            col.label(text="Vertex Group B:")
-            col.prop_search(md, "vertex_group_b", ob, "vertex_groups", text="")
-            col.label(text="Default Weight B:")
-            col.prop(md, "default_weight_b", text="")
+        col = split.column()
+        col.label(text="Vertex Group B:")
+        col.prop_search(md, "vertex_group_b", ob, "vertex_groups", text="")
+        col.label(text="Default Weight B:")
+        col.prop(md, "default_weight_b", text="")
 
-            col.label(text="Mix Set:")
-            col.prop(md, "mix_set", text="")
+        col.label(text="Mix Set:")
+        col.prop(md, "mix_set", text="")
 
-            # Common mask options…
-            layout.separator()
-            self.weight_vg_mask(layout, ob, md)
+        # Common mask options
+        layout.separator()
+        self.vertex_weight_mask(layout, ob, md)
 
     def VERTEX_WEIGHT_PROXIMITY(self, layout, ob, md):
-        if ob.type == 'MESH':
-            split = layout.split()
-            col = split.column()
-            col.label(text="Vertex Group:")
-            col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+        split = layout.split()
+        
+        col = split.column()
+        col.label(text="Vertex Group:")
+        col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
 
-            col = split.column()
-            col.label(text="Target Object:")
-            col.prop(md, "target", text="")
+        col = split.column()
+        col.label(text="Target Object:")
+        col.prop(md, "target", text="")
 
-            row = layout.row()
-            row.prop(md, "proximity_mode", expand=True)
-            if md.proximity_mode == 'GEOMETRY':
-                row = layout.row()
-                row.prop(md, "proximity_geometry", expand=True)
+        layout.row().prop(md, "proximity_mode", expand=True)
+        if md.proximity_mode == 'GEOMETRY':
+            layout.row().prop(md, "proximity_geometry", expand=True)
 
-            row = layout.split()
-            row.prop(md, "min_dist")
-            row.prop(md, "max_dist")
+        row = layout.row()
+        row.prop(md, "min_dist")
+        row.prop(md, "max_dist")
 
-            layout.prop(md, "falloff_type")
+        layout.prop(md, "falloff_type")
 
-            # Common mask options…
-            layout.separator()
-            self.weight_vg_mask(layout, ob, md)
+        # Common mask options
+        layout.separator()
+        self.vertex_weight_mask(layout, ob, md)
 
 if __name__ == "__main__":  # only for live edit.
     bpy.utils.register_module(__name__)
index 657c0fe652a43784a6a470c49c36fc3656c66958..a1b86b51f5ff2a1942b569feff12c1010e98b102 100644 (file)
@@ -81,7 +81,7 @@ class DATA_PT_distance(DataButtonsPanel, bpy.types.Panel):
         speaker = context.speaker
 
         split = layout.split()
-        
+
         col = split.column()
         col.label("Volume:")
         col.prop(speaker, "volume_min", text="Minimum")
index 161e4b10cff86ca8e186a078fb2a0bb9c39c9c21..5ea55d824718bc59bccf53fc6edeff883cc8f3d5 100644 (file)
@@ -344,7 +344,7 @@ class RENDER_PT_game_performance(RenderButtonsPanel, Panel):
         row = col.row()
         row.prop(gs, "use_frame_rate")
         row.prop(gs, "use_display_lists")
-        
+
         col.prop(gs, "restrict_animation_updates")
 
 
index 13edc3471d2034b786116f4bd2763286842b91d3..67aca5eb4c151d37d76e7e0eb4060030f8e2c37e 100644 (file)
@@ -773,7 +773,18 @@ class USERPREF_MT_ndof_settings(Menu):
 
             layout.separator()
             layout.label(text="orbit options")
-            layout.prop(input_prefs, "ndof_orbit_invert_axes")
+            if input_prefs.view_rotate_method == 'TRACKBALL':
+                layout.prop(input_prefs, "ndof_roll_invert_axis")
+                layout.prop(input_prefs, "ndof_tilt_invert_axis")
+                layout.prop(input_prefs, "ndof_rotate_invert_axis")
+            else:
+                layout.prop(input_prefs, "ndof_orbit_invert_axes")
+
+            layout.separator()
+            layout.label(text="pan options")
+            layout.prop(input_prefs, "ndof_panx_invert_axis")
+            layout.prop(input_prefs, "ndof_pany_invert_axis")
+            layout.prop(input_prefs, "ndof_panz_invert_axis")
 
             layout.separator()
             layout.label(text="fly options")
index c7b3a28ecfdc9c7603332b8eee2110825737b366..58fc56d2c731be9d603a6b2d85abacfb5b56b2f6 100644 (file)
@@ -398,6 +398,11 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
                sock->stack_index= 0;
                
                sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL);
+               
+               /* XXX some compositor node (e.g. image, render layers) still store
+                * some persistent buffer data here, need to clear this to avoid dangling pointers.
+                */
+               sock->cache = NULL;
        }
        
        BLI_duplicatelist(&nnode->outputs, &node->outputs);
@@ -407,6 +412,11 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
                sock->stack_index= 0;
                
                sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL);
+               
+               /* XXX some compositor node (e.g. image, render layers) still store
+                * some persistent buffer data here, need to clear this to avoid dangling pointers.
+                */
+               sock->cache = NULL;
        }
        
        /* don't increase node->id users, freenode doesn't decrement either */
index de01c0003731511aa6aa9d3fa5ae768a1a33f4bd..431c67833f157eeb259afcbac676b2917c73bb1f 100644 (file)
@@ -49,7 +49,7 @@
 // XXX exporter writes wrong data for shared armatures.  A separate
 // controller should be written for each armature-mesh binding how do
 // we make controller ids then?
-ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw) : COLLADASW::LibraryControllers(sw) {}
+ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryControllers(sw), export_settings(export_settings) {}
 
 // write bone nodes
 void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce)
@@ -90,14 +90,14 @@ void ArmatureExporter::add_instance_controller(Object *ob)
        ins.add();
 }
 
-void ArmatureExporter::export_controllers(Scene *sce, bool export_selected)
+void ArmatureExporter::export_controllers(Scene *sce)
 {
        scene = sce;
 
        openLibrary();
 
        GeometryFunctor gf;
-       gf.forEachMeshObjectInScene<ArmatureExporter>(sce, *this, export_selected);
+       gf.forEachMeshObjectInScene<ArmatureExporter>(sce, *this, this->export_settings->selected);
 
        closeLibrary();
 }
index b3441c797e8e9ec5f349c58e1812a772012885c8..554a8a7cfe675036e7ea6aafef3ec1f6544aaee5 100644 (file)
 #include "TransformWriter.h"
 #include "InstanceWriter.h"
 
+#include "ExportSettings.h"
+
 // XXX exporter writes wrong data for shared armatures.  A separate
 // controller should be written for each armature-mesh binding how do
 // we make controller ids then?
 class ArmatureExporter: public COLLADASW::LibraryControllers, protected TransformWriter, protected InstanceWriter
 {
-private:
-       Scene *scene;
-
 public:
-       ArmatureExporter(COLLADASW::StreamWriter *sw);
+       ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
 
        // write bone nodes
        void add_armature_bones(Object *ob_arm, Scene *sce);
@@ -65,13 +64,14 @@ public:
 
        void add_instance_controller(Object *ob);
 
-       void export_controllers(Scene *sce, bool export_selected);
+       void export_controllers(Scene *sce);
 
        void operator()(Object *ob);
 
 private:
-
+       Scene *scene;
        UnitConverter converter;
+       const ExportSettings *export_settings;
 
 #if 0
        std::vector<Object*> written_armatures;
@@ -119,25 +119,4 @@ private:
                                                                        Object *ob_arm, ListBase *defbase);
 };
 
-/*
-struct GeometryFunctor {
-       // f should have
-       // void operator()(Object* ob)
-       template<class Functor>
-       void forEachMeshObjectInScene(Scene *sce, Functor &f)
-       {
-               
-               Base *base= (Base*) sce->base.first;
-               while(base) {
-                       Object *ob = base->object;
-                       
-                       if (ob->type == OB_MESH && ob->data) {
-                               f(ob);
-                       }
-                       base= base->next;
-                       
-               }
-       }
-};*/
-
 #endif
index cc7229383e36cc495adb0401f87110d130d793c1..2ee34091fc9d5e621951b3a1e43cafc39f175679 100644 (file)
@@ -52,6 +52,7 @@ set(SRC
        DocumentImporter.cpp
        EffectExporter.cpp
        ErrorHandler.cpp
+       ExportSettings.cpp
        ExtraHandler.cpp
        ExtraTags.cpp
        GeometryExporter.cpp
@@ -77,6 +78,7 @@ set(SRC
        DocumentImporter.h
        EffectExporter.h
        ErrorHandler.h
+       ExportSettings.h
        ExtraHandler.h
        ExtraTags.h
        GeometryExporter.h
index 8de7fb440f3dd719c01fe9e22fa1d787f208419d..520650bc82efc4903bdf684763f1b4c19f6122dc 100644 (file)
@@ -39,7 +39,7 @@
 
 #include "collada_internal.h"
 
-CamerasExporter::CamerasExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryCameras(sw){}
+CamerasExporter::CamerasExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings): COLLADASW::LibraryCameras(sw), export_settings(export_settings) {}
 
 template<class Functor>
 void forEachCameraObjectInScene(Scene *sce, Functor &f, bool export_selected)
@@ -56,11 +56,11 @@ void forEachCameraObjectInScene(Scene *sce, Functor &f, bool export_selected)
        }
 }
 
-void CamerasExporter::exportCameras(Scene *sce, bool export_selected)
+void CamerasExporter::exportCameras(Scene *sce)
 {
        openLibrary();
        
-       forEachCameraObjectInScene(sce, *this, export_selected);
+       forEachCameraObjectInScene(sce, *this, this->export_settings->selected);
        
        closeLibrary();
 }
index 999a6ddd3e5aab2593e64e5a34a43ae49f708fe0..8d08fe23f8009f1adffed65cbe3259aa0a9bc39d 100644 (file)
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
+#include "ExportSettings.h"
+
 class CamerasExporter: COLLADASW::LibraryCameras
 {
 public:
-       CamerasExporter(COLLADASW::StreamWriter *sw);
-       void exportCameras(Scene *sce, bool export_selected);
+       CamerasExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
+       void exportCameras(Scene *sce);
        void operator()(Object *ob, Scene *sce);
+private:
+       const ExportSettings *export_settings;
 };
 
 #endif
index 85f37d29f22ef5de1d9d3c3a25ea2d98ff9d4ac6..d562e51b9226e1f72b4b35cd5f68a0798219c66f 100644 (file)
@@ -110,6 +110,7 @@ extern char build_rev[];
 
 #include "collada_internal.h"
 #include "DocumentExporter.h"
+#include "ExportSettings.h"
 
 // can probably go after refactor is complete
 #include "InstanceWriter.h"
@@ -145,11 +146,13 @@ char *bc_CustomData_get_active_layer_name(const CustomData *data, int type)
        return data->layers[layer_index].name;
 }
 
+DocumentExporter::DocumentExporter(const ExportSettings *export_settings) : export_settings(export_settings) {}
+
 // TODO: it would be better to instantiate animations rather than create a new one per object
 // COLLADA allows this through multiple <channel>s in <animation>.
 // For this to work, we need to know objects that use a certain action.
 
-void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename, bool selected)
+void DocumentExporter::exportCurrentScene(Scene *sce)
 {
        PointerRNA sceneptr, unit_settings;
        PropertyRNA *system; /* unused , *scale; */
@@ -157,7 +160,7 @@ void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename, bool
        clear_global_id_map();
        
        COLLADABU::NativeString native_filename =
-               COLLADABU::NativeString(std::string(filename));
+               COLLADABU::NativeString(std::string(this->export_settings->filepath));
        COLLADASW::StreamWriter sw(native_filename);
 
        // open <collada>
@@ -227,32 +230,32 @@ void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename, bool
        
        // <library_cameras>
        if(has_object_type(sce, OB_CAMERA)) {
-               CamerasExporter ce(&sw);
-               ce.exportCameras(sce, selected);
+               CamerasExporter ce(&sw, this->export_settings);
+               ce.exportCameras(sce);
        }
        
        // <library_lights>
        if(has_object_type(sce, OB_LAMP)) {
-               LightsExporter le(&sw);
-               le.exportLights(sce, selected);
+               LightsExporter le(&sw, this->export_settings);
+               le.exportLights(sce);
        }
 
        // <library_images>
-       ImagesExporter ie(&sw, filename);
-       ie.exportImages(sce, selected);
+       ImagesExporter ie(&sw, this->export_settings);
+       ie.exportImages(sce);
        
        // <library_effects>
-       EffectsExporter ee(&sw);
-       ee.exportEffects(sce, selected);
+       EffectsExporter ee(&sw, this->export_settings);
+       ee.exportEffects(sce);
        
        // <library_materials>
-       MaterialsExporter me(&sw);
-       me.exportMaterials(sce, selected);
+       MaterialsExporter me(&sw, this->export_settings);
+       me.exportMaterials(sce);
 
        // <library_geometries>
        if(has_object_type(sce, OB_MESH)) {
-               GeometryExporter ge(&sw);
-               ge.exportGeom(sce, selected);
+               GeometryExporter ge(&sw, this->export_settings);
+               ge.exportGeom(sce);
        }
 
        // <library_animations>
@@ -260,14 +263,14 @@ void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename, bool
        ae.exportAnimations(sce);
 
        // <library_controllers>
-       ArmatureExporter arm_exporter(&sw);
+       ArmatureExporter arm_exporter(&sw, this->export_settings);
        if(has_object_type(sce, OB_ARMATURE)) {
-               arm_exporter.export_controllers(sce, selected);
+               arm_exporter.export_controllers(sce);
        }
 
        // <library_visual_scenes>
-       SceneExporter se(&sw, &arm_exporter);
-       se.exportScene(sce, selected);
+       SceneExporter se(&sw, &arm_exporter, this->export_settings);
+       se.exportScene(sce);
        
        // <scene>
        std::string scene_name(translate_id(id_name(sce)));
index 923313c4ed9c841edb93d9770a24a9466bd0de6e..83724505efa71d0c7af98f4858ce57f5f8edea9a 100644 (file)
 #ifndef __DOCUMENTEXPORTER_H__
 #define __DOCUMENTEXPORTER_H__
 
+#include "ExportSettings.h"
+
 struct Scene;
 
 class DocumentExporter
 {
  public:
-       void exportCurrentScene(Scene *sce, const char* filename, bool selected);
+       DocumentExporter(const ExportSettings *export_settings);
+       void exportCurrentScene(Scene *sce);
        void exportScenes(const char* filename);
+private:
+       const ExportSettings *export_settings;
 };
 
 #endif
index 355e384d0004a78fd0c892ba0317556be84a6c93..ed37dada195a6d2a870b5ef87e271de71783743f 100644 (file)
@@ -55,7 +55,7 @@ static std::string getActiveUVLayerName(Object *ob)
        return "";
 }
 
-EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw) : COLLADASW::LibraryEffects(sw){}
+EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryEffects(sw), export_settings(export_settings) {}
 
 bool EffectsExporter::hasEffects(Scene *sce)
 {
@@ -78,12 +78,12 @@ bool EffectsExporter::hasEffects(Scene *sce)
        return false;
 }
 
-void EffectsExporter::exportEffects(Scene *sce, bool export_selected)
+void EffectsExporter::exportEffects(Scene *sce)
 {
        if(hasEffects(sce)) {
                openLibrary();
                MaterialFunctor mf;
-               mf.forEachMaterialInScene<EffectsExporter>(sce, *this, export_selected);
+               mf.forEachMaterialInScene<EffectsExporter>(sce, *this, this->export_settings->selected);
 
                closeLibrary();
        }
index 86143ae4d07759dc2361ebe8452c43dc318c6de2..dc1f4c4474b054c30f20b085cf7a2a4a4146384b 100644 (file)
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
+#include "ExportSettings.h"
+
 class EffectsExporter: COLLADASW::LibraryEffects
 {
 public:
-       EffectsExporter(COLLADASW::StreamWriter *sw);
-       void exportEffects(Scene *sce, bool export_selected);
+       EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
+       void exportEffects(Scene *sce);
 
        void operator()(Material *ma, Object *ob);
        
@@ -66,6 +68,8 @@ private:
        void writePhong(COLLADASW::EffectProfile &ep, Material *ma);
        
        bool hasEffects(Scene *sce);
+       
+       const ExportSettings *export_settings;
 };
 
 #endif
diff --git a/source/blender/collada/ExportSettings.cpp b/source/blender/collada/ExportSettings.cpp
new file mode 100644 (file)
index 0000000..19f1c05
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/collada/ExportSettings.cpp
+ *  \ingroup collada
+ */
+
+#include "ExportSettings.h"
diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h
new file mode 100644 (file)
index 0000000..2636ca8
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file ExportSettings.h
+ *  \ingroup collada
+ */
+
+#ifndef __EXPORTSETTINGS_H__
+#define __EXPORTSETTINGS_H__
+
+struct ExportSettings
+{
+ public:
+ bool selected;
+ char *filepath;
+};
+
+#endif
index b724844b1ec6f4536c50e9396fc994d811cc82c8..4da0a4c6e1fc7b8a672798efa181a5f2c56ae54c 100644 (file)
 #include "collada_internal.h"
 
 // TODO: optimize UV sets by making indexed list with duplicates removed
-GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw) : COLLADASW::LibraryGeometries(sw) {}
+GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings) {}
 
 
-void GeometryExporter::exportGeom(Scene *sce, bool export_selected)
+void GeometryExporter::exportGeom(Scene *sce)
 {
        openLibrary();
 
        mScene = sce;
        GeometryFunctor gf;
-       gf.forEachMeshObjectInScene<GeometryExporter>(sce, *this, export_selected);
+       gf.forEachMeshObjectInScene<GeometryExporter>(sce, *this, this->export_settings->selected);
 
        closeLibrary();
 }
index d9d265a66fceb705186c801b20567d1db0c393ad..64c51b6324ee85296e0be635ff2472a6fc1e640d 100644 (file)
@@ -42,6 +42,8 @@
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
+#include "ExportSettings.h"
+
 // TODO: optimize UV sets by making indexed list with duplicates removed
 class GeometryExporter : COLLADASW::LibraryGeometries
 {
@@ -58,9 +60,9 @@ class GeometryExporter : COLLADASW::LibraryGeometries
        Scene *mScene;
 
 public:
-       GeometryExporter(COLLADASW::StreamWriter *sw);
+       GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
 
-       void exportGeom(Scene *sce, bool export_selected);
+       void exportGeom(Scene *sce);
 
        void operator()(Object *ob);
 
@@ -96,6 +98,8 @@ public:
        /* int getTriCount(MFace *faces, int totface);*/
 private:
        std::set<std::string> exportedGeometry;
+       
+       const ExportSettings *export_settings;
 };
 
 struct GeometryFunctor {
index 8e426e9dba86cfaf9efc6c35e23fe5112ad63f35..747f3c783d70bd09d0e321379b1a95a64338cfd9 100644 (file)
@@ -43,7 +43,7 @@
 #include "BLI_path_util.h"
 #include "BLI_string.h"
 
-ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, const char* filename) : COLLADASW::LibraryImages(sw), mfilename(filename)
+ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryImages(sw), export_settings(export_settings)
 {}
 
 bool ImagesExporter::hasImages(Scene *sce)
@@ -71,12 +71,12 @@ bool ImagesExporter::hasImages(Scene *sce)
        return false;
 }
 
-void ImagesExporter::exportImages(Scene *sce, bool export_selected)
+void ImagesExporter::exportImages(Scene *sce)
 {
        if(hasImages(sce)) {
                openLibrary();
                MaterialFunctor mf;
-               mf.forEachMaterialInScene<ImagesExporter>(sce, *this, export_selected);
+               mf.forEachMaterialInScene<ImagesExporter>(sce, *this, this->export_settings->selected);
 
                closeLibrary();
        }
@@ -97,7 +97,7 @@ void ImagesExporter::operator()(Material *ma, Object *ob)
                        char src[FILE_MAX];
                        char dir[FILE_MAX];
                        
-                       BLI_split_dirfile(mfilename, dir, NULL);
+                       BLI_split_dirfile(this->export_settings->filepath, dir, NULL);
 
                        BKE_rebase_path(abs, sizeof(abs), rel, sizeof(rel), G.main->name, image->name, dir);
 
index 6b81c099259bc9ecba588d5b6746da670d74246a..9e5767fd9d383ea3d083f3d19444d805099deb95 100644 (file)
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
+#include "ExportSettings.h"
+
 class ImagesExporter: COLLADASW::LibraryImages
 {
-       const char *mfilename;
-       std::vector<std::string> mImages; // contains list of written images, to avoid duplicates
 public:
-       ImagesExporter(COLLADASW::StreamWriter *sw, const char* filename);
+       ImagesExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
        
-       void exportImages(Scene *sce, bool export_selected);
+       void exportImages(Scene *sce);
        void operator()(Material *ma, Object *ob);
 private:
+       std::vector<std::string> mImages; // contains list of written images, to avoid duplicates
        bool hasImages(Scene *sce);
+       const ExportSettings *export_settings;
 };
 
 #endif
index 31ade5604a703ef459c22f74d44925c1ddb6a63f..3d5814cb6dbb12c203feb2b5f1028a5c47443e9d 100644 (file)
@@ -52,13 +52,13 @@ void forEachLampObjectInScene(Scene *sce, Functor &f, bool export_selected)
        }
 }
 
-LightsExporter::LightsExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryLights(sw){}
+LightsExporter::LightsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings): COLLADASW::LibraryLights(sw), export_settings(export_settings) {}
 
-void LightsExporter::exportLights(Scene *sce, bool export_selected)
+void LightsExporter::exportLights(Scene *sce)
 {
        openLibrary();
        
-       forEachLampObjectInScene(sce, *this, export_selected);
+       forEachLampObjectInScene(sce, *this, this->export_settings->selected);
        
        closeLibrary();
 }
index 2ae1a19fdb183e7e639d86225a68483749bb32d7..6c52ed2b76d00fba43d64b06df7a73c81bb8f2c6 100644 (file)
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
+#include "ExportSettings.h"
+
 class LightsExporter: COLLADASW::LibraryLights
 {
 public:
-       LightsExporter(COLLADASW::StreamWriter *sw);
-       void exportLights(Scene *sce, bool export_selected);
+       LightsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
+       void exportLights(Scene *sce);
        void operator()(Object *ob);
 private:
        bool exportBlenderProfile(COLLADASW::Light &cla, Lamp *la);
+       const ExportSettings *export_settings;
 };
 
 #endif
index 9d29177578dbedc9290aa9a598ee807426807a30..37c1a6f6b68ef043a03585f86aeb977eb747ee03 100644 (file)
 #include "COLLADABUUtils.h"
 #include "collada_internal.h"
 
-MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryMaterials(sw){}
+MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings): COLLADASW::LibraryMaterials(sw), export_settings(export_settings) {}
 
-void MaterialsExporter::exportMaterials(Scene *sce, bool export_selected)
+void MaterialsExporter::exportMaterials(Scene *sce)
 {
        if(hasMaterials(sce)) {
                openLibrary();
 
                MaterialFunctor mf;
-               mf.forEachMaterialInScene<MaterialsExporter>(sce, *this, export_selected);
+               mf.forEachMaterialInScene<MaterialsExporter>(sce, *this, this->export_settings->selected);
 
                closeLibrary();
        }
index c080e4b05965fed78c68eb5b44a30053ec020bba..97a1e27358f38c660c81653ccbc4e087d0342062 100644 (file)
 
 #include "GeometryExporter.h"
 #include "collada_internal.h"
+#include "ExportSettings.h"
 
 class MaterialsExporter: COLLADASW::LibraryMaterials
 {
 public:
-       MaterialsExporter(COLLADASW::StreamWriter *sw);
-       void exportMaterials(Scene *sce, bool export_selected);
+       MaterialsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
+       void exportMaterials(Scene *sce);
        void operator()(Material *ma, Object *ob);
 
 private:
        bool hasMaterials(Scene *sce);
+       const ExportSettings *export_settings;
 };
 
 // used in forEachMaterialInScene
index 96f20ac21c3a8dbc40f6e09f9af60e81a0ccea72..5109df0bb6a4989ffca69246549212a7f144a06f 100644 (file)
 
 #include "SceneExporter.h"
 
-SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm)
-       : COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm)
+SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings)
+       : COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm), export_settings(export_settings)
 {}
        
-void SceneExporter::exportScene(Scene *sce, bool export_selected)
+void SceneExporter::exportScene(Scene *sce)
 {
        // <library_visual_scenes> <visual_scene>
        std::string id_naming = id_name(sce);
        openVisualScene(translate_id(id_naming), id_naming);
-       exportHierarchy(sce, export_selected);
+       exportHierarchy(sce);
        closeVisualScene();
        closeLibrary();
 }
 
-void SceneExporter::exportHierarchy(Scene *sce, bool export_selected)
+void SceneExporter::exportHierarchy(Scene *sce)
 {
        Base *base= (Base*) sce->base.first;
        while(base) {
@@ -56,7 +56,7 @@ void SceneExporter::exportHierarchy(Scene *sce, bool export_selected)
                                        case OB_LAMP:
                                        case OB_ARMATURE:
                                        case OB_EMPTY:
-                                               if (export_selected && !(ob->flag & SELECT)) {
+                                               if (this->export_settings->selected && !(ob->flag & SELECT)) {
                                                        break;
                                                }
                                                // write nodes....
index 65dbd616b204a7af7b8252141a1458a2d2993926..919cba61ec049d309600ddb08e006f0529489927 100644 (file)
@@ -90,16 +90,20 @@ extern "C" {
 
 #include "ArmatureExporter.h"
 
+#include "ExportSettings.h"
+
 class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter, protected InstanceWriter
 {
-       ArmatureExporter *arm_exporter;
 public:
-       SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm);
-       void exportScene(Scene *sce, bool export_selected);
+       SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings);
+       void exportScene(Scene *sce);
 
 private:
-       void exportHierarchy(Scene *sce, bool export_selected);
+       void exportHierarchy(Scene *sce);
        void writeNodes(Object *ob, Scene *sce);
+       
+       ArmatureExporter *arm_exporter;
+       const ExportSettings *export_settings;
 };
 
 #endif
index 4caca20531f9073f2af4c481bbcdbe77a5476eb4..8059b1cf3ffa126084d48dff83ad7413fc2f58d8 100644 (file)
@@ -30,6 +30,7 @@
 /* COLLADABU_ASSERT, may be able to remove later */
 #include "COLLADABUPlatform.h"
 
+#include "ExportSettings.h"
 #include "DocumentExporter.h"
 #include "DocumentImporter.h"
 
@@ -53,7 +54,10 @@ extern "C"
 
        int collada_export(Scene *sce, const char *filepath, int selected)
        {
-               DocumentExporter exp;
+               ExportSettings export_settings;
+               
+               export_settings.selected = selected != 0;
+               export_settings.filepath = (char *)filepath;
 
                /* annoying, collada crashes if file cant be created! [#27162] */
                if(!BLI_exist(filepath)) {
@@ -64,7 +68,8 @@ extern "C"
                }
                /* end! */
 
-               exp.exportCurrentScene(sce, filepath, selected);
+               DocumentExporter exporter(&export_settings);
+               exporter.exportCurrentScene(sce);
 
                return 1;
        }
index 660dc6fbad8b4e74db28a1caad515d7527e66102..bb6d7446fdc95e667bb8a127c1dd3c3339ba29c1 100644 (file)
@@ -87,8 +87,8 @@ char datatoc_blenderbuttons[]= {
 206,209,152,209,161,151,242,151,147,191,109,124,165,253,234,192,235, 25,175,219,198,194,198, 30,190,201,120, 51, 49, 94,244, 86,
 251,237,193,119,220,119, 29,239,163,223, 15, 79,228,124, 32,127, 40,255,104,249,177,245, 83,208,167,251,147, 25,147,147,255,  4,
   3,152,243,252, 99, 51, 45,219,  0,  0,  0,  6, 98, 75, 71, 68,  0,255,  0,255,  0,255,160,189,167,147,  0,  0,  0,  9,112, 72,
- 89,115,  0,  0, 13,215,  0,  0, 13,215,  1, 66, 40,155,120,  0,  0,  0,  7,116, 73, 77, 69,  7,219,  9,  7,  8,  5, 53,  1, 61,
-125, 90,  0,  0, 32,  0, 73, 68, 65, 84,120,218,236, 93,119,120, 20,213,226, 61, 51, 59,179,187,217,146, 77, 35, 61,144, 66,  9,
+ 89,115,  0,  0, 13,215,  0,  0, 13,215,  1, 66, 40,155,120,  0,  0,  0,  7,116, 73, 77, 69,  7,219,  9,  8, 18, 45,  9, 58,221,
+153,135,  0,  0, 32,  0, 73, 68, 65, 84,120,218,236, 93,119,120, 20,213,226, 61, 51, 59,179,187,217,146, 77, 35, 61,144, 66,  9,
  96,  0, 67, 81,130, 84, 65, 80,140,138, 10, 86,132,167,207,103,197,134,  5, 84, 68, 68, 32, 54, 64,240, 39,242,208,167,128,160,
 128,  5,  4,164, 68, 74,232, 29,233,  9,144,  4, 18, 66, 58,201, 38,219,203,220,223, 31,217, 89, 55,203,182, 64, 98,129,123,190,
 111,190,221,157,157, 57,115,239,157,123,239,156, 57,183,  1, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
index eb6854d254811c8d17062bafd86d0198dbc45cef..612d1b18426680f3015e88d83bc41230fb6f321f 100644 (file)
@@ -827,7 +827,7 @@ static int similar_face_select__internal(EditMesh *em, int mode, float thresh)
                                float angle;
                                for(efa= em->faces.first; efa; efa= efa->next) {
                                        if (!(efa->f & SELECT) && !efa->h) {
-                                               angle= RAD2DEGF(angle_v2v2(base_efa->n, efa->n));
+                                               angle= RAD2DEGF(angle_v3v3(base_efa->n, efa->n));
                                                if (angle/180.0f<=thresh) {
                                                        EM_select_face(efa, 1);
                                                        selcount++;
@@ -842,7 +842,7 @@ static int similar_face_select__internal(EditMesh *em, int mode, float thresh)
                                base_dot= dot_v3v3(base_efa->cent, base_efa->n);
                                for(efa= em->faces.first; efa; efa= efa->next) {
                                        if (!(efa->f & SELECT) && !efa->h) {
-                                               angle= RAD2DEGF(angle_v2v2(base_efa->n, efa->n));
+                                               angle= RAD2DEGF(angle_v3v3(base_efa->n, efa->n));
                                                if (angle/180.0f<=thresh) {
                                                        dot=dot_v3v3(efa->cent, base_efa->n);
                                                        if (fabsf(base_dot-dot) <= thresh) {
@@ -989,7 +989,7 @@ static int similar_edge_select__internal(EditMesh *em, int mode, float thresh)
                                for(eed= em->edges.first; eed; eed= eed->next) {
                                        if (!(eed->f & SELECT) && !eed->h) {
                                                sub_v3_v3v3(dir, eed->v1->co, eed->v2->co);
-                                               angle= RAD2DEGF(angle_v2v2(base_dir, dir));
+                                               angle= RAD2DEGF(angle_v3v3(base_dir, dir));
                                                
                                                if (angle>90.0f) /* use the smallest angle between the edges */
                                                        angle= fabsf(angle-180.0f);
@@ -1159,7 +1159,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
                                float angle;
                                for(eve= em->verts.first; eve; eve= eve->next) {
                                        if (!(eve->f & SELECT) && !eve->h) {
-                                               angle= RAD2DEGF(angle_v2v2(base_eve->no, eve->no));
+                                               angle= RAD2DEGF(angle_v3v3(base_eve->no, eve->no));
                                                if (angle/180.0f<=thresh) {
                                                        eve->f |= SELECT;
                                                        selcount++;
index 9ff2923f7339934c6e891ee5e2e0ede6567647b5..44e00ed8181272926671fa07d5f214df32c25c0c 100644 (file)
@@ -3234,13 +3234,13 @@ static float measure_facepair(EditVert *v1, EditVert *v2, EditVert *v3, EditVert
        normal_tri_v3( noA2,v1->co, v3->co, v4->co);
 
        if(noA1[0] == noA2[0] && noA1[1] == noA2[1] && noA1[2] == noA2[2]) normalADiff = 0.0;
-       else normalADiff = RAD2DEGF(angle_v2v2(noA1, noA2));
+       else normalADiff = RAD2DEGF(angle_v3v3(noA1, noA2));
                //if(!normalADiff) normalADiff = 179;
        normal_tri_v3( noB1,v2->co, v3->co, v4->co);
        normal_tri_v3( noB2,v4->co, v1->co, v2->co);
 
        if(noB1[0] == noB2[0] && noB1[1] == noB2[1] && noB1[2] == noB2[2]) normalBDiff = 0.0;
-       else normalBDiff = RAD2DEGF(angle_v2v2(noB1, noB2));
+       else normalBDiff = RAD2DEGF(angle_v3v3(noB1, noB2));
                //if(!normalBDiff) normalBDiff = 179;
 
        measure += (normalADiff/360) + (normalBDiff/360);
@@ -3255,10 +3255,10 @@ static float measure_facepair(EditVert *v1, EditVert *v2, EditVert *v3, EditVert
        diff = 0.0;
 
        diff = (
-               fabsf(RAD2DEGF(angle_v2v2(edgeVec1, edgeVec2)) - 90) +
-               fabsf(RAD2DEGF(angle_v2v2(edgeVec2, edgeVec3)) - 90) +
-               fabsf(RAD2DEGF(angle_v2v2(edgeVec3, edgeVec4)) - 90) +
-               fabsf(RAD2DEGF(angle_v2v2(edgeVec4, edgeVec1)) - 90)) / 360;
+               fabsf(RAD2DEGF(angle_v3v3(edgeVec1, edgeVec2)) - 90) +
+               fabsf(RAD2DEGF(angle_v3v3(edgeVec2, edgeVec3)) - 90) +
+               fabsf(RAD2DEGF(angle_v3v3(edgeVec3, edgeVec4)) - 90) +
+               fabsf(RAD2DEGF(angle_v3v3(edgeVec4, edgeVec1)) - 90)) / 360;
        if(!diff) return 0.0;
 
        measure +=  diff;
@@ -4869,7 +4869,7 @@ void mesh_set_face_flags(EditMesh *em, short mode)
 /* helper to find edge for edge_rip */
 static float mesh_rip_edgedist(ARegion *ar, float mat[][4], float *co1, float *co2, const int mval[2])
 {
-       float vec1[3], vec2[3], mvalf[2];
+       float vec1[2], vec2[2], mvalf[2];
 
        ED_view3d_project_float(ar, co1, vec1, mat);
        ED_view3d_project_float(ar, co2, vec2, mat);
index 7b9e1a2dc2f60b26e07bc4ac8f86e96d39a41663..8cbed31bacc6aab807685e489694897d0fee6fc2 100644 (file)
@@ -639,7 +639,7 @@ static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *nt
        float colw= 0.6f*node_group_frame;
        float col1= 6 - node_group_frame;
        float col2= col1 + colw+6;
-       float col3= node_group_frame - arrowbutw - 6;
+       float col3= - arrowbutw - 6;
        /* layout stuff for buttons on group right frame */
        float cor1= 6;
        float cor2= cor1 + arrowbutw + 6;
@@ -660,6 +660,7 @@ static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *nt
         * 1) input: not internal
         * 2) output: (node type uses const outputs) and (group output is unlinked)
         */
+       draw_value = 0;
        switch (in_out) {
        case SOCK_IN:
                draw_value = !(gsock && (gsock->flag & SOCK_INTERNAL));
@@ -667,8 +668,6 @@ static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *nt
        case SOCK_OUT:
                if (gnode->typeinfo->flag & NODE_CONST_OUTPUT)
                        draw_value = !(gsock && gsock->link);
-               else
-                       draw_value = 0;
                break;
        }
        if (draw_value) {
@@ -713,7 +712,7 @@ static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *nt
                uiBlockSetDirection(gnode->block, 0);
                
                /* remove button */
-               offset = (in_out==SOCK_IN ? col3 : col1);
+               offset = (in_out==SOCK_IN ? col3 : cor1);
                uiBlockSetEmboss(gnode->block, UI_EMBOSSN);
                bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_remove", 0, ICON_X,
                                                   gsock->locx+offset, gsock->locy-0.5f*arrowbutw, arrowbutw, arrowbutw, "");
index 6be8978cb5b7cb45226f2923dfb23facf8e6d2f2..ba1e8d3dd592191235c455bae04f1c371d8fb1c5 100644 (file)
@@ -220,7 +220,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
        PointerRNA ptr;
        bNodeSocket *nsock;
        float locx, locy;
-       float dy= locy;
+       float dy;
        int buty;
        
        /* get "global" coords */
index b5633d509979f2764defcc44432710b277e0cac9..5f58f540aae229574acf7923c66612d60b13c744 100644 (file)
@@ -447,9 +447,8 @@ void snode_set_context(SpaceNode *snode, Scene *scene)
        else if(snode->treetype==NTREE_COMPOSIT) {
                snode->id= &scene->id;
                
-               /* bit clumsy but reliable way to see if we draw first time */
-               if(snode->nodetree==NULL)
-                       ntreeCompositForceHidden(scene->nodetree, scene);
+               /* update output sockets based on available layers */
+               ntreeCompositForceHidden(scene->nodetree, scene);
        }
        else if(snode->treetype==NTREE_TEXTURE) {
                Tex *tx= NULL;
@@ -608,28 +607,45 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
 static int compare_nodes(bNode *a, bNode *b)
 {
        bNode *parent;
+       /* These tell if either the node or any of the parent nodes is selected.
+        * A selected parent means an unselected node is also in foreground!
+        */
+       int a_select=(a->flag & NODE_SELECT), b_select=(b->flag & NODE_SELECT);
+       int a_active=(a->flag & NODE_ACTIVE), b_active=(b->flag & NODE_ACTIVE);
        
        /* if one is an ancestor of the other */
        /* XXX there might be a better sorting algorithm for stable topological sort, this is O(n^2) worst case */
        for (parent = a->parent; parent; parent=parent->parent) {
+               /* if b is an ancestor, it is always behind a */
                if (parent==b)
                        return 1;
+               /* any selected ancestor moves the node forward */
+               if (parent->flag & NODE_ACTIVE)
+                       a_active = 1;
+               if (parent->flag & NODE_SELECT)
+                       a_select = 1;
        }
        for (parent = b->parent; parent; parent=parent->parent) {
+               /* if a is an ancestor, it is always behind b */
                if (parent==a)
                        return 0;
+               /* any selected ancestor moves the node forward */
+               if (parent->flag & NODE_ACTIVE)
+                       b_active = 1;
+               if (parent->flag & NODE_SELECT)
+                       b_select = 1;
        }
 
        /* if one of the nodes is in the background and the other not */
-       if ((a->flag & NODE_BACKGROUND) && !(b->typeinfo->flag & NODE_BACKGROUND))
+       if ((a->flag & NODE_BACKGROUND) && !(b->flag & NODE_BACKGROUND))
                return 0;
-       else if (!(a->flag & NODE_BACKGROUND) && (b->typeinfo->flag & NODE_BACKGROUND))
+       else if (!(a->flag & NODE_BACKGROUND) && (b->flag & NODE_BACKGROUND))
                return 1;
        
        /* if one has a higher selection state (active > selected > nothing) */
-       if (!(b->flag & NODE_ACTIVE) && (a->flag & NODE_ACTIVE))
+       if (!b_active && a_active)
                return 1;
-       else if (!(b->flag & NODE_SELECT) && ((a->flag & NODE_ACTIVE) || (a->flag & NODE_SELECT)))
+       else if (!b_select && (a_active || a_select))
                return 1;
        
        return 0;
@@ -776,7 +792,7 @@ static int edit_node_invoke_properties(bContext *C, wmOperator *op)
 static void edit_node_properties_get(wmOperator *op, bNodeTree *ntree, bNode **rnode, bNodeSocket **rsock, int *rin_out)
 {
        bNode *node;
-       bNodeSocket *sock;
+       bNodeSocket *sock=NULL;
        char nodename[32];
        int sockindex;
        int in_out;
index 19e8d42db2d6ea94c8625e81c4c970c155cc7ce7..761de836cfb6120e1a64f65aacaf856d25172f0b 100644 (file)
@@ -1017,18 +1017,26 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event
                
                        if (has_rotation) {
                
-                               const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES;
-               
                                rv3d->view = RV3D_VIEW_USER;
                
                                if (U.flag & USER_TRACKBALL) {
+                                       const int invert_roll = U.ndof_flag & NDOF_ROLL_INVERT_AXIS;
+                                       const int invert_tilt = U.ndof_flag & NDOF_TILT_INVERT_AXIS;
+                                       const int invert_rot = U.ndof_flag & NDOF_ROTATE_INVERT_AXIS;
+
                                        float rot[4];
                                        float axis[3];
                                        float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis);
-               
-                                       if (invert)
-                                               angle = -angle;
-               
+
+                                       if (invert_roll)
+                                               axis[2] = -axis[2];
+
+                                       if (invert_tilt)
+                                               axis[0] = -axis[0];
+
+                                       if (invert_rot)
+                                               axis[1] = -axis[1];
+
                                        // transform rotation axis from view to world coordinates
                                        mul_qt_v3(view_inv, axis);
                
@@ -1042,6 +1050,8 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event
                                        mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
                                } else {
                                        /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
+                                       const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES;
+
                                        float angle, rot[4];
                                        float xvec[3] = {1,0,0};
                
@@ -1143,10 +1153,26 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
                        const float vertical_sensitivity = 0.4f;
                        const float lateral_sensitivity = 0.6f;
 
-                       float pan_vec[3] = {lateral_sensitivity * ndof->tvec[0],
-                                                               vertical_sensitivity * ndof->tvec[1],
-                                                               forward_sensitivity * ndof->tvec[2]
-                                                          };
+                       const int invert_panx = U.ndof_flag & NDOF_PANX_INVERT_AXIS;
+                       const int invert_pany = U.ndof_flag & NDOF_PANY_INVERT_AXIS;
+                       const int invert_panz = U.ndof_flag & NDOF_PANZ_INVERT_AXIS;
+
+                       float pan_vec[3];
+
+                       if (invert_panx)
+                               pan_vec[0] = -lateral_sensitivity * ndof->tvec[0];
+                       else
+                               pan_vec[0] = lateral_sensitivity * ndof->tvec[0];
+
+                       if (invert_panz)
+                               pan_vec[1] = -vertical_sensitivity * ndof->tvec[1];
+                       else
+                               pan_vec[1] = vertical_sensitivity * ndof->tvec[1];
+
+                       if (invert_pany)
+                               pan_vec[2] = -forward_sensitivity * ndof->tvec[2];
+                       else
+                               pan_vec[2] = forward_sensitivity * ndof->tvec[2];
 
                        mul_v3_fl(pan_vec, speed * dt);
 #endif
index 1ced05e054ca8e78c3dd1a4c071a1f4569247dd5..369df3870701145e4183af8ea3608928ef6aba5d 100644 (file)
@@ -613,6 +613,12 @@ extern UserDef U; /* from blenkernel blender.c */
 /* zoom is up/down if this flag is set (otherwise forward/backward) */
 #define NDOF_ZOOM_UPDOWN (1 << 7)
 #define NDOF_ZOOM_INVERT (1 << 8)
+#define NDOF_ROTATE_INVERT_AXIS (1 << 9)
+#define NDOF_TILT_INVERT_AXIS (1 << 10)
+#define NDOF_ROLL_INVERT_AXIS (1 << 11)
+#define NDOF_PANX_INVERT_AXIS (1 << 12)
+#define NDOF_PANY_INVERT_AXIS (1 << 13)
+#define NDOF_PANZ_INVERT_AXIS (1 << 14)
 
 
 #ifdef __cplusplus
index 2e8e8520dbf012b1206e1dc1ee0a1ed5de6f3b2b..07967103a403bd5c6a0a9908b69921bd437a38b8 100644 (file)
@@ -68,6 +68,7 @@ EnumPropertyItem modifier_type_items[] ={
        {eModifierType_Screw, "SCREW", ICON_MOD_SCREW, "Screw", ""},
        {eModifierType_Solidify, "SOLIDIFY", ICON_MOD_SOLIDIFY, "Solidify", ""},
        {eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subdivision Surface", ""},
+       {0, "", 0, "Modify", ""},
        {eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""},
        {eModifierType_WeightVGEdit, "VERTEX_WEIGHT_EDIT", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Edit", ""},
        {eModifierType_WeightVGMix, "VERTEX_WEIGHT_MIX", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Mix", ""},
@@ -2510,7 +2511,7 @@ static void rna_def_modifier_weightvg_mask(BlenderRNA *brna, StructRNA *srna)
 
        prop= RNA_def_property(srna, "mask_constant", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
-       RNA_def_property_ui_range(prop, -1.0, 1.0, 10, 0);
+       RNA_def_property_ui_range(prop, 0.0, 1.0, 10, 0);
        RNA_def_property_ui_text(prop, "Influence", "Global influence of current modifications on vgroup.");
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
 
@@ -2707,9 +2708,9 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
                {0, NULL, 0, NULL, NULL}};
 
        static EnumPropertyItem proximity_geometry_items[] = {
-               {MOD_WVG_PROXIMITY_GEOM_VERTS, "VERTEX", ICON_VERTEXSEL, "Vertex", ""},
-               {MOD_WVG_PROXIMITY_GEOM_EDGES, "EDGE", ICON_EDGESEL, "Edge", ""},
-               {MOD_WVG_PROXIMITY_GEOM_FACES, "FACE", ICON_FACESEL, "Face", ""},
+               {MOD_WVG_PROXIMITY_GEOM_VERTS, "VERTEX", ICON_VERTEXSEL, "Vertex", "Compute distance to nearest vertex."},
+               {MOD_WVG_PROXIMITY_GEOM_EDGES, "EDGE", ICON_EDGESEL, "Edge", "Compute distance to nearest edge."},
+               {MOD_WVG_PROXIMITY_GEOM_FACES, "FACE", ICON_FACESEL, "Face", "Compute distance to nearest face."},
                {0, NULL, 0, NULL, NULL}};
 
        static EnumPropertyItem weightvg_proximity_falloff_type_items[] = {
@@ -2748,7 +2749,9 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
        RNA_def_property_enum_sdna(prop, NULL, "proximity_flags");
        RNA_def_property_enum_items(prop, proximity_geometry_items);
        RNA_def_property_flag(prop, PROP_ENUM_FLAG); /* important to run before default set */
-       RNA_def_property_ui_text(prop, "Proximity Geometry", "Use shortest distance to target object's geometry as weight");
+       RNA_def_property_ui_text(prop, "Proximity Geometry",
+                                "Use the shortest computed distance to target object's geometry "
+                                "as weight.");
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
 
        prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
@@ -2760,13 +2763,13 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
        prop= RNA_def_property(srna, "min_dist", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, 0.0, FLT_MAX);
        RNA_def_property_ui_range(prop, 0.0, 1000.0, 10, 0);
-       RNA_def_property_ui_text(prop, "Lowest Dist", "Distance mapping to weight 0.0.");
+       RNA_def_property_ui_text(prop, "Lowest Dist", "Distance mapping to weight 0.0 (or weight 1.0 if above Highest Dist).");
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
 
        prop= RNA_def_property(srna, "max_dist", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, 0.0, FLT_MAX);
        RNA_def_property_ui_range(prop, 0.0, 1000.0, 10, 0);
-       RNA_def_property_ui_text(prop, "Highest Dist", "Distance mapping to weight 1.0.");
+       RNA_def_property_ui_text(prop, "Highest Dist", "Distance mapping to weight 1.0 (or weight 0.0 if below Lowest Dist).");
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
 
        prop= RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE);
index a861c5b8e214e8a2756d2fe3ec189c5d5d00cabf..81271515986240dbde897918f8dc16af0f8bf6a5 100644 (file)
@@ -2042,6 +2042,7 @@ static void rna_def_userdef_solidlight(BlenderRNA *brna)
 {
        StructRNA *srna;
        PropertyRNA *prop;
+       static float default_dir[3] = {0.f, 1.f, 0.f};
 
        srna= RNA_def_struct(brna, "UserSolidLight", NULL);
        RNA_def_struct_sdna(srna, "SolidLight");
@@ -2055,6 +2056,7 @@ static void rna_def_userdef_solidlight(BlenderRNA *brna)
        prop= RNA_def_property(srna, "direction", PROP_FLOAT, PROP_DIRECTION);
        RNA_def_property_float_sdna(prop, NULL, "vec");
        RNA_def_property_array(prop, 3);
+       RNA_def_property_float_array_default(prop, default_dir);
        RNA_def_property_ui_text(prop, "Direction", "The direction that the OpenGL light is shining");
        RNA_def_property_update(prop, 0, "rna_UserDef_viewport_lights_update");
 
@@ -2874,6 +2876,36 @@ static void rna_def_userdef_input(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Invert Axes", "Toggle between moving the viewpoint or moving the scene being viewed");
        /* in 3Dx docs, this is called 'object mode' vs. 'target camera mode' */
 
+       /* 3D view: roll */
+       prop= RNA_def_property(srna, "ndof_roll_invert_axis", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROLL_INVERT_AXIS);
+       RNA_def_property_ui_text(prop, "Invert roll Axis", "Invert roll axis");
+
+       /* 3D view: tilt */
+       prop= RNA_def_property(srna, "ndof_tilt_invert_axis", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_TILT_INVERT_AXIS);
+       RNA_def_property_ui_text(prop, "Invert tilt Axis", "Invert tilt axis");
+
+       /* 3D view: rotate */
+       prop= RNA_def_property(srna, "ndof_rotate_invert_axis", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ROTATE_INVERT_AXIS);
+       RNA_def_property_ui_text(prop, "Invert rotation Axis", "Invert rotation axis");
+
+       /* 3D view: pan x */
+       prop= RNA_def_property(srna, "ndof_panx_invert_axis", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_PANX_INVERT_AXIS);
+       RNA_def_property_ui_text(prop, "Invert x Axis", "Invert x axis");
+
+       /* 3D view: pan y */
+       prop= RNA_def_property(srna, "ndof_pany_invert_axis", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_PANY_INVERT_AXIS);
+       RNA_def_property_ui_text(prop, "Invert y Axis", "Invert y axis");
+
+       /* 3D view: pan z */
+       prop= RNA_def_property(srna, "ndof_panz_invert_axis", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_PANZ_INVERT_AXIS);
+       RNA_def_property_ui_text(prop, "Invert z Axis", "Invert z axis");
+
        /* 3D view: fly */
        prop= RNA_def_property(srna, "ndof_lock_horizon", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_LOCK_HORIZON);
index ffb783f8adc9f265c25611b0629ac631c31f1fc4..0dbf8a91d214ec307d47f360cd3beb81805236b1 100644 (file)
@@ -199,10 +199,24 @@ void do_map(float *weights, const int nidx, const float min_d, const float max_d
 {
        const float range_inv= 1.0f / (max_d - min_d); /* invert since multiplication is faster */
        unsigned int i= nidx;
-       while (i-- > 0) {
-               if     (weights[i] >= max_d) weights[i]= 1.0f; /* most likely case first */
-               else if(weights[i] <= min_d) weights[i]= 0.0f;
-               else                         weights[i]= (weights[i] - min_d) * range_inv;
+       if(max_d == min_d) {
+               while (i-- > 0) {
+                       weights[i] = (weights[i] >= max_d) ? 1.0f : 0.0f; /* "Step" behavior... */
+               }
+       }
+       else if(max_d > min_d) {
+               while (i-- > 0) {
+                       if     (weights[i] >= max_d) weights[i]= 1.0f; /* most likely case first */
+                       else if(weights[i] <= min_d) weights[i]= 0.0f;
+                       else                         weights[i]= (weights[i] - min_d) * range_inv;
+               }
+       }
+       else {
+               while (i-- > 0) {
+                       if     (weights[i] <= max_d) weights[i]= 1.0f; /* most likely case first */
+                       else if(weights[i] >= min_d) weights[i]= 0.0f;
+                       else                         weights[i]= (weights[i] - min_d) * range_inv;
+               }
        }
 
        if(!ELEM(mode, MOD_WVG_MAPPING_NONE, MOD_WVG_MAPPING_CURVE)) {
@@ -481,6 +495,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
                                        new_w[i] = dists_e ? minf(dists_e[i], new_w[i]) : new_w[i];
                                        new_w[i] = dists_f ? minf(dists_f[i], new_w[i]) : new_w[i];
                                }
+                               if(dists_v) MEM_freeN(dists_v);
+                               if(dists_e) MEM_freeN(dists_e);
+                               if(dists_f) MEM_freeN(dists_f);
                        }
                        /* Else, fall back to default obj2vert behavior. */
                        else {
@@ -492,14 +509,14 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
                }
        }
 
+       /* Map distances to weights. */
+       do_map(new_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type);
+
        /* Do masking. */
        weightvg_do_mask(numIdx, indices, org_w, new_w, ob, ret, wmd->mask_constant,
                         wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel,
                         wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);
 
-       /* Map distances to weights. */
-       do_map(org_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type);
-
        /* Update vgroup. Note we never add nor remove vertices from vgroup here. */
        weightvg_update_vg(dvert, defgrp_idx, numIdx, indices, org_w, 0, 0.0f, 0, 0.0f);
 
index 3206fbad56768735e3e5de8b2870b608014e8518..3ee0eebe8e92c1e54a79227d2ad5d32e45359434 100644 (file)
@@ -341,15 +341,15 @@ static void *exec_composite_node(void *nodeexec_v)
 }
 
 /* return total of executable nodes, for timecursor */
-static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
+static int setExecutableNodes(bNodeTreeExec *exec, ThreadData *thd)
 {
+       bNodeTree *ntree = exec->nodetree;
        bNodeStack *nsin[MAX_SOCKET];   /* arbitrary... watch this */
        bNodeStack *nsout[MAX_SOCKET];  /* arbitrary... watch this */
+       bNodeExec *nodeexec;
        bNode *node;
        bNodeSocket *sock;
-       int totnode= 0, group_edit= 0;
-       
-       /* note; do not add a dependency sort here, the stack was created already */
+       int n, totnode= 0, group_edit= 0;
        
        /* if we are in group edit, viewer nodes get skipped when group has viewer */
        for(node= ntree->nodes.first; node; node= node->next)
@@ -357,10 +357,12 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
                        if(ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER))
                                group_edit= 1;
        
-       for(node= ntree->nodes.first; node; node= node->next) {
+       /* NB: using the exec data list here to have valid dependency sort */
+       for(n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
                int a;
+               node = nodeexec->node;
                
-               node_get_stack(node, thd->stack, nsin, nsout);
+               node_get_stack(node, exec->stack, nsin, nsout);
                
                /* test the outputs */
                /* skip value-only nodes (should be in type!) */
@@ -422,10 +424,11 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
        /* last step: set the stack values for only-value nodes */
        /* just does all now, compared to a full buffer exec this is nothing */
        if(totnode) {
-               for(node= ntree->nodes.first; node; node= node->next) {
+               for(n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
+                       node = nodeexec->node;
                        if(node->need_exec==0 && node_only_value(node)) {
                                if(node->typeinfo->execfunc) {
-                                       node_get_stack(node, thd->stack, nsin, nsout);
+                                       node_get_stack(node, exec->stack, nsin, nsout);
                                        node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
                                }
                        }
@@ -436,14 +439,17 @@ static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
 }
 
 /* while executing tree, free buffers from nodes that are not needed anymore */
-static void freeExecutableNode(bNodeTree *ntree, bNodeTreeExec *exec)
+static void freeExecutableNode(bNodeTreeExec *exec)
 {
        /* node outputs can be freed when:
        - not a render result or image node
        - when node outputs go to nodes all being set NODE_FINISHED
        */
+       bNodeTree *ntree = exec->nodetree;
+       bNodeExec *nodeexec;
        bNode *node;
        bNodeSocket *sock;
+       int n;
        
        /* set exec flag for finished nodes that might need freed */
        for(node= ntree->nodes.first; node; node= node->next) {
@@ -451,8 +457,11 @@ static void freeExecutableNode(bNodeTree *ntree, bNodeTreeExec *exec)
                        if(node->exec & NODE_FINISHED)
                                node->exec |= NODE_FREEBUFS;
        }
-       /* clear this flag for input links that are not done yet */
-       for(node= ntree->nodes.first; node; node= node->next) {
+       /* clear this flag for input links that are not done yet.
+        * Using the exec data for valid dependency sort.
+        */
+       for(n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
+               node = nodeexec->node;
                if((node->exec & NODE_FINISHED)==0) {
                        for(sock= node->inputs.first; sock; sock= sock->next)
                                if(sock->link)
@@ -526,7 +535,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
        ListBase threads;
        ThreadData thdata;
        int totnode, curnode, rendering= 1, n;
-       bNodeTreeExec *exec= NULL;
+       bNodeTreeExec *exec= ntree->execdata;
        
        if(ntree==NULL) return;
        
@@ -551,7 +560,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
        BLI_srandom(rd->cfra);
 
        /* sets need_exec tags in nodes */
-       curnode = totnode= setExecutableNodes(ntree, &thdata);
+       curnode = totnode= setExecutableNodes(exec, &thdata);
 
        BLI_init_threads(&threads, exec_composite_node, rd->threads);
        
@@ -597,7 +606,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
                                        
                                        /* freeing unused buffers */
                                        if(rd->scemode & R_COMP_FREE)
-                                               freeExecutableNode(ntree, exec);
+                                               freeExecutableNode(exec);
                                }
                        }
                        else rendering= 1;
index 07f3eb943cc891b81f145089432f1a7f547d9a05..d7830b6a260b35bac62745f53ec1710dfbf14a7f 100644 (file)
@@ -878,7 +878,7 @@ static void loop_sync(bNodeTree *ntree, int sync_in_out)
                while (sync && ((sync->flag & SOCK_INTERNAL) || !(sync->flag & SOCK_DYNAMIC)))
                        sync = sync->next;
                
-               if (!(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC)) {
+               if (sync && !(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC)) {
                        if (sock->storage==NULL) {
                                /* if mirror index is 0, the sockets is newly added and a new mirror must be created. */
                                mirror = node_group_expose_socket(ntree, sock, sync_in_out);
index 642e4be10d7db9cbba879d861a7c832afe605c55..c50005bef678fdc824fbc97d2015108a5caed18c 100644 (file)
@@ -211,7 +211,7 @@ void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
        memset(shr, 0, sizeof(ShadeResult));
        
        if (!exec)
-               exec = ntree->execdata = ntreeShaderBeginExecTree(exec->nodetree, 1);
+               exec = ntree->execdata = ntreeShaderBeginExecTree(ntree, 1);
        
        nts= ntreeGetThreadStack(exec, shi->thread);
        ntreeExecThreadNodes(exec, nts, &scd, shi->thread);
index b7e67ec5a93610b847e5b1246c312f6cdd695505..a1571dc028c41745e6dbb1f70b39a83d0aa26341 100644 (file)
@@ -209,6 +209,10 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
 }
 
 /* returns the exception string as a new PyUnicode object, depends on external traceback module */
+#if 0
+
+/* this version uses traceback module but somehow fails on UI errors */
+
 PyObject *PyC_ExceptionBuffer(void)
 {
        PyObject *traceback_mod= NULL;
@@ -236,6 +240,78 @@ error_cleanup:
 
        return ret;
 }
+#else /* verbose, non-threadsafe version */
+PyObject *PyC_ExceptionBuffer(void)
+{
+       PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */
+       PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */
+       PyObject *string_io = NULL;
+       PyObject *string_io_buf = NULL;
+       PyObject *string_io_mod= NULL;
+       PyObject *string_io_getvalue= NULL;
+
+       PyObject *error_type, *error_value, *error_traceback;
+
+       if (!PyErr_Occurred())
+               return NULL;
+
+       PyErr_Fetch(&error_type, &error_value, &error_traceback);
+
+       PyErr_Clear();
+
+       /* import io
+        * string_io = io.StringIO()
+        */
+
+       if(! (string_io_mod= PyImport_ImportModule("io")) ) {
+               goto error_cleanup;
+       }
+       else if (! (string_io = PyObject_CallMethod(string_io_mod, (char *)"StringIO", NULL))) {
+               goto error_cleanup;
+       }
+       else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) {
+               goto error_cleanup;
+       }
+
+       Py_INCREF(stdout_backup); // since these were borrowed we dont want them freed when replaced.
+       Py_INCREF(stderr_backup);
+
+       PySys_SetObject("stdout", string_io); // both of these are free'd when restoring
+       PySys_SetObject("stderr", string_io);
+
+       PyErr_Restore(error_type, error_value, error_traceback);
+       PyErr_Print(); /* print the error */
+       PyErr_Clear();
+
+       string_io_buf = PyObject_CallObject(string_io_getvalue, NULL);
+
+       PySys_SetObject("stdout", stdout_backup);
+       PySys_SetObject("stderr", stderr_backup);
+
+       Py_DECREF(stdout_backup); /* now sys owns the ref again */
+       Py_DECREF(stderr_backup);
+
+       Py_DECREF(string_io_mod);
+       Py_DECREF(string_io_getvalue);
+       Py_DECREF(string_io); /* free the original reference */
+
+       PyErr_Clear();
+       return string_io_buf;
+
+
+error_cleanup:
+       /* could not import the module so print the error and close */
+       Py_XDECREF(string_io_mod);
+       Py_XDECREF(string_io);
+
+       PyErr_Restore(error_type, error_value, error_traceback);
+       PyErr_Print(); /* print the error */
+       PyErr_Clear();
+
+       return NULL;
+}
+#endif
+
 
 /* string conversion, escape non-unicode chars, coerce must be set to NULL */
 const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
index 8861f128c4b2a8e21690dc13fe6e2abbdc73bb0d..518ebeafc80d31a620a3e686131ef72e21ca2b1a 100644 (file)
@@ -441,12 +441,17 @@ static void wm_operator_reports(bContext *C, wmOperator *op, int retval, int pop
                if(op->reports->list.first) {
                        /* FIXME, temp setting window, see other call to uiPupMenuReports for why */
                        wmWindow *win_prev= CTX_wm_window(C);
+                       ScrArea *area_prev= CTX_wm_area(C);
+                       ARegion *ar_prev= CTX_wm_region(C);
+
                        if(win_prev==NULL)
                                CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first);
 
                        uiPupMenuReports(C, op->reports);
 
                        CTX_wm_window_set(C, win_prev);
+                       CTX_wm_area_set(C, area_prev);
+                       CTX_wm_region_set(C, ar_prev);
                }
        }
        
@@ -1394,6 +1399,9 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
                                                         * only have because lib linking errors need to be seen by users :(
                                                         * it can be removed without breaking anything but then no linking errors - campbell */
                                                        wmWindow *win_prev= CTX_wm_window(C);
+                                                       ScrArea *area_prev= CTX_wm_area(C);
+                                                       ARegion *ar_prev= CTX_wm_region(C);
+
                                                        if(win_prev==NULL)
                                                                CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first);
 
@@ -1405,6 +1413,8 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
                                                        BLI_movelisttolist(&CTX_wm_reports(C)->list, &handler->op->reports->list);
 
                                                        CTX_wm_window_set(C, win_prev);
+                                                       CTX_wm_area_set(C, area_prev);
+                                                       CTX_wm_region_set(C, ar_prev);
                                                }
 
                                                WM_operator_free(handler->op);
index 0e94ad72d350ea2d22898be8bd37022df3d418a3..854fa688ea4d9b108da23f340f4764abe3a6071d 100644 (file)
@@ -47,6 +47,7 @@
 #include "BKE_blender.h"
 #include "BKE_context.h"
 #include "BKE_idprop.h"
+#include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_screen.h"
@@ -680,6 +681,17 @@ wmKeyMap *WM_modalkeymap_add(wmKeyConfig *keyconf, const char *idname, EnumPrope
        wmKeyMap *km= WM_keymap_find(keyconf, idname, 0, 0);
        km->flag |= KEYMAP_MODAL;
        km->modal_items= items;
+
+       if(!items) {
+               /* init modal items from default config */
+               wmWindowManager *wm = G.main->wm.first;
+               wmKeyMap *defaultkm= WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, 0, 0);
+
+               if(defaultkm) {
+                       km->modal_items = defaultkm->modal_items;
+                       km->poll = defaultkm->poll;
+               }
+       }
        
        return km;
 }