svn merge -r39991:40034 https://svn.blender.org/svnroot/bf-blender/trunk/blender
This commit is contained in:
@@ -452,15 +452,8 @@ if(UNIX AND NOT APPLE)
|
|||||||
if(WITH_OPENCOLLADA)
|
if(WITH_OPENCOLLADA)
|
||||||
find_package(OpenCOLLADA)
|
find_package(OpenCOLLADA)
|
||||||
if(OPENCOLLADA_FOUND)
|
if(OPENCOLLADA_FOUND)
|
||||||
set(PCRE /usr CACHE PATH "PCRE Directory")
|
find_package(XML2)
|
||||||
mark_as_advanced(PCRE)
|
find_package(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)
|
|
||||||
else()
|
else()
|
||||||
set(WITH_OPENCOLLADA OFF)
|
set(WITH_OPENCOLLADA OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -49,12 +49,14 @@ SET(_opencollada_FIND_COMPONENTS
|
|||||||
OpenCOLLADAFramework
|
OpenCOLLADAFramework
|
||||||
OpenCOLLADABaseUtils
|
OpenCOLLADABaseUtils
|
||||||
GeneratedSaxParser
|
GeneratedSaxParser
|
||||||
UTF
|
|
||||||
MathMLSolver
|
MathMLSolver
|
||||||
pcre
|
)
|
||||||
|
|
||||||
|
# Fedora openCOLLADA package links these statically
|
||||||
|
SET(_opencollada_FIND_STATIC_COMPONENTS
|
||||||
|
UTF
|
||||||
ftoa
|
ftoa
|
||||||
buffer
|
buffer
|
||||||
xml2
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(_opencollada_SEARCH_DIRS
|
SET(_opencollada_SEARCH_DIRS
|
||||||
@@ -104,6 +106,25 @@ FOREACH(COMPONENT ${_opencollada_FIND_COMPONENTS})
|
|||||||
LIST(APPEND _opencollada_LIBRARIES "${OPENCOLLADA_${UPPERCOMPONENT}_LIBRARY}")
|
LIST(APPEND _opencollada_LIBRARIES "${OPENCOLLADA_${UPPERCOMPONENT}_LIBRARY}")
|
||||||
ENDFOREACH()
|
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
|
# handle the QUIETLY and REQUIRED arguments and set OPENCOLLADA_FOUND to TRUE if
|
||||||
# all listed variables are TRUE
|
# all listed variables are TRUE
|
||||||
|
|||||||
43
build_files/cmake/Modules/FindPCRE.cmake
Normal file
43
build_files/cmake/Modules/FindPCRE.cmake
Normal file
@@ -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()
|
||||||
88
build_files/cmake/Modules/FindXML2.cmake
Normal file
88
build_files/cmake/Modules/FindXML2.cmake
Normal file
@@ -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)
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ USE_SDK=True
|
|||||||
################### Cocoa & architecture settings ##################
|
################### Cocoa & architecture settings ##################
|
||||||
#############################################################################
|
#############################################################################
|
||||||
WITH_GHOST_COCOA=True
|
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'
|
cmd = 'uname -p'
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ def createTexture(cont):
|
|||||||
object = cont.owner
|
object = cont.owner
|
||||||
|
|
||||||
# get the reference pointer (ID) of the internal texture
|
# 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
|
# create a texture object
|
||||||
object_texture = texture.Texture(object, ID)
|
object_texture = texture.Texture(object, ID)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class HelloWorldOperator(bpy.types.Operator):
|
|||||||
print("Hello World")
|
print("Hello World")
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
bpy.utils.register_class(SimpleOperator)
|
bpy.utils.register_class(HelloWorldOperator)
|
||||||
|
|
||||||
# test call to the newly defined operator
|
# test call to the newly defined operator
|
||||||
bpy.ops.wm.hello_world()
|
bpy.ops.wm.hello_world()
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
Tips and Tricks
|
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
|
Use The Terminal
|
||||||
@@ -14,44 +16,36 @@ 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.
|
* 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::
|
.. 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.
|
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.
|
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.
|
||||||
|
|
||||||
|
|
||||||
Executing External Scripts
|
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"
|
filename = "/full/path/to/myscript.py"
|
||||||
exec(compile(open(filename).read(), filename, 'exec'))
|
exec(compile(open(filename).read(), filename, 'exec'))
|
||||||
|
|
||||||
|
|
||||||
You might also want to reference the file relative to the blend file.
|
You might want to reference a script relative to the blend file.
|
||||||
|
|
||||||
.. code-block::
|
.. code-block:: python
|
||||||
|
|
||||||
filename = "/full/path/to/script.py"
|
|
||||||
exec(compile(open(filename).read(), filename, 'exec'))
|
|
||||||
|
|
||||||
|
|
||||||
You might want to reference a script thats at the same location as the blend file.
|
|
||||||
|
|
||||||
.. code-block::
|
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import os
|
import os
|
||||||
@@ -61,11 +55,11 @@ You might want to reference a script thats at the same location as the blend fil
|
|||||||
|
|
||||||
|
|
||||||
Executing Modules
|
Executing Modules
|
||||||
^^^^^^^^^^^^^^^^^
|
-----------------
|
||||||
|
|
||||||
This example shows loading a script in as a module and executing a module function.
|
This example shows loading a script in as a module and executing a module function.
|
||||||
|
|
||||||
.. code-block::
|
.. code-block:: python
|
||||||
|
|
||||||
import myscript
|
import myscript
|
||||||
import imp
|
import imp
|
||||||
@@ -74,18 +68,18 @@ This example shows loading a script in as a module and executing a module functi
|
|||||||
myscript.main()
|
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.
|
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.
|
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 sys
|
||||||
import os
|
import os
|
||||||
impory bpy
|
import bpy
|
||||||
|
|
||||||
blend_dir = os.path.basename(bpy.data.filepath)
|
blend_dir = os.path.basename(bpy.data.filepath)
|
||||||
if blend_dir not in sys.path:
|
if blend_dir not in sys.path:
|
||||||
@@ -100,21 +94,103 @@ While this is not best practice - for testing you can extend the search path, th
|
|||||||
Don't Use Blender!
|
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. 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
|
||||||
|
|
||||||
|
blender myscene.blend --background --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.
|
||||||
|
|
||||||
|
* save a new blend file, or export the file using one of blenders exporters.
|
||||||
|
|
||||||
|
* if the results can be displayed as text - print them or write them to a file.
|
||||||
|
|
||||||
|
|
||||||
|
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
|
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.
|
||||||
|
|
||||||
Bundled Python
|
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.
|
||||||
==============
|
|
||||||
|
|
||||||
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.
|
Examples include:
|
||||||
|
|
||||||
|
* Run The Gimp in batch mode to execute custom scripts for advanced image processing.
|
||||||
|
|
||||||
|
* Write out 3D models to use external mesh manipulation tools and read back in the results.
|
||||||
|
|
||||||
|
* 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:
|
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 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.
|
* 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.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import code
|
||||||
|
code.interact(locals=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(locals=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(locals={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
|
Advanced
|
||||||
@@ -124,10 +200,28 @@ Advanced
|
|||||||
Blender as a module
|
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)
|
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
|
|
||||||
-----------------
|
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ sphinx-build doc/python_api/sphinx-in doc/python_api/sphinx-out
|
|||||||
INFO_DOCS = (
|
INFO_DOCS = (
|
||||||
("info_quickstart.rst", "Blender/Python Quickstart: new to blender/scripting and want to get you're feet wet?"),
|
("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_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"),
|
("info_gotcha.rst", "Gotcha's: some of the problems you may come up against when writing scripts"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -353,7 +353,10 @@ class Mesh(bpy_types.ID):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def edge_keys(self):
|
def edge_keys(self):
|
||||||
return [edge_key for face in self.faces for edge_key in face.edge_keys]
|
return list({edge_key
|
||||||
|
for face in self.faces
|
||||||
|
for edge_key in face.edge_keys
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class MeshEdge(StructRNA):
|
class MeshEdge(StructRNA):
|
||||||
@@ -373,17 +376,31 @@ class MeshFace(StructRNA):
|
|||||||
face_verts = self.vertices[:]
|
face_verts = self.vertices[:]
|
||||||
mesh_verts = self.id_data.vertices
|
mesh_verts = self.id_data.vertices
|
||||||
if len(face_verts) == 3:
|
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:
|
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
|
@property
|
||||||
def edge_keys(self):
|
def edge_keys(self):
|
||||||
verts = self.vertices[:]
|
verts = self.vertices[:]
|
||||||
if len(verts) == 3:
|
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]),
|
||||||
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])
|
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):
|
class Text(bpy_types.ID):
|
||||||
|
|||||||
@@ -685,7 +685,6 @@ data_path_update = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
from bpy.types import Operator
|
from bpy.types import Operator
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -271,7 +271,8 @@ class BakeAction(Operator):
|
|||||||
|
|
||||||
|
|
||||||
class ClearUselessActions(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_idname = "anim.clear_useless_actions"
|
||||||
bl_label = "Clear Useless Actions"
|
bl_label = "Clear Useless Actions"
|
||||||
bl_options = {'REGISTER', 'UNDO'}
|
bl_options = {'REGISTER', 'UNDO'}
|
||||||
@@ -292,12 +293,14 @@ class ClearUselessActions(Operator):
|
|||||||
if ((self.only_unused is False) or
|
if ((self.only_unused is False) or
|
||||||
(action.use_fake_user and action.users == 1)):
|
(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!
|
# and should be left alone as that's what fake users are for!
|
||||||
if not action.fcurves:
|
if not action.fcurves:
|
||||||
# mark action for deletion
|
# mark action for deletion
|
||||||
action.user_clear()
|
action.user_clear()
|
||||||
removed += 1
|
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'}
|
return {'FINISHED'}
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ class DATA_PT_skeleton(ArmatureButtonsPanel, Panel):
|
|||||||
if context.scene.render.engine == "BLENDER_GAME":
|
if context.scene.render.engine == "BLENDER_GAME":
|
||||||
layout.row().prop(arm, "vert_deformer", expand=True)
|
layout.row().prop(arm, "vert_deformer", expand=True)
|
||||||
|
|
||||||
|
|
||||||
class DATA_PT_display(ArmatureButtonsPanel, Panel):
|
class DATA_PT_display(ArmatureButtonsPanel, Panel):
|
||||||
bl_label = "Display"
|
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")
|
layout.template_ID(ob, "pose_library", new="poselib.new", unlink="poselib.unlink")
|
||||||
|
|
||||||
if poselib:
|
if poselib:
|
||||||
|
# list of poses in pose library
|
||||||
# list of poses in pose library
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.template_list(poselib, "pose_markers", poselib.pose_markers, "active_index", rows=5)
|
row.template_list(poselib, "pose_markers", poselib.pose_markers, "active_index", rows=5)
|
||||||
|
|
||||||
# column of operators for active pose
|
# column of operators for active pose
|
||||||
# - goes beside list
|
# - goes beside list
|
||||||
col = row.column(align=True)
|
col = row.column(align=True)
|
||||||
@@ -206,9 +206,9 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel):
|
|||||||
if pose_marker_active is not None:
|
if pose_marker_active is not None:
|
||||||
col.operator("poselib.pose_remove", icon='ZOOMOUT', text="").pose = pose_marker_active.name
|
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.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
|
# properties for active marker
|
||||||
if pose_marker_active is not None:
|
if pose_marker_active is not None:
|
||||||
layout.prop(pose_marker_active, "name")
|
layout.prop(pose_marker_active, "name")
|
||||||
|
|||||||
@@ -742,22 +742,23 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||||||
col.prop(md, "narrowness", slider=True)
|
col.prop(md, "narrowness", slider=True)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def weight_vg_mask(layout, ob, md):
|
def vertex_weight_mask(layout, ob, md):
|
||||||
layout.label(text="Influence/Mask Options:")
|
layout.label(text="Influence/Mask Options:")
|
||||||
split = layout.split()
|
row = layout.row()
|
||||||
col1 = split.column()
|
|
||||||
col2 = split.column()
|
|
||||||
|
|
||||||
col1.label(text="Global Influence:")
|
split = layout.split(percentage=0.4)
|
||||||
col2.prop(md, "mask_constant", text="")
|
split.label(text="Global Influence:")
|
||||||
|
split.prop(md, "mask_constant", text="")
|
||||||
|
|
||||||
if not md.mask_texture:
|
if not md.mask_texture:
|
||||||
col1.label(text="Vertex Group Mask:")
|
split = layout.split(percentage=0.4)
|
||||||
col2.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="")
|
split.label(text="Vertex Group Mask:")
|
||||||
|
split.prop_search(md, "mask_vertex_group", ob, "vertex_groups", text="")
|
||||||
|
|
||||||
if not md.mask_vertex_group:
|
if not md.mask_vertex_group:
|
||||||
col1.label(text="Texture Mask:")
|
split = layout.split(percentage=0.4)
|
||||||
col2.template_ID(md, "mask_texture", new="texture.new")
|
split.label(text="Texture Mask:")
|
||||||
|
split.template_ID(md, "mask_texture", new="texture.new")
|
||||||
if md.mask_texture:
|
if md.mask_texture:
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
col = split.column()
|
col = split.column()
|
||||||
@@ -772,7 +773,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||||||
elif md.mask_tex_mapping == 'UV' and ob.type == 'MESH':
|
elif md.mask_tex_mapping == 'UV' and ob.type == 'MESH':
|
||||||
layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_textures")
|
layout.prop_search(md, "mask_tex_uv_layer", ob.data, "uv_textures")
|
||||||
|
|
||||||
def WEIGHT_VGEDIT(self, layout, ob, md):
|
def VERTEX_WEIGHT_EDIT(self, layout, ob, md):
|
||||||
if ob.type == 'MESH':
|
if ob.type == 'MESH':
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
col = split.column()
|
col = split.column()
|
||||||
@@ -783,25 +784,28 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||||||
col.label(text="Default Weight:")
|
col.label(text="Default Weight:")
|
||||||
col.prop(md, "default_weight", text="")
|
col.prop(md, "default_weight", text="")
|
||||||
|
|
||||||
layout.prop(md, "mapping_mode")
|
layout.prop(md, "falloff_type")
|
||||||
if md.mapping_mode == 'CURVE':
|
if md.falloff_type == 'CURVE':
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
col.template_curve_mapping(md, "map_curve")
|
col.template_curve_mapping(md, "map_curve")
|
||||||
|
|
||||||
row = layout.row()
|
split = layout.split(percentage=0.4)
|
||||||
row.prop(md, "use_add")
|
split.prop(md, "use_add")
|
||||||
row.prop(md, "use_remove")
|
row = split.row()
|
||||||
row = layout.row()
|
row.active = md.use_add
|
||||||
if md.use_add:
|
row.prop(md, "add_threshold")
|
||||||
row.prop(md, "add_threshold")
|
|
||||||
if md.use_remove:
|
split = layout.split(percentage=0.4)
|
||||||
row.prop(md, "remove_threshold")
|
split.prop(md, "use_remove")
|
||||||
|
row = split.row()
|
||||||
|
row.active = md.use_remove
|
||||||
|
row.prop(md, "remove_threshold")
|
||||||
|
|
||||||
# Common mask options…
|
# Common mask options…
|
||||||
layout.separator()
|
layout.separator()
|
||||||
self.weight_vg_mask(layout, ob, md)
|
self.vertex_weight_mask(layout, ob, md)
|
||||||
|
|
||||||
def WEIGHT_VGMIX(self, layout, ob, md):
|
def VERTEX_WEIGHT_MIX(self, layout, ob, md):
|
||||||
if ob.type == 'MESH':
|
if ob.type == 'MESH':
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
col = split.column()
|
col = split.column()
|
||||||
@@ -824,9 +828,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||||||
|
|
||||||
# Common mask options…
|
# Common mask options…
|
||||||
layout.separator()
|
layout.separator()
|
||||||
self.weight_vg_mask(layout, ob, md)
|
self.vertex_weight_mask(layout, ob, md)
|
||||||
|
|
||||||
def WEIGHT_VGPROXIMITY(self, layout, ob, md):
|
def VERTEX_WEIGHT_PROXIMITY(self, layout, ob, md):
|
||||||
if ob.type == 'MESH':
|
if ob.type == 'MESH':
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
col = split.column()
|
col = split.column()
|
||||||
@@ -847,11 +851,11 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||||||
row.prop(md, "min_dist")
|
row.prop(md, "min_dist")
|
||||||
row.prop(md, "max_dist")
|
row.prop(md, "max_dist")
|
||||||
|
|
||||||
layout.prop(md, "mapping_mode")
|
layout.prop(md, "falloff_type")
|
||||||
|
|
||||||
# Common mask options…
|
# Common mask options…
|
||||||
layout.separator()
|
layout.separator()
|
||||||
self.weight_vg_mask(layout, ob, md)
|
self.vertex_weight_mask(layout, ob, md)
|
||||||
|
|
||||||
if __name__ == "__main__": # only for live edit.
|
if __name__ == "__main__": # only for live edit.
|
||||||
bpy.utils.register_module(__name__)
|
bpy.utils.register_module(__name__)
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class DATA_PT_distance(DataButtonsPanel, bpy.types.Panel):
|
|||||||
speaker = context.speaker
|
speaker = context.speaker
|
||||||
|
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
col.label("Volume:")
|
col.label("Volume:")
|
||||||
col.prop(speaker, "volume_min", text="Minimum")
|
col.prop(speaker, "volume_min", text="Minimum")
|
||||||
|
|||||||
@@ -344,7 +344,7 @@ class RENDER_PT_game_performance(RenderButtonsPanel, Panel):
|
|||||||
row = col.row()
|
row = col.row()
|
||||||
row.prop(gs, "use_frame_rate")
|
row.prop(gs, "use_frame_rate")
|
||||||
row.prop(gs, "use_display_lists")
|
row.prop(gs, "use_display_lists")
|
||||||
|
|
||||||
col.prop(gs, "restrict_animation_updates")
|
col.prop(gs, "restrict_animation_updates")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -773,7 +773,18 @@ class USERPREF_MT_ndof_settings(Menu):
|
|||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
layout.label(text="orbit options")
|
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.separator()
|
||||||
layout.label(text="fly options")
|
layout.label(text="fly options")
|
||||||
|
|||||||
@@ -398,6 +398,11 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
|
|||||||
sock->stack_index= 0;
|
sock->stack_index= 0;
|
||||||
|
|
||||||
sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL);
|
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);
|
BLI_duplicatelist(&nnode->outputs, &node->outputs);
|
||||||
@@ -407,6 +412,11 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
|
|||||||
sock->stack_index= 0;
|
sock->stack_index= 0;
|
||||||
|
|
||||||
sock->default_value = (oldsock->default_value ? MEM_dupallocN(oldsock->default_value) : NULL);
|
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 */
|
/* don't increase node->id users, freenode doesn't decrement either */
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
// XXX exporter writes wrong data for shared armatures. A separate
|
// XXX exporter writes wrong data for shared armatures. A separate
|
||||||
// controller should be written for each armature-mesh binding how do
|
// controller should be written for each armature-mesh binding how do
|
||||||
// we make controller ids then?
|
// 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
|
// write bone nodes
|
||||||
void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce)
|
void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce)
|
||||||
@@ -90,14 +90,14 @@ void ArmatureExporter::add_instance_controller(Object *ob)
|
|||||||
ins.add();
|
ins.add();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArmatureExporter::export_controllers(Scene *sce, bool export_selected)
|
void ArmatureExporter::export_controllers(Scene *sce)
|
||||||
{
|
{
|
||||||
scene = sce;
|
scene = sce;
|
||||||
|
|
||||||
openLibrary();
|
openLibrary();
|
||||||
|
|
||||||
GeometryFunctor gf;
|
GeometryFunctor gf;
|
||||||
gf.forEachMeshObjectInScene<ArmatureExporter>(sce, *this, export_selected);
|
gf.forEachMeshObjectInScene<ArmatureExporter>(sce, *this, this->export_settings->selected);
|
||||||
|
|
||||||
closeLibrary();
|
closeLibrary();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,16 +47,15 @@
|
|||||||
#include "TransformWriter.h"
|
#include "TransformWriter.h"
|
||||||
#include "InstanceWriter.h"
|
#include "InstanceWriter.h"
|
||||||
|
|
||||||
|
#include "ExportSettings.h"
|
||||||
|
|
||||||
// XXX exporter writes wrong data for shared armatures. A separate
|
// XXX exporter writes wrong data for shared armatures. A separate
|
||||||
// controller should be written for each armature-mesh binding how do
|
// controller should be written for each armature-mesh binding how do
|
||||||
// we make controller ids then?
|
// we make controller ids then?
|
||||||
class ArmatureExporter: public COLLADASW::LibraryControllers, protected TransformWriter, protected InstanceWriter
|
class ArmatureExporter: public COLLADASW::LibraryControllers, protected TransformWriter, protected InstanceWriter
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
Scene *scene;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ArmatureExporter(COLLADASW::StreamWriter *sw);
|
ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
|
||||||
|
|
||||||
// write bone nodes
|
// write bone nodes
|
||||||
void add_armature_bones(Object *ob_arm, Scene *sce);
|
void add_armature_bones(Object *ob_arm, Scene *sce);
|
||||||
@@ -65,13 +64,14 @@ public:
|
|||||||
|
|
||||||
void add_instance_controller(Object *ob);
|
void add_instance_controller(Object *ob);
|
||||||
|
|
||||||
void export_controllers(Scene *sce, bool export_selected);
|
void export_controllers(Scene *sce);
|
||||||
|
|
||||||
void operator()(Object *ob);
|
void operator()(Object *ob);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Scene *scene;
|
||||||
UnitConverter converter;
|
UnitConverter converter;
|
||||||
|
const ExportSettings *export_settings;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
std::vector<Object*> written_armatures;
|
std::vector<Object*> written_armatures;
|
||||||
@@ -119,25 +119,4 @@ private:
|
|||||||
Object *ob_arm, ListBase *defbase);
|
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
|
#endif
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ set(SRC
|
|||||||
DocumentImporter.cpp
|
DocumentImporter.cpp
|
||||||
EffectExporter.cpp
|
EffectExporter.cpp
|
||||||
ErrorHandler.cpp
|
ErrorHandler.cpp
|
||||||
|
ExportSettings.cpp
|
||||||
ExtraHandler.cpp
|
ExtraHandler.cpp
|
||||||
ExtraTags.cpp
|
ExtraTags.cpp
|
||||||
GeometryExporter.cpp
|
GeometryExporter.cpp
|
||||||
@@ -77,6 +78,7 @@ set(SRC
|
|||||||
DocumentImporter.h
|
DocumentImporter.h
|
||||||
EffectExporter.h
|
EffectExporter.h
|
||||||
ErrorHandler.h
|
ErrorHandler.h
|
||||||
|
ExportSettings.h
|
||||||
ExtraHandler.h
|
ExtraHandler.h
|
||||||
ExtraTags.h
|
ExtraTags.h
|
||||||
GeometryExporter.h
|
GeometryExporter.h
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
#include "collada_internal.h"
|
#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>
|
template<class Functor>
|
||||||
void forEachCameraObjectInScene(Scene *sce, Functor &f, bool export_selected)
|
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();
|
openLibrary();
|
||||||
|
|
||||||
forEachCameraObjectInScene(sce, *this, export_selected);
|
forEachCameraObjectInScene(sce, *this, this->export_settings->selected);
|
||||||
|
|
||||||
closeLibrary();
|
closeLibrary();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,12 +36,16 @@
|
|||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
|
|
||||||
|
#include "ExportSettings.h"
|
||||||
|
|
||||||
class CamerasExporter: COLLADASW::LibraryCameras
|
class CamerasExporter: COLLADASW::LibraryCameras
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CamerasExporter(COLLADASW::StreamWriter *sw);
|
CamerasExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
|
||||||
void exportCameras(Scene *sce, bool export_selected);
|
void exportCameras(Scene *sce);
|
||||||
void operator()(Object *ob, Scene *sce);
|
void operator()(Object *ob, Scene *sce);
|
||||||
|
private:
|
||||||
|
const ExportSettings *export_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ extern char build_rev[];
|
|||||||
|
|
||||||
#include "collada_internal.h"
|
#include "collada_internal.h"
|
||||||
#include "DocumentExporter.h"
|
#include "DocumentExporter.h"
|
||||||
|
#include "ExportSettings.h"
|
||||||
|
|
||||||
// can probably go after refactor is complete
|
// can probably go after refactor is complete
|
||||||
#include "InstanceWriter.h"
|
#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;
|
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
|
// 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>.
|
// COLLADA allows this through multiple <channel>s in <animation>.
|
||||||
// For this to work, we need to know objects that use a certain action.
|
// 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;
|
PointerRNA sceneptr, unit_settings;
|
||||||
PropertyRNA *system; /* unused , *scale; */
|
PropertyRNA *system; /* unused , *scale; */
|
||||||
@@ -157,7 +160,7 @@ void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename, bool
|
|||||||
clear_global_id_map();
|
clear_global_id_map();
|
||||||
|
|
||||||
COLLADABU::NativeString native_filename =
|
COLLADABU::NativeString native_filename =
|
||||||
COLLADABU::NativeString(std::string(filename));
|
COLLADABU::NativeString(std::string(this->export_settings->filepath));
|
||||||
COLLADASW::StreamWriter sw(native_filename);
|
COLLADASW::StreamWriter sw(native_filename);
|
||||||
|
|
||||||
// open <collada>
|
// open <collada>
|
||||||
@@ -227,32 +230,32 @@ void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename, bool
|
|||||||
|
|
||||||
// <library_cameras>
|
// <library_cameras>
|
||||||
if(has_object_type(sce, OB_CAMERA)) {
|
if(has_object_type(sce, OB_CAMERA)) {
|
||||||
CamerasExporter ce(&sw);
|
CamerasExporter ce(&sw, this->export_settings);
|
||||||
ce.exportCameras(sce, selected);
|
ce.exportCameras(sce);
|
||||||
}
|
}
|
||||||
|
|
||||||
// <library_lights>
|
// <library_lights>
|
||||||
if(has_object_type(sce, OB_LAMP)) {
|
if(has_object_type(sce, OB_LAMP)) {
|
||||||
LightsExporter le(&sw);
|
LightsExporter le(&sw, this->export_settings);
|
||||||
le.exportLights(sce, selected);
|
le.exportLights(sce);
|
||||||
}
|
}
|
||||||
|
|
||||||
// <library_images>
|
// <library_images>
|
||||||
ImagesExporter ie(&sw, filename);
|
ImagesExporter ie(&sw, this->export_settings);
|
||||||
ie.exportImages(sce, selected);
|
ie.exportImages(sce);
|
||||||
|
|
||||||
// <library_effects>
|
// <library_effects>
|
||||||
EffectsExporter ee(&sw);
|
EffectsExporter ee(&sw, this->export_settings);
|
||||||
ee.exportEffects(sce, selected);
|
ee.exportEffects(sce);
|
||||||
|
|
||||||
// <library_materials>
|
// <library_materials>
|
||||||
MaterialsExporter me(&sw);
|
MaterialsExporter me(&sw, this->export_settings);
|
||||||
me.exportMaterials(sce, selected);
|
me.exportMaterials(sce);
|
||||||
|
|
||||||
// <library_geometries>
|
// <library_geometries>
|
||||||
if(has_object_type(sce, OB_MESH)) {
|
if(has_object_type(sce, OB_MESH)) {
|
||||||
GeometryExporter ge(&sw);
|
GeometryExporter ge(&sw, this->export_settings);
|
||||||
ge.exportGeom(sce, selected);
|
ge.exportGeom(sce);
|
||||||
}
|
}
|
||||||
|
|
||||||
// <library_animations>
|
// <library_animations>
|
||||||
@@ -260,14 +263,14 @@ void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename, bool
|
|||||||
ae.exportAnimations(sce);
|
ae.exportAnimations(sce);
|
||||||
|
|
||||||
// <library_controllers>
|
// <library_controllers>
|
||||||
ArmatureExporter arm_exporter(&sw);
|
ArmatureExporter arm_exporter(&sw, this->export_settings);
|
||||||
if(has_object_type(sce, OB_ARMATURE)) {
|
if(has_object_type(sce, OB_ARMATURE)) {
|
||||||
arm_exporter.export_controllers(sce, selected);
|
arm_exporter.export_controllers(sce);
|
||||||
}
|
}
|
||||||
|
|
||||||
// <library_visual_scenes>
|
// <library_visual_scenes>
|
||||||
SceneExporter se(&sw, &arm_exporter);
|
SceneExporter se(&sw, &arm_exporter, this->export_settings);
|
||||||
se.exportScene(sce, selected);
|
se.exportScene(sce);
|
||||||
|
|
||||||
// <scene>
|
// <scene>
|
||||||
std::string scene_name(translate_id(id_name(sce)));
|
std::string scene_name(translate_id(id_name(sce)));
|
||||||
|
|||||||
@@ -29,13 +29,18 @@
|
|||||||
#ifndef __DOCUMENTEXPORTER_H__
|
#ifndef __DOCUMENTEXPORTER_H__
|
||||||
#define __DOCUMENTEXPORTER_H__
|
#define __DOCUMENTEXPORTER_H__
|
||||||
|
|
||||||
|
#include "ExportSettings.h"
|
||||||
|
|
||||||
struct Scene;
|
struct Scene;
|
||||||
|
|
||||||
class DocumentExporter
|
class DocumentExporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void exportCurrentScene(Scene *sce, const char* filename, bool selected);
|
DocumentExporter(const ExportSettings *export_settings);
|
||||||
|
void exportCurrentScene(Scene *sce);
|
||||||
void exportScenes(const char* filename);
|
void exportScenes(const char* filename);
|
||||||
|
private:
|
||||||
|
const ExportSettings *export_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ static std::string getActiveUVLayerName(Object *ob)
|
|||||||
return "";
|
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)
|
bool EffectsExporter::hasEffects(Scene *sce)
|
||||||
{
|
{
|
||||||
@@ -78,12 +78,12 @@ bool EffectsExporter::hasEffects(Scene *sce)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectsExporter::exportEffects(Scene *sce, bool export_selected)
|
void EffectsExporter::exportEffects(Scene *sce)
|
||||||
{
|
{
|
||||||
if(hasEffects(sce)) {
|
if(hasEffects(sce)) {
|
||||||
openLibrary();
|
openLibrary();
|
||||||
MaterialFunctor mf;
|
MaterialFunctor mf;
|
||||||
mf.forEachMaterialInScene<EffectsExporter>(sce, *this, export_selected);
|
mf.forEachMaterialInScene<EffectsExporter>(sce, *this, this->export_settings->selected);
|
||||||
|
|
||||||
closeLibrary();
|
closeLibrary();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,11 +43,13 @@
|
|||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
|
|
||||||
|
#include "ExportSettings.h"
|
||||||
|
|
||||||
class EffectsExporter: COLLADASW::LibraryEffects
|
class EffectsExporter: COLLADASW::LibraryEffects
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EffectsExporter(COLLADASW::StreamWriter *sw);
|
EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
|
||||||
void exportEffects(Scene *sce, bool export_selected);
|
void exportEffects(Scene *sce);
|
||||||
|
|
||||||
void operator()(Material *ma, Object *ob);
|
void operator()(Material *ma, Object *ob);
|
||||||
|
|
||||||
@@ -66,6 +68,8 @@ private:
|
|||||||
void writePhong(COLLADASW::EffectProfile &ep, Material *ma);
|
void writePhong(COLLADASW::EffectProfile &ep, Material *ma);
|
||||||
|
|
||||||
bool hasEffects(Scene *sce);
|
bool hasEffects(Scene *sce);
|
||||||
|
|
||||||
|
const ExportSettings *export_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
29
source/blender/collada/ExportSettings.cpp
Normal file
29
source/blender/collada/ExportSettings.cpp
Normal file
@@ -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"
|
||||||
39
source/blender/collada/ExportSettings.h
Normal file
39
source/blender/collada/ExportSettings.h
Normal file
@@ -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
|
||||||
@@ -44,16 +44,16 @@
|
|||||||
#include "collada_internal.h"
|
#include "collada_internal.h"
|
||||||
|
|
||||||
// TODO: optimize UV sets by making indexed list with duplicates removed
|
// 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();
|
openLibrary();
|
||||||
|
|
||||||
mScene = sce;
|
mScene = sce;
|
||||||
GeometryFunctor gf;
|
GeometryFunctor gf;
|
||||||
gf.forEachMeshObjectInScene<GeometryExporter>(sce, *this, export_selected);
|
gf.forEachMeshObjectInScene<GeometryExporter>(sce, *this, this->export_settings->selected);
|
||||||
|
|
||||||
closeLibrary();
|
closeLibrary();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,8 @@
|
|||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
|
|
||||||
|
#include "ExportSettings.h"
|
||||||
|
|
||||||
// TODO: optimize UV sets by making indexed list with duplicates removed
|
// TODO: optimize UV sets by making indexed list with duplicates removed
|
||||||
class GeometryExporter : COLLADASW::LibraryGeometries
|
class GeometryExporter : COLLADASW::LibraryGeometries
|
||||||
{
|
{
|
||||||
@@ -58,9 +60,9 @@ class GeometryExporter : COLLADASW::LibraryGeometries
|
|||||||
Scene *mScene;
|
Scene *mScene;
|
||||||
|
|
||||||
public:
|
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);
|
void operator()(Object *ob);
|
||||||
|
|
||||||
@@ -96,6 +98,8 @@ public:
|
|||||||
/* int getTriCount(MFace *faces, int totface);*/
|
/* int getTriCount(MFace *faces, int totface);*/
|
||||||
private:
|
private:
|
||||||
std::set<std::string> exportedGeometry;
|
std::set<std::string> exportedGeometry;
|
||||||
|
|
||||||
|
const ExportSettings *export_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GeometryFunctor {
|
struct GeometryFunctor {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
#include "BLI_path_util.h"
|
#include "BLI_path_util.h"
|
||||||
#include "BLI_string.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)
|
bool ImagesExporter::hasImages(Scene *sce)
|
||||||
@@ -71,12 +71,12 @@ bool ImagesExporter::hasImages(Scene *sce)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImagesExporter::exportImages(Scene *sce, bool export_selected)
|
void ImagesExporter::exportImages(Scene *sce)
|
||||||
{
|
{
|
||||||
if(hasImages(sce)) {
|
if(hasImages(sce)) {
|
||||||
openLibrary();
|
openLibrary();
|
||||||
MaterialFunctor mf;
|
MaterialFunctor mf;
|
||||||
mf.forEachMaterialInScene<ImagesExporter>(sce, *this, export_selected);
|
mf.forEachMaterialInScene<ImagesExporter>(sce, *this, this->export_settings->selected);
|
||||||
|
|
||||||
closeLibrary();
|
closeLibrary();
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ void ImagesExporter::operator()(Material *ma, Object *ob)
|
|||||||
char src[FILE_MAX];
|
char src[FILE_MAX];
|
||||||
char dir[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);
|
BKE_rebase_path(abs, sizeof(abs), rel, sizeof(rel), G.main->name, image->name, dir);
|
||||||
|
|
||||||
|
|||||||
@@ -40,17 +40,19 @@
|
|||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
|
|
||||||
|
#include "ExportSettings.h"
|
||||||
|
|
||||||
class ImagesExporter: COLLADASW::LibraryImages
|
class ImagesExporter: COLLADASW::LibraryImages
|
||||||
{
|
{
|
||||||
const char *mfilename;
|
|
||||||
std::vector<std::string> mImages; // contains list of written images, to avoid duplicates
|
|
||||||
public:
|
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);
|
void operator()(Material *ma, Object *ob);
|
||||||
private:
|
private:
|
||||||
|
std::vector<std::string> mImages; // contains list of written images, to avoid duplicates
|
||||||
bool hasImages(Scene *sce);
|
bool hasImages(Scene *sce);
|
||||||
|
const ExportSettings *export_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -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();
|
openLibrary();
|
||||||
|
|
||||||
forEachLampObjectInScene(sce, *this, export_selected);
|
forEachLampObjectInScene(sce, *this, this->export_settings->selected);
|
||||||
|
|
||||||
closeLibrary();
|
closeLibrary();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,14 +37,17 @@
|
|||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
|
|
||||||
|
#include "ExportSettings.h"
|
||||||
|
|
||||||
class LightsExporter: COLLADASW::LibraryLights
|
class LightsExporter: COLLADASW::LibraryLights
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LightsExporter(COLLADASW::StreamWriter *sw);
|
LightsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
|
||||||
void exportLights(Scene *sce, bool export_selected);
|
void exportLights(Scene *sce);
|
||||||
void operator()(Object *ob);
|
void operator()(Object *ob);
|
||||||
private:
|
private:
|
||||||
bool exportBlenderProfile(COLLADASW::Light &cla, Lamp *la);
|
bool exportBlenderProfile(COLLADASW::Light &cla, Lamp *la);
|
||||||
|
const ExportSettings *export_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -33,15 +33,15 @@
|
|||||||
#include "COLLADABUUtils.h"
|
#include "COLLADABUUtils.h"
|
||||||
#include "collada_internal.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)) {
|
if(hasMaterials(sce)) {
|
||||||
openLibrary();
|
openLibrary();
|
||||||
|
|
||||||
MaterialFunctor mf;
|
MaterialFunctor mf;
|
||||||
mf.forEachMaterialInScene<MaterialsExporter>(sce, *this, export_selected);
|
mf.forEachMaterialInScene<MaterialsExporter>(sce, *this, this->export_settings->selected);
|
||||||
|
|
||||||
closeLibrary();
|
closeLibrary();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,16 +44,18 @@
|
|||||||
|
|
||||||
#include "GeometryExporter.h"
|
#include "GeometryExporter.h"
|
||||||
#include "collada_internal.h"
|
#include "collada_internal.h"
|
||||||
|
#include "ExportSettings.h"
|
||||||
|
|
||||||
class MaterialsExporter: COLLADASW::LibraryMaterials
|
class MaterialsExporter: COLLADASW::LibraryMaterials
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MaterialsExporter(COLLADASW::StreamWriter *sw);
|
MaterialsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
|
||||||
void exportMaterials(Scene *sce, bool export_selected);
|
void exportMaterials(Scene *sce);
|
||||||
void operator()(Material *ma, Object *ob);
|
void operator()(Material *ma, Object *ob);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool hasMaterials(Scene *sce);
|
bool hasMaterials(Scene *sce);
|
||||||
|
const ExportSettings *export_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
// used in forEachMaterialInScene
|
// used in forEachMaterialInScene
|
||||||
|
|||||||
@@ -28,21 +28,21 @@
|
|||||||
|
|
||||||
#include "SceneExporter.h"
|
#include "SceneExporter.h"
|
||||||
|
|
||||||
SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm)
|
SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings)
|
||||||
: COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm)
|
: 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>
|
// <library_visual_scenes> <visual_scene>
|
||||||
std::string id_naming = id_name(sce);
|
std::string id_naming = id_name(sce);
|
||||||
openVisualScene(translate_id(id_naming), id_naming);
|
openVisualScene(translate_id(id_naming), id_naming);
|
||||||
exportHierarchy(sce, export_selected);
|
exportHierarchy(sce);
|
||||||
closeVisualScene();
|
closeVisualScene();
|
||||||
closeLibrary();
|
closeLibrary();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneExporter::exportHierarchy(Scene *sce, bool export_selected)
|
void SceneExporter::exportHierarchy(Scene *sce)
|
||||||
{
|
{
|
||||||
Base *base= (Base*) sce->base.first;
|
Base *base= (Base*) sce->base.first;
|
||||||
while(base) {
|
while(base) {
|
||||||
@@ -56,7 +56,7 @@ void SceneExporter::exportHierarchy(Scene *sce, bool export_selected)
|
|||||||
case OB_LAMP:
|
case OB_LAMP:
|
||||||
case OB_ARMATURE:
|
case OB_ARMATURE:
|
||||||
case OB_EMPTY:
|
case OB_EMPTY:
|
||||||
if (export_selected && !(ob->flag & SELECT)) {
|
if (this->export_settings->selected && !(ob->flag & SELECT)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// write nodes....
|
// write nodes....
|
||||||
|
|||||||
@@ -29,6 +29,10 @@
|
|||||||
#ifndef __SCENEEXPORTER_H__
|
#ifndef __SCENEEXPORTER_H__
|
||||||
#define __SCENEEXPORTER_H__
|
#define __SCENEEXPORTER_H__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
@@ -86,16 +90,20 @@ extern "C" {
|
|||||||
|
|
||||||
#include "ArmatureExporter.h"
|
#include "ArmatureExporter.h"
|
||||||
|
|
||||||
|
#include "ExportSettings.h"
|
||||||
|
|
||||||
class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter, protected InstanceWriter
|
class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter, protected InstanceWriter
|
||||||
{
|
{
|
||||||
ArmatureExporter *arm_exporter;
|
|
||||||
public:
|
public:
|
||||||
SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm);
|
SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings);
|
||||||
void exportScene(Scene *sce, bool export_selected);
|
void exportScene(Scene *sce);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void exportHierarchy(Scene *sce, bool export_selected);
|
void exportHierarchy(Scene *sce);
|
||||||
void writeNodes(Object *ob, Scene *sce);
|
void writeNodes(Object *ob, Scene *sce);
|
||||||
|
|
||||||
|
ArmatureExporter *arm_exporter;
|
||||||
|
const ExportSettings *export_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
/* COLLADABU_ASSERT, may be able to remove later */
|
/* COLLADABU_ASSERT, may be able to remove later */
|
||||||
#include "COLLADABUPlatform.h"
|
#include "COLLADABUPlatform.h"
|
||||||
|
|
||||||
|
#include "ExportSettings.h"
|
||||||
#include "DocumentExporter.h"
|
#include "DocumentExporter.h"
|
||||||
#include "DocumentImporter.h"
|
#include "DocumentImporter.h"
|
||||||
|
|
||||||
@@ -53,7 +54,10 @@ extern "C"
|
|||||||
|
|
||||||
int collada_export(Scene *sce, const char *filepath, int selected)
|
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] */
|
/* annoying, collada crashes if file cant be created! [#27162] */
|
||||||
if(!BLI_exist(filepath)) {
|
if(!BLI_exist(filepath)) {
|
||||||
@@ -64,7 +68,8 @@ extern "C"
|
|||||||
}
|
}
|
||||||
/* end! */
|
/* end! */
|
||||||
|
|
||||||
exp.exportCurrentScene(sce, filepath, selected);
|
DocumentExporter exporter(&export_settings);
|
||||||
|
exporter.exportCurrentScene(sce);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -589,7 +589,7 @@ DEF_ICON(MOD_MULTIRES)
|
|||||||
DEF_ICON(MOD_SMOKE)
|
DEF_ICON(MOD_SMOKE)
|
||||||
DEF_ICON(MOD_SOLIDIFY)
|
DEF_ICON(MOD_SOLIDIFY)
|
||||||
DEF_ICON(MOD_SCREW)
|
DEF_ICON(MOD_SCREW)
|
||||||
DEF_ICON(MOD_WEIGHTVG)
|
DEF_ICON(MOD_VERTEX_WEIGHT)
|
||||||
#ifndef DEF_ICON_BLANK_SKIP
|
#ifndef DEF_ICON_BLANK_SKIP
|
||||||
DEF_ICON(BLANK161)
|
DEF_ICON(BLANK161)
|
||||||
DEF_ICON(BLANK162)
|
DEF_ICON(BLANK162)
|
||||||
|
|||||||
@@ -639,7 +639,7 @@ static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *nt
|
|||||||
float colw= 0.6f*node_group_frame;
|
float colw= 0.6f*node_group_frame;
|
||||||
float col1= 6 - node_group_frame;
|
float col1= 6 - node_group_frame;
|
||||||
float col2= col1 + colw+6;
|
float col2= col1 + colw+6;
|
||||||
float col3= node_group_frame - arrowbutw - 6;
|
float col3= - arrowbutw - 6;
|
||||||
/* layout stuff for buttons on group right frame */
|
/* layout stuff for buttons on group right frame */
|
||||||
float cor1= 6;
|
float cor1= 6;
|
||||||
float cor2= cor1 + arrowbutw + 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
|
* 1) input: not internal
|
||||||
* 2) output: (node type uses const outputs) and (group output is unlinked)
|
* 2) output: (node type uses const outputs) and (group output is unlinked)
|
||||||
*/
|
*/
|
||||||
|
draw_value = 0;
|
||||||
switch (in_out) {
|
switch (in_out) {
|
||||||
case SOCK_IN:
|
case SOCK_IN:
|
||||||
draw_value = !(gsock && (gsock->flag & SOCK_INTERNAL));
|
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:
|
case SOCK_OUT:
|
||||||
if (gnode->typeinfo->flag & NODE_CONST_OUTPUT)
|
if (gnode->typeinfo->flag & NODE_CONST_OUTPUT)
|
||||||
draw_value = !(gsock && gsock->link);
|
draw_value = !(gsock && gsock->link);
|
||||||
else
|
|
||||||
draw_value = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (draw_value) {
|
if (draw_value) {
|
||||||
@@ -713,7 +712,7 @@ static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *nt
|
|||||||
uiBlockSetDirection(gnode->block, 0);
|
uiBlockSetDirection(gnode->block, 0);
|
||||||
|
|
||||||
/* remove button */
|
/* remove button */
|
||||||
offset = (in_out==SOCK_IN ? col3 : col1);
|
offset = (in_out==SOCK_IN ? col3 : cor1);
|
||||||
uiBlockSetEmboss(gnode->block, UI_EMBOSSN);
|
uiBlockSetEmboss(gnode->block, UI_EMBOSSN);
|
||||||
bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_remove", 0, ICON_X,
|
bt = uiDefIconButO(gnode->block, BUT, "NODE_OT_group_socket_remove", 0, ICON_X,
|
||||||
gsock->locx+offset, gsock->locy-0.5f*arrowbutw, arrowbutw, arrowbutw, "");
|
gsock->locx+offset, gsock->locy-0.5f*arrowbutw, arrowbutw, arrowbutw, "");
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
|
|||||||
PointerRNA ptr;
|
PointerRNA ptr;
|
||||||
bNodeSocket *nsock;
|
bNodeSocket *nsock;
|
||||||
float locx, locy;
|
float locx, locy;
|
||||||
float dy= locy;
|
float dy;
|
||||||
int buty;
|
int buty;
|
||||||
|
|
||||||
/* get "global" coords */
|
/* get "global" coords */
|
||||||
|
|||||||
@@ -447,9 +447,8 @@ void snode_set_context(SpaceNode *snode, Scene *scene)
|
|||||||
else if(snode->treetype==NTREE_COMPOSIT) {
|
else if(snode->treetype==NTREE_COMPOSIT) {
|
||||||
snode->id= &scene->id;
|
snode->id= &scene->id;
|
||||||
|
|
||||||
/* bit clumsy but reliable way to see if we draw first time */
|
/* update output sockets based on available layers */
|
||||||
if(snode->nodetree==NULL)
|
ntreeCompositForceHidden(scene->nodetree, scene);
|
||||||
ntreeCompositForceHidden(scene->nodetree, scene);
|
|
||||||
}
|
}
|
||||||
else if(snode->treetype==NTREE_TEXTURE) {
|
else if(snode->treetype==NTREE_TEXTURE) {
|
||||||
Tex *tx= NULL;
|
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)
|
static int compare_nodes(bNode *a, bNode *b)
|
||||||
{
|
{
|
||||||
bNode *parent;
|
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 */
|
/* 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 */
|
/* 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) {
|
for (parent = a->parent; parent; parent=parent->parent) {
|
||||||
|
/* if b is an ancestor, it is always behind a */
|
||||||
if (parent==b)
|
if (parent==b)
|
||||||
return 1;
|
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) {
|
for (parent = b->parent; parent; parent=parent->parent) {
|
||||||
|
/* if a is an ancestor, it is always behind b */
|
||||||
if (parent==a)
|
if (parent==a)
|
||||||
return 0;
|
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 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;
|
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;
|
return 1;
|
||||||
|
|
||||||
/* if one has a higher selection state (active > selected > nothing) */
|
/* 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;
|
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 1;
|
||||||
|
|
||||||
return 0;
|
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)
|
static void edit_node_properties_get(wmOperator *op, bNodeTree *ntree, bNode **rnode, bNodeSocket **rsock, int *rin_out)
|
||||||
{
|
{
|
||||||
bNode *node;
|
bNode *node;
|
||||||
bNodeSocket *sock;
|
bNodeSocket *sock=NULL;
|
||||||
char nodename[32];
|
char nodename[32];
|
||||||
int sockindex;
|
int sockindex;
|
||||||
int in_out;
|
int in_out;
|
||||||
|
|||||||
@@ -1017,18 +1017,26 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event
|
|||||||
|
|
||||||
if (has_rotation) {
|
if (has_rotation) {
|
||||||
|
|
||||||
const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES;
|
|
||||||
|
|
||||||
rv3d->view = RV3D_VIEW_USER;
|
rv3d->view = RV3D_VIEW_USER;
|
||||||
|
|
||||||
if (U.flag & USER_TRACKBALL) {
|
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 rot[4];
|
||||||
float axis[3];
|
float axis[3];
|
||||||
float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis);
|
float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis);
|
||||||
|
|
||||||
if (invert)
|
if (invert_roll)
|
||||||
angle = -angle;
|
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
|
// transform rotation axis from view to world coordinates
|
||||||
mul_qt_v3(view_inv, axis);
|
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);
|
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
|
||||||
} else {
|
} else {
|
||||||
/* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
|
/* 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 angle, rot[4];
|
||||||
float xvec[3] = {1,0,0};
|
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 vertical_sensitivity = 0.4f;
|
||||||
const float lateral_sensitivity = 0.6f;
|
const float lateral_sensitivity = 0.6f;
|
||||||
|
|
||||||
float pan_vec[3] = {lateral_sensitivity * ndof->tvec[0],
|
const int invert_panx = U.ndof_flag & NDOF_PANX_INVERT_AXIS;
|
||||||
vertical_sensitivity * ndof->tvec[1],
|
const int invert_pany = U.ndof_flag & NDOF_PANY_INVERT_AXIS;
|
||||||
forward_sensitivity * ndof->tvec[2]
|
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);
|
mul_v3_fl(pan_vec, speed * dt);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -802,7 +802,7 @@ typedef struct WeightVGEditModifierData {
|
|||||||
char defgrp_name[32]; /* Name of vertex group to edit. */
|
char defgrp_name[32]; /* Name of vertex group to edit. */
|
||||||
|
|
||||||
short edit_flags; /* Using MOD_WVG_EDIT_* flags. */
|
short edit_flags; /* Using MOD_WVG_EDIT_* flags. */
|
||||||
short mapping_mode; /* Using MOD_WVG_MAPPING_* defines. */
|
short falloff_type; /* Using MOD_WVG_MAPPING_* defines. */
|
||||||
float default_weight; /* Weight for vertices not in vgroup. */
|
float default_weight; /* Weight for vertices not in vgroup. */
|
||||||
|
|
||||||
/* Mapping stuff. */
|
/* Mapping stuff. */
|
||||||
@@ -919,7 +919,7 @@ typedef struct WeightVGProximityModifierData {
|
|||||||
float min_dist, max_dist; /* Distances mapping to 0.0/1.0 weights. */
|
float min_dist, max_dist; /* Distances mapping to 0.0/1.0 weights. */
|
||||||
|
|
||||||
/* Put here to avoid breaking existing struct... */
|
/* Put here to avoid breaking existing struct... */
|
||||||
short mapping_mode; /* Using MOD_WVG_MAPPING_* defines. */
|
short falloff_type; /* Using MOD_WVG_MAPPING_* defines. */
|
||||||
|
|
||||||
/* Padding... */
|
/* Padding... */
|
||||||
short pad_s1;
|
short pad_s1;
|
||||||
|
|||||||
@@ -607,6 +607,12 @@ extern UserDef U; /* from blenkernel blender.c */
|
|||||||
/* zoom is up/down if this flag is set (otherwise forward/backward) */
|
/* zoom is up/down if this flag is set (otherwise forward/backward) */
|
||||||
#define NDOF_ZOOM_UPDOWN (1 << 7)
|
#define NDOF_ZOOM_UPDOWN (1 << 7)
|
||||||
#define NDOF_ZOOM_INVERT (1 << 8)
|
#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
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -69,9 +69,9 @@ EnumPropertyItem modifier_type_items[] ={
|
|||||||
{eModifierType_Solidify, "SOLIDIFY", ICON_MOD_SOLIDIFY, "Solidify", ""},
|
{eModifierType_Solidify, "SOLIDIFY", ICON_MOD_SOLIDIFY, "Solidify", ""},
|
||||||
{eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subdivision Surface", ""},
|
{eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subdivision Surface", ""},
|
||||||
{eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""},
|
{eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""},
|
||||||
{eModifierType_WeightVGEdit, "WEIGHT_VGEDIT", ICON_MOD_WEIGHTVG, "WeightVG Edit", ""},
|
{eModifierType_WeightVGEdit, "VERTEX_WEIGHT_EDIT", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Edit", ""},
|
||||||
{eModifierType_WeightVGMix, "WEIGHT_VGMIX", ICON_MOD_WEIGHTVG, "WeightVG Mix", ""},
|
{eModifierType_WeightVGMix, "VERTEX_WEIGHT_MIX", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Mix", ""},
|
||||||
{eModifierType_WeightVGProximity, "WEIGHT_VGPROXIMITY", ICON_MOD_WEIGHTVG, "WeightVG Proximity", ""},
|
{eModifierType_WeightVGProximity, "VERTEX_WEIGHT_PROXIMITY", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Proximity", ""},
|
||||||
{0, "", 0, "Deform", ""},
|
{0, "", 0, "Deform", ""},
|
||||||
{eModifierType_Armature, "ARMATURE", ICON_MOD_ARMATURE, "Armature", ""},
|
{eModifierType_Armature, "ARMATURE", ICON_MOD_ARMATURE, "Armature", ""},
|
||||||
{eModifierType_Cast, "CAST", ICON_MOD_CAST, "Cast", ""},
|
{eModifierType_Cast, "CAST", ICON_MOD_CAST, "Cast", ""},
|
||||||
@@ -191,11 +191,11 @@ static StructRNA* rna_Modifier_refine(struct PointerRNA *ptr)
|
|||||||
case eModifierType_Warp:
|
case eModifierType_Warp:
|
||||||
return &RNA_WarpModifier;
|
return &RNA_WarpModifier;
|
||||||
case eModifierType_WeightVGEdit:
|
case eModifierType_WeightVGEdit:
|
||||||
return &RNA_WeightVGEditModifier;
|
return &RNA_VertexWeightEditModifier;
|
||||||
case eModifierType_WeightVGMix:
|
case eModifierType_WeightVGMix:
|
||||||
return &RNA_WeightVGMixModifier;
|
return &RNA_VertexWeightMixModifier;
|
||||||
case eModifierType_WeightVGProximity:
|
case eModifierType_WeightVGProximity:
|
||||||
return &RNA_WeightVGProximityModifier;
|
return &RNA_VertexWeightProximityModifier;
|
||||||
default:
|
default:
|
||||||
return &RNA_Modifier;
|
return &RNA_Modifier;
|
||||||
}
|
}
|
||||||
@@ -2513,7 +2513,7 @@ static void rna_def_modifier_weightvg_mask(BlenderRNA *brna, StructRNA *srna)
|
|||||||
|
|
||||||
prop= RNA_def_property(srna, "mask_constant", PROP_FLOAT, PROP_NONE);
|
prop= RNA_def_property(srna, "mask_constant", PROP_FLOAT, PROP_NONE);
|
||||||
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
|
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_ui_text(prop, "Influence", "Global influence of current modifications on vgroup.");
|
||||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||||
|
|
||||||
@@ -2555,7 +2555,7 @@ static void rna_def_modifier_weightvg_mask(BlenderRNA *brna, StructRNA *srna)
|
|||||||
|
|
||||||
static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
|
static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
|
||||||
{
|
{
|
||||||
static EnumPropertyItem weightvg_edit_mapping_mode_items[] = {
|
static EnumPropertyItem weightvg_edit_falloff_type_items[] = {
|
||||||
{MOD_WVG_MAPPING_NONE, "LINEAR", ICON_LINCURVE, "Linear", ""},
|
{MOD_WVG_MAPPING_NONE, "LINEAR", ICON_LINCURVE, "Linear", ""},
|
||||||
{MOD_WVG_MAPPING_CURVE, "CURVE", ICON_RNDCURVE, "Custom Curve", ""},
|
{MOD_WVG_MAPPING_CURVE, "CURVE", ICON_RNDCURVE, "Custom Curve", ""},
|
||||||
{MOD_WVG_MAPPING_SHARP, "SHARP", ICON_SHARPCURVE, "Sharp", ""},
|
{MOD_WVG_MAPPING_SHARP, "SHARP", ICON_SHARPCURVE, "Sharp", ""},
|
||||||
@@ -2569,11 +2569,11 @@ static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
|
|||||||
StructRNA *srna;
|
StructRNA *srna;
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
|
|
||||||
srna= RNA_def_struct(brna, "WeightVGEditModifier", "Modifier");
|
srna= RNA_def_struct(brna, "VertexWeightEditModifier", "Modifier");
|
||||||
RNA_def_struct_ui_text(srna, "WeightVG Edit Modifier",
|
RNA_def_struct_ui_text(srna, "WeightVG Edit Modifier",
|
||||||
"Edit the weights of vertices in a group.");
|
"Edit the weights of vertices in a group.");
|
||||||
RNA_def_struct_sdna(srna, "WeightVGEditModifierData");
|
RNA_def_struct_sdna(srna, "WeightVGEditModifierData");
|
||||||
RNA_def_struct_ui_icon(srna, ICON_MOD_WEIGHTVG);
|
RNA_def_struct_ui_icon(srna, ICON_MOD_VERTEX_WEIGHT);
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
|
prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
|
||||||
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
|
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
|
||||||
@@ -2581,9 +2581,9 @@ static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
|
|||||||
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGModifier_vgroup_set");
|
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightVGModifier_vgroup_set");
|
||||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "mapping_mode", PROP_ENUM, PROP_NONE);
|
prop= RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE);
|
||||||
RNA_def_property_enum_items(prop, weightvg_edit_mapping_mode_items);
|
RNA_def_property_enum_items(prop, weightvg_edit_falloff_type_items);
|
||||||
RNA_def_property_ui_text(prop, "Mapping Mode", "How weights are mapped to there new values.");
|
RNA_def_property_ui_text(prop, "Falloff Type", "How weights are mapped to there new values.");
|
||||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "use_add", PROP_BOOLEAN, PROP_NONE);
|
prop= RNA_def_property(srna, "use_add", PROP_BOOLEAN, PROP_NONE);
|
||||||
@@ -2653,11 +2653,11 @@ static void rna_def_modifier_weightvgmix(BlenderRNA *brna)
|
|||||||
StructRNA *srna;
|
StructRNA *srna;
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
|
|
||||||
srna= RNA_def_struct(brna, "WeightVGMixModifier", "Modifier");
|
srna= RNA_def_struct(brna, "VertexWeightMixModifier", "Modifier");
|
||||||
RNA_def_struct_ui_text(srna, "WeightVG Mix Modifier",
|
RNA_def_struct_ui_text(srna, "WeightVG Mix Modifier",
|
||||||
"Mix the weights of two vertex groups.");
|
"Mix the weights of two vertex groups.");
|
||||||
RNA_def_struct_sdna(srna, "WeightVGMixModifierData");
|
RNA_def_struct_sdna(srna, "WeightVGMixModifierData");
|
||||||
RNA_def_struct_ui_icon(srna, ICON_MOD_WEIGHTVG);
|
RNA_def_struct_ui_icon(srna, ICON_MOD_VERTEX_WEIGHT);
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "vertex_group_a", PROP_STRING, PROP_NONE);
|
prop= RNA_def_property(srna, "vertex_group_a", PROP_STRING, PROP_NONE);
|
||||||
RNA_def_property_string_sdna(prop, NULL, "defgrp_name_a");
|
RNA_def_property_string_sdna(prop, NULL, "defgrp_name_a");
|
||||||
@@ -2710,12 +2710,12 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
|
|||||||
{0, NULL, 0, NULL, NULL}};
|
{0, NULL, 0, NULL, NULL}};
|
||||||
|
|
||||||
static EnumPropertyItem proximity_geometry_items[] = {
|
static EnumPropertyItem proximity_geometry_items[] = {
|
||||||
{MOD_WVG_PROXIMITY_GEOM_VERTS, "VERTEX", ICON_VERTEXSEL, "Vertex", ""},
|
{MOD_WVG_PROXIMITY_GEOM_VERTS, "VERTEX", ICON_VERTEXSEL, "Vertex", "Compute distance to nearest vertex."},
|
||||||
{MOD_WVG_PROXIMITY_GEOM_EDGES, "EDGE", ICON_EDGESEL, "Edge", ""},
|
{MOD_WVG_PROXIMITY_GEOM_EDGES, "EDGE", ICON_EDGESEL, "Edge", "Compute distance to nearest edge."},
|
||||||
{MOD_WVG_PROXIMITY_GEOM_FACES, "FACE", ICON_FACESEL, "Face", ""},
|
{MOD_WVG_PROXIMITY_GEOM_FACES, "FACE", ICON_FACESEL, "Face", "Compute distance to nearest face."},
|
||||||
{0, NULL, 0, NULL, NULL}};
|
{0, NULL, 0, NULL, NULL}};
|
||||||
|
|
||||||
static EnumPropertyItem weightvg_proximity_mapping_mode_items[] = {
|
static EnumPropertyItem weightvg_proximity_falloff_type_items[] = {
|
||||||
{MOD_WVG_MAPPING_NONE, "LINEAR", ICON_LINCURVE, "Linear", ""},
|
{MOD_WVG_MAPPING_NONE, "LINEAR", ICON_LINCURVE, "Linear", ""},
|
||||||
/* No curve mapping here! */
|
/* No curve mapping here! */
|
||||||
{MOD_WVG_MAPPING_SHARP, "SHARP", ICON_SHARPCURVE, "Sharp", ""},
|
{MOD_WVG_MAPPING_SHARP, "SHARP", ICON_SHARPCURVE, "Sharp", ""},
|
||||||
@@ -2729,12 +2729,12 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
|
|||||||
StructRNA *srna;
|
StructRNA *srna;
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
|
|
||||||
srna= RNA_def_struct(brna, "WeightVGProximityModifier", "Modifier");
|
srna= RNA_def_struct(brna, "VertexWeightProximityModifier", "Modifier");
|
||||||
RNA_def_struct_ui_text(srna, "WeightVG Proximity Modifier",
|
RNA_def_struct_ui_text(srna, "WeightVG Proximity Modifier",
|
||||||
"Set the weights of vertices in a group from a target object's "
|
"Set the weights of vertices in a group from a target object's "
|
||||||
"distance.");
|
"distance.");
|
||||||
RNA_def_struct_sdna(srna, "WeightVGProximityModifierData");
|
RNA_def_struct_sdna(srna, "WeightVGProximityModifierData");
|
||||||
RNA_def_struct_ui_icon(srna, ICON_MOD_WEIGHTVG);
|
RNA_def_struct_ui_icon(srna, ICON_MOD_VERTEX_WEIGHT);
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
|
prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
|
||||||
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
|
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
|
||||||
@@ -2751,7 +2751,9 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
|
|||||||
RNA_def_property_enum_sdna(prop, NULL, "proximity_flags");
|
RNA_def_property_enum_sdna(prop, NULL, "proximity_flags");
|
||||||
RNA_def_property_enum_items(prop, proximity_geometry_items);
|
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_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");
|
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
|
prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
|
||||||
@@ -2763,18 +2765,18 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
|
|||||||
prop= RNA_def_property(srna, "min_dist", PROP_FLOAT, PROP_NONE);
|
prop= RNA_def_property(srna, "min_dist", PROP_FLOAT, PROP_NONE);
|
||||||
RNA_def_property_range(prop, 0.0, FLT_MAX);
|
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_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");
|
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "max_dist", PROP_FLOAT, PROP_NONE);
|
prop= RNA_def_property(srna, "max_dist", PROP_FLOAT, PROP_NONE);
|
||||||
RNA_def_property_range(prop, 0.0, FLT_MAX);
|
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_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");
|
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "mapping_mode", PROP_ENUM, PROP_NONE);
|
prop= RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE);
|
||||||
RNA_def_property_enum_items(prop, weightvg_proximity_mapping_mode_items);
|
RNA_def_property_enum_items(prop, weightvg_proximity_falloff_type_items);
|
||||||
RNA_def_property_ui_text(prop, "Mapping Mode", "How weights are mapped to there new values.");
|
RNA_def_property_ui_text(prop, "Falloff Type", "How weights are mapped to there new values.");
|
||||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||||
|
|
||||||
/* Common masking properties. */
|
/* Common masking properties. */
|
||||||
|
|||||||
@@ -2791,6 +2791,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");
|
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' */
|
/* 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 */
|
/* 3D view: fly */
|
||||||
prop= RNA_def_property(srna, "ndof_lock_horizon", PROP_BOOLEAN, PROP_NONE);
|
prop= RNA_def_property(srna, "ndof_lock_horizon", PROP_BOOLEAN, PROP_NONE);
|
||||||
RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_LOCK_HORIZON);
|
RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_LOCK_HORIZON);
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
/*
|
/*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
* The Original Code is Copyright (C) 2011 by Bastien Montagne.
|
* The Original Code is Copyright (C) 2011 by Bastien Montagne.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s): None yet.
|
* Contributor(s): None yet.
|
||||||
*
|
*
|
||||||
* ***** END GPL LICENSE BLOCK *****
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX I'd like to make modified weights visible in WeightPaint mode,
|
* XXX I'd like to make modified weights visible in WeightPaint mode,
|
||||||
* but couldn't figure a way to do this…
|
* but couldn't figure a way to do this...
|
||||||
* Maybe this will need changes in mesh_calc_modifiers (DerivedMesh.c)?
|
* Maybe this will need changes in mesh_calc_modifiers (DerivedMesh.c)?
|
||||||
* Or the WeightPaint mode code itself?
|
* Or the WeightPaint mode code itself?
|
||||||
*/
|
*/
|
||||||
@@ -63,16 +63,16 @@
|
|||||||
* vertex index (in case the weight tables do not cover the whole vertices...).
|
* vertex index (in case the weight tables do not cover the whole vertices...).
|
||||||
* cmap might be NULL, in which case curve mapping mode will return unmodified data.
|
* cmap might be NULL, in which case curve mapping mode will return unmodified data.
|
||||||
*/
|
*/
|
||||||
void weightvg_do_map(int num, float *new_w, short mode, CurveMapping *cmap)
|
void weightvg_do_map(int num, float *new_w, short falloff_type, CurveMapping *cmap)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Return immediately, if we have nothing to do! */
|
/* Return immediately, if we have nothing to do! */
|
||||||
/* Also security checks... */
|
/* Also security checks... */
|
||||||
if(((mode == MOD_WVG_MAPPING_CURVE) && (cmap == NULL))
|
if(((falloff_type == MOD_WVG_MAPPING_CURVE) && (cmap == NULL))
|
||||||
|| !ELEM7(mode, MOD_WVG_MAPPING_CURVE, MOD_WVG_MAPPING_SHARP, MOD_WVG_MAPPING_SMOOTH,
|
|| !ELEM7(falloff_type, MOD_WVG_MAPPING_CURVE, MOD_WVG_MAPPING_SHARP, MOD_WVG_MAPPING_SMOOTH,
|
||||||
MOD_WVG_MAPPING_ROOT, MOD_WVG_MAPPING_SPHERE, MOD_WVG_MAPPING_RANDOM,
|
MOD_WVG_MAPPING_ROOT, MOD_WVG_MAPPING_SPHERE, MOD_WVG_MAPPING_RANDOM,
|
||||||
MOD_WVG_MAPPING_STEP))
|
MOD_WVG_MAPPING_STEP))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Map each weight (vertex) to its new value, accordingly to the chosen mode. */
|
/* Map each weight (vertex) to its new value, accordingly to the chosen mode. */
|
||||||
@@ -81,7 +81,7 @@ void weightvg_do_map(int num, float *new_w, short mode, CurveMapping *cmap)
|
|||||||
|
|
||||||
/* Code borrowed from the warp modifier. */
|
/* Code borrowed from the warp modifier. */
|
||||||
/* Closely matches PROP_SMOOTH and similar. */
|
/* Closely matches PROP_SMOOTH and similar. */
|
||||||
switch(mode) {
|
switch(falloff_type) {
|
||||||
case MOD_WVG_MAPPING_CURVE:
|
case MOD_WVG_MAPPING_CURVE:
|
||||||
fac = curvemapping_evaluateF(cmap, 0, fac);
|
fac = curvemapping_evaluateF(cmap, 0, fac);
|
||||||
break;
|
break;
|
||||||
@@ -131,7 +131,7 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne
|
|||||||
if (texture) {
|
if (texture) {
|
||||||
/* The texture coordinates. */
|
/* The texture coordinates. */
|
||||||
float (*tex_co)[3];
|
float (*tex_co)[3];
|
||||||
/* See mapping note below… */
|
/* See mapping note below... */
|
||||||
MappingInfoModifierData t_map;
|
MappingInfoModifierData t_map;
|
||||||
float (*v_co)[3];
|
float (*v_co)[3];
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne
|
|||||||
|
|
||||||
texres.nor = NULL;
|
texres.nor = NULL;
|
||||||
get_texture_value(texture, tex_co[idx], &texres);
|
get_texture_value(texture, tex_co[idx], &texres);
|
||||||
/* Get the good channel value… */
|
/* Get the good channel value... */
|
||||||
switch(tex_use_channel) {
|
switch(tex_use_channel) {
|
||||||
case MOD_WVG_MASK_TEX_USE_INT:
|
case MOD_WVG_MASK_TEX_USE_INT:
|
||||||
org_w[i] = (new_w[i] * texres.tin * fact) + (org_w[i] * (1.0f - (texres.tin*fact)));
|
org_w[i] = (new_w[i] * texres.tin * fact) + (org_w[i] * (1.0f - (texres.tin*fact)));
|
||||||
|
|||||||
@@ -1,30 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
* The Original Code is Copyright (C) 2011 by Bastien Montagne.
|
* The Original Code is Copyright (C) 2011 by Bastien Montagne.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s): None yet.
|
* Contributor(s): None yet.
|
||||||
*
|
*
|
||||||
* ***** END GPL LICENSE BLOCK *****
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \file blender/modifiers/intern/MOD_util.h
|
/** \file blender/modifiers/intern/MOD_util.h
|
||||||
* \ingroup modifiers
|
* \ingroup modifiers
|
||||||
|
|||||||
@@ -1,30 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
* The Original Code is Copyright (C) 2011 by Bastien Montagne.
|
* The Original Code is Copyright (C) 2011 by Bastien Montagne.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s): None yet.
|
* Contributor(s): None yet.
|
||||||
*
|
*
|
||||||
* ***** END GPL LICENSE BLOCK *****
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX I'd like to make modified weights visible in WeightPaint mode,
|
* XXX I'd like to make modified weights visible in WeightPaint mode,
|
||||||
@@ -62,7 +62,7 @@ static void initData(ModifierData *md)
|
|||||||
{
|
{
|
||||||
WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md;
|
WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md;
|
||||||
wmd->edit_flags = 0;
|
wmd->edit_flags = 0;
|
||||||
wmd->mapping_mode = MOD_WVG_MAPPING_NONE;
|
wmd->falloff_type = MOD_WVG_MAPPING_NONE;
|
||||||
wmd->default_weight = 0.0f;
|
wmd->default_weight = 0.0f;
|
||||||
|
|
||||||
wmd->cmap_curve = curvemapping_add(1, 0.0, 0.0, 1.0, 1.0);
|
wmd->cmap_curve = curvemapping_add(1, 0.0, 0.0, 1.0, 1.0);
|
||||||
@@ -90,7 +90,7 @@ static void copyData(ModifierData *md, ModifierData *target)
|
|||||||
BLI_strncpy(twmd->defgrp_name, wmd->defgrp_name, sizeof(twmd->defgrp_name));
|
BLI_strncpy(twmd->defgrp_name, wmd->defgrp_name, sizeof(twmd->defgrp_name));
|
||||||
|
|
||||||
twmd->edit_flags = wmd->edit_flags;
|
twmd->edit_flags = wmd->edit_flags;
|
||||||
twmd->mapping_mode = wmd->mapping_mode;
|
twmd->falloff_type = wmd->falloff_type;
|
||||||
twmd->default_weight = wmd->default_weight;
|
twmd->default_weight = wmd->default_weight;
|
||||||
|
|
||||||
twmd->cmap_curve = curvemapping_copy(wmd->cmap_curve);
|
twmd->cmap_curve = curvemapping_copy(wmd->cmap_curve);
|
||||||
@@ -268,8 +268,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Do mapping. */
|
/* Do mapping. */
|
||||||
if (wmd->mapping_mode != MOD_WVG_MAPPING_NONE) {
|
if (wmd->falloff_type != MOD_WVG_MAPPING_NONE) {
|
||||||
weightvg_do_map(numVerts, new_w, wmd->mapping_mode, wmd->cmap_curve);
|
weightvg_do_map(numVerts, new_w, wmd->falloff_type, wmd->cmap_curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do masking. */
|
/* Do masking. */
|
||||||
@@ -298,7 +298,7 @@ static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
|
|||||||
|
|
||||||
|
|
||||||
ModifierTypeInfo modifierType_WeightVGEdit = {
|
ModifierTypeInfo modifierType_WeightVGEdit = {
|
||||||
/* name */ "WeightVGEdit",
|
/* name */ "VertexWeightEdit",
|
||||||
/* structName */ "WeightVGEditModifierData",
|
/* structName */ "WeightVGEditModifierData",
|
||||||
/* structSize */ sizeof(WeightVGEditModifierData),
|
/* structSize */ sizeof(WeightVGEditModifierData),
|
||||||
/* type */ eModifierTypeType_Nonconstructive,
|
/* type */ eModifierTypeType_Nonconstructive,
|
||||||
|
|||||||
@@ -1,30 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
* The Original Code is Copyright (C) 2011 by Bastien Montagne.
|
* The Original Code is Copyright (C) 2011 by Bastien Montagne.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s): None yet.
|
* Contributor(s): None yet.
|
||||||
*
|
*
|
||||||
* ***** END GPL LICENSE BLOCK *****
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX I'd like to make modified weights visible in WeightPaint mode,
|
* XXX I'd like to make modified weights visible in WeightPaint mode,
|
||||||
@@ -438,7 +438,7 @@ static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
|
|||||||
|
|
||||||
|
|
||||||
ModifierTypeInfo modifierType_WeightVGMix = {
|
ModifierTypeInfo modifierType_WeightVGMix = {
|
||||||
/* name */ "WeightVGMix",
|
/* name */ "VertexWeightMix",
|
||||||
/* structName */ "WeightVGMixModifierData",
|
/* structName */ "WeightVGMixModifierData",
|
||||||
/* structSize */ sizeof(WeightVGMixModifierData),
|
/* structSize */ sizeof(WeightVGMixModifierData),
|
||||||
/* type */ eModifierTypeType_Nonconstructive,
|
/* type */ eModifierTypeType_Nonconstructive,
|
||||||
|
|||||||
@@ -1,30 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
* The Original Code is Copyright (C) 2011 by Bastien Montagne.
|
* The Original Code is Copyright (C) 2011 by Bastien Montagne.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s): None yet.
|
* Contributor(s): None yet.
|
||||||
*
|
*
|
||||||
* ***** END GPL LICENSE BLOCK *****
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX I'd like to make modified weights visible in WeightPaint mode,
|
* XXX I'd like to make modified weights visible in WeightPaint mode,
|
||||||
@@ -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 */
|
const float range_inv= 1.0f / (max_d - min_d); /* invert since multiplication is faster */
|
||||||
unsigned int i= nidx;
|
unsigned int i= nidx;
|
||||||
while (i-- > 0) {
|
if(max_d == min_d) {
|
||||||
if (weights[i] >= max_d) weights[i]= 1.0f; /* most likely case first */
|
while (i-- > 0) {
|
||||||
else if(weights[i] <= min_d) weights[i]= 0.0f;
|
weights[i] = (weights[i] >= max_d) ? 1.0f : 0.0f; /* "Step" behavior... */
|
||||||
else weights[i]= (weights[i] - min_d) * range_inv;
|
}
|
||||||
|
}
|
||||||
|
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)) {
|
if(!ELEM(mode, MOD_WVG_MAPPING_NONE, MOD_WVG_MAPPING_CURVE)) {
|
||||||
@@ -220,7 +234,7 @@ static void initData(ModifierData *md)
|
|||||||
wmd->proximity_mode = MOD_WVG_PROXIMITY_OBJECT;
|
wmd->proximity_mode = MOD_WVG_PROXIMITY_OBJECT;
|
||||||
wmd->proximity_flags = MOD_WVG_PROXIMITY_GEOM_VERTS;
|
wmd->proximity_flags = MOD_WVG_PROXIMITY_GEOM_VERTS;
|
||||||
|
|
||||||
wmd->mapping_mode = MOD_WVG_MAPPING_NONE;
|
wmd->falloff_type = MOD_WVG_MAPPING_NONE;
|
||||||
|
|
||||||
wmd->mask_constant = 1.0f;
|
wmd->mask_constant = 1.0f;
|
||||||
wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */
|
wmd->mask_tex_use_channel = MOD_WVG_MASK_TEX_USE_INT; /* Use intensity by default. */
|
||||||
@@ -238,7 +252,7 @@ static void copyData(ModifierData *md, ModifierData *target)
|
|||||||
twmd->proximity_flags = wmd->proximity_flags;
|
twmd->proximity_flags = wmd->proximity_flags;
|
||||||
twmd->proximity_ob_target = wmd->proximity_ob_target;
|
twmd->proximity_ob_target = wmd->proximity_ob_target;
|
||||||
|
|
||||||
twmd->mapping_mode = wmd->mapping_mode;
|
twmd->falloff_type = wmd->falloff_type;
|
||||||
|
|
||||||
twmd->mask_constant = wmd->mask_constant;
|
twmd->mask_constant = wmd->mask_constant;
|
||||||
BLI_strncpy(twmd->mask_defgrp_name, wmd->mask_defgrp_name, sizeof(twmd->mask_defgrp_name));
|
BLI_strncpy(twmd->mask_defgrp_name, wmd->mask_defgrp_name, sizeof(twmd->mask_defgrp_name));
|
||||||
@@ -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_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];
|
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, fall back to default obj2vert behavior. */
|
||||||
else {
|
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. */
|
/* Do masking. */
|
||||||
weightvg_do_mask(numIdx, indices, org_w, new_w, ob, ret, wmd->mask_constant,
|
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_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel,
|
||||||
wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);
|
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->mapping_mode);
|
|
||||||
|
|
||||||
/* Update vgroup. Note we never add nor remove vertices from vgroup here. */
|
/* 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);
|
weightvg_update_vg(dvert, defgrp_idx, numIdx, indices, org_w, 0, 0.0f, 0, 0.0f);
|
||||||
|
|
||||||
@@ -522,7 +539,7 @@ static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
|
|||||||
|
|
||||||
|
|
||||||
ModifierTypeInfo modifierType_WeightVGProximity = {
|
ModifierTypeInfo modifierType_WeightVGProximity = {
|
||||||
/* name */ "WeightVGProximity",
|
/* name */ "VertexWeightProximity",
|
||||||
/* structName */ "WeightVGProximityModifierData",
|
/* structName */ "WeightVGProximityModifierData",
|
||||||
/* structSize */ sizeof(WeightVGProximityModifierData),
|
/* structSize */ sizeof(WeightVGProximityModifierData),
|
||||||
/* type */ eModifierTypeType_Nonconstructive,
|
/* type */ eModifierTypeType_Nonconstructive,
|
||||||
|
|||||||
@@ -341,15 +341,15 @@ static void *exec_composite_node(void *nodeexec_v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* return total of executable nodes, for timecursor */
|
/* 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 *nsin[MAX_SOCKET]; /* arbitrary... watch this */
|
||||||
bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
|
bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */
|
||||||
|
bNodeExec *nodeexec;
|
||||||
bNode *node;
|
bNode *node;
|
||||||
bNodeSocket *sock;
|
bNodeSocket *sock;
|
||||||
int totnode= 0, group_edit= 0;
|
int n, totnode= 0, group_edit= 0;
|
||||||
|
|
||||||
/* note; do not add a dependency sort here, the stack was created already */
|
|
||||||
|
|
||||||
/* if we are in group edit, viewer nodes get skipped when group has viewer */
|
/* if we are in group edit, viewer nodes get skipped when group has viewer */
|
||||||
for(node= ntree->nodes.first; node; node= node->next)
|
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))
|
if(ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER))
|
||||||
group_edit= 1;
|
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;
|
int a;
|
||||||
|
node = nodeexec->node;
|
||||||
|
|
||||||
node_get_stack(node, thd->stack, nsin, nsout);
|
node_get_stack(node, exec->stack, nsin, nsout);
|
||||||
|
|
||||||
/* test the outputs */
|
/* test the outputs */
|
||||||
/* skip value-only nodes (should be in type!) */
|
/* 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 */
|
/* last step: set the stack values for only-value nodes */
|
||||||
/* just does all now, compared to a full buffer exec this is nothing */
|
/* just does all now, compared to a full buffer exec this is nothing */
|
||||||
if(totnode) {
|
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->need_exec==0 && node_only_value(node)) {
|
||||||
if(node->typeinfo->execfunc) {
|
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);
|
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 */
|
/* 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:
|
/* node outputs can be freed when:
|
||||||
- not a render result or image node
|
- not a render result or image node
|
||||||
- when node outputs go to nodes all being set NODE_FINISHED
|
- when node outputs go to nodes all being set NODE_FINISHED
|
||||||
*/
|
*/
|
||||||
|
bNodeTree *ntree = exec->nodetree;
|
||||||
|
bNodeExec *nodeexec;
|
||||||
bNode *node;
|
bNode *node;
|
||||||
bNodeSocket *sock;
|
bNodeSocket *sock;
|
||||||
|
int n;
|
||||||
|
|
||||||
/* set exec flag for finished nodes that might need freed */
|
/* set exec flag for finished nodes that might need freed */
|
||||||
for(node= ntree->nodes.first; node; node= node->next) {
|
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)
|
if(node->exec & NODE_FINISHED)
|
||||||
node->exec |= NODE_FREEBUFS;
|
node->exec |= NODE_FREEBUFS;
|
||||||
}
|
}
|
||||||
/* clear this flag for input links that are not done yet */
|
/* clear this flag for input links that are not done yet.
|
||||||
for(node= ntree->nodes.first; node; node= node->next) {
|
* 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) {
|
if((node->exec & NODE_FINISHED)==0) {
|
||||||
for(sock= node->inputs.first; sock; sock= sock->next)
|
for(sock= node->inputs.first; sock; sock= sock->next)
|
||||||
if(sock->link)
|
if(sock->link)
|
||||||
@@ -526,7 +535,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
|
|||||||
ListBase threads;
|
ListBase threads;
|
||||||
ThreadData thdata;
|
ThreadData thdata;
|
||||||
int totnode, curnode, rendering= 1, n;
|
int totnode, curnode, rendering= 1, n;
|
||||||
bNodeTreeExec *exec= NULL;
|
bNodeTreeExec *exec= ntree->execdata;
|
||||||
|
|
||||||
if(ntree==NULL) return;
|
if(ntree==NULL) return;
|
||||||
|
|
||||||
@@ -551,7 +560,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
|
|||||||
BLI_srandom(rd->cfra);
|
BLI_srandom(rd->cfra);
|
||||||
|
|
||||||
/* sets need_exec tags in nodes */
|
/* 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);
|
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 */
|
/* freeing unused buffers */
|
||||||
if(rd->scemode & R_COMP_FREE)
|
if(rd->scemode & R_COMP_FREE)
|
||||||
freeExecutableNode(ntree, exec);
|
freeExecutableNode(exec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else rendering= 1;
|
else rendering= 1;
|
||||||
|
|||||||
@@ -36,7 +36,8 @@
|
|||||||
|
|
||||||
/* **************** VALUE ******************** */
|
/* **************** VALUE ******************** */
|
||||||
static bNodeSocketTemplate cmp_node_value_out[]= {
|
static bNodeSocketTemplate cmp_node_value_out[]= {
|
||||||
{ SOCK_FLOAT, 0, "Value"},
|
/* XXX value nodes use the output sockets for buttons, so we need explicit limits here! */
|
||||||
|
{ SOCK_FLOAT, 0, "Value", 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX},
|
||||||
{ -1, 0, "" }
|
{ -1, 0, "" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -878,7 +878,7 @@ static void loop_sync(bNodeTree *ntree, int sync_in_out)
|
|||||||
while (sync && ((sync->flag & SOCK_INTERNAL) || !(sync->flag & SOCK_DYNAMIC)))
|
while (sync && ((sync->flag & SOCK_INTERNAL) || !(sync->flag & SOCK_DYNAMIC)))
|
||||||
sync = sync->next;
|
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 (sock->storage==NULL) {
|
||||||
/* if mirror index is 0, the sockets is newly added and a new mirror must be created. */
|
/* 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);
|
mirror = node_group_expose_socket(ntree, sock, sync_in_out);
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
|
|||||||
memset(shr, 0, sizeof(ShadeResult));
|
memset(shr, 0, sizeof(ShadeResult));
|
||||||
|
|
||||||
if (!exec)
|
if (!exec)
|
||||||
exec = ntree->execdata = ntreeShaderBeginExecTree(exec->nodetree, 1);
|
exec = ntree->execdata = ntreeShaderBeginExecTree(ntree, 1);
|
||||||
|
|
||||||
nts= ntreeGetThreadStack(exec, shi->thread);
|
nts= ntreeGetThreadStack(exec, shi->thread);
|
||||||
ntreeExecThreadNodes(exec, nts, &scd, shi->thread);
|
ntreeExecThreadNodes(exec, nts, &scd, shi->thread);
|
||||||
|
|||||||
@@ -36,7 +36,8 @@
|
|||||||
|
|
||||||
/* **************** VALUE ******************** */
|
/* **************** VALUE ******************** */
|
||||||
static bNodeSocketTemplate sh_node_value_out[]= {
|
static bNodeSocketTemplate sh_node_value_out[]= {
|
||||||
{ SOCK_FLOAT, 0, "Value"},
|
/* XXX value nodes use the output sockets for buttons, so we need explicit limits here! */
|
||||||
|
{ SOCK_FLOAT, 0, "Value", 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX},
|
||||||
{ -1, 0, "" }
|
{ -1, 0, "" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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 */
|
/* 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 *PyC_ExceptionBuffer(void)
|
||||||
{
|
{
|
||||||
PyObject *traceback_mod= NULL;
|
PyObject *traceback_mod= NULL;
|
||||||
@@ -236,6 +240,78 @@ error_cleanup:
|
|||||||
|
|
||||||
return ret;
|
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 */
|
/* string conversion, escape non-unicode chars, coerce must be set to NULL */
|
||||||
const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
|
const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
|
||||||
|
|||||||
@@ -441,12 +441,17 @@ static void wm_operator_reports(bContext *C, wmOperator *op, int retval, int pop
|
|||||||
if(op->reports->list.first) {
|
if(op->reports->list.first) {
|
||||||
/* FIXME, temp setting window, see other call to uiPupMenuReports for why */
|
/* FIXME, temp setting window, see other call to uiPupMenuReports for why */
|
||||||
wmWindow *win_prev= CTX_wm_window(C);
|
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)
|
if(win_prev==NULL)
|
||||||
CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first);
|
CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first);
|
||||||
|
|
||||||
uiPupMenuReports(C, op->reports);
|
uiPupMenuReports(C, op->reports);
|
||||||
|
|
||||||
CTX_wm_window_set(C, win_prev);
|
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 :(
|
* 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 */
|
* it can be removed without breaking anything but then no linking errors - campbell */
|
||||||
wmWindow *win_prev= CTX_wm_window(C);
|
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)
|
if(win_prev==NULL)
|
||||||
CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first);
|
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);
|
BLI_movelisttolist(&CTX_wm_reports(C)->list, &handler->op->reports->list);
|
||||||
|
|
||||||
CTX_wm_window_set(C, win_prev);
|
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);
|
WM_operator_free(handler->op);
|
||||||
|
|||||||
Reference in New Issue
Block a user