merging trunk 15964 -> 16116
authorMartin Poirier <theeth@yahoo.com>
Thu, 14 Aug 2008 21:16:48 +0000 (21:16 +0000)
committerMartin Poirier <theeth@yahoo.com>
Thu, 14 Aug 2008 21:16:48 +0000 (21:16 +0000)
93 files changed:
CMakeLists.txt
config/linux2-config.py
projectfiles_vc7/blender/BPY_python/BPY_python.vcproj
projectfiles_vc7/blender/blender.sln
projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj
projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
release/VERSION
release/datafiles/splash.jpg
release/scripts/flt_export.py
release/scripts/flt_palettemanager.py
release/scripts/import_dxf.py
release/scripts/ply_export.py
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_texture.h
source/blender/blenkernel/bad_level_call_stubs/stubs.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenkernel/intern/texture.c
source/blender/blenlib/BLI_kdopbvh.h
source/blender/blenlib/intern/BLI_kdopbvh.c
source/blender/include/BIF_editarmature.h
source/blender/include/BIF_editmesh.h
source/blender/include/butspace.h
source/blender/python/BPY_interface.c
source/blender/python/api2_2x/Blender.c
source/blender/python/api2_2x/Constraint.c
source/blender/python/api2_2x/Mathutils.c
source/blender/python/api2_2x/Mathutils.h
source/blender/python/api2_2x/Texture.c
source/blender/python/api2_2x/doc/Render.py
source/blender/python/api2_2x/doc/Texture.py
source/blender/render/intern/source/rayshade.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/editarmature.c
source/blender/src/editmesh_mods.c
source/blender/src/editobject.c
source/blender/src/header_view3d.c
source/blender/src/poselib.c
source/blender/src/splash.jpg.c
source/blender/src/transform_conversions.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/Converter/BL_ActionActuator.cpp
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/BL_ShapeActionActuator.cpp
source/gameengine/Converter/KX_ConvertActuators.cpp
source/gameengine/Converter/KX_IpoConvert.cpp
source/gameengine/Expressions/InputParser.cpp
source/gameengine/Expressions/ListValue.cpp
source/gameengine/Expressions/PyObjectPlus.cpp
source/gameengine/Expressions/PyObjectPlus.h
source/gameengine/Expressions/Value.cpp
source/gameengine/Expressions/Value.h
source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
source/gameengine/GameLogic/SCA_ILogicBrick.cpp
source/gameengine/GameLogic/SCA_PythonController.cpp
source/gameengine/GamePlayer/ghost/GPG_Application.cpp
source/gameengine/Ketsji/BL_Shader.cpp
source/gameengine/Ketsji/CMakeLists.txt
source/gameengine/Ketsji/KX_CameraActuator.cpp
source/gameengine/Ketsji/KX_CameraActuator.h
source/gameengine/Ketsji/KX_ConstraintActuator.cpp
source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_IpoActuator.cpp
source/gameengine/Ketsji/KX_MeshProxy.cpp
source/gameengine/Ketsji/KX_ObjectActuator.cpp
source/gameengine/Ketsji/KX_ParentActuator.cpp
source/gameengine/Ketsji/KX_ParentActuator.h
source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_PythonInit.h
source/gameengine/Ketsji/KX_RadarSensor.cpp
source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
source/gameengine/Ketsji/KX_TouchEventManager.cpp
source/gameengine/Ketsji/KX_TrackToActuator.cpp
source/gameengine/Ketsji/KX_TrackToActuator.h
source/gameengine/Ketsji/KX_VehicleWrapper.cpp
source/gameengine/Ketsji/SConscript
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.h
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
source/gameengine/PyDoc/KX_CameraActuator.py
source/gameengine/PyDoc/KX_ParentActuator.py
source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py
source/gameengine/PyDoc/KX_TrackToActuator.py
tools/btools.py

index 5a23e77d9f81fa04100e840f1bab164e442a317f..0ea26750ec1c75aa03c40b02972b068cdbfaaeb0 100644 (file)
@@ -183,9 +183,9 @@ IF(UNIX)
   SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++")
 
   IF(WITH_OPENMP)
-    SET(LLIBS "${LLIBS} -lgomp ")
-    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")
-    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ")
+    SET(LLIBS "${LLIBS} -lgomp")
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp")
+    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
   ENDIF(WITH_OPENMP)
 
 
index 6bde0664fe598475cc2e4f3a984037a1f9f3c577..fe4325361a83b4874abda7fedc749fae31fbdb1e 100644 (file)
@@ -139,7 +139,7 @@ BF_OPENJPEG_LIB = ''
 BF_OPENJPEG_INC = '${BF_OPENJPEG}/include'
 BF_OPENJPEG_LIBPATH='${BF_OPENJPEG}/lib'
 
-WITH_BF_REDCODE = 'true'  
+WITH_BF_REDCODE = 'false'  
 BF_REDCODE = '#extern/libredcode'
 BF_REDCODE_LIB = ''
 # Uncomment the following two lines to use system's ffmpeg
index a31b9130db358e5824a2e84b0e8b4bd9fd41aa7a..97f70a26db4ffdbafaed1bd9cbadd3fa8431ab2e 100644 (file)
                        <Tool
                                Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
                </Configuration>
+               <Configuration
+                       Name="BlenderPlayer Debug|Win32"
+                       OutputDirectory="$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="4"
+                       UseOfMFC="0"
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"
+                       CharacterSet="2">
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\img;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenloader;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\SoundSystem"
+                               PreprocessorDefinitions="_DEBUG,WIN32,_LIB;WITH_FFMPEG"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="1"
+                               DisableLanguageExtensions="FALSE"
+                               DefaultCharIsUnsigned="TRUE"
+                               UsePrecompiledHeader="2"
+                               PrecompiledHeaderFile="..\..\..\..\build\msvc_7\source\blender\python\debug\BPY_python.pch"
+                               AssemblerListingLocation="..\..\..\..\build\msvc_7\source\blender\python\debug\"
+                               ObjectFile="..\..\..\..\build\msvc_7\source\blender\python\debug\"
+                               ProgramDataBaseFileName="..\..\..\..\build\msvc_7\source\blender\python\debug\"
+                               WarningLevel="4"
+                               SuppressStartupBanner="TRUE"
+                               Detect64BitPortabilityProblems="FALSE"
+                               DebugInformationFormat="3"
+                               CompileAs="0"
+                               DisableSpecificWarnings="4100"/>
+                       <Tool
+                               Name="VCCustomBuildTool"/>
+                       <Tool
+                               Name="VCLibrarianTool"
+                               OutputFile="..\..\..\..\build\msvc_7\libs\debug\BPY_python.lib"
+                               SuppressStartupBanner="TRUE"/>
+                       <Tool
+                               Name="VCMIDLTool"/>
+                       <Tool
+                               Name="VCPostBuildEventTool"/>
+                       <Tool
+                               Name="VCPreBuildEventTool"/>
+                       <Tool
+                               Name="VCPreLinkEventTool"/>
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                               Culture="1033"/>
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"/>
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"/>
+                       <Tool
+                               Name="VCManagedWrapperGeneratorTool"/>
+                       <Tool
+                               Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+               </Configuration>
+               <Configuration
+                       Name="BlenderPlayer Release|Win32"
+                       OutputDirectory="$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="4"
+                       UseOfMFC="0"
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"
+                       CharacterSet="2">
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               InlineFunctionExpansion="1"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\img;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenloader;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\SoundSystem;..\..\..\..\lib\windows\ffmpeg\include"
+                               PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
+                               StringPooling="TRUE"
+                               RuntimeLibrary="0"
+                               EnableFunctionLevelLinking="TRUE"
+                               DefaultCharIsUnsigned="TRUE"
+                               UsePrecompiledHeader="2"
+                               PrecompiledHeaderFile="..\..\..\..\build\msvc_7\source\blender\python\BPY_python.pch"
+                               AssemblerListingLocation="..\..\..\..\build\msvc_7\source\blender\python\"
+                               ObjectFile="..\..\..\..\build\msvc_7\source\blender\python\"
+                               ProgramDataBaseFileName="..\..\..\..\build\msvc_7\source\blender\python\"
+                               WarningLevel="3"
+                               SuppressStartupBanner="TRUE"
+                               Detect64BitPortabilityProblems="FALSE"
+                               CompileAs="0"
+                               DisableSpecificWarnings="4100"/>
+                       <Tool
+                               Name="VCCustomBuildTool"/>
+                       <Tool
+                               Name="VCLibrarianTool"
+                               OutputFile="..\..\..\..\build\msvc_7\libs\BPY_python.lib"
+                               SuppressStartupBanner="TRUE"/>
+                       <Tool
+                               Name="VCMIDLTool"/>
+                       <Tool
+                               Name="VCPostBuildEventTool"/>
+                       <Tool
+                               Name="VCPreBuildEventTool"/>
+                       <Tool
+                               Name="VCPreLinkEventTool"/>
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                               PreprocessorDefinitions="NDEBUG"
+                               Culture="1033"/>
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"/>
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"/>
+                       <Tool
+                               Name="VCManagedWrapperGeneratorTool"/>
+                       <Tool
+                               Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+               </Configuration>
        </Configurations>
        <References>
        </References>
index 60c2d8f2d4c821e30cbdfe8399a2e19243d84316..1b069fa46773cd6f9774d8b338ecd33e6a6d433e 100644 (file)
@@ -152,6 +152,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GP_ghost", "..\gameengine\g
                {E109F1A5-FDD3-4F56-A1C4-96867EEA4C5B} = {E109F1A5-FDD3-4F56-A1C4-96867EEA4C5B}
                {727F90AC-ABE6-40BF-8937-C2F2F1D13DEA} = {727F90AC-ABE6-40BF-8937-C2F2F1D13DEA}
                {E90C7BC2-CF30-4A60-A8F2-0050D592E358} = {E90C7BC2-CF30-4A60-A8F2-0050D592E358}
+               {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA} = {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}
                {32CC75E2-EE85-45E6-8E3D-513F58464F43} = {32CC75E2-EE85-45E6-8E3D-513F58464F43}
                {9A307EE5-CD77-47BC-BD87-62508C7E19D8} = {9A307EE5-CD77-47BC-BD87-62508C7E19D8}
                {AB590CED-F71F-4A17-A89B-18583ECD633D} = {AB590CED-F71F-4A17-A89B-18583ECD633D}
@@ -248,6 +249,8 @@ Global
                Debug = Debug
                Release = Release
        EndGlobalSection
+       GlobalSection(ProjectDependencies) = postSolution
+       EndGlobalSection
        GlobalSection(ProjectConfiguration) = postSolution
                {F78B7FC9-DE32-465E-9F26-BB0B6B7A2EAF}.3D Plugin Debug.ActiveCfg = Blender Debug|Win32
                {F78B7FC9-DE32-465E-9F26-BB0B6B7A2EAF}.3D Plugin Release.ActiveCfg = Blender Release|Win32
@@ -387,8 +390,10 @@ Global
                {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}.Blender Debug.Build.0 = Blender Debug|Win32
                {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}.Blender Release.ActiveCfg = Blender Release|Win32
                {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}.Blender Release.Build.0 = Blender Release|Win32
-               {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}.BlenderPlayer Debug.ActiveCfg = Blender Debug|Win32
-               {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}.BlenderPlayer Release.ActiveCfg = Blender Release|Win32
+               {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}.BlenderPlayer Debug.ActiveCfg = BlenderPlayer Debug|Win32
+               {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}.BlenderPlayer Debug.Build.0 = BlenderPlayer Debug|Win32
+               {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}.BlenderPlayer Release.ActiveCfg = BlenderPlayer Release|Win32
+               {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}.BlenderPlayer Release.Build.0 = BlenderPlayer Release|Win32
                {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}.Debug.ActiveCfg = Blender Debug|Win32
                {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}.Debug.Build.0 = Blender Debug|Win32
                {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}.Release.ActiveCfg = Blender Release|Win32
index 8efff1742b074f7732c1ead055d5e44bc5268489..0ea3503a289f2cd6a2ac849dd40b91dea88faf81 100644 (file)
                        <File
                                RelativePath="..\..\..\source\blender\blenkernel\intern\brush.c">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\blenkernel\intern\bvhutils.c">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\blenkernel\intern\CCGSubSurf.c">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\blenkernel\BKE_brush.h">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\blenkernel\BKE_bvhutils.h">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\blenkernel\BKE_cdderivedmesh.h">
                        </File>
index 323d2cc9b045b89c50f82afb229a7ac05aaf3cc0..c046d434cb34c14a93134a7e54ad05f1dfb8fad8 100644 (file)
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\python\api2_2x"
                                PreprocessorDefinitions="JANCODEPANCO;WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG;USE_SUMO_SOLID;WITH_GLEXT"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
                        <Tool
                                Name="VCCLCompilerTool"
                                InlineFunctionExpansion="1"
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\python\api2_2x"
                                PreprocessorDefinitions="NDEBUG;WIN32;_LIB;USE_SUMO_SOLID;WITH_GLEXT"
                                StringPooling="TRUE"
                                RuntimeLibrary="0"
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\python\api2_2x"
                                PreprocessorDefinitions="JANCODEPANCO;WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG;USE_SUMO_SOLID;WITH_GLEXT"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
                        <Tool
                                Name="VCCLCompilerTool"
                                InlineFunctionExpansion="1"
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet;..\..\..\source\blender\python\api2_2x"
                                PreprocessorDefinitions="NDEBUG;WIN32;_LIB;USE_SUMO_SOLID;WITH_GLEXT"
                                StringPooling="TRUE"
                                RuntimeLibrary="0"
index e72716a7902eb50ea60dcfdf6258de2d5f5ebd09..5d8213c95e7315cd60de7ebf6c1df9697be3b052 100644 (file)
@@ -1 +1 @@
-2.46
+2.47
index 6a1bd28d50979cc38a4309b6cf55a24af7a9343d..684a12c3cbb11786236b5951c7b8b6c86c0edddf 100644 (file)
Binary files a/release/datafiles/splash.jpg and b/release/datafiles/splash.jpg differ
index 2b9db74c77076a38d5c9642f879259fb9e3fdbb5..c099c8e62d165dab42b555bba98e33d1e4979113 100644 (file)
@@ -525,8 +525,8 @@ class FaceDesc:
        def __init__(self):
                self.vertex_index_lst = []
                self.mface = None
-               self.texture_index = -1
-               self.material_index = -1
+               self.texture_index = 65535
+               self.material_index = 65535
                self.color_index = 127
                self.renderstyle = 0
                self.twoside = 0
@@ -979,8 +979,14 @@ class FLTNode(Node):
                        self.header.fw.write_char(0)                                    # Reserved
                        self.header.fw.write_char(alpha)                                    # Template
                        self.header.fw.write_short(-1)                                  # Detail tex pat index
-                       self.header.fw.write_short(face_desc.texture_index)             # Tex pattern index
-                       self.header.fw.write_short(face_desc.material_index)            # material index
+                       if face_desc.texture_index == -1:
+                               self.header.fw.write_ushort(65535)
+                       else:
+                               self.header.fw.write_ushort(face_desc.texture_index)    # Tex pattern index
+                       if face_desc.material_index == -1:
+                               self.header.fw.write_ushort(65535)
+                       else:
+                               self.header.fw.write_ushort(face_desc.material_index)           # material index
                        self.header.fw.write_short(0)                                   # SMC code
                        self.header.fw.write_short(0)                                   # Feature                                       code
                        self.header.fw.write_int(0)                                     # IR material code
@@ -1015,7 +1021,10 @@ class FLTNode(Node):
                                self.header.fw.write_ushort(8 + (mtex * 8))             # Length
                                self.header.fw.write_uint(uvmask)                                                               # UV mask
                                for i in xrange(mtex):
-                                       self.header.fw.write_ushort(face_desc.images[i])                        # Tex pattern index
+                                       if face_desc.images[i] == -1:
+                                               self.header.fw.write_ushort(65535)
+                                       else:
+                                               self.header.fw.write_ushort(face_desc.images[i])                        # Tex pattern index
                                        self.header.fw.write_ushort(0)                                                          # Tex effect
                                        self.header.fw.write_ushort(0)                                                          # Tex Mapping index
                                        self.header.fw.write_ushort(0)                                                          # Tex data. User defined
@@ -1070,7 +1079,7 @@ class FLTNode(Node):
 
                 if self.opcode == 63 and options.state['externalspath']:
                                try:
-                                       exportdict['3t200!filename'] = os.path.join(options.state['externalspath'],self.object.DupGroup.name+'.flt')
+                                       exportdict['3t200!filename'] = os.path.join(options.state['externalspath'],self.object.DupGroup.name+'.flt').replace("\\", "/")
                                        self.header.xrefnames.append(self.object.DupGroup.name)
                                except:
                                        pass
@@ -1092,7 +1101,7 @@ class FLTNode(Node):
                                write_prop(self.header.fw,ftype,self.object.properties['FLT']['EXT'][propname],length)
                        #write extension data
                        for i in xrange(datalen):
-                               self.header.fw.write_char(self.object.properties['FLT']['EXT']['data'][i])
+                               self.header.fw.write_uchar(struct.unpack('>B', struct.pack('>B', self.object.properties['FLT']['EXT']['data'][i]))[0])
                        self.write_pop_extension()
 
 
@@ -1180,8 +1189,8 @@ class Database(Node):
                        desc = self.GRR.request_vertex_desc(i)
                        self.fw.write_short(70)                         # Vertex with color normal and uv opcode.
                        self.fw.write_ushort(64)                        # Length of record
-                       self.fw.write_ushort(0)                                                 # Color name index
-                       self.fw.write_short(0x20000000)                                 # Flags
+                       self.fw.write_ushort(0)                         # Color name index
+                       self.fw.write_short(1 << 14)                    # Frozen Normal
                        self.fw.write_double(desc.x)
                        self.fw.write_double(desc.y)
                        self.fw.write_double(desc.z)
@@ -1245,7 +1254,7 @@ class Database(Node):
                        cpalette = defaultp.pal
                count = len(cpalette)
                for i in xrange(count):
-                       color = struct.unpack('>BBBB',struct.pack('>I',cpalette[i]))
+                       color = struct.unpack('>BBBB',struct.pack('>i',cpalette[i]))
                        self.fw.write_uchar(color[3])               # alpha
                        self.fw.write_uchar(color[2])               # b
                        self.fw.write_uchar(color[1])               # g
index 6edaf2974ab04c3227e9d949163e509a5715884a..c2f1380a6fa1b388c8cf457ce8dd36701df9d5d2 100644 (file)
@@ -25,7 +25,7 @@ http://wiki.blender.org/index.php/Scripts/Manual/FLTools
 """
 
 # --------------------------------------------------------------------------
-# flt_palettemanager.py version 0.1 2005/04/08
+# flt_palettemanager.py version 1.0 2005/04/08
 # --------------------------------------------------------------------------
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
@@ -55,6 +55,75 @@ import flt_properties
 import flt_defaultp as defaultp
 from flt_properties import *
 
+def RGBtoHSV( r, g, b):
+       minc = min( r, g, b )
+       maxc = max( r, g, b )
+       v = maxc                                
+
+       delta = maxc - minc
+
+       if( max != 0 ):
+               s = delta / maxc                
+       else:
+               s = 0
+               h = -1
+               return (h,s,v)
+
+       if( r == maxc ):
+               h = ( g - b ) / delta           
+       elif( g == maxc ):
+               h = 2 + ( b - r ) / delta
+       else:
+               h = 4 + ( r - g ) / delta
+
+       h *= 60
+       if( h < 0 ):
+               h += 360
+
+       return(h,s,v)
+
+def HSVtoRGB(h,s,v):
+
+       if( s == 0 ):
+               return (v,v,v)
+       
+
+       h /= 60
+       i = math.floor( h)
+       f = h - i
+       p = v * ( 1 - s )
+       q = v * ( 1 - s * f )
+       t = v * ( 1 - s * ( 1 - f ) )
+
+       if i == 0:
+               r = v
+               g = t
+               b = p
+       elif i == 1:
+               r = q
+               g = v
+               b = p
+
+       elif i== 2:
+               r = p
+               g = v
+               b = t
+       elif i==3:
+               r = p
+               g = q
+               b = v
+       elif i==4:
+               r = t
+               g = p
+               b = v
+
+       else:
+               r = v
+               g = p
+               b = q
+       
+       return(r,g,b)
+
 
 palette_size = 12
 palette_x = 0
@@ -68,6 +137,14 @@ cinc = 1.0 / 1024.0
 cstep = 0.0
 picker = None
 ptt = ""
+
+
+ts1=None
+ts2=None
+ts3=None
+ts4=None
+ts5=None
+
 for i in xrange(1024):
        colors.append([cstep,cstep,cstep])
        cstep = cstep + cinc
@@ -128,7 +205,7 @@ def event(evt,val):
                         Draw.Redraw(1)
        
        #copy current color and intensity to selected faces.
-       elif evt == Draw.CKEY:
+       elif evt == Draw.VKEY:
                
                if Blender.Window.EditMode():
                        Blender.Window.EditMode(0)
@@ -136,7 +213,7 @@ def event(evt,val):
                state = update_state()
                
                #retrieve color from palette
-               color = struct.unpack('>BBBB',struct.pack('>I',colors[curswatch]))
+               color = struct.unpack('>BBBB',struct.pack('>i',colors[curswatch]))
                actmesh = state["activeMesh"]
                if actmesh: 
                        if(Blender.Window.GetKeyQualifiers() != Blender.Window.Qual["CTRL"]):
@@ -182,7 +259,7 @@ def event(evt,val):
                        Blender.Window.RedrawAll()
        
        #grab color and intensity from active face
-       elif evt == Draw.VKEY:
+       elif evt == Draw.CKEY:
                if Blender.Window.EditMode():
                        Blender.Window.EditMode(0)
                        editmode = 1
@@ -211,6 +288,23 @@ def event(evt,val):
                        Blender.Window.EditMode(1)
                
                Blender.Window.RedrawAll()
+               
+       elif evt == Draw.GKEY:
+               if Blender.Window.EditMode():
+                       Blender.Window.EditMode(0)
+                       editmode =1
+               state = update_state()
+               
+               actmesh = state["activeMesh"]
+               activeFace = state["activeFace"]
+               
+               if activeFace and "FLT_COL" in actmesh.faces.properties:
+                       (index,intensity) = unpack_face_index(activeFace.getProperty("FLT_COL"))
+                       for face in actmesh.faces:
+                               (index2, intensity2) = unpack_face_index(face.getProperty("FLT_COL"))
+                               if index == index2:
+                                       face.sel = 1
+                               
                        
        elif evt == Draw.ESCKEY:
                Draw.Exit()
@@ -225,11 +319,11 @@ def update_all():
        for object in state["activeScene"].objects:
                if object.type == "Mesh":
                        mesh = object.getData(mesh=True)
-                       if 'FLT_COL' in mesh.faces.properties:
+                       if 'FLT_COL' in mesh.faces.properties and "FLT_Fcol" in mesh.getColorLayerNames():
                                mesh.activeColorLayer = "FLT_Fcol"
                                for face in mesh.faces:
                                        (index,intensity) = unpack_face_index(face.getProperty('FLT_COL'))
-                                       color = struct.unpack('>BBBB',struct.pack('>I',colors[index]))
+                                       color = struct.unpack('>BBBB',struct.pack('>i',colors[index]))
                                        #update the vertex colors for this face
                                        for col in face.col:
                                                col.r = int(color[0] * intensity)
@@ -284,8 +378,13 @@ def draw_palette():
        global colors
        global curint
        global curswatch
-        global picker
-
+       global picker
+       global ts1
+       global ts2
+       global ts3
+       global ts4
+       global ts5
+       
        state = update_state()
        init_pal()
 
@@ -297,7 +396,7 @@ def draw_palette():
        for x in xrange(32):
                ypos = palette_y
                for y in xrange(32):
-                       color = struct.unpack('>BBBB',struct.pack('>I',colors[cid]))
+                       color = struct.unpack('>BBBB',struct.pack('>i',colors[cid]))
                        glColor3f(color[0]/255.0,color[1]/255.0,color[2]/255.0)
                        glBegin(GL_POLYGON)
                        glVertex2i(xpos,ypos)
@@ -328,7 +427,7 @@ def draw_palette():
                xpos = xpos + ssize
        
        #draw intensity gradient
-       color = struct.unpack('>BBBB',struct.pack('>I',colors[curswatch]))
+       color = struct.unpack('>BBBB',struct.pack('>i',colors[curswatch]))
        color = [color[0]/255.0,color[1]/255.0,color[2]/255.0]
        colsteps = [color[0]/255.0,color[1]/255.0,color[2]/255.0]
        stripwidth = (palette_size * 32.0) / 256
@@ -355,15 +454,15 @@ def draw_palette():
        xpos = ((palette_size*32) * (1.0 - curint)) + palette_x
        glColor3f(1.0,1.0,1.0)
        glBegin(GL_LINE_LOOP)
-       glVertex2i(xpos-6,grady-1)
-       glVertex2i(xpos+6,grady-1)
-       glVertex2i(xpos+6,grady+palette_size+1)
-       glVertex2i(xpos-6,grady+palette_size+1)
+       glVertex2i(int(xpos-6),int(grady-1))
+       glVertex2i(int(xpos+6),int(grady-1))
+       glVertex2i(int(xpos+6),int(grady+palette_size+1))
+       glVertex2i(int(xpos-6),int(grady+palette_size+1))
        #glVertex2i(xpos-6,grady+7)
        glEnd()
 
        #draw color picker
-       color = struct.unpack('>BBBB',struct.pack('>I',colors[curswatch]))
+       color = struct.unpack('>BBBB',struct.pack('>i',colors[curswatch]))
        pickcol = (color[0]/255.0,color[1]/255.0,color[2]/255.0)
        picker = Blender.Draw.ColorPicker(1,highlight[0][0]+1,highlight[0][1]+1,ssize-2,ssize-2,pickcol,ptt)
 
@@ -377,6 +476,24 @@ def draw_palette():
        glVertex2i(highlight[0][0],highlight[0][1])
        glEnd()                 
 
+       #draw text string explanations
+       xpos = palette_size*32+20
+       ypos = palette_size*32+10
+       glRasterPos2d(xpos,ypos)
+       ts1     = Blender.Draw.Text("FLT Palette Manager V 1.0")
+       ypos = ypos - 20
+       glRasterPos2d(xpos,ypos)
+       ts3 = Blender.Draw.Text("CKEY - Copy Active Face Color*")
+       ypos = ypos - 20
+       glRasterPos2d(xpos,ypos)
+       ts2 = Blender.Draw.Text("VKEY - Paste Color to Selected Faces")
+       ypos = ypos - 20
+       glRasterPos2d(xpos,ypos)
+       ts4 = Blender.Draw.Text("GKEY - Select Faces With Same Color")
+       ypos = ypos - 15
+       glRasterPos2d(xpos,ypos)
+       ts5 = Blender.Draw.Text("(*Requires mesh with UV coordinates)", 'small')
+
 def gui():
        glClearColor(0.5,0.5,0.5,1.0)
        glClear(GL_COLOR_BUFFER_BIT)
@@ -385,4 +502,4 @@ def gui():
 
 init_pal()
 Draw.Register(gui,event,but_event)
-       
+       
\ No newline at end of file
index 09e51c22a9fb5e2e75d01651b174cf54790ec062..bb0119a9a813596dfddda1ed91bb6676b34a79b6 100644 (file)
@@ -7,7 +7,7 @@ Group: 'Import'
 Tooltip: 'Import for DXF geometry data (Drawing eXchange Format).'
 """
 __author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)'
-__version__ = '1.12 - 2008.07.04 by migius'
+__version__ = '1.12 - 2008.08.03 by migius'
 __url__ = ["http://blenderartists.org/forum/showthread.php?t=84319",
         "http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"]
 __email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"]
@@ -88,7 +88,7 @@ in creating new objects in scene database - probably a database management probl
 
 """
 History:
- v1.0 - 2008.01. by migius
+ v1.0 - 2007/2008 by migius
  planned tasks:
  -- (to see more, search for "--todo--" in script code)
  -- command-line-mode/batch-mode
index cecde5a0b593c84553cdfa85dc1229a71a3c48d8..19a4a60674e5556dc815dd8203320da292f8903c 100644 (file)
@@ -13,7 +13,7 @@ from Blender import Mesh, Scene, Window, sys, Image, Draw
 import BPyMesh
 
 __author__ = "Bruce Merry"
-__version__ = "0.92"
+__version__ = "0.93"
 __bpydoc__ = """\
 This script exports Stanford PLY files from Blender. It supports normals, 
 colours, and texture coordinates per face or per vertex.
@@ -37,6 +37,8 @@ Only one mesh can be exported at a time.
 # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 # Vector rounding se we can use as keys
 #
+# Updated on Aug 11, 2008 by Campbell Barton
+#    - added 'comment' prefix to comments - Needed to comply with the PLY spec.
 #
 # Updated on Jan 1, 2007 by Gabe Ghearing
 #    - fixed normals so they are correctly smooth/flat
@@ -162,7 +164,7 @@ def file_callback(filename):
        
        file.write('ply\n')
        file.write('format ascii 1.0\n')
-       file.write('Created by Blender3D %s - www.blender.org, source file: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] ))
+       file.write('comment Created by Blender3D %s - www.blender.org, source file: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] ))
        
        file.write('element vertex %d\n' % len(verts))
        
@@ -210,7 +212,6 @@ def file_callback(filename):
                        if faceUV:                      uvcoord=        rvec2d(uv[j])
                        elif vertexUV:          uvcoord=        rvec2d(v.uvco)
                        if vertexColors:        color=          col[j].r, col[j].g, col[j].b
-                       co = v.co
                        
                        file.write('%d ' % vdict[v.index][normal, uvcoord, color])
                        
index d951c8401e3b27a60bbaa5f9109ff0d979f4cb8c..e1eb6718a3069e9d535c7b3f75ce97fe17b06555 100644 (file)
@@ -40,8 +40,8 @@ extern "C" {
 struct ListBase;
 struct MemFile;
 
-#define BLENDER_VERSION                        246
-#define BLENDER_SUBVERSION             1
+#define BLENDER_VERSION                        247
+#define BLENDER_SUBVERSION             0
 
 #define BLENDER_MINVERSION             245
 #define BLENDER_MINSUBVERSION  15
index fade0f8cbaa4a1b1555b7c85894c2658e076a859..c162a04e0557a7859302a0d69ec7e16890049ab5 100644 (file)
@@ -73,6 +73,7 @@ void    BKE_free_envmap(struct EnvMap *env);
 struct EnvMap *BKE_add_envmap(void);
 struct EnvMap *BKE_copy_envmap(struct EnvMap *env);
 
+int     BKE_texture_dependsOnTime(const struct Tex *texture);
 
 #endif
 
index 3ad11a61de33125e6a08cc76b2ae8805c6cfb462..561d8d7c2a6bda1c843898f112ff3f971a776f71 100644 (file)
@@ -117,10 +117,14 @@ float BPY_pydriver_eval(struct IpoDriver *driver)
 {
        return 0;
 }
+
+/*
 int EXPP_dict_set_item_str(struct PyObject *dict, char *key, struct PyObject *value)
 {
        return 0;
 }
+*/
+
 void Node_SetStack(struct BPy_Node *self, struct bNodeStack **stack, int type){}
 void InitNode(struct BPy_Node *self, struct bNode *node){}
 void Node_SetShi(struct BPy_Node *self, struct ShadeInput *shi){}
index 1f8dd74a6ebd333cd266f6e739b63a3ece142979..1592c3e55042b2289c41581fd87ddcde7c84155d 100644 (file)
@@ -734,9 +734,8 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
        ParticleCacheKey *cache;
        ParticleSystemModifierData *psmd;
        float ctime, pa_time, scale = 1.0f;
-       float tmat[4][4], mat[4][4], obrotmat[4][4], pamat[4][4], size=0.0;
+       float tmat[4][4], mat[4][4], pamat[4][4], size=0.0;
        float (*obmat)[4], (*oldobmat)[4];
-       float xvec[3] = {-1.0, 0.0, 0.0}, q[4];
        int lay, a, b, k, step_nbr = 0, counter, hair = 0;
        int totpart, totchild, totgroup=0, pa_num;
 
@@ -898,14 +897,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                                        /* to give ipos in object correct offset */
                                        where_is_object_time(ob, ctime-pa_time);
                                        
-                                       if(!hair) {
-                                               vectoquat(xvec, ob->trackflag, ob->upflag, q);
-                                               QuatToMat4(q, obrotmat);
-                                               obrotmat[3][3]= 1.0f;
-                                               Mat4MulMat4(mat, obrotmat, pamat);
-                                       }
-                                       else
-                                               Mat4CpyMat4(mat, pamat);
+                                       Mat4CpyMat4(mat, pamat);
 
                                        Mat4MulMat4(tmat, obmat, mat);
                                        Mat4MulFloat3((float *)tmat, size*scale);
index 503654717aed1f8026bd1e9a570fb8365f75d3ac..1dc76296c28783d75d5164f5ca7280fc7fd6c0f6 100644 (file)
@@ -97,6 +97,7 @@
 #include "BKE_material.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
+#include "BKE_texture.h"
 #include "BKE_utildefines.h"
 #include "depsgraph_private.h"
 #include "BKE_bmesh.h"
@@ -2999,6 +3000,20 @@ CustomDataMask displaceModifier_requiredDataMask(ModifierData *md)
        return dataMask;
 }
 
+static int displaceModifier_dependsOnTime(ModifierData *md)
+{
+       DisplaceModifierData *dmd = (DisplaceModifierData *)md;
+
+       if(dmd->texture)
+       {
+               return BKE_texture_dependsOnTime(dmd->texture);
+       }
+       else
+       {
+               return 0;
+       }
+}
+
 static void displaceModifier_foreachObjectLink(ModifierData *md, Object *ob,
                                               ObjectWalkFunc walk, void *userData)
 {
@@ -7354,6 +7369,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->initData = displaceModifier_initData;
                mti->copyData = displaceModifier_copyData;
                mti->requiredDataMask = displaceModifier_requiredDataMask;
+               mti->dependsOnTime = displaceModifier_dependsOnTime;
                mti->foreachObjectLink = displaceModifier_foreachObjectLink;
                mti->foreachIDLink = displaceModifier_foreachIDLink;
                mti->updateDepgraph = displaceModifier_updateDepgraph;
index 7dca87d5c135ad53b2de60acda7a7af89b365e44..d1c0cdec71ddba7556b8c3abe640c2cbf876c872 100644 (file)
@@ -4653,7 +4653,7 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
        PTCacheID pid;
        int totpart, oldtotpart, totchild, oldtotchild, p;
        float disp, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0;
-       int init= 0, distr= 0, alloc= 0, usecache= 0;
+       int init= 0, distr= 0, alloc= 0, usecache= 0, only_children_changed= 0;
        int framenr, framedelta, startframe, endframe;
 
        part= psys->part;
@@ -4720,6 +4720,7 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
        totchild = get_psys_tot_child(psys);
 
        if(oldtotpart != totpart || (psys->part->childtype && oldtotchild != totchild)) {
+               only_children_changed = (oldtotpart == totpart);
                realloc_particles(ob, psys, totpart);
                alloc = 1;
                distr= 1;
@@ -4740,14 +4741,17 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
 
                        if((psys->part->type == PART_HAIR) && !(psys->flag & PSYS_HAIR_DONE))
                        /* don't generate children while growing hair - waste of time */
-                       psys_free_children(psys);
-               else if(get_psys_tot_child(psys))
-                       distribute_particles(ob, psys, PART_FROM_CHILD);
+                               psys_free_children(psys);
+                       else if(get_psys_tot_child(psys))
+                               distribute_particles(ob, psys, PART_FROM_CHILD);
                }
-               initialize_all_particles(ob, psys, psmd);
 
-               if(alloc)
-                       reset_all_particles(ob, psys, psmd, 0.0, cfra, oldtotpart);
+               if(only_children_changed==0) {
+                       initialize_all_particles(ob, psys, psmd);
+
+                       if(alloc)
+                               reset_all_particles(ob, psys, psmd, 0.0, cfra, oldtotpart);
+               }
 
                /* flag for possible explode modifiers after this system */
                psmd->flag |= eParticleSystemFlag_Pars;
index d5b5ab6d63e65eb5dd61bee4a794948b5be0897c..d465c058d30e88a9197c6d42cb8587ce3f9cc4e8 100644 (file)
@@ -69,6 +69,8 @@ variables on the UI for now
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 #include "BLI_ghash.h"
+#include "BLI_threads.h"
+
 #include "BKE_curve.h"
 #include "BKE_effect.h"
 #include "BKE_global.h"
@@ -118,6 +120,20 @@ typedef struct SBScratch {
        float aabbmin[3],aabbmax[3];
 }SBScratch;
 
+typedef struct  SB_thread_context{
+        Object *ob;
+               float forcetime;
+               float timenow;
+               int ifirst;
+               int ilast;
+               ListBase *do_effector;
+               int do_deflector;
+               float fieldfactor;
+               float windfactor;
+               int nr;
+               int tot;
+}SB_thread_context;
+
 #define NLF_BUILD  1 
 #define NLF_SOLVE  2 
 
@@ -1514,17 +1530,15 @@ int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp
 
 
 
-void scan_for_ext_spring_forces(Object *ob,float timenow)
+void _scan_for_ext_spring_forces(Object *ob,float timenow,int ifirst,int ilast, struct ListBase *do_effector)
 {
        SoftBody *sb = ob->soft;
-       ListBase *do_effector;
        int a;
        float damp; 
        float feedback[3];
-       do_effector= pdInitEffectors(ob,NULL);
 
        if (sb && sb->totspring){
-               for(a=0; a<sb->totspring; a++) {
+               for(a=ifirst; a<ilast; a++) {
                        BodySpring *bs = &sb->bspring[a];
                        bs->ext_force[0]=bs->ext_force[1]=bs->ext_force[2]=0.0f; 
                        feedback[0]=feedback[1]=feedback[2]=0.0f;
@@ -1584,9 +1598,88 @@ void scan_for_ext_spring_forces(Object *ob,float timenow)
                        }
                }
        }
-       if(do_effector)
-               pdEndEffectors(do_effector);
 }
+
+
+void scan_for_ext_spring_forces(Object *ob,float timenow)
+{
+  SoftBody *sb = ob->soft;
+  ListBase *do_effector= NULL; 
+  do_effector= pdInitEffectors(ob,NULL);
+  if (sb){
+  _scan_for_ext_spring_forces(ob,timenow,0,sb->totspring,do_effector);
+  }
+  if(do_effector)
+  pdEndEffectors(do_effector);
+}
+
+void *exec_scan_for_ext_spring_forces(void *data)
+{
+       SB_thread_context *pctx = (SB_thread_context*)data;
+       _scan_for_ext_spring_forces(pctx->ob,pctx->timenow,pctx->ifirst,pctx->ilast,pctx->do_effector);
+       return 0;
+} 
+
+void sb_sfesf_threads_run(struct Object *ob, float timenow,int totsprings,int *ptr_to_break_func())
+{
+    ListBase *do_effector = NULL; 
+       ListBase threads;
+       SB_thread_context *sb_threads;
+       int i, totthread,left,dec;
+       int lowsprings =10; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */
+
+       do_effector= pdInitEffectors(ob,NULL);
+
+       /* figure the number of threads while preventing pretty pointless threading overhead */
+       if(totsprings < lowsprings) {totthread=1;}
+       else{
+               if(G.scene->r.mode & R_FIXED_THREADS)
+                       totthread= G.scene->r.threads;
+               else
+                       totthread= BLI_system_thread_count();
+       }
+       /*left to do--> what if we got zillions of CPUs running but 'totsprings' tasks to spread*/
+
+       sb_threads= MEM_callocN(sizeof(SB_thread_context)*totthread, "SBSpringsThread");
+       memset(sb_threads, 0, sizeof(SB_thread_context)*totthread);
+       left = totsprings;
+       dec = totsprings/totthread +1;
+       for(i=0; i<totthread; i++) {
+               sb_threads[i].ob = ob; 
+               sb_threads[i].forcetime = 0.0; // not used here 
+               sb_threads[i].timenow = timenow; 
+               sb_threads[i].ilast   = left; 
+               left = left - dec;
+               if (left >0){
+                       sb_threads[i].ifirst  = left;
+               }
+               else
+                       sb_threads[i].ifirst  = 0; 
+        sb_threads[i].do_effector = do_effector;
+        sb_threads[i].do_deflector = 0;// not used here
+               sb_threads[i].fieldfactor = 0.0f;// not used here
+               sb_threads[i].windfactor  = 0.0f;// not used here
+               sb_threads[i].nr= i;
+               sb_threads[i].tot= totthread;
+       }
+       if(totthread > 1) {
+               BLI_init_threads(&threads, exec_scan_for_ext_spring_forces, totthread);
+
+               for(i=0; i<totthread; i++)
+                       BLI_insert_thread(&threads, &sb_threads[i]);
+
+               BLI_end_threads(&threads);
+       }
+       else
+               exec_scan_for_ext_spring_forces(&sb_threads[0]);
+    /* clean up */
+       MEM_freeN(sb_threads);
+
+         if(do_effector)
+  pdEndEffectors(do_effector);
+}
+
+
 /* --- the spring external section*/
 
 int choose_winner(float*w, float* pos,float*a,float*b,float*c,float*ca,float*cb,float*cc)
@@ -2023,109 +2116,72 @@ static void sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float fo
 }
 
 
-static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int nl_flags)
+/* since this is definitely the most CPU consuming task here .. try to spread it */
+/* core function _softbody_calc_forces_slice_in_a_thread */
+/* result is int to be able to flag user break */
+int _softbody_calc_forces_slice_in_a_thread(Object *ob, float forcetime, float timenow,int ifirst,int ilast,int *ptr_to_break_func(),ListBase *do_effector,int do_deflector,float fieldfactor, float windfactor)
 {
-/* rule we never alter free variables :bp->vec bp->pos in here ! 
- * this will ruin adaptive stepsize AKA heun! (BM) 
- */
+       float iks;
+       int bb,do_selfcollision,do_springcollision,do_aero;
+       int number_of_points_here = ilast - ifirst;
        SoftBody *sb= ob->soft; /* is supposed to be there */
        BodyPoint  *bp;
-       BodyPoint *bproot;
-       BodySpring *bs; 
-       ListBase *do_effector;
-       float iks, ks, kd, gravity;
-       float fieldfactor = 1000.0f, windfactor  = 250.0f;   
-       float tune = sb->ballstiff;
-       int a, b,  do_deflector,do_selfcollision,do_springcollision,do_aero;
-
-
-/* jacobian
-       NLboolean success;
-
-       if(nl_flags){
-               nlBegin(NL_SYSTEM);
-               nlBegin(NL_MATRIX);
-       }
-*/
-       
-       
-       gravity = sb->grav * sb_grav_force_scale(ob);   
-       
+       /* intitialize */
+       if (sb) {
        /* check conditions for various options */
-       do_deflector= query_external_colliders(ob);
+    /* +++ could be done on object level to squeeze out the last bits of it */
        do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
        do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
        do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
-       
-       iks  = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
-       bproot= sb->bpoint; /* need this for proper spring addressing */
-       
-       if (do_springcollision || do_aero)  scan_for_ext_spring_forces(ob,timenow);
-       /* after spring scan because it uses Effoctors too */
-       do_effector= pdInitEffectors(ob,NULL);
+    /* --- could be done on object level to squeeze out the last bits of it */
+       }
+       else {
+               printf("Error expected a SB here \n");
+               return (999);
+       }
 
-       if (do_deflector) {
-               float defforce[3];
-               do_deflector = sb_detect_aabb_collisionCached(defforce,ob->lay,ob,timenow);
+/* debugerin */
+       if  (sb->totpoint < ifirst) {
+               printf("Aye 998");
+               return (998);
        }
+/* debugerin */
 
-       for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+
+       bp = &sb->bpoint[ifirst]; 
+       for(bb=number_of_points_here; bb>0; bb--, bp++) {
                /* clear forces  accumulator */
                bp->force[0]= bp->force[1]= bp->force[2]= 0.0;
-               if(nl_flags & NLF_BUILD){
-                       //int ia =3*(sb->totpoint-a);
-                       //int op =3*sb->totpoint;
-                       /* dF/dV = v */ 
-                       /* jacobioan
-                       nlMatrixAdd(op+ia,ia,-forcetime);
-                       nlMatrixAdd(op+ia+1,ia+1,-forcetime);
-                       nlMatrixAdd(op+ia+2,ia+2,-forcetime);
-               
-                       nlMatrixAdd(ia,ia,1);
-                       nlMatrixAdd(ia+1,ia+1,1);
-                       nlMatrixAdd(ia+2,ia+2,1);
-
-                       nlMatrixAdd(op+ia,op+ia,1);
-                       nlMatrixAdd(op+ia+1,op+ia+1,1);
-                       nlMatrixAdd(op+ia+2,op+ia+2,1);
-                       */
-
-
-               }
-
                /* naive ball self collision */
                /* needs to be done if goal snaps or not */
                if(do_selfcollision){
                                int attached;
                                BodyPoint   *obp;
+                               BodySpring *bs; 
                                int c,b;
                                float velcenter[3],dvel[3],def[3];
                                float distance;
                                float compare;
+               float bstune = sb->ballstiff;
 
-                               for(c=sb->totpoint, obp= sb->bpoint; c>=a; c--, obp++) {
-                                       
-                                       //if ((bp->octantflag & obp->octantflag) == 0) continue;
-
+                               for(c=sb->totpoint, obp= sb->bpoint; c>=ifirst+bb; c--, obp++) {
                                        compare = (obp->colball + bp->colball);         
                                        VecSubf(def, bp->pos, obp->pos);
-
                                        /* rather check the AABBoxes before ever calulating the real distance */
                                        /* mathematically it is completly nuts, but performace is pretty much (3) times faster */
                                        if ((ABS(def[0]) > compare) || (ABS(def[1]) > compare) || (ABS(def[2]) > compare)) continue;
-
                     distance = Normalize(def);
                                        if (distance < compare ){
                                                /* exclude body points attached with a spring */
                                                attached = 0;
                                                for(b=obp->nofsprings;b>0;b--){
                                                        bs = sb->bspring + obp->springs[b-1];
-                                                       if (( sb->totpoint-a == bs->v2)  || ( sb->totpoint-a == bs->v1)){
+                                                       if (( ilast-bb == bs->v2)  || ( ilast-bb == bs->v1)){
                                                                attached=1;
                                                                continue;}
                                                }
                                                if (!attached){
-                                                       float f = tune/(distance) + tune/(compare*compare)*distance - 2.0f*tune/compare ;
+                                                       float f = bstune/(distance) + bstune/(compare*compare)*distance - 2.0f*bstune/compare ;
 
                                                        VecMidf(velcenter, bp->vec, obp->vec);
                                                        VecSubf(dvel,velcenter,bp->vec);
@@ -2134,38 +2190,12 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int
                                                        Vec3PlusStVec(bp->force,f*(1.0f-sb->balldamp),def);
                                                        Vec3PlusStVec(bp->force,sb->balldamp,dvel);
 
-                                                       if(nl_flags & NLF_BUILD){
-                                                               //int ia =3*(sb->totpoint-a);
-                                                               //int ic =3*(sb->totpoint-c);
-                                                               //int op =3*sb->totpoint;
-                                                               //float mvel = forcetime*sb->nodemass*sb->balldamp;
-                                                               //float mpos = forcetime*tune*(1.0f-sb->balldamp);
-                                                               /*some quick and dirty entries to the jacobian*/
-                                                               //dfdx_goal(ia,ia,op,mpos);
-                                                               //dfdv_goal(ia,ia,mvel);
-                                                               /* exploit force(a,b) == -force(b,a) part1/2 */
-                                                               //dfdx_goal(ic,ic,op,mpos);
-                                                               //dfdv_goal(ic,ic,mvel);
-                                                               
-                                                               
-                                                               /*TODO sit down an X-out the true jacobian entries*/
-                                                               /*well does not make to much sense because the eigenvalues
-                                                               of the jacobian go negative; and negative eigenvalues
-                                                               on a complex iterative system z(n+1)=A * z(n) 
-                                                               give imaginary roots in the charcateristic polynom
-                                                               --> solutions that to z(t)=u(t)* exp ( i omega t) --> oscilations we don't want here 
-                                                               where u(t) is a unknown amplitude function (worst case rising fast)
-                                                               */ 
-                                                       }
-
                                                        /* exploit force(a,b) == -force(b,a) part2/2 */
                                                        VecSubf(dvel,velcenter,obp->vec);
                                                        VecMulf(dvel,sb->nodemass);
 
                                                        Vec3PlusStVec(obp->force,sb->balldamp,dvel);
                                                        Vec3PlusStVec(obp->force,-f*(1.0f-sb->balldamp),def);
-
-
                                                }
                                        }
                                }
@@ -2179,20 +2209,13 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int
                        /* do goal stuff */
                        if(ob->softflag & OB_SB_GOAL) {
                                /* true elastic goal */
+                               float ks,kd;
                                VecSubf(auxvect,bp->pos,bp->origT);
                                ks  = 1.0f/(1.0f- bp->goal*sb->goalspring)-1.0f ;
                                bp->force[0]+= -ks*(auxvect[0]);
                                bp->force[1]+= -ks*(auxvect[1]);
                                bp->force[2]+= -ks*(auxvect[2]);
 
-                               if(nl_flags & NLF_BUILD){
-                                       //int ia =3*(sb->totpoint-a);
-                                       //int op =3*(sb->totpoint);
-                                       /* depending on my pos */ 
-                                       //dfdx_goal(ia,ia,op,ks*forcetime);
-                               }
-
-
                                /* calulate damping forces generated by goals*/
                                VecSubf(velgoal,bp->origS, bp->origE);
                                kd =  sb->goalfrict * sb_fric_force_scale(ob) ;
@@ -2202,13 +2225,6 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int
                                        bp->force[0]-= kd * (auxvect[0]);
                                        bp->force[1]-= kd * (auxvect[1]);
                                        bp->force[2]-= kd * (auxvect[2]);
-                                       if(nl_flags & NLF_BUILD){
-                                               //int ia =3*(sb->totpoint-a);
-                                               Normalize(auxvect);
-                                               /* depending on my vel */ 
-                                               //dfdv_goal(ia,ia,kd*forcetime);
-                                       }
-
                                }
                                else {
                                        bp->force[0]-= kd * (velgoal[0] - bp->vec[0]);
@@ -2218,14 +2234,15 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int
                        }
                        /* done goal stuff */
                        
-                       
                        /* gravitation */
+                       if (sb){ 
+                       float gravity = sb->grav * sb_grav_force_scale(ob);     
                        bp->force[2]-= gravity*sb->nodemass; /* individual mass of node here */
-                       //bp->force[1]-= gravity*sb->nodemass; /* individual mass of node here */
-
+                       }
                        
                        /* particle field & vortex */
                        if(do_effector) {
+                               float kd;
                                float force[3]= {0.0f, 0.0f, 0.0f};
                                float speed[3]= {0.0f, 0.0f, 0.0f};
                                float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */
@@ -2246,21 +2263,12 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int
                        }
                        else {
                                /* BP friction in media (not) moving*/
-                               kd= sb->mediafrict* sb_fric_force_scale(ob);  
+                               float kd = sb->mediafrict* sb_fric_force_scale(ob);  
                                /* assume it to be proportional to actual velocity */
                                bp->force[0]-= bp->vec[0]*kd;
                                bp->force[1]-= bp->vec[1]*kd;
                                bp->force[2]-= bp->vec[2]*kd;
                                /* friction in media done */
-                               if(nl_flags & NLF_BUILD){
-                                       //int ia =3*(sb->totpoint-a);
-                                       /* da/dv =  */ 
-
-//                                     nlMatrixAdd(ia,ia,forcetime*kd);
-//                                     nlMatrixAdd(ia+1,ia+1,forcetime*kd);
-//                                     nlMatrixAdd(ia+2,ia+2,forcetime*kd);
-                               }
-
                        }
                        /* +++cached collision targets */
                        bp->choke = 0.0f;
@@ -2268,44 +2276,25 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int
                        bp->flag &= ~SBF_DOFUZZY;
                        if(do_deflector) {
                                float cfforce[3],defforce[3] ={0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f}, facenormal[3], cf = 1.0f,intrusion;
-                               kd = 1.0f;
+                               float kd = 1.0f;
 
                                if (sb_deflect_face(ob,bp->pos,facenormal,defforce,&cf,timenow,vel,&intrusion)){
-                                       if ((!nl_flags)&&(intrusion < 0.0f)){
-                                               /*bjornmose:  uugh.. what an evil hack 
-                                               violation of the 'don't touch bp->pos in here' rule 
-                                               but works nice, like this-->
-                                               we predict the solution beeing out of the collider
-                                               in heun step No1 and leave the heun step No2 adapt to it
-                                               so we kind of introduced a implicit solver for this case 
-                                               */
-                                               Vec3PlusStVec(bp->pos,-intrusion,facenormal);
-
-                                               sb->scratch->flag |= SBF_DOFUZZY;
-                                               bp->flag |= SBF_DOFUZZY;
-                                           bp->choke = sb->choke*0.01f;
-                                       }
-                                       else{
+
                                                        VECSUB(cfforce,bp->vec,vel);
                                                        Vec3PlusStVec(bp->force,-cf*50.0f,cfforce);
-                                       }
-                                       Vec3PlusStVec(bp->force,kd,defforce);
-                                       if (nl_flags & NLF_BUILD){
-                                               // int ia =3*(sb->totpoint-a);
-                                               // int op =3*sb->totpoint;
-                                               //dfdx_goal(ia,ia,op,mpos); // don't do unless you know
-                                               //dfdv_goal(ia,ia,-cf);
-
-                                       }
-  
+                                       
+                                       Vec3PlusStVec(bp->force,kd,defforce);  
                                }
 
                        }
                        /* ---cached collision targets */
 
                        /* +++springs */
+                       iks  = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
                        if(ob->softflag & OB_SB_EDGES) {
                                if (sb->bspring){ /* spring list exists at all ? */
+                                       int b;
+                                       BodySpring *bs; 
                                        for(b=bp->nofsprings;b>0;b--){
                                                bs = sb->bspring + bp->springs[b-1];
                                                if (do_springcollision || do_aero){
@@ -2315,90 +2304,513 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int
 
                                                }
                         // sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float forcetime,int nl_flags)
-                                               sb_spring_force(ob,sb->totpoint-a,bs,iks,forcetime,nl_flags);
+                                               sb_spring_force(ob,ilast-bb,bs,iks,forcetime,0);
                                        }/* loop springs */
                                }/* existing spring list */ 
                        }/*any edges*/
                        /* ---springs */
                }/*omit on snap */
        }/*loop all bp's*/
+return 0; /*done fine*/
+}
+
+void *exec_softbody_calc_forces(void *data)
+{
+       SB_thread_context *pctx = (SB_thread_context*)data;
+    _softbody_calc_forces_slice_in_a_thread(pctx->ob,pctx->forcetime,pctx->timenow,pctx->ifirst,pctx->ilast,NULL,pctx->do_effector,pctx->do_deflector,pctx->fieldfactor,pctx->windfactor);
+       return 0;
+} 
+
+void sb_cf_threads_run(struct Object *ob, float forcetime, float timenow,int totpoint,int *ptr_to_break_func(),struct ListBase *do_effector,int do_deflector,float fieldfactor, float windfactor)
+{
+       ListBase threads;
+       SB_thread_context *sb_threads;
+       int i, totthread,left,dec;
+       int lowpoints =10; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */
+
+       /* figure the number of threads while preventing pretty pointless threading overhead */
+       if(totpoint < lowpoints) {totthread=1;}
+       else{
+               if(G.scene->r.mode & R_FIXED_THREADS)
+                       totthread= G.scene->r.threads;
+               else
+                       totthread= BLI_system_thread_count();
+       }
+       /*left to do--> what if we got zillions of CPUs running but 'totpoint' tasks to spread*/
+
+       sb_threads= MEM_callocN(sizeof(SB_thread_context)*totthread, "SBThread");
+       memset(sb_threads, 0, sizeof(SB_thread_context)*totthread);
+       left = totpoint;
+       dec = totpoint/totthread +1;
+       for(i=0; i<totthread; i++) {
+               sb_threads[i].ob = ob; 
+               sb_threads[i].forcetime = forcetime; 
+               sb_threads[i].timenow = timenow; 
+               sb_threads[i].ilast   = left; 
+               left = left - dec;
+               if (left >0){
+                       sb_threads[i].ifirst  = left;
+               }
+               else
+                       sb_threads[i].ifirst  = 0; 
+        sb_threads[i].do_effector = do_effector;
+        sb_threads[i].do_deflector = do_deflector;
+               sb_threads[i].fieldfactor = fieldfactor;
+               sb_threads[i].windfactor  = windfactor;
+               sb_threads[i].nr= i;
+               sb_threads[i].tot= totthread;
+       }
+
+
+       if(totthread > 1) {
+               BLI_init_threads(&threads, exec_softbody_calc_forces, totthread);
+
+               for(i=0; i<totthread; i++)
+                       BLI_insert_thread(&threads, &sb_threads[i]);
+
+               BLI_end_threads(&threads);
+       }
+       else
+               exec_softbody_calc_forces(&sb_threads[0]);
+    /* clean up */
+       MEM_freeN(sb_threads);
+}
+
+static void softbody_calc_forcesEx(Object *ob, float forcetime, float timenow, int nl_flags)
+{
+/* rule we never alter free variables :bp->vec bp->pos in here ! 
+ * this will ruin adaptive stepsize AKA heun! (BM) 
+ */
+       SoftBody *sb= ob->soft; /* is supposed to be there */
+       BodyPoint *bproot;
+       ListBase *do_effector;
+       float iks, gravity;
+       float fieldfactor = 1000.0f, windfactor  = 250.0f;   
+       int   do_deflector,do_selfcollision,do_springcollision,do_aero;
+       
+       gravity = sb->grav * sb_grav_force_scale(ob);   
+       
+       /* check conditions for various options */
+       do_deflector= query_external_colliders(ob);
+       do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
+       do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
+       do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
+       
+       iks  = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
+       bproot= sb->bpoint; /* need this for proper spring addressing */
+       
+       if (do_springcollision || do_aero)  
+       sb_sfesf_threads_run(ob,timenow,sb->totspring,NULL);    
+       
+       /* after spring scan because it uses Effoctors too */
+       do_effector= pdInitEffectors(ob,NULL);
 
+       if (do_deflector) {
+               float defforce[3];
+               do_deflector = sb_detect_aabb_collisionCached(defforce,ob->lay,ob,timenow);
+       }
+
+       sb_cf_threads_run(ob,forcetime,timenow,sb->totpoint,NULL,do_effector,do_deflector,fieldfactor,windfactor);
 
        /* finally add forces caused by face collision */
        if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob,timenow);
        
        /* finish matrix and solve */
-#if (0) // remove onl linking for now .. still i am not sure .. the jacobian can be usefull .. so keep that BM
-       if(nl_flags & NLF_SOLVE){
-               //double sct,sst=PIL_check_seconds_timer();
-               for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
-                       int iv =3*(sb->totpoint-a);
-                       int ip =3*(2*sb->totpoint-a);
-                       int n;
-                       for (n=0;n<3;n++) {nlRightHandSideSet(0, iv+n, bp->force[0+n]);}
-                       for (n=0;n<3;n++) {nlRightHandSideSet(0, ip+n, bp->vec[0+n]);}
+       if(do_effector) pdEndEffectors(do_effector);
+}
+
+
+
+
+static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int nl_flags)
+{
+       /* redirection to the new threaded Version */
+       if (G.rt !=16){ 
+               softbody_calc_forcesEx(ob, forcetime, timenow, nl_flags);
+               return;
+       }
+       else{
+               /* so the following will die  */
+               /* |||||||||||||||||||||||||| */
+               /* VVVVVVVVVVVVVVVVVVVVVVVVVV */
+
+               /* rule we never alter free variables :bp->vec bp->pos in here ! 
+               * this will ruin adaptive stepsize AKA heun! (BM) 
+               */
+               SoftBody *sb= ob->soft; /* is supposed to be there */
+               BodyPoint  *bp;
+               BodyPoint *bproot;
+               BodySpring *bs; 
+               ListBase *do_effector;
+               float iks, ks, kd, gravity;
+               float fieldfactor = 1000.0f, windfactor  = 250.0f;   
+               float tune = sb->ballstiff;
+               int a, b,  do_deflector,do_selfcollision,do_springcollision,do_aero;
+
+
+               /* jacobian
+               NLboolean success;
+
+               if(nl_flags){
+               nlBegin(NL_SYSTEM);
+               nlBegin(NL_MATRIX);
                }
-               nlEnd(NL_MATRIX);
-               nlEnd(NL_SYSTEM);
+               */
+
+
+               gravity = sb->grav * sb_grav_force_scale(ob);   
+
+               /* check conditions for various options */
+               do_deflector= query_external_colliders(ob);
+               do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
+               do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
+               do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
+
+               iks  = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
+               bproot= sb->bpoint; /* need this for proper spring addressing */
 
-               if ((G.rt >0) && (nl_flags & NLF_BUILD))
-               { 
-                       printf("####MEE#####\n");
-                       nlPrintMatrix();
+               if (do_springcollision || do_aero)  scan_for_ext_spring_forces(ob,timenow);
+               /* after spring scan because it uses Effoctors too */
+               do_effector= pdInitEffectors(ob,NULL);
+
+               if (do_deflector) {
+                       float defforce[3];
+                       do_deflector = sb_detect_aabb_collisionCached(defforce,ob->lay,ob,timenow);
                }
 
-               success= nlSolveAdvanced(NULL, 1);
+               for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+                       /* clear forces  accumulator */
+                       bp->force[0]= bp->force[1]= bp->force[2]= 0.0;
+                       if(nl_flags & NLF_BUILD){
+                               //int ia =3*(sb->totpoint-a);
+                               //int op =3*sb->totpoint;
+                               /* dF/dV = v */ 
+                               /* jacobioan
+                               nlMatrixAdd(op+ia,ia,-forcetime);
+                               nlMatrixAdd(op+ia+1,ia+1,-forcetime);
+                               nlMatrixAdd(op+ia+2,ia+2,-forcetime);
+
+                               nlMatrixAdd(ia,ia,1);
+                               nlMatrixAdd(ia+1,ia+1,1);
+                               nlMatrixAdd(ia+2,ia+2,1);
+
+                               nlMatrixAdd(op+ia,op+ia,1);
+                               nlMatrixAdd(op+ia+1,op+ia+1,1);
+                               nlMatrixAdd(op+ia+2,op+ia+2,1);
+                               */
 
-               // nlPrintMatrix(); /* for debug purpose .. anyhow cropping B vector looks like working */
-               if(success){
-                       float f;
-                       int index =0;
-                       /* for debug purpose .. anyhow cropping B vector looks like working */
-                       if (G.rt >0)
-                               for(a=2*sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
-                                       f=nlGetVariable(0,index);
-                                       printf("(%f ",f);index++;
-                                       f=nlGetVariable(0,index);
-                                       printf("%f ",f);index++;
-                                       f=nlGetVariable(0,index);
-                                       printf("%f)",f);index++;
+
+                       }
+
+                       /* naive ball self collision */
+                       /* needs to be done if goal snaps or not */
+                       if(do_selfcollision){
+                               int attached;
+                               BodyPoint   *obp;
+                               int c,b;
+                               float velcenter[3],dvel[3],def[3];
+                               float distance;
+                               float compare;
+
+                               for(c=sb->totpoint, obp= sb->bpoint; c>=a; c--, obp++) {
+
+                                       //if ((bp->octantflag & obp->octantflag) == 0) continue;
+
+                                       compare = (obp->colball + bp->colball);         
+                                       VecSubf(def, bp->pos, obp->pos);
+
+                                       /* rather check the AABBoxes before ever calulating the real distance */
+                                       /* mathematically it is completly nuts, but performace is pretty much (3) times faster */
+                                       if ((ABS(def[0]) > compare) || (ABS(def[1]) > compare) || (ABS(def[2]) > compare)) continue;
+
+                                       distance = Normalize(def);
+                                       if (distance < compare ){
+                                               /* exclude body points attached with a spring */
+                                               attached = 0;
+                                               for(b=obp->nofsprings;b>0;b--){
+                                                       bs = sb->bspring + obp->springs[b-1];
+                                                       if (( sb->totpoint-a == bs->v2)  || ( sb->totpoint-a == bs->v1)){
+                                                               attached=1;
+                                                               continue;}
+                                               }
+                                               if (!attached){
+                                                       float f = tune/(distance) + tune/(compare*compare)*distance - 2.0f*tune/compare ;
+
+                                                       VecMidf(velcenter, bp->vec, obp->vec);
+                                                       VecSubf(dvel,velcenter,bp->vec);
+                                                       VecMulf(dvel,sb->nodemass);
+
+                                                       Vec3PlusStVec(bp->force,f*(1.0f-sb->balldamp),def);
+                                                       Vec3PlusStVec(bp->force,sb->balldamp,dvel);
+
+                                                       if(nl_flags & NLF_BUILD){
+                                                               //int ia =3*(sb->totpoint-a);
+                                                               //int ic =3*(sb->totpoint-c);
+                                                               //int op =3*sb->totpoint;
+                                                               //float mvel = forcetime*sb->nodemass*sb->balldamp;
+                                                               //float mpos = forcetime*tune*(1.0f-sb->balldamp);
+                                                               /*some quick and dirty entries to the jacobian*/
+                                                               //dfdx_goal(ia,ia,op,mpos);
+                                                               //dfdv_goal(ia,ia,mvel);
+                                                               /* exploit force(a,b) == -force(b,a) part1/2 */
+                                                               //dfdx_goal(ic,ic,op,mpos);
+                                                               //dfdv_goal(ic,ic,mvel);
+
+
+                                                               /*TODO sit down an X-out the true jacobian entries*/
+                                                               /*well does not make to much sense because the eigenvalues
+                                                               of the jacobian go negative; and negative eigenvalues
+                                                               on a complex iterative system z(n+1)=A * z(n) 
+                                                               give imaginary roots in the charcateristic polynom
+                                                               --> solutions that to z(t)=u(t)* exp ( i omega t) --> oscilations we don't want here 
+                                                               where u(t) is a unknown amplitude function (worst case rising fast)
+                                                               */ 
+                                                       }
+
+                                                       /* exploit force(a,b) == -force(b,a) part2/2 */
+                                                       VecSubf(dvel,velcenter,obp->vec);
+                                                       VecMulf(dvel,sb->nodemass);
+
+                                                       Vec3PlusStVec(obp->force,sb->balldamp,dvel);
+                                                       Vec3PlusStVec(obp->force,-f*(1.0f-sb->balldamp),def);
+
+
+                                               }
+                                       }
                                }
+                       }
+                       /* naive ball self collision done */
 
-                               index =0;
-                               for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+                       if(bp->goal < SOFTGOALSNAP){ /* ommit this bp when it snaps */
+                               float auxvect[3];  
+                               float velgoal[3];
+
+                               /* do goal stuff */
+                               if(ob->softflag & OB_SB_GOAL) {
+                                       /* true elastic goal */
+                                       VecSubf(auxvect,bp->pos,bp->origT);
+                                       ks  = 1.0f/(1.0f- bp->goal*sb->goalspring)-1.0f ;
+                                       bp->force[0]+= -ks*(auxvect[0]);
+                                       bp->force[1]+= -ks*(auxvect[1]);
+                                       bp->force[2]+= -ks*(auxvect[2]);
+
+                                       if(nl_flags & NLF_BUILD){
+                                               //int ia =3*(sb->totpoint-a);
+                                               //int op =3*(sb->totpoint);
+                                               /* depending on my pos */ 
+                                               //dfdx_goal(ia,ia,op,ks*forcetime);
+                                       }
+
+
+                                       /* calulate damping forces generated by goals*/
+                                       VecSubf(velgoal,bp->origS, bp->origE);
+                                       kd =  sb->goalfrict * sb_fric_force_scale(ob) ;
+                                       VecAddf(auxvect,velgoal,bp->vec);
+
+                                       if (forcetime > 0.0 ) { /* make sure friction does not become rocket motor on time reversal */
+                                               bp->force[0]-= kd * (auxvect[0]);
+                                               bp->force[1]-= kd * (auxvect[1]);
+                                               bp->force[2]-= kd * (auxvect[2]);
+                                               if(nl_flags & NLF_BUILD){
+                                                       //int ia =3*(sb->totpoint-a);
+                                                       Normalize(auxvect);
+                                                       /* depending on my vel */ 
+                                                       //dfdv_goal(ia,ia,kd*forcetime);
+                                               }
+
+                                       }
+                                       else {
+                                               bp->force[0]-= kd * (velgoal[0] - bp->vec[0]);
+                                               bp->force[1]-= kd * (velgoal[1] - bp->vec[1]);
+                                               bp->force[2]-= kd * (velgoal[2] - bp->vec[2]);
+                                       }
+                               }
+                               /* done goal stuff */
+
+
+                               /* gravitation */
+                               bp->force[2]-= gravity*sb->nodemass; /* individual mass of node here */
+                               //bp->force[1]-= gravity*sb->nodemass; /* individual mass of node here */
+
+
+                               /* particle field & vortex */
+                               if(do_effector) {
+                                       float force[3]= {0.0f, 0.0f, 0.0f};
+                                       float speed[3]= {0.0f, 0.0f, 0.0f};
+                                       float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */
+
+                                       pdDoEffectors(do_effector, bp->pos, force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
+
+                                       /* apply forcefield*/
+                                       VecMulf(force,fieldfactor* eval_sb_fric_force_scale); 
+                                       VECADD(bp->force, bp->force, force);
+
+                                       /* BP friction in moving media */       
+                                       kd= sb->mediafrict* eval_sb_fric_force_scale;  
+                                       bp->force[0] -= kd * (bp->vec[0] + windfactor*speed[0]/eval_sb_fric_force_scale);
+                                       bp->force[1] -= kd * (bp->vec[1] + windfactor*speed[1]/eval_sb_fric_force_scale);
+                                       bp->force[2] -= kd * (bp->vec[2] + windfactor*speed[2]/eval_sb_fric_force_scale);
+                                       /* now we'll have nice centrifugal effect for vortex */
+
+                               }
+                               else {
+                                       /* BP friction in media (not) moving*/
+                                       kd= sb->mediafrict* sb_fric_force_scale(ob);  
+                                       /* assume it to be proportional to actual velocity */
+                                       bp->force[0]-= bp->vec[0]*kd;
+                                       bp->force[1]-= bp->vec[1]*kd;
+                                       bp->force[2]-= bp->vec[2]*kd;
+                                       /* friction in media done */
+                                       if(nl_flags & NLF_BUILD){
+                                               //int ia =3*(sb->totpoint-a);
+                                               /* da/dv =  */ 
+
+                                               //                                      nlMatrixAdd(ia,ia,forcetime*kd);
+                                               //                                      nlMatrixAdd(ia+1,ia+1,forcetime*kd);
+                                               //                                      nlMatrixAdd(ia+2,ia+2,forcetime*kd);
+                                       }
+
+                               }
+                               /* +++cached collision targets */
+                               bp->choke = 0.0f;
+                               bp->choke2 = 0.0f;
+                               bp->flag &= ~SBF_DOFUZZY;
+                               if(do_deflector) {
+                                       float cfforce[3],defforce[3] ={0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f}, facenormal[3], cf = 1.0f,intrusion;
+                                       kd = 1.0f;
+
+                                       if (sb_deflect_face(ob,bp->pos,facenormal,defforce,&cf,timenow,vel,&intrusion)){
+                                               if ((!nl_flags)&&(intrusion < 0.0f)){
+                                                       /*bjornmose:  uugh.. what an evil hack 
+                                                       violation of the 'don't touch bp->pos in here' rule 
+                                                       but works nice, like this-->
+                                                       we predict the solution beeing out of the collider
+                                                       in heun step No1 and leave the heun step No2 adapt to it
+                                                       so we kind of introduced a implicit solver for this case 
+                                                       */
+                                                       Vec3PlusStVec(bp->pos,-intrusion,facenormal);
+
+                                                       sb->scratch->flag |= SBF_DOFUZZY;
+                                                       bp->flag |= SBF_DOFUZZY;
+                                                       bp->choke = sb->choke*0.01f;
+                                               }
+                                               else{
+                                                       VECSUB(cfforce,bp->vec,vel);
+                                                       Vec3PlusStVec(bp->force,-cf*50.0f,cfforce);
+                                               }
+                                               Vec3PlusStVec(bp->force,kd,defforce);
+                                               if (nl_flags & NLF_BUILD){
+                                                       // int ia =3*(sb->totpoint-a);
+                                                       // int op =3*sb->totpoint;
+                                                       //dfdx_goal(ia,ia,op,mpos); // don't do unless you know
+                                                       //dfdv_goal(ia,ia,-cf);
+
+                                               }
+
+                                       }
+
+                               }
+                               /* ---cached collision targets */
+
+                               /* +++springs */
+                               if(ob->softflag & OB_SB_EDGES) {
+                                       if (sb->bspring){ /* spring list exists at all ? */
+                                               for(b=bp->nofsprings;b>0;b--){
+                                                       bs = sb->bspring + bp->springs[b-1];
+                                                       if (do_springcollision || do_aero){
+                                                               VecAddf(bp->force,bp->force,bs->ext_force);
+                                                               if (bs->flag & BSF_INTERSECT)
+                                                                       bp->choke = bs->cf; 
+
+                                                       }
+                                                       // sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float forcetime,int nl_flags)
+                                                       // rather remove nl_falgs from code .. will make things a lot cleaner
+                                                       sb_spring_force(ob,sb->totpoint-a,bs,iks,forcetime,0);
+                                               }/* loop springs */
+                                       }/* existing spring list */ 
+                               }/*any edges*/
+                               /* ---springs */
+                       }/*omit on snap */
+               }/*loop all bp's*/
+
+
+               /* finally add forces caused by face collision */
+               if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob,timenow);
+
+               /* finish matrix and solve */
+#if (0) // remove onl linking for now .. still i am not sure .. the jacobian can be usefull .. so keep that BM
+               if(nl_flags & NLF_SOLVE){
+                       //double sct,sst=PIL_check_seconds_timer();
+                       for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+                               int iv =3*(sb->totpoint-a);
+                               int ip =3*(2*sb->totpoint-a);
+                               int n;
+                               for (n=0;n<3;n++) {nlRightHandSideSet(0, iv+n, bp->force[0+n]);}
+                               for (n=0;n<3;n++) {nlRightHandSideSet(0, ip+n, bp->vec[0+n]);}
+                       }
+                       nlEnd(NL_MATRIX);
+                       nlEnd(NL_SYSTEM);
+
+                       if ((G.rt == 32) && (nl_flags & NLF_BUILD))
+                       { 
+                               printf("####MEE#####\n");
+                               nlPrintMatrix();
+                       }
+
+                       success= nlSolveAdvanced(NULL, 1);
+
+                       // nlPrintMatrix(); /* for debug purpose .. anyhow cropping B vector looks like working */
+                       if(success){
+                               float f;
+                               int index =0;
+                               /* for debug purpose .. anyhow cropping B vector looks like working */
+                               if (G.rt ==32)
+                                       for(a=2*sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+                                               f=nlGetVariable(0,index);
+                                               printf("(%f ",f);index++;
+                                               f=nlGetVariable(0,index);
+                                               printf("%f ",f);index++;
+                                               f=nlGetVariable(0,index);
+                                               printf("%f)",f);index++;
+                                       }
+
+                                       index =0;
+                                       for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+                                               f=nlGetVariable(0,index);
+                                               bp->impdv[0] = f; index++;
+                                               f=nlGetVariable(0,index);
+                                               bp->impdv[1] = f; index++;
+                                               f=nlGetVariable(0,index);
+                                               bp->impdv[2] = f; index++;
+                                       }
+                                       /*
+                                       for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
                                        f=nlGetVariable(0,index);
-                                       bp->impdv[0] = f; index++;
+                                       bp->impdx[0] = f; index++;
                                        f=nlGetVariable(0,index);
-                                       bp->impdv[1] = f; index++;
+                                       bp->impdx[1] = f; index++;
                                        f=nlGetVariable(0,index);
-                                       bp->impdv[2] = f; index++;
-                               }
-                               /*
+                                       bp->impdx[2] = f; index++;
+                                       }
+                                       */
+                       }
+                       else{
+                               printf("Matrix inversion failed \n");
                                for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
-                               f=nlGetVariable(0,index);
-                               bp->impdx[0] = f; index++;
-                               f=nlGetVariable(0,index);
-                               bp->impdx[1] = f; index++;
-                               f=nlGetVariable(0,index);
-                               bp->impdx[2] = f; index++;
+                                       VECCOPY(bp->impdv,bp->force);
                                }
-                               */
-               }
-               else{
-                       printf("Matrix inversion failed \n");
-                       for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
-                               VECCOPY(bp->impdv,bp->force);
+
                        }
 
+                       //sct=PIL_check_seconds_timer();
+                       //if (sct-sst > 0.01f) printf(" implicit solver time %f %s \r",sct-sst,ob->id.name);
                }
-
-               //sct=PIL_check_seconds_timer();
-               //if (sct-sst > 0.01f) printf(" implicit solver time %f %s \r",sct-sst,ob->id.name);
-       }
-       /* cleanup */
+               /* cleanup */
 #endif
-       if(do_effector) pdEndEffectors(do_effector);
+               if(do_effector) pdEndEffectors(do_effector);
+       }
 }
+
 static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *err, int mid_flags)
 {
        /* time evolution */
@@ -2458,7 +2870,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
                        /* x(t + dt) = x(t) + v(t~) * dt */ 
                        VecMulf(dx,forcetime);
 
-                       /* the freezer */
+                       /* the freezer coming sooner or later */
                        /*
                        if  ((Inpf(dx,dx)<freezeloc )&&(Inpf(bp->force,bp->force)<freezeforce )){
                                bp->frozen /=2;
@@ -3529,6 +3941,7 @@ static void softbody_step(Object *ob, SoftBody *sb, float dtime)
                                                         * we don't want to lock up the system if physics fail
                */
                int loops =0 ; 
+               
                SoftHeunTol = sb->rklimit; /* humm .. this should be calculated from sb parameters and sizes */
                if (sb->minloops > 0) forcetimemax = 1.0f / sb->minloops;
                
@@ -3546,13 +3959,13 @@ static void softbody_step(Object *ob, SoftBody *sb, float dtime)
                        sb->scratch->flag &= ~SBF_DOFUZZY;
                        /* do predictive euler step */
                        softbody_calc_forces(ob, forcetime,timedone/dtime,0);
-                       softbody_apply_forces(ob, forcetime, 1, NULL,mid_flags);
 
+                       softbody_apply_forces(ob, forcetime, 1, NULL,mid_flags);
 
                        /* crop new slope values to do averaged slope step */
                        softbody_calc_forces(ob, forcetime,timedone/dtime,0);
-                       softbody_apply_forces(ob, forcetime, 2, &err,mid_flags);
 
+                       softbody_apply_forces(ob, forcetime, 2, &err,mid_flags);
                        softbody_apply_goalsnap(ob);
                        
                        if (err > SoftHeunTol) { /* error needs to be scaled to some quantity */
@@ -3603,7 +4016,7 @@ static void softbody_step(Object *ob, SoftBody *sb, float dtime)
                //                              if(G.f & G_DEBUG){
                if(sb->solverflags & SBSO_MONITOR ){
                        if (loops > HEUNWARNLIMIT) /* monitor high loop counts */
-                               printf("\r       needed %d steps/frame ",loops);
+                               printf("\r needed %d steps/frame",loops);
                }
                
        }
@@ -3627,7 +4040,7 @@ static void softbody_step(Object *ob, SoftBody *sb, float dtime)
 
        if(sb->solverflags & SBSO_MONITOR ){
                sct=PIL_check_seconds_timer();
-               if (sct-sst > 0.5f) printf(" solver time %f %s \r",sct-sst,ob->id.name);
+               if (sct-sst > 0.5f) printf(" solver time %f sec %s \n",sct-sst,ob->id.name);
        }
 }
 
index ad139220785679c33887bf8f297e34c7a4c9f8be..936381c85cc41c0e2ba6851a249974937670f19b 100644 (file)
@@ -545,6 +545,8 @@ Tex *copy_texture(Tex *tex)
        if(texn->type==TEX_IMAGE) id_us_plus((ID *)texn->ima);
        else texn->ima= 0;
        
+       id_us_plus((ID *)texn->ipo);
+       
        if(texn->plugin) {
                texn->plugin= MEM_dupallocN(texn->plugin);
                open_plugin_tex(texn->plugin);
@@ -845,3 +847,19 @@ void BKE_free_envmap(EnvMap *env)
 }
 
 /* ------------------------------------------------------------------------- */
+int BKE_texture_dependsOnTime(const struct Tex *texture)
+{
+       if(texture->plugin) {
+               // assume all plugins depend on time
+               return 1;
+       } else if(      texture->ima && 
+                       ELEM(texture->ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
+               return 1;
+       } else if(texture->ipo) {
+               // assume any ipo means the texture is animated
+               return 1;
+       }
+       return 0;
+}
+
+/* ------------------------------------------------------------------------- */
index b81ff0ee66f9588e15bd218969553d2524490cac..6d9a17efebffe7bcb2dcd5969638e57ba5f32b4c 100644 (file)
@@ -1,4 +1,6 @@
 /**
+ *
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -40,6 +42,35 @@ typedef struct BVHTreeOverlap {
        int indexB;
 } BVHTreeOverlap;
 
+typedef struct BVHTreeNearest
+{
+       int index;                      /* the index of the nearest found (untouched if none is found within a dist radius from the given coordinates) */
+       float co[3];            /* nearest coordinates (untouched it none is found within a dist radius from the given coordinates) */
+       float no[3];            /* normal at nearest coordinates (untouched it none is found within a dist radius from the given coordinates) */
+       float dist;                     /* squared distance to search arround */
+} BVHTreeNearest;
+
+typedef struct BVHTreeRay
+{
+       float origin[3];        /* ray origin */
+       float direction[3];     /* ray direction */
+} BVHTreeRay;
+
+typedef struct BVHTreeRayHit
+{
+       int index;                      /* index of the tree node (untouched if no hit is found) */
+       float co[3];            /* coordinates of the hit point */
+       float no[3];            /* normal on hit point */
+       float dist;                     /* distance to the hit point */
+} BVHTreeRayHit;
+
+/* callback must update nearest in case it finds a nearest result */
+typedef void (*BVHTree_NearestPointCallback) (void *userdata, int index, const float *co, BVHTreeNearest *nearest);
+
+/* callback must update hit in case it finds a nearest successful hit */
+typedef void (*BVHTree_RayCastCallback) (void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit);
+
+
 BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis);
 void BLI_bvhtree_free(BVHTree *tree);
 
@@ -56,5 +87,10 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result)
 
 float BLI_bvhtree_getepsilon(BVHTree *tree);
 
+/* find nearest node to the given coordinates (if nearest is given it will only search nodes where square distance is smaller than nearest->dist) */
+int BLI_bvhtree_find_nearest(BVHTree *tree, const float *co, BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata);
+
+int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata);
+
 #endif // BLI_KDOPBVH_H
 
index 4ceb9762a7b687c4bc4bb23f776aac190b667b58..9671551a7f10212041fd0cfb9bb59d8a82274e6f 100644 (file)
@@ -28,8 +28,9 @@
 
 #include "math.h"
 #include <stdio.h>
-#include <stdlib.h> 
+#include <stdlib.h>
 #include <string.h>
+#include <assert.h>
 
 #include "MEM_guardedalloc.h"
 
 #include <omp.h>
 #endif
 
+
+
+#define MAX_TREETYPE 32
+
 typedef struct BVHNode
 {
-       struct BVHNode **children; // max 8 children
-       struct BVHNode *parent; // needed for bottom - top update
-       float *bv; // Bounding volume of all nodes, max 13 axis
-       int index; /* face, edge, vertex index */
-       char totnode; // how many nodes are used, used for speedup
-       char traversed;  // how many nodes already traversed until this level?
-       char main_axis;
+       struct BVHNode **children;
+       float *bv;              // Bounding volume of all nodes, max 13 axis
+       int index;              // face, edge, vertex index
+       char totnode;   // how many nodes are used, used for speedup
+       char main_axis; // Axis used to split this node
 } BVHNode;
 
 struct BVHTree
@@ -72,8 +75,34 @@ typedef struct BVHOverlapData
        BVHTree *tree1, *tree2; 
        BVHTreeOverlap *overlap; 
        int i, max_overlap; /* i is number of overlaps */
+       int start_axis, stop_axis;
 } BVHOverlapData;
-////////////////////////////////////////
+
+typedef struct BVHNearestData
+{
+       BVHTree *tree;
+       float   *co;
+       BVHTree_NearestPointCallback callback;
+       void    *userdata;
+       float proj[13];                 //coordinates projection over axis
+       BVHTreeNearest nearest;
+
+} BVHNearestData;
+
+typedef struct BVHRayCastData
+{
+       BVHTree *tree;
+
+       BVHTree_RayCastCallback callback;
+       void    *userdata;
+
+
+       BVHTreeRay    ray;
+       float ray_dot_axis[13];
+
+       BVHTreeRayHit hit;
+} BVHRayCastData;
+////////////////////////////////////////m
 
 
 ////////////////////////////////////////////////////////////////////////
@@ -244,7 +273,7 @@ int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis){
        int begin = _begin, end = _end, cut;
        while(end-begin > 3)
        {
-               cut = bvh_partition(a, begin, end, bvh_medianof3(a, begin, (begin+end)/2, end-1, axis), axis ); 
+               cut = bvh_partition(a, begin, end, bvh_medianof3(a, begin, (begin+end)/2, end-1, axis), axis );
                if(cut <= n)
                        begin = cut;
                else
@@ -255,124 +284,15 @@ int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis){
        return n;
 }
 
-
 //////////////////////////////////////////////////////////////////////////////////////////////////////
 
-void BLI_bvhtree_free(BVHTree *tree)
-{      
-       if(tree)
-       {
-               MEM_freeN(tree->nodes);
-               MEM_freeN(tree->nodearray);
-               MEM_freeN(tree->nodebv);
-               MEM_freeN(tree->nodechild);
-               MEM_freeN(tree);
-       }
-}
-
-BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
-{
-       BVHTree *tree;
-       int numbranches=0, i;
-       
-       // only support up to octree
-       if(tree_type > 8)
-               return NULL;
-
-       tree = (BVHTree *)MEM_callocN(sizeof(BVHTree), "BVHTree");
-       
-       if(tree)
-       {
-               tree->epsilon = epsilon;
-               tree->tree_type = tree_type; 
-               tree->axis = axis;
-               
-               if(axis == 26)
-               {
-                       tree->start_axis = 0;
-                       tree->stop_axis = 13;
-               }
-               else if(axis == 18)
-               {
-                       tree->start_axis = 7;
-                       tree->stop_axis = 13;
-               }
-               else if(axis == 14)
-               {
-                       tree->start_axis = 0;
-                       tree->stop_axis = 7;
-               }
-               else if(axis == 8) // AABB
-               {
-                       tree->start_axis = 0;
-                       tree->stop_axis = 4;
-               }
-               else if(axis == 6) // OBB
-               {
-                       tree->start_axis = 0;
-                       tree->stop_axis = 3;
-               }
-               else
-               {
-                       MEM_freeN(tree);
-                       return NULL;
-               }
-
-
-               // calculate max number of branches, our bvh kdop is "almost perfect"
-               for(i = 1; i <= (int)ceil((float)((float)log(maxsize)/(float)log(tree_type))); i++)
-                       numbranches += (pow(tree_type, i) / tree_type);
-               
-               tree->nodes = (BVHNode **)MEM_callocN(sizeof(BVHNode *)*(numbranches+maxsize + tree_type), "BVHNodes");
-               
-               if(!tree->nodes)
-               {
-                       MEM_freeN(tree);
-                       return NULL;
-               }
-               
-               tree->nodebv = (float*)MEM_callocN(sizeof(float)* axis * (numbranches+maxsize + tree_type), "BVHNodeBV");
-               if(!tree->nodebv)
-               {
-                       MEM_freeN(tree->nodes);
-                       MEM_freeN(tree);
-               }
-
-               tree->nodechild = (BVHNode**)MEM_callocN(sizeof(BVHNode*) * tree_type * (numbranches+maxsize + tree_type), "BVHNodeBV");
-               if(!tree->nodechild)
-               {
-                       MEM_freeN(tree->nodebv);
-                       MEM_freeN(tree->nodes);
-                       MEM_freeN(tree);
-               }
-
-               tree->nodearray = (BVHNode *)MEM_callocN(sizeof(BVHNode)*(numbranches+maxsize + tree_type), "BVHNodeArray");
-               
-               if(!tree->nodearray)
-               {
-                       MEM_freeN(tree->nodechild);
-                       MEM_freeN(tree->nodebv);
-                       MEM_freeN(tree->nodes);
-                       MEM_freeN(tree);
-                       return NULL;
-               }
-
-               //link the dynamic bv and child links
-               for(i=0; i< numbranches+maxsize + tree_type; i++)
-               {
-                       tree->nodearray[i].bv = tree->nodebv + i * axis;
-                       tree->nodearray[i].children = tree->nodechild + i * tree_type;
-               }
-               
-       }
-
-       return tree;
-}
-
-
+/*
+ * BVHTree bounding volumes functions
+ */
 static void create_kdop_hull(BVHTree *tree, BVHNode *node, float *co, int numpoints, int moving)
 {
        float newminmax;
+       float *bv = node->bv;
        int i, k;
        
        // don't init boudings for the moving case
@@ -380,8 +300,8 @@ static void create_kdop_hull(BVHTree *tree, BVHNode *node, float *co, int numpoi
        {
                for (i = tree->start_axis; i < tree->stop_axis; i++)
                {
-                       node->bv[2*i] = FLT_MAX;
-                       node->bv[2*i + 1] = -FLT_MAX;
+                       bv[2*i] = FLT_MAX;
+                       bv[2*i + 1] = -FLT_MAX;
                }
        }
        
@@ -391,10 +311,10 @@ static void create_kdop_hull(BVHTree *tree, BVHNode *node, float *co, int numpoi
                for (i = tree->start_axis; i < tree->stop_axis; i++)
                {
                        newminmax = INPR(&co[k * 3], KDOP_AXES[i]);
-                       if (newminmax < node->bv[2 * i])
-                               node->bv[2 * i] = newminmax;
-                       if (newminmax > node->bv[(2 * i) + 1])
-                               node->bv[(2 * i) + 1] = newminmax;
+                       if (newminmax < bv[2 * i])
+                               bv[2 * i] = newminmax;
+                       if (newminmax > bv[(2 * i) + 1])
+                               bv[(2 * i) + 1] = newminmax;
                }
        }
 }
@@ -405,6 +325,7 @@ static void refit_kdop_hull(BVHTree *tree, BVHNode *node, int start, int end)
        float newmin,newmax;
        int i, j;
        float *bv = node->bv;
+
        
        for (i = tree->start_axis; i < tree->stop_axis; i++)
        {
@@ -426,37 +347,7 @@ static void refit_kdop_hull(BVHTree *tree, BVHNode *node, int start, int end)
                                bv[(2 * i) + 1] = newmax;
                }
        }
-}
-
-int BLI_bvhtree_insert(BVHTree *tree, int index, float *co, int numpoints)
-{
-       BVHNode *node= NULL;
-       int i;
-       
-       // insert should only possible as long as tree->totbranch is 0
-       if(tree->totbranch > 0)
-               return 0;
-       
-       if(tree->totleaf+1 >= MEM_allocN_len(tree->nodes))
-               return 0;
-       
-       // TODO check if have enough nodes in array
-       
-       node = tree->nodes[tree->totleaf] = &(tree->nodearray[tree->totleaf]);
-       tree->totleaf++;
-       
-       create_kdop_hull(tree, node, co, numpoints, 0);
-       
-       // inflate the bv with some epsilon
-       for (i = tree->start_axis; i < tree->stop_axis; i++)
-       {
-               node->bv[(2 * i)] -= tree->epsilon; // minimum 
-               node->bv[(2 * i) + 1] += tree->epsilon; // maximum 
-       }
 
-       node->index= index;
-       
-       return 1;
 }
 
 // only supports x,y,z axis in the moment
@@ -484,45 +375,76 @@ static char get_largest_axis(float *bv)
        }
 }
 
-static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end)
+// bottom-up update of bvh node BV
+// join the children on the parent BV
+static void node_join(BVHTree *tree, BVHNode *node)
 {
-       int i, tend;
-       BVHNode *tnode;
-       int slice = (end-start+tree->tree_type-1)/tree->tree_type;      //division rounded up
+       int i, j;
        
-       // Determine which axis to split along
-       char laxis = get_largest_axis(node->bv);
+       for (i = tree->start_axis; i < tree->stop_axis; i++)
+       {
+               node->bv[2*i] = FLT_MAX;
+               node->bv[2*i + 1] = -FLT_MAX;
+       }
        
-       // split nodes along longest axis
-       for (i=0; start < end; start += slice, i++) //i counts the current child
-       {       
-               tend = start + slice;
-               
-               if(tend > end) tend = end;
-               
-               if(tend-start == 1)     // ok, we have 1 left for this node
+       for (i = 0; i < tree->tree_type; i++)
+       {
+               if (node->children[i]) 
                {
-                       node->children[i] = tree->nodes[start];
-                       node->children[i]->parent = node;
+                       for (j = tree->start_axis; j < tree->stop_axis; j++)
+                       {
+                               // update minimum 
+                               if (node->children[i]->bv[(2 * j)] < node->bv[(2 * j)]) 
+                                       node->bv[(2 * j)] = node->children[i]->bv[(2 * j)];
+                               
+                               // update maximum 
+                               if (node->children[i]->bv[(2 * j) + 1] > node->bv[(2 * j) + 1])
+                                       node->bv[(2 * j) + 1] = node->children[i]->bv[(2 * j) + 1];
+                       }
                }
                else
-               {
-                       tnode = node->children[i] = tree->nodes[tree->totleaf  + tree->totbranch] = &(tree->nodearray[tree->totbranch + tree->totleaf]);
-                       tree->totbranch++;
-                       tnode->parent = node;
-                       
-                       if(tend != end)
-                               partition_nth_element(tree->nodes, start, end, tend, laxis);
-                       refit_kdop_hull(tree, tnode, start, tend);
-                       bvh_div_nodes(tree, tnode, start, tend);
-               }
-               node->totnode++;
+                       break;
        }
-       
-       return;
+}
+
+/*
+ * Debug and information functions
+ */
+static void bvhtree_print_tree(BVHTree *tree, BVHNode *node, int depth)
+{
+       int i;
+       for(i=0; i<depth; i++) printf(" ");
+       printf(" - %d (%d): ", node->index, node - tree->nodearray);
+       for(i=2*tree->start_axis; i<2*tree->stop_axis; i++)
+               printf("%.3f ", node->bv[i]);
+       printf("\n");
+
+       for(i=0; i<tree->tree_type; i++)
+               if(node->children[i])
+                       bvhtree_print_tree(tree, node->children[i], depth+1);
+}
+
+static void bvhtree_info(BVHTree *tree)
+{
+       printf("BVHTree info\n");
+       printf("tree_type = %d, axis = %d, epsilon = %f\n", tree->tree_type, tree->axis, tree->epsilon);
+       printf("nodes = %d, branches = %d, leafs = %d\n", tree->totbranch + tree->totleaf,  tree->totbranch, tree->totleaf);
+       printf("Memory per node = %dbytes\n", sizeof(BVHNode) + sizeof(BVHNode*)*tree->tree_type + sizeof(float)*tree->axis);
+       printf("BV memory = %dbytes\n", MEM_allocN_len(tree->nodebv));
+
+       printf("Total memory = %dbytes\n", sizeof(BVHTree)
+               + MEM_allocN_len(tree->nodes)
+               + MEM_allocN_len(tree->nodearray)
+               + MEM_allocN_len(tree->nodechild)
+               + MEM_allocN_len(tree->nodebv)
+               );
+
+//     bvhtree_print_tree(tree, tree->nodes[tree->totleaf], 0);
 }
 
 #if 0
+
+
 static void verify_tree(BVHTree *tree)
 {
        int i, j, check = 0;
@@ -570,81 +492,497 @@ static void verify_tree(BVHTree *tree)
        printf("branches: %d, leafs: %d, total: %d\n", tree->totbranch, tree->totleaf, tree->totbranch + tree->totleaf);
 }
 #endif
-       
-void BLI_bvhtree_balance(BVHTree *tree)
+
+//Helper data and structures to build a min-leaf generalized implicit tree
+//This code can be easily reduced (basicly this is only method to calculate pow(k, n) in O(1).. and stuff like that)
+typedef struct BVHBuildHelper
 {
-       BVHNode *node;
-       
-       if(tree->totleaf == 0)
-               return;
-       
-       // create root node
-       node = tree->nodes[tree->totleaf] = &(tree->nodearray[tree->totleaf]);
-       tree->totbranch++;
-       
-       // refit root bvh node
-       refit_kdop_hull(tree, tree->nodes[tree->totleaf], 0, tree->totleaf);
-       // create + balance tree
-       bvh_div_nodes(tree, tree->nodes[tree->totleaf], 0, tree->totleaf);
-       
-       // verify_tree(tree);
-}
+       int tree_type;                          //
+       int totleafs;                           //
 
-// overlap - is it possbile for 2 bv's to collide ?
-static int tree_overlap(float *bv1, float *bv2, int start_axis, int stop_axis)
+       int leafs_per_child  [32];      //Min number of leafs that are archievable from a node at depth N
+       int branches_on_level[32];      //Number of nodes at depth N (tree_type^N)
+
+       int remain_leafs;                       //Number of leafs that are placed on the level that is not 100% filled
+
+} BVHBuildHelper;
+
+static void build_implicit_tree_helper(BVHTree *tree, BVHBuildHelper *data)
 {
-       float *bv1_end = bv1 + (stop_axis<<1);
-               
-       bv1 += start_axis<<1;
-       bv2 += start_axis<<1;
-       
-       // test all axis if min + max overlap
-       for (; bv1 != bv1_end; bv1+=2, bv2+=2)
+       int depth = 0;
+       int remain;
+       int nnodes;
+
+       data->totleafs = tree->totleaf;
+       data->tree_type= tree->tree_type;
+
+       //Calculate the smallest tree_type^n such that tree_type^n >= num_leafs
+       for(
+               data->leafs_per_child[0] = 1;
+               data->leafs_per_child[0] <  data->totleafs;
+               data->leafs_per_child[0] *= data->tree_type
+       );
+
+       data->branches_on_level[0] = 1;
+
+       //We could stop the loop first (but I am lazy to find out when)
+       for(depth = 1; depth < 32; depth++)
        {
-               if ((*(bv1) > *(bv2 + 1)) || (*(bv2) > *(bv1 + 1))) 
-                       return 0;
+               data->branches_on_level[depth] = data->branches_on_level[depth-1] * data->tree_type;
+               data->leafs_per_child  [depth] = data->leafs_per_child  [depth-1] / data->tree_type;
        }
-       
-       return 1;
+
+       remain = data->totleafs - data->leafs_per_child[1];
+       nnodes = (remain + data->tree_type - 2) / (data->tree_type - 1);
+       data->remain_leafs = remain + nnodes;
 }
 
-static void traverse(BVHOverlapData *data, BVHNode *node1, BVHNode *node2)
+// return the min index of all the leafs archivable with the given branch
+static int implicit_leafs_index(BVHBuildHelper *data, int depth, int child_index)
 {
-       int j;
-       
-       if(tree_overlap(node1->bv, node2->bv, MIN2(data->tree1->start_axis, data->tree2->start_axis), MIN2(data->tree1->stop_axis, data->tree2->stop_axis)))
-       {
-               // check if node1 is a leaf
-               if(!node1->totnode)
-               {
-                       // check if node2 is a leaf
-                       if(!node2->totnode)
-                       {
-                               
-                               if(node1 == node2)
-                               {
-                                       return;
-                               }
-                                       
-                               if(data->i >= data->max_overlap)
-                               {       
-                                       // try to make alloc'ed memory bigger
-                                       data->overlap = realloc(data->overlap, sizeof(BVHTreeOverlap)*data->max_overlap*2);
-                                       
-                                       if(!data->overlap)
-                                       {
-                                               printf("Out of Memory in traverse\n");
-                                               return;
-                                       }
-                                       data->max_overlap *= 2;
-                               }
-                               
-                               // both leafs, insert overlap!
-                               data->overlap[data->i].indexA = node1->index;
-                               data->overlap[data->i].indexB = node2->index;
+       int min_leaf_index = child_index * data->leafs_per_child[depth-1];
+       if(min_leaf_index <= data->remain_leafs)
+               return min_leaf_index;
+       else if(data->leafs_per_child[depth])
+               return data->totleafs - (data->branches_on_level[depth-1] - child_index) * data->leafs_per_child[depth];
+       else
+               return data->remain_leafs;
+}
 
-                               data->i++;
-                       }
+/**
+ * Generalized implicit tree build
+ *
+ * An implicit tree is a tree where its structure is implied, thus there is no need to store child pointers or indexs.
+ * Its possible to find the position of the child or the parent with simple maths (multiplication and adittion). This type
+ * of tree is for example used on heaps.. where node N has its childs at indexs N*2 and N*2+1.
+ *
+ * Altought in this case the tree type is general.. and not know until runtime.
+ * tree_type stands for the maximum number of childs that a tree node can have.
+ * All tree types >= 2 are supported.
+ *
+ * Advantages of the used trees include:
+ *  - No need to store child/parent relations (they are implicit);
+ *  - Any node child always has an index greater than the parent;
+ *  - Brother nodes are sequencial in memory;
+ *
+ *
+ * Some math relations derived for general implicit trees:
+ *
+ *   K = tree_type, ( 2 <= K )
+ *   ROOT = 1
+ *   N child of node A = A * K + (2 - K) + N, (0 <= N < K)
+ *
+ * Util methods:
+ *   TODO...
+ *    (looping elements, knowing if its a leaf or not.. etc...)
+ */
+
+// This functions returns the number of branches needed to have the requested number of leafs.
+static int implicit_needed_branches(int tree_type, int leafs)
+{
+       return MAX2(1, (leafs + tree_type - 3) / (tree_type-1) );
+}
+
+/*
+ * This function handles the problem of "sorting" the leafs (along the split_axis).
+ *
+ * It arranges the elements in the given partitions such that:
+ *  - any element in partition N is less or equal to any element in partition N+1.
+ *  - if all elements are diferent all partition will get the same subset of elements
+ *    as if the array was sorted.
+ *
+ * partition P is described as the elements in the range ( nth[P] , nth[P+1] ]
+ *
+ * TODO: This can be optimized a bit by doing a specialized nth_element instead of K nth_elements
+ */
+static void split_leafs(BVHNode **leafs_array, int *nth, int partitions, int split_axis)
+{
+       int i;
+       for(i=0; i < partitions-1; i++)
+       {
+               if(nth[i] >= nth[partitions])
+                       break;
+
+               partition_nth_element(leafs_array, nth[i], nth[partitions], nth[i+1], split_axis);
+       }
+}
+
+/*
+ * This functions builds an optimal implicit tree from the given leafs.
+ * Where optimal stands for:
+ *  - The resulting tree will have the smallest number of branches;
+ *  - At most only one branch will have NULL childs;
+ *  - All leafs will be stored at level N or N+1.
+ *
+ * This function creates an implicit tree on branches_array, the leafs are given on the leafs_array.
+ *
+ * The tree is built per depth levels. First branchs at depth 1.. then branches at depth 2.. etc..
+ * The reason is that we can build level N+1 from level N witouth any data dependencies.. thus it allows
+ * to use multithread building.
+ *
+ * To archieve this is necessary to find how much leafs are accessible from a certain branch, BVHBuildHelper
+ * implicit_needed_branches and implicit_leafs_index are auxiliar functions to solve that "optimal-split".
+ */
+static void non_recursive_bvh_div_nodes(BVHTree *tree, BVHNode *branches_array, BVHNode **leafs_array, int num_leafs)
+{
+       int i;
+
+       const int tree_type   = tree->tree_type;
+       const int tree_offset = 2 - tree->tree_type; //this value is 0 (on binary trees) and negative on the others
+       const int num_branches= implicit_needed_branches(tree_type, num_leafs);
+
+       BVHBuildHelper data;
+       int depth;
+
+       branches_array--;       //Implicit trees use 1-based indexs
+       
+       build_implicit_tree_helper(tree, &data);
+
+       //Loop tree levels (log N) loops
+       for(i=1, depth = 1; i <= num_branches; i = i*tree_type + tree_offset, depth++)
+       {
+               const int first_of_next_level = i*tree_type + tree_offset;
+               const int  end_j = MIN2(first_of_next_level, num_branches + 1); //index of last branch on this level
+               int j;
+
+               //Loop all branches on this level
+#pragma omp parallel for private(j) schedule(static)
+               for(j = i; j < end_j; j++)
+               {
+                       int k;
+                       const int parent_level_index= j-i;
+                       BVHNode* parent = branches_array + j;
+                       int nth_positions[ MAX_TREETYPE + 1];
+                       char split_axis;
+
+                       int parent_leafs_begin = implicit_leafs_index(&data, depth, parent_level_index);
+                       int parent_leafs_end   = implicit_leafs_index(&data, depth, parent_level_index+1);
+
+                       //This calculates the bounding box of this branch
+                       //and chooses the largest axis as the axis to divide leafs
+                       refit_kdop_hull(tree, parent, parent_leafs_begin, parent_leafs_end);
+                       split_axis = get_largest_axis(parent->bv);
+
+                       //Save split axis (this can be used on raytracing to speedup the query time)
+                       parent->main_axis = split_axis / 2;
+
+                       //Split the childs along the split_axis, note: its not needed to sort the whole leafs array
+                       //Only to assure that the elements are partioned on a way that each child takes the elements
+                       //it would take in case the whole array was sorted.
+                       //Split_leafs takes care of that "sort" problem.
+                       nth_positions[        0] = parent_leafs_begin;
+                       nth_positions[tree_type] = parent_leafs_end;
+                       for(k = 1; k < tree_type; k++)
+                       {
+                               int child_index = j * tree_type + tree_offset + k;
+                               int child_level_index = child_index - first_of_next_level; //child level index
+                               nth_positions[k] = implicit_leafs_index(&data, depth+1, child_level_index);
+                       }
+
+                       split_leafs(leafs_array, nth_positions, tree_type, split_axis);
+
+
+                       //Setup children and totnode counters
+                       //Not really needed but currently most of BVH code relies on having an explicit children structure
+                       for(k = 0; k < tree_type; k++)
+                       {
+                               int child_index = j * tree_type + tree_offset + k;
+                               int child_level_index = child_index - first_of_next_level; //child level index
+
+                               int child_leafs_begin = implicit_leafs_index(&data, depth+1, child_level_index);
+                               int child_leafs_end   = implicit_leafs_index(&data, depth+1, child_level_index+1);
+
+                               if(child_leafs_end - child_leafs_begin > 1)
+                                       parent->children[k] = branches_array + child_index;
+                               else if(child_leafs_end - child_leafs_begin == 1)
+                                       parent->children[k] = leafs_array[ child_leafs_begin ];
+                               else
+                                       break;
+
+                               parent->totnode = k+1;
+                       }
+               }
+       }
+}
+
+
+/*
+ * BLI_bvhtree api
+ */
+BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
+{
+       BVHTree *tree;
+       int numnodes, i;
+       
+       // theres not support for trees below binary-trees :P
+       if(tree_type < 2)
+               return NULL;
+       
+       if(tree_type > MAX_TREETYPE)
+               return NULL;
+
+       tree = (BVHTree *)MEM_callocN(sizeof(BVHTree), "BVHTree");
+       
+       if(tree)
+       {
+               tree->epsilon = epsilon;
+               tree->tree_type = tree_type; 
+               tree->axis = axis;
+               
+               if(axis == 26)
+               {
+                       tree->start_axis = 0;
+                       tree->stop_axis = 13;
+               }
+               else if(axis == 18)
+               {
+                       tree->start_axis = 7;
+                       tree->stop_axis = 13;
+               }
+               else if(axis == 14)
+               {
+                       tree->start_axis = 0;
+                       tree->stop_axis = 7;
+               }
+               else if(axis == 8) // AABB
+               {
+                       tree->start_axis = 0;
+                       tree->stop_axis = 4;
+               }
+               else if(axis == 6) // OBB
+               {
+                       tree->start_axis = 0;
+                       tree->stop_axis = 3;
+               }
+               else
+               {
+                       MEM_freeN(tree);
+                       return NULL;
+               }
+
+
+               //Allocate arrays
+               numnodes = maxsize + implicit_needed_branches(tree_type, maxsize) + tree_type;
+
+               tree->nodes = (BVHNode **)MEM_callocN(sizeof(BVHNode *)*numnodes, "BVHNodes");
+               
+               if(!tree->nodes)
+               {
+                       MEM_freeN(tree);
+                       return NULL;
+               }
+               
+               tree->nodebv = (float*)MEM_callocN(sizeof(float)* axis * numnodes, "BVHNodeBV");
+               if(!tree->nodebv)
+               {
+                       MEM_freeN(tree->nodes);
+                       MEM_freeN(tree);
+               }
+
+               tree->nodechild = (BVHNode**)MEM_callocN(sizeof(BVHNode*) * tree_type * numnodes, "BVHNodeBV");
+               if(!tree->nodechild)
+               {
+                       MEM_freeN(tree->nodebv);
+                       MEM_freeN(tree->nodes);
+                       MEM_freeN(tree);
+               }
+
+               tree->nodearray = (BVHNode *)MEM_callocN(sizeof(BVHNode)* numnodes, "BVHNodeArray");
+               
+               if(!tree->nodearray)
+               {
+                       MEM_freeN(tree->nodechild);
+                       MEM_freeN(tree->nodebv);
+                       MEM_freeN(tree->nodes);
+                       MEM_freeN(tree);
+                       return NULL;
+               }
+
+               //link the dynamic bv and child links
+               for(i=0; i< numnodes; i++)
+               {
+                       tree->nodearray[i].bv = tree->nodebv + i * axis;
+                       tree->nodearray[i].children = tree->nodechild + i * tree_type;
+               }
+               
+       }
+
+       return tree;
+}
+
+void BLI_bvhtree_free(BVHTree *tree)
+{      
+       if(tree)
+       {
+               MEM_freeN(tree->nodes);
+               MEM_freeN(tree->nodearray);
+               MEM_freeN(tree->nodebv);
+               MEM_freeN(tree->nodechild);
+               MEM_freeN(tree);
+       }
+}
+
+void BLI_bvhtree_balance(BVHTree *tree)
+{
+       int i;
+
+       BVHNode*  branches_array = tree->nodearray + tree->totleaf;
+       BVHNode** leafs_array    = tree->nodes;
+
+       //This function should only be called once (some big bug goes here if its being called more than once per tree)
+       assert(tree->totbranch == 0);
+
+       //Build the implicit tree
+       non_recursive_bvh_div_nodes(tree, branches_array, leafs_array, tree->totleaf);
+
+       //current code expects the branches to be linked to the nodes array
+       //we perform that linkage here
+       tree->totbranch = implicit_needed_branches(tree->tree_type, tree->totleaf);
+       for(i = 0; i < tree->totbranch; i++)
+               tree->nodes[tree->totleaf + i] = branches_array + i;
+
+       //bvhtree_info(tree);
+}
+
+int BLI_bvhtree_insert(BVHTree *tree, int index, float *co, int numpoints)
+{
+       int i;
+       BVHNode *node = NULL;
+       
+       // insert should only possible as long as tree->totbranch is 0
+       if(tree->totbranch > 0)
+               return 0;
+       
+       if(tree->totleaf+1 >= MEM_allocN_len(tree->nodes)/sizeof(*(tree->nodes)))
+               return 0;
+       
+       // TODO check if have enough nodes in array
+       
+       node = tree->nodes[tree->totleaf] = &(tree->nodearray[tree->totleaf]);
+       tree->totleaf++;
+       
+       create_kdop_hull(tree, node, co, numpoints, 0);
+       node->index= index;
+       
+       // inflate the bv with some epsilon
+       for (i = tree->start_axis; i < tree->stop_axis; i++)
+       {
+               node->bv[(2 * i)] -= tree->epsilon; // minimum 
+               node->bv[(2 * i) + 1] += tree->epsilon; // maximum 
+       }
+
+       return 1;
+}
+
+
+// call before BLI_bvhtree_update_tree()
+int BLI_bvhtree_update_node(BVHTree *tree, int index, float *co, float *co_moving, int numpoints)
+{
+       int i;
+       BVHNode *node= NULL;
+       
+       // check if index exists
+       if(index > tree->totleaf)
+               return 0;
+       
+       node = tree->nodearray + index;
+       
+       create_kdop_hull(tree, node, co, numpoints, 0);
+       
+       if(co_moving)
+               create_kdop_hull(tree, node, co_moving, numpoints, 1);
+       
+       // inflate the bv with some epsilon
+       for (i = tree->start_axis; i < tree->stop_axis; i++)
+       {
+               node->bv[(2 * i)] -= tree->epsilon; // minimum 
+               node->bv[(2 * i) + 1] += tree->epsilon; // maximum 
+       }
+
+       return 1;
+}
+
+// call BLI_bvhtree_update_node() first for every node/point/triangle
+void BLI_bvhtree_update_tree(BVHTree *tree)
+{
+       //Update bottom=>top
+       //TRICKY: the way we build the tree all the childs have an index greater than the parent
+       //This allows us todo a bottom up update by starting on the biger numbered branch
+
+       BVHNode** root  = tree->nodes + tree->totleaf;
+       BVHNode** index = tree->nodes + tree->totleaf + tree->totbranch-1;
+
+       for (; index >= root; index--)
+               node_join(tree, *index);
+}
+
+float BLI_bvhtree_getepsilon(BVHTree *tree)
+{
+       return tree->epsilon;
+}
+
+
+/*
+ * BLI_bvhtree_overlap
+ */
+// overlap - is it possbile for 2 bv's to collide ?
+static int tree_overlap(BVHNode *node1, BVHNode *node2, int start_axis, int stop_axis)
+{
+       float *bv1 = node1->bv;
+       float *bv2 = node2->bv;
+
+       float *bv1_end = bv1 + (stop_axis<<1);
+               
+       bv1 += start_axis<<1;
+       bv2 += start_axis<<1;
+       
+       // test all axis if min + max overlap
+       for (; bv1 != bv1_end; bv1+=2, bv2+=2)
+       {
+               if ((*(bv1) > *(bv2 + 1)) || (*(bv2) > *(bv1 + 1))) 
+                       return 0;
+       }
+       
+       return 1;
+}
+
+static void traverse(BVHOverlapData *data, BVHNode *node1, BVHNode *node2)
+{
+       int j;
+       
+       if(tree_overlap(node1, node2, data->start_axis, data->stop_axis))
+       {
+               // check if node1 is a leaf
+               if(!node1->totnode)
+               {
+                       // check if node2 is a leaf
+                       if(!node2->totnode)
+                       {
+                               
+                               if(node1 == node2)
+                               {
+                                       return;
+                               }
+                                       
+                               if(data->i >= data->max_overlap)
+                               {       
+                                       // try to make alloc'ed memory bigger
+                                       data->overlap = realloc(data->overlap, sizeof(BVHTreeOverlap)*data->max_overlap*2);
+                                       
+                                       if(!data->overlap)
+                                       {
+                                               printf("Out of Memory in traverse\n");
+                                               return;
+                                       }
+                                       data->max_overlap *= 2;
+                               }
+                               
+                               // both leafs, insert overlap!
+                               data->overlap[data->i].indexA = node1->index;
+                               data->overlap[data->i].indexB = node2->index;
+
+                               data->i++;
+                       }
                        else
                        {
                                for(j = 0; j < data->tree2->tree_type; j++)
@@ -678,7 +1016,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result)
                return 0;
        
        // fast check root nodes for collision before doing big splitting + traversal
-       if(!tree_overlap(tree1->nodes[tree1->totleaf]->bv, tree2->nodes[tree2->totleaf]->bv, MIN2(tree1->start_axis, tree2->start_axis), MIN2(tree1->stop_axis, tree2->stop_axis)))
+       if(!tree_overlap(tree1->nodes[tree1->totleaf], tree2->nodes[tree2->totleaf], MIN2(tree1->start_axis, tree2->start_axis), MIN2(tree1->stop_axis, tree2->stop_axis)))
                return 0;
 
        data = MEM_callocN(sizeof(BVHOverlapData *)* tree1->tree_type, "BVHOverlapData_star");
@@ -693,6 +1031,8 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result)
                data[j]->tree2 = tree2;
                data[j]->max_overlap = MAX2(tree1->totleaf, tree2->totleaf);
                data[j]->i = 0;
+               data[j]->start_axis = MIN2(tree1->start_axis, tree2->start_axis);
+               data[j]->stop_axis  = MIN2(tree1->stop_axis,  tree2->stop_axis );
        }
 
 #pragma omp parallel for private(j) schedule(static)
@@ -724,88 +1064,251 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result)
 }
 
 
-// bottom up update of bvh tree:
-// join the 4 children here
-static void node_join(BVHTree *tree, BVHNode *node)
+/*
+ * Nearest neighbour - BLI_bvhtree_find_nearest
+ */
+static float squared_dist(const float *a, const float *b)
 {
-       int i, j;
-       
-       for (i = tree->start_axis; i < tree->stop_axis; i++)
+       float tmp[3];
+       VECSUB(tmp, a, b);
+       return INPR(tmp, tmp);
+}
+
+//Determines the nearest point of the given node BV. Returns the squared distance to that point.
+static float calc_nearest_point(BVHNearestData *data, BVHNode *node, float *nearest)
+{
+       int i;
+       const float *bv = node->bv;
+
+       //nearest on AABB hull
+       for(i=0; i != 3; i++, bv += 2)
        {
-               node->bv[2*i] = FLT_MAX;
-               node->bv[2*i + 1] = -FLT_MAX;
+               if(bv[0] > data->proj[i])
+                       nearest[i] = bv[0];
+               else if(bv[1] < data->proj[i])
+                       nearest[i] = bv[1];
+               else
+                       nearest[i] = data->proj[i];
        }
-       
-       for (i = 0; i < tree->tree_type; i++)
+
+/*
+       //nearest on a general hull
+       VECCOPY(nearest, data->co);
+       for(i = data->tree->start_axis; i != data->tree->stop_axis; i++, bv+=2)
        {
-               if (node->children[i]) 
+               float proj = INPR( nearest, KDOP_AXES[i]);
+               float dl = bv[0] - proj;
+               float du = bv[1] - proj;
+
+               if(dl > 0)
                {
-                       for (j = tree->start_axis; j < tree->stop_axis; j++)
-                       {
-                               // update minimum 
-                               if (node->children[i]->bv[(2 * j)] < node->bv[(2 * j)]) 
-                                       node->bv[(2 * j)] = node->children[i]->bv[(2 * j)];
-                               
-                               // update maximum 
-                               if (node->children[i]->bv[(2 * j) + 1] > node->bv[(2 * j) + 1])
-                                       node->bv[(2 * j) + 1] = node->children[i]->bv[(2 * j) + 1];
-                       }
+                       VECADDFAC(nearest, nearest, KDOP_AXES[i], dl);
                }
+               else if(du < 0)
+               {
+                       VECADDFAC(nearest, nearest, KDOP_AXES[i], du);
+               }
+       }
+*/
+       return squared_dist(data->co, nearest);
+}
+
+
+// TODO: use a priority queue to reduce the number of nodes looked on
+static void dfs_find_nearest(BVHNearestData *data, BVHNode *node)
+{
+       int i;
+       float nearest[3], sdist;
+
+       sdist = calc_nearest_point(data, node, nearest);
+       if(sdist >= data->nearest.dist) return;
+
+       if(node->totnode == 0)
+       {
+               if(data->callback)
+                       data->callback(data->userdata , node->index, data->co, &data->nearest);
                else
-                       break;
+               {
+                       data->nearest.index     = node->index;
+                       VECCOPY(data->nearest.co, nearest);
+                       data->nearest.dist      = sdist;
+               }
+       }
+       else
+       {
+               for(i=0; i != node->totnode; i++)
+                       dfs_find_nearest(data, node->children[i]);
        }
 }
 
-// call before BLI_bvhtree_update_tree()
-int BLI_bvhtree_update_node(BVHTree *tree, int index, float *co, float *co_moving, int numpoints)
+int BLI_bvhtree_find_nearest(BVHTree *tree, const float *co, BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
 {
-       BVHNode *node= NULL;
-       int i = 0;
-       
-       // check if index exists
-       if(index > tree->totleaf)
-               return 0;
-       
-       node = tree->nodearray + index;
-       
-       create_kdop_hull(tree, node, co, numpoints, 0);
-       
-       if(co_moving)
-               create_kdop_hull(tree, node, co_moving, numpoints, 1);
-       
-       // inflate the bv with some epsilon
-       for (i = tree->start_axis; i < tree->stop_axis; i++)
+       int i;
+
+       BVHNearestData data;
+       BVHNode* root = tree->nodes[tree->totleaf];
+
+       //init data to search
+       data.tree = tree;
+       data.co = co;
+
+       data.callback = callback;
+       data.userdata = userdata;
+
+       for(i = data.tree->start_axis; i != data.tree->stop_axis; i++)
        {
-               node->bv[(2 * i)] -= tree->epsilon; // minimum 
-               node->bv[(2 * i) + 1] += tree->epsilon; // maximum 
+               data.proj[i] = INPR(data.co, KDOP_AXES[i]);
        }
-       
-       return 1;
+
+       if(nearest)
+       {
+               memcpy( &data.nearest , nearest, sizeof(*nearest) );
+       }
+       else
+       {
+               data.nearest.index = -1;
+               data.nearest.dist = FLT_MAX;
+       }
+
+       //dfs search
+       if(root)
+               dfs_find_nearest(&data, root);
+
+       //copy back results
+       if(nearest)
+       {
+               memcpy(nearest, &data.nearest, sizeof(*nearest));
+       }
+
+       return data.nearest.index;
 }
 
-// call BLI_bvhtree_update_node() first for every node/point/triangle
-void BLI_bvhtree_update_tree(BVHTree *tree)
+
+/*
+ * Raycast - BLI_bvhtree_ray_cast
+ *
+ * raycast is done by performing a DFS on the BVHTree and saving the closest hit
+ */
+
+//Determines the distance that the ray must travel to hit the bounding volume of the given node
+static float ray_nearest_hit(BVHRayCastData *data, BVHNode *node)
 {
-       BVHNode *leaf, *parent;
-       
-       // reset tree traversing flag
-       for (leaf = tree->nodearray + tree->totleaf; leaf != tree->nodearray + tree->totleaf + tree->totbranch; leaf++)
-               leaf->traversed = 0;
+       int i;
+       const float *bv = node->bv;
+
+       float low = 0, upper = data->hit.dist;
+
+       for(i=0; i != 3; i++, bv += 2)
+       {
+               if(data->ray_dot_axis[i] == 0.0f)
+               {
+                       //axis aligned ray
+                       if(data->ray.origin[i] < bv[0]
+                       || data->ray.origin[i] > bv[1])
+                               return FLT_MAX;
+               }
+               else
+               {
+                       float ll = (bv[0] - data->ray.origin[i]) / data->ray_dot_axis[i];
+                       float lu = (bv[1] - data->ray.origin[i]) / data->ray_dot_axis[i];
+
+                       if(data->ray_dot_axis[i] > 0)
+                       {
+                               if(ll > low)   low = ll;
+                               if(lu < upper) upper = lu;
+                       }
+                       else
+                       {
+                               if(lu > low)   low = lu;
+                               if(ll < upper) upper = ll;
+                       }
        
-       for (leaf = tree->nodearray; leaf != tree->nodearray + tree->totleaf; leaf++)
+                       if(low > upper) return FLT_MAX;
+               }
+       }
+       return low;
+}
+
+static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
+{
+       int i;
+
+       //ray-bv is really fast.. and simple tests revealed its worth to test it
+       //before calling the ray-primitive functions
+       float dist = ray_nearest_hit(data, node);
+       if(dist >= data->hit.dist) return;
+
+       if(node->totnode == 0)
+       {
+               if(data->callback)
+                       data->callback(data->userdata, node->index, &data->ray, &data->hit);
+               else
+               {
+                       data->hit.index = node->index;
+                       data->hit.dist  = dist;
+                       VECADDFAC(data->hit.co, data->ray.origin, data->ray.direction, dist);
+               }
+       }
+       else
        {
-               for (parent = leaf->parent; parent; parent = parent->parent)
+               //pick loop direction to dive into the tree (based on ray direction and split axis)
+               if(data->ray_dot_axis[ node->main_axis ] > 0)
                {
-                       parent->traversed++;    // we tried to go up in hierarchy 
-                       if (parent->traversed < parent->totnode) 
-                               break;  // we do not need to check further 
-                       else 
-                               node_join(tree, parent);
+                       for(i=0; i != node->totnode; i++)
+                       {
+                               dfs_raycast(data, node->children[i]);
+                       }
+               }
+               else
+               {
+                       for(i=node->totnode-1; i >= 0; i--)
+                       {
+                               dfs_raycast(data, node->children[i]);
+                       }
                }
        }
 }
 
-float BLI_bvhtree_getepsilon(BVHTree *tree)
+int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
 {
-       return tree->epsilon;
+       int i;
+       BVHRayCastData data;
+       BVHNode * root = tree->nodes[tree->totleaf];
+
+       data.tree = tree;
+
+       data.callback = callback;
+       data.userdata = userdata;
+
+       VECCOPY(data.ray.origin,    co);
+       VECCOPY(data.ray.direction, dir);
+
+       Normalize(data.ray.direction);
+
+       for(i=0; i<3; i++)
+       {
+               data.ray_dot_axis[i] = INPR( data.ray.direction, KDOP_AXES[i]);
+
+               if(fabs(data.ray_dot_axis[i]) < 1e-7)
+                       data.ray_dot_axis[i] = 0.0;
+       }
+
+
+       if(hit)
+               memcpy( &data.hit, hit, sizeof(*hit) );
+       else
+       {
+               data.hit.index = -1;
+               data.hit.dist = FLT_MAX;
+       }
+
+       if(root)
+               dfs_raycast(&data, root);
+
+
+       if(hit)
+               memcpy( hit, &data.hit, sizeof(*hit) );
+
+       return data.hit.index;
 }
+
index 0776ef2cbaf316220556785bfd1ecf6b2234bda4..f69ebd133bd80291dae9708f3ac538e62e2415e8 100644 (file)
@@ -116,6 +116,7 @@ void        setflag_armature(short mode);
 void    unique_editbone_name (struct ListBase *ebones, char *name);
 
 void   auto_align_armature(short mode);
+void   switch_direction_armature(void);
 
 void   create_vgroups_from_armature(struct Object *ob, struct Object *par);
 void   add_verts_to_dgroups(struct Object *ob, struct Object *par, int heat, int mirror);
@@ -137,7 +138,6 @@ void        transform_armature_mirror_update(void);
 void   hide_selected_armature_bones(void);
 void   hide_unselected_armature_bones(void);
 void   show_all_armature_bones(void);
-void   set_locks_armature_bones(short lock);
 
 #define        BONESEL_ROOT    0x10000000
 #define        BONESEL_TIP             0x20000000
@@ -149,6 +149,10 @@ void       set_locks_armature_bones(short lock);
 /* from autoarmature */
 void BIF_retargetArmature();
 
+/* useful macros */
+#define EBONE_VISIBLE(arm, ebone) ((arm->layer & ebone->layer) && !(ebone->flag & BONE_HIDDEN_A))
+#define EBONE_EDITABLE(ebone) ((ebone->flag & BONE_SELECTED) && !(ebone->flag & BONE_EDITMODE_LOCKED)) 
+
 /* used in bone_select_hierachy() */
 #define BONE_SELECT_PARENT     0
 #define BONE_SELECT_CHILD      1
index ca9f3d6a378f4cd9a7e6baf8812f1c3f263ff19a..9354a577ac160fea47c87498c192da23ff97afd8 100644 (file)
@@ -132,7 +132,7 @@ extern int EM_check_backbuf(unsigned int index);
 extern void EM_free_backbuf(void);
 
 extern void EM_selectmode_menu(void);
-
+extern void EM_mesh_copy_face(short type);
 
 extern void vertexnoise(void);
 extern void vertexsmooth(void);
index 4207047d24e831a2307db88f06606ccae472cd9e..6cf010571c479ba61b2d8d06e735084656bbc50c 100644 (file)
@@ -594,7 +594,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
 
 #define B_VPCOLSLI             2801
 #define B_VPGAMMA              2802
-
+#define B_COPY_TF_TRANSP       2803
 #define B_COPY_TF_MODE         2804
 #define B_COPY_TF_UV           2805
 #define B_COPY_TF_COL          2806
index 06e8c564ef056397af2479828c76f3f09bcd3b17..69bff059356ef6de3fae913a960fa3b5dfc5a1b8 100644 (file)
@@ -163,7 +163,7 @@ PyObject *RunPython( Text * text, PyObject * globaldict );
 PyObject *CreateGlobalDictionary( void );
 void ReleaseGlobalDictionary( PyObject * dict );
 void DoAllScriptsFromList( ListBase * list, short event );
-PyObject *importText( char *name );
+static PyObject *importText( char *name );
 void init_ourImport( void );
 void init_ourReload( void );
 PyObject *blender_import( PyObject * self, PyObject * args );
@@ -1104,12 +1104,10 @@ int BPY_menu_do_python( short menutype, int event )
 *****************************************************************************/
 void BPY_free_compiled_text( struct Text *text )
 {
-       if( !text->compiled )
-               return;
-       Py_DECREF( ( PyObject * ) text->compiled );
-       text->compiled = NULL;
-
-       return;
+       if( text->compiled ) {
+               Py_DECREF( ( PyObject * ) text->compiled );
+               text->compiled = NULL;
+       }
 }
 
 /*****************************************************************************
@@ -2780,48 +2778,38 @@ void DoAllScriptsFromList( ListBase * list, short event )
        return;
 }
 
-PyObject *importText( char *name )
+static PyObject *importText( char *name )
 {
        Text *text;
-       char *txtname;
+       char txtname[22]; /* 21+NULL */
        char *buf = NULL;
        int namelen = strlen( name );
-
-       txtname = malloc( namelen + 3 + 1 );
-       if( !txtname )
-               return NULL;
-
+       
+       if (namelen>21-3) return NULL; /* we know this cant be importable, the name is too long for blender! */
+       
        memcpy( txtname, name, namelen );
        memcpy( &txtname[namelen], ".py", 4 );
 
-       text = ( Text * ) & ( G.main->text.first );
-
-       while( text ) {
+       for(text = G.main->text.first; text; text = text->id.next) {
                if( !strcmp( txtname, text->id.name+2 ) )
                        break;
-               text = text->id.next;
        }
 
-       if( !text ) {
-               free( txtname );
+       if( !text )
                return NULL;
-       }
 
        if( !text->compiled ) {
                buf = txt_to_buf( text );
-               text->compiled =
-                       Py_CompileString( buf, text->id.name+2, Py_file_input );
+               text->compiled = Py_CompileString( buf, text->id.name+2, Py_file_input );
                MEM_freeN( buf );
 
                if( PyErr_Occurred(  ) ) {
                        PyErr_Print(  );
                        BPY_free_compiled_text( text );
-                       free( txtname );
                        return NULL;
                }
        }
 
-       free( txtname );
        return PyImport_ExecCodeModule( name, text->compiled );
 }
 
index 420d292cdcef7073eec1c18f12e0ad6ba2eda759..2b190a6c828cf1534e3ebe092a7f063e8ff1c95f 100644 (file)
@@ -1074,7 +1074,7 @@ void M_Blender_Init(void)
        PyDict_SetItemString(dict, "Material", Material_Init());
        PyDict_SetItemString(dict, "Mesh", Mesh_Init()); 
        PyDict_SetItemString(dict, "Metaball", Metaball_Init());
-       PyDict_SetItemString(dict, "Mathutils", Mathutils_Init());
+       PyDict_SetItemString(dict, "Mathutils", Mathutils_Init("Blender.Mathutils"));
        PyDict_SetItemString(dict, "Geometry", Geometry_Init());
        PyDict_SetItemString(dict, "Modifier", Modifier_Init());
        PyDict_SetItemString(dict, "NMesh", NMesh_Init());
index 8db6a49465e3d2cb0ab832f4613fa8e65d31ddc4..a62a5ee7ed8b23566c0a17d770b61afa0d6afa4c 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "Constraint.h" /*This must come first*/
 
+#include "DNA_armature_types.h"
 #include "DNA_object_types.h"
 #include "DNA_effect_types.h"
 #include "DNA_vec_types.h"
@@ -43,6 +44,7 @@
 #include "BKE_constraint.h"
 #include "BLI_blenlib.h"
 #include "BIF_editconstraint.h"
+#include "BIF_poseobject.h"
 #include "BSE_editipo.h"
 #include "MEM_guardedalloc.h"
 #include "butspace.h"
@@ -2286,19 +2288,32 @@ static PyObject *ConstraintSeq_moveDown( BPy_ConstraintSeq *self, BPy_Constraint
 
 static PyObject *ConstraintSeq_remove( BPy_ConstraintSeq *self, BPy_Constraint *value )
 {
-       bConstraint *con = locate_constr( self,  value );
+       bConstraint *con = locate_constr(self, value);
+       bPoseChannel *active= NULL;
 
        /* if we can't locate the constraint, return (exception already set) */
-       if( !con )
+       if (!con)
                return (PyObject *)NULL;
 
-       /* do the actual removal */
-       if( self->pchan )
-               BLI_remlink( &self->pchan->constraints, con );
-       else
-               BLI_remlink( &self->obj->constraints, con);
+       /* check if we need to set temporary 'active' flag for pchan */
+       if (self->pchan) {
+               active= get_active_posechannel(self->obj);
+               
+               if (active != self->pchan) {
+                       if (active) active->bone->flag &= ~BONE_ACTIVE;
+                       self->pchan->bone->flag |= BONE_ACTIVE;
+               }
+       }
+       
+       /* del_constr_func() frees constraint + its data */
        del_constr_func( self->obj, con );
 
+       /* reset active pchan (if applicable) */
+       if (self->pchan && self->pchan!=active) {
+               if (active) active->bone->flag |= BONE_ACTIVE;
+               self->pchan->bone->flag &= ~BONE_ACTIVE;
+       }
+       
        /* erase the link to the constraint */
        value->con = NULL;
 
index 85c56a616288dd9a3574270577643ed0b75ec590..217e096060f9d372fbad81a726e588d083ad2c8f 100644 (file)
@@ -106,8 +106,9 @@ struct PyMethodDef M_Mathutils_methods[] = {
        {"Point", (PyCFunction) M_Mathutils_Point, METH_VARARGS, M_Mathutils_Point_doc},
        {NULL, NULL, 0, NULL}
 };
-//----------------------------MODULE INIT-------------------------
-PyObject *Mathutils_Init(void)
+/*----------------------------MODULE INIT-------------------------*/
+/* from can be Blender.Mathutils or GameLogic.Mathutils for the BGE */
+PyObject *Mathutils_Init(char *from)
 {
        PyObject *submodule;
 
@@ -125,8 +126,7 @@ PyObject *Mathutils_Init(void)
        if( PyType_Ready( &quaternion_Type ) < 0 )
                return NULL;
        
-       submodule = Py_InitModule3("Blender.Mathutils",
-                                   M_Mathutils_methods, M_Mathutils_doc);
+       submodule = Py_InitModule3(from, M_Mathutils_methods, M_Mathutils_doc);
        return (submodule);
 }
 //-----------------------------METHODS----------------------------
index dd9aae2abed4a7fa2b2ff1e81e5ae43252ca1df1..76d53cb6c4cdf8b93de1852a5373eced088a77a0 100644 (file)
@@ -38,7 +38,7 @@
 #include "euler.h"
 #include "point.h"
 
-PyObject *Mathutils_Init( void );
+PyObject *Mathutils_Init( char * from );
 PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat);
 PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec);
 PyObject *row_point_multiplication(PointObject* pt, MatrixObject * mat);
index 696c78f2bac24005b19c88f3481d201736cb4231..7ba8ad88ea69cc16d83d5edbc761b9b58847e59c 100644 (file)
 #define EXPP_TEX_LACUNARITY_MAX             6.0f
 #define EXPP_TEX_OCTS_MIN                   0.0f
 #define EXPP_TEX_OCTS_MAX                   8.0f
+#define EXPP_TEX_OFST_MIN                   0.0f
+#define EXPP_TEX_OFST_MAX                   6.0f
+#define EXPP_TEX_GAIN_MIN                   0.0f
+#define EXPP_TEX_GAIN_MAX                   6.0f
 #define EXPP_TEX_ISCALE_MIN                 0.0f
 #define EXPP_TEX_ISCALE_MAX                 10.0f
 #define EXPP_TEX_EXP_MIN                    0.010f
@@ -430,6 +434,8 @@ GETFUNC( getNoiseDepth );
 GETFUNC( getNoiseSize );
 GETFUNC( getNoiseType );
 GETFUNC( getOcts );
+GETFUNC( getOffset );
+GETFUNC( getGain );
 GETFUNC( getRepeat );
 GETFUNC( getRGBCol );
 GETFUNC( getSType );
@@ -478,6 +484,8 @@ SETFUNC( setNoiseDepth );
 SETFUNC( setNoiseSize );
 SETFUNC( setNoiseType );
 SETFUNC( setOcts );
+SETFUNC( setOffset );
+SETFUNC( setGain );
 SETFUNC( setRepeat );
 SETFUNC( setRGBCol );
 SETFUNC( setSType );
@@ -646,6 +654,14 @@ static PyGetSetDef BPy_Texture_getseters[] = {
         (getter)Texture_getLacunarity, (setter)Texture_setLacunarity,
         "Gap between succesive frequencies (for Musgrave textures)",
         NULL},
+       {"offset",
+        (getter)Texture_getOffset, (setter)Texture_setOffset,
+        "Fractal offset (for Musgrave textures)",
+        NULL},
+       {"gain",
+        (getter)Texture_getGain, (setter)Texture_setGain,
+        "Gain multiplier (for Musgrave textures)",
+        NULL},
        {"noiseBasis",
         (getter)Texture_getNoiseBasis, (setter)Texture_setNoiseBasis,
         "Noise basis type (wood, stucci, marble, clouds, Musgrave, distorted noise)",
@@ -1837,6 +1853,20 @@ static int Texture_setLacunarity( BPy_Texture * self, PyObject * value )
                                                                EXPP_TEX_LACUNARITY_MAX );
 }
 
+static int Texture_setOffset( BPy_Texture * self, PyObject * value )
+{
+       return EXPP_setFloatClamped ( value, &self->texture->mg_offset,
+                                                               EXPP_TEX_OFST_MIN,
+                                                               EXPP_TEX_OFST_MAX );
+}
+
+static int Texture_setGain( BPy_Texture * self, PyObject * value )
+{
+       return EXPP_setFloatClamped ( value, &self->texture->mg_gain,
+                                                               EXPP_TEX_GAIN_MIN,
+                                                               EXPP_TEX_GAIN_MAX );
+}
+
 static int Texture_setOcts( BPy_Texture * self, PyObject * value )
 {
        return EXPP_setFloatClamped ( value, &self->texture->mg_octaves,
@@ -2168,6 +2198,16 @@ static PyObject *Texture_getOcts( BPy_Texture *self )
        return PyFloat_FromDouble( self->texture->mg_octaves );
 }
 
+static PyObject *Texture_getOffset( BPy_Texture *self )
+{
+       return PyFloat_FromDouble( self->texture->mg_offset );
+}
+
+static PyObject *Texture_getGain( BPy_Texture *self )
+{
+       return PyFloat_FromDouble( self->texture->mg_gain );
+}
+
 static PyObject *Texture_getRepeat( BPy_Texture *self )
 {
        return Py_BuildValue( "(i,i)", self->texture->xrepeat,
index d4dc83e84a039491b9c8e9c24e8b07b4eaf83893..5300fdab808aaccf216c289d288181f9a6a645aa 100644 (file)
@@ -170,17 +170,6 @@ def SetRenderWinPos(locationList):
   the location of the Render window on the screen.
   """
 
-def EnableEdgeShift():
-  """
-  Globally with the unified renderer enabled the outlines of the render
-  are shifted a bit.
-  """
-
-def EnableEdgeAll():
-  """
-  Globally consider transparent faces for edge-rendering with the unified renderer.
-  """
-
 class RenderData:
   """
   The RenderData object
@@ -772,7 +761,7 @@ class RenderData:
     """
     Get/set the starting frame for sequence rendering.
     @type frame: int (optional)
-    @param frame: must be between 1 - 18000
+    @param frame: must be a valid Blender frame number.
     @rtype: int (if prototype is empty)
     @return: Current starting frame for the scene.
     """
@@ -781,7 +770,7 @@ class RenderData:
     """
     Get/set the ending frame for sequence rendering.
     @type frame: int (optional)
-    @param frame: must be between 1 - 18000
+    @param frame: must be a valid Blender frame number.
     @rtype: int (if prototype is empty)
     @return: Current ending frame for the scene.
     """
index 7f42d06240b0a13840458ef46c6c17b5d588c350..cebb7de70115b6e36cebd40b498a1b9ba16089e2 100644 (file)
@@ -344,6 +344,12 @@ class Texture:
        @ivar octs:  Number of frequencies (for Musgrave textures).
        Value is clamped to the range [0.0,8.0].
        @type octs:  float
+       @ivar offset:  Fractal offset (for hetero terrain and multifractal Musgrave textures).
+       Value is clamped to the range [0.0,6.0].
+       @type offset:  float
+       @ivar gain:  Gain multiplier (for multifractal Musgrave textures).
+       Value is clamped to the range [0.0,6.0].
+       @type gain:  float
        @ivar repeat:  Repetition multiplier (for image textures).
        @type repeat:  tuple of 2 ints
        @ivar rgbCol:  RGB color tuple.
index 1155d2ea81770585ae378545482eb3d3e1555740..c352a83d0f411d9e4466c102f1cacf056e9077f6 100644 (file)
@@ -263,7 +263,12 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
        shade_input_set_shade_texco(shi);
        
        if(is->mode==RE_RAY_SHADOW_TRA) 
-               shade_color(shi, shr);
+               if(shi->mat->nodetree && shi->mat->use_nodes) {
+                       ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
+                       shi->mat= vlr->mat;             /* shi->mat is being set in nodetree */
+               }
+               else
+                       shade_color(shi, shr);
        else {
                if(shi->mat->nodetree && shi->mat->use_nodes) {
                        ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
index 114eb3293085f0e7232a5a7288edda92da5cabdc..906405344c47d7f3e2949ddda6111c11791da33d 100644 (file)
@@ -5746,13 +5746,9 @@ void sculptmode_draw_interface_textures(uiBlock *block, unsigned short cx, unsig
 
 void do_fpaintbuts(unsigned short event)
 {
-       Mesh *me;
        Object *ob;
        bDeformGroup *defGroup;
-       MTFace *activetf, *tf;
-       MFace *mf;
-       MCol *activemcol;
-       int a;
+       MTFace *activetf;
        SculptData *sd= &G.scene->sculptdata;
        ID *id, *idtest;
        extern VPaint Gwp;         /* from vpaint */
@@ -5770,45 +5766,19 @@ void do_fpaintbuts(unsigned short event)
                vpaint_dogamma();
                break;
        case B_COPY_TF_MODE:
+               EM_mesh_copy_face(4); /* todo, get rid of magic numbers */
+               break;
+       case B_COPY_TF_TRANSP:
+               EM_mesh_copy_face(5);
+               break;
        case B_COPY_TF_UV:
+               EM_mesh_copy_face(3);
+               break;
        case B_COPY_TF_COL:
+               EM_mesh_copy_face(6);
+               break;
        case B_COPY_TF_TEX:
-               me= get_mesh(OBACT);
-               activetf= get_active_mtface(NULL, &activemcol, 0);
-
-               if(me && activetf) {
-                       for (a=0, tf=me->mtface, mf=me->mface; a < me->totface; a++, tf++, mf++) {
-                               if(tf!=activetf && (mf->flag & ME_FACE_SEL)) {
-                                       if(event==B_COPY_TF_MODE) {
-                                               tf->mode= activetf->mode;
-                                               tf->transp= activetf->transp;
-                                       }
-                                       else if(event==B_COPY_TF_UV) {
-                                               memcpy(tf->uv, activetf->uv, sizeof(tf->uv));
-                                               tf->tpage= activetf->tpage;
-                                               tf->tile= activetf->tile;
-
-                                               if(activetf->mode & TF_TILES) tf->mode |= TF_TILES;
-                                               else tf->mode &= ~TF_TILES;
-
-                                       }
-                                       else if(event==B_COPY_TF_TEX) {
-                                               tf->tpage= activetf->tpage;
-                                               tf->tile= activetf->tile;
-
-                                               if(activetf->mode & TF_TILES) tf->mode |= TF_TILES;
-                                               else tf->mode &= ~TF_TILES;
-                                       }
-                                       else if(event==B_COPY_TF_COL && activemcol)
-                                               memcpy(&me->mcol[a*4], activemcol, sizeof(MCol)*4);
-                               }
-                       }
-
-                       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
-                       do_shared_vertexcol(me);
-                       allqueue(REDRAWVIEW3D, 0);
-                       allqueue(REDRAWIMAGE, 0);
-               }
+               EM_mesh_copy_face(2);
                break;
        case B_SET_VCOL:
                if(FACESEL_PAINT_TEST) 
@@ -6245,8 +6215,20 @@ static void editing_panel_mesh_texface(void)
        if(uiNewPanel(curarea, block, "Texture Face", "Editing", 960, 0, 318, 204)==0) return;
        
        tf = get_active_mtface(NULL, NULL, 0);
+       
        if(tf) {
+               uiDefBut(block, LABEL, B_NOP, "Active Face Mode",       600,185,300,19, NULL, 0.0, 0.0, 0, 0, "Face mode its used for TexFace display and the game engine ");
+               uiDefBut(block, BUT,B_COPY_TF_MODE, "Copy", 850,185,50,19, 0, 0, 0, 0, 0, "Copy active faces mode to other selected (View3D Ctrl+C)");
+               
+               /* Other copy buttons, layout isnt that nice */
                uiBlockBeginAlign(block);
+               uiDefBut(block, BUT,B_COPY_TF_UV, "CopyUV", 600,15,100,19, 0, 0, 0, 0, 0, "Copy active faces UVs to other selected (View3D Ctrl+C)");
+               uiDefBut(block, BUT,B_COPY_TF_TEX, "CopyTex", 700,15,100,19, 0, 0, 0, 0, 0, "Copy active faces Texture to other selected (View3D Ctrl+C)");             
+               uiDefBut(block, BUT,B_COPY_TF_COL, "CopyColor", 800,15,100,19, 0, 0, 0, 0, 0, "Copy active faces Color to other selected (View3D Ctrl+C)");
+               uiBlockEndAlign(block);
+               
+               uiBlockBeginAlign(block);
+               
                uiDefButBitS(block, TOG, TF_TEX, B_REDR_3D_IMA, "Tex",  600,160,60,19, &tf->mode, 0, 0, 0, 0, "Render face with texture");
                uiDefButBitS(block, TOG, TF_TILES, B_REDR_3D_IMA, "Tiles",      660,160,60,19, &tf->mode, 0, 0, 0, 0, "Use tilemode for face");
                uiDefButBitS(block, TOG, TF_LIGHT, REDRAWVIEW3D, "Light",       720,160,60,19, &tf->mode, 0, 0, 0, 0, "Use light for face");
@@ -6257,24 +6239,30 @@ static void editing_panel_mesh_texface(void)
                uiDefButBitS(block, TOG, TF_SHAREDCOL, REDRAWVIEW3D, "Shared",  600,135,60,19, &tf->mode, 0, 0, 0, 0, "Blend vertex colors across face when vertices are shared");
                uiDefButBitS(block, TOG, TF_TWOSIDE, REDRAWVIEW3D, "Twoside",660,135,60,19, &tf->mode, 0, 0, 0, 0, "Render face twosided");
                uiDefButBitS(block, TOG, TF_OBCOL, REDRAWVIEW3D, "ObColor",720,135,60,19, &tf->mode, 0, 0, 0, 0, "Use ObColor instead of vertex colors");
-
-               uiBlockBeginAlign(block);
+               uiBlockEndAlign(block);
                
+               uiBlockBeginAlign(block);
                uiDefButBitS(block, TOG, TF_BILLBOARD, B_TFACE_HALO, "Halo",    600,110,60,19, &tf->mode, 0, 0, 0, 0, "Screen aligned billboard");
                uiDefButBitS(block, TOG, TF_BILLBOARD2, B_TFACE_BILLB, "Billboard",660,110,60,19, &tf->mode, 0, 0, 0, 0, "Billboard with Z-axis constraint");
                uiDefButBitS(block, TOG, TF_SHADOW, REDRAWVIEW3D, "Shadow", 720,110,60,19, &tf->mode, 0, 0, 0, 0, "Face is used for shadow");
                uiDefButBitS(block, TOG, TF_BMFONT, REDRAWVIEW3D, "Text", 780,110,60,19, &tf->mode, 0, 0, 0, 0, "Enable bitmap text on face");
                uiDefButBitS(block, TOG, TF_ALPHASORT, REDRAWVIEW3D, "Sort", 840,110,60,19, &tf->mode, 0, 0, 0, 0, "Enable sorting of faces for correct alpha drawing (slow, use Clip Alpha instead when possible)");
-
+               uiBlockEndAlign(block);
+               
+               uiDefBut(block, LABEL, B_NOP, "Active Face Alpha Blending (Transp)",    600,75,300,19, NULL, 0.0, 0.0, 0, 0, "Face mode its used for TexFace display and the game engine");
+               uiDefBut(block, BUT,B_COPY_TF_TRANSP, "Copy", 850,75,50,19, 0, 0, 0, 0, 0, "Copy active faces transp to other selected (View3D Ctrl+C)");
+               
                uiBlockBeginAlign(block);
                uiBlockSetCol(block, TH_BUT_SETTING1);
-               uiDefButC(block, ROW, REDRAWVIEW3D, "Opaque",   600,80,60,19, &tf->transp, 2.0, (float)TF_SOLID,0, 0, "Render color of textured face as color");
-               uiDefButC(block, ROW, REDRAWVIEW3D, "Add",              660,80,60,19, &tf->transp, 2.0, (float)TF_ADD,  0, 0, "Render face transparent and add color of face");
-               uiDefButC(block, ROW, REDRAWVIEW3D, "Alpha",    720,80,60,19, &tf->transp, 2.0, (float)TF_ALPHA,0, 0, "Render polygon transparent, depending on alpha channel of the texture");
-               uiDefButC(block, ROW, REDRAWVIEW3D, "Clip Alpha",       780,80,80,19, &tf->transp, 2.0, (float)TF_CLIP,0, 0, "Use the images alpha values clipped with no blending (binary alpha)");
-       }
-       else
+               uiDefButC(block, ROW, REDRAWVIEW3D, "Opaque",           600,50,60,19, &tf->transp, 2.0, (float)TF_SOLID,0, 0, "Render color of textured face as color");
+               uiDefButC(block, ROW, REDRAWVIEW3D, "Add",                      660,50,60,19, &tf->transp, 2.0, (float)TF_ADD,  0, 0, "Render face transparent and add color of face");
+               uiDefButC(block, ROW, REDRAWVIEW3D, "Alpha",            720,50,60,19, &tf->transp, 2.0, (float)TF_ALPHA,0, 0, "Render polygon transparent, depending on alpha channel of the texture");
+               uiDefButC(block, ROW, REDRAWVIEW3D, "Clip Alpha",       780,50,80,19, &tf->transp, 2.0, (float)TF_CLIP,0, 0,  "Use the images alpha values clipped with no blending (binary alpha)");
+               uiBlockEndAlign(block);
+               
+       } else {
                uiDefBut(block,LABEL,B_NOP, "(No Active Face)", 10,200,150,19,0,0,0,0,0,"");
+       }
 
 }
 
index 2c7802c3302dcd61028112a58e9b6cc05c218407..58f3bff09c8f1bf8f2486a61e73a74c08cf9ff2e 100644 (file)
@@ -173,6 +173,7 @@ static void constraint_active_func(void *ob_v, void *con_v)
        }
        
        lb= get_active_constraints(ob);
+       if (lb == NULL) return;
        
        for(con= lb->first; con; con= con->next) {
                if(con==con_v) con->flag |= CONSTRAINT_ACTIVE;
@@ -307,7 +308,7 @@ void del_constr_func (void *ob_v, void *con_v)
        }
        /* remove constraint itself */
        lb= get_active_constraints(ob_v);
-       free_constraint_data (con);
+       free_constraint_data(con);
        BLI_freelinkN(lb, con);
        
        constraint_active_func(ob_v, NULL);
index 80a01bc5ccea6a9e374b31439f8361b063b2a39b..92c2db0eb5784e5b2e462a6aa2b856923f91a853 100644 (file)
@@ -854,6 +854,7 @@ static void separate_armature_bones (Object *ob, short sel)
        BLI_freelistN(&edbo);
 }
 
+/* separate selected bones into their armature */
 void separate_armature (void)
 {
        Object *oldob, *newob;
@@ -1094,13 +1095,13 @@ void armature_select_hierarchy(short direction, short add_to_sel)
        arm= (bArmature *)ob->data;
        
        for (curbone= G.edbo.first; curbone; curbone= curbone->next) {
-               if (arm->layer & curbone->layer) {
+               if (EBONE_VISIBLE(arm, curbone)) {
                        if (curbone->flag & (BONE_ACTIVE)) {
                                if (direction == BONE_SELECT_PARENT) {
                                        if (curbone->parent == NULL) continue;
                                        else pabone = curbone->parent;
                                        
-                                       if ((arm->layer & pabone->layer) && !(pabone->flag & BONE_HIDDEN_A)) {
+                                       if (EBONE_VISIBLE(arm, pabone)) {
                                                pabone->flag |= (BONE_ACTIVE|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
                                                if (pabone->parent)     pabone->parent->flag |= BONE_TIPSEL;
                                                
@@ -1109,11 +1110,12 @@ void armature_select_hierarchy(short direction, short add_to_sel)
                                                break;
                                        }
                                        
-                               } else { // BONE_SELECT_CHILD
+                               } 
+                               else { // BONE_SELECT_CHILD
                                        chbone = editbone_get_child(curbone, 1);
                                        if (chbone == NULL) continue;
                                        
-                                       if ((arm->layer & chbone->layer) && !(chbone->flag & BONE_HIDDEN_A)) {
+                                       if (EBONE_VISIBLE(arm, chbone)) {
                                                chbone->flag |= (BONE_ACTIVE|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
                                                
                                                if (!add_to_sel) {
@@ -1159,17 +1161,18 @@ void setflag_armature (short mode)
        
        /* get flag to set (sync these with the ones used in eBone_Flag */
        if (mode == 2)
-               flag= pupmenu("Disable Setting%t|Draw Wire%x1|Deform%x2|Mult VG%x3|Hinge%x4|No Scale%x5");
+               flag= pupmenu("Disable Setting%t|Draw Wire%x1|Deform%x2|Mult VG%x3|Hinge%x4|No Scale%x5|Locked%x6");
        else if (mode == 1)
-               flag= pupmenu("Enable Setting%t|Draw Wire%x1|Deform%x2|Mult VG%x3|Hinge%x4|No Scale%x5");
+               flag= pupmenu("Enable Setting%t|Draw Wire%x1|Deform%x2|Mult VG%x3|Hinge%x4|No Scale%x5|Locked%x6");
        else
-               flag= pupmenu("Toggle Setting%t|Draw Wire%x1|Deform%x2|Mult VG%x3|Hinge%x4|No Scale%x5");
+               flag= pupmenu("Toggle Setting%t|Draw Wire%x1|Deform%x2|Mult VG%x3|Hinge%x4|No Scale%x5|Locked%x6");
        switch (flag) {
                case 1:         flag = BONE_DRAWWIRE;   break;
                case 2:         flag = BONE_NO_DEFORM; break;
                case 3:         flag = BONE_MULT_VG_ENV; break;
                case 4:         flag = BONE_HINGE; break;
                case 5:         flag = BONE_NO_SCALE; break;
+               case 6:         flag = BONE_EDITMODE_LOCKED; break;
                default:        return;
        }
        
@@ -1725,12 +1728,12 @@ void auto_align_armature(short mode)
        float   *cursor= give_cursor();
                
        for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
-               if (arm->layer & ebone->layer) {
+               if (EBONE_VISIBLE(arm, ebone)) {
                        if (arm->flag & ARM_MIRROR_EDIT)
                                flipbone = armature_bone_get_mirrored(ebone);
                        
                        if ((ebone->flag & BONE_SELECTED) || 
-                               (flipbone && flipbone->flag & BONE_SELECTED)) 
+                               (flipbone && (flipbone->flag & BONE_SELECTED))) 
                        {
                                /* specific method used to calculate roll depends on mode */
                                if (mode == 1) {
@@ -1975,7 +1978,7 @@ void addvert_armature(void)
        
        /* find the active or selected bone */
        for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
-               if (arm->layer & ebone->layer) {
+               if (EBONE_VISIBLE(arm, ebone)) {
                        if (ebone->flag & (BONE_ACTIVE|BONE_TIPSEL)) 
                                break;
                }
@@ -1983,7 +1986,7 @@ void addvert_armature(void)
        
        if (ebone==NULL) {
                for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
-                       if (arm->layer & ebone->layer) {
+                       if (EBONE_VISIBLE(arm, ebone)) {
                                if (ebone->flag & (BONE_ACTIVE|BONE_ROOTSEL)) 
                                        break;
                        }
@@ -2066,11 +2069,12 @@ static EditBone *get_named_editbone(char *name)
 {
        EditBone  *eBone;
 
-       if (name)
+       if (name) {
                for (eBone=G.edbo.first; eBone; eBone=eBone->next) {
                        if (!strcmp(name, eBone->name))
                                return eBone;
                }
+       }
 
        return NULL;
 }
@@ -2136,7 +2140,7 @@ void adduplicate_armature(void)
        /* Select mirrored bones */
        if (arm->flag & ARM_MIRROR_EDIT) {
                for (curBone=G.edbo.first; curBone; curBone=curBone->next) {
-                       if (arm->layer & curBone->layer) {
+                       if (EBONE_VISIBLE(arm, curBone)) {
                                if (curBone->flag & BONE_SELECTED) {
                                        eBone = armature_bone_get_mirrored(curBone);
                                        if (eBone)
@@ -2148,13 +2152,13 @@ void adduplicate_armature(void)
        
        /*      Find the selected bones and duplicate them as needed */
        for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next) {
-               if (arm->layer & curBone->layer) {
+               if (EBONE_VISIBLE(arm, curBone)) {
                        if (curBone->flag & BONE_SELECTED) {
                                eBone=MEM_callocN(sizeof(EditBone), "addup_editbone");
                                eBone->flag |= BONE_SELECTED;
                                
                                /*      Copy data from old bone to new bone */
-                               memcpy (eBone, curBone, sizeof(EditBone));
+                               memcpy(eBone, curBone, sizeof(EditBone));
                                
                                curBone->temp = eBone;
                                eBone->temp = curBone;
@@ -2204,7 +2208,7 @@ void adduplicate_armature(void)
 
        /*      Run though the list and fix the pointers */
        for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next) {
-               if (arm->layer & curBone->layer) {
+               if (EBONE_VISIBLE(arm, curBone)) {
                        if (curBone->flag & BONE_SELECTED) {
                                eBone=(EditBone*) curBone->temp;
                                
@@ -2236,7 +2240,7 @@ void adduplicate_armature(void)
        /*      Deselect the old bones and select the new ones */
        
        for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next) {
-               if (arm->layer & curBone->layer)
+               if (EBONE_VISIBLE(arm, curBone))
                        curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE);
        }
        
@@ -2373,7 +2377,7 @@ void fill_bones_armature(void)
        
        /* loop over all bones, and only consider if visible */
        for (ebo= G.edbo.first; ebo; ebo= ebo->next) {
-               if ((arm->layer & ebo->layer) && !(ebo->flag & BONE_HIDDEN_A)) {
+               if (EBONE_VISIBLE(arm, ebo)) {
                        if (!(ebo->flag & BONE_CONNECTED) && (ebo->flag & BONE_ROOTSEL))
                                fill_add_joint(ebo, 0, &points);
                        if (ebo->flag & BONE_TIPSEL) 
@@ -2608,7 +2612,7 @@ void merge_armature(void)
                        /* only consider bones that are visible and selected */
                        for (ebo=chain->data; ebo; child=ebo, ebo=ebo->parent) {
                                /* check if visible + selected */
-                               if ( (arm->layer & ebo->layer) && !(ebo->flag & BONE_HIDDEN_A) &&
+                               if ( EBONE_VISIBLE(arm, ebo) &&
                                         ((ebo->flag & BONE_CONNECTED) || (ebo->parent==NULL)) &&
                                         (ebo->flag & (BONE_SELECTED|BONE_ACTIVE)) )
                                {
@@ -2659,7 +2663,7 @@ void hide_selected_armature_bones(void)
        EditBone *ebone;
        
        for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
-               if (arm->layer & ebone->layer) {
+               if (EBONE_VISIBLE(arm, ebone)) {
                        if (ebone->flag & (BONE_SELECTED)) {
                                ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
                                ebone->flag |= BONE_HIDDEN_A;
@@ -2678,7 +2682,7 @@ void hide_unselected_armature_bones(void)
        
        for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
                bArmature *arm= G.obedit->data;
-               if (arm->layer & ebone->layer) {
+               if (EBONE_VISIBLE(arm, ebone)) {
                        if (ebone->flag & (BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL));
                        else {
                                ebone->flag &= ~BONE_ACTIVE;
@@ -2711,32 +2715,6 @@ void show_all_armature_bones(void)
        BIF_undo_push("Reveal Bones");
 }
 
-/* Sets editmode transform locks for bones (adds if lock==1, clears otherwise) */
-void set_locks_armature_bones(short lock)
-{
-       bArmature *arm= G.obedit->data;
-       EditBone *ebone;
-       
-       for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
-               if (arm->layer & ebone->layer) {
-                       if (ebone->flag & BONE_SELECTED) {
-                               if (lock)
-                                       ebone->flag |= BONE_EDITMODE_LOCKED;
-                               else    
-                                       ebone->flag &= ~BONE_EDITMODE_LOCKED;
-                       }
-               }
-       }
-       countall();
-       allqueue(REDRAWVIEW3D, 0);
-       allqueue(REDRAWBUTSEDIT, 0);
-       
-       if (lock)
-               BIF_undo_push("Lock Bones");
-       else
-               BIF_undo_push("Unlock Bones");
-}
-
 /* check for null, before calling! */
 static void bone_connect_to_existing_parent(EditBone *bone)
 {
@@ -2803,7 +2781,7 @@ void make_bone_parent(void)
        
        /* find active bone to parent to */
        for (actbone = G.edbo.first; actbone; actbone=actbone->next) {
-               if (arm->layer & actbone->layer) {
+               if (EBONE_VISIBLE(arm, actbone)) {
                        if (actbone->flag & BONE_ACTIVE)
                                break;
                }
@@ -2815,7 +2793,7 @@ void make_bone_parent(void)
 
        /* find selected bones */
        for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
-               if (arm->layer & ebone->layer) {
+               if (EBONE_VISIBLE(arm, ebone)) {
                        if ((ebone->flag & BONE_SELECTED) && (ebone != actbone)) {
                                foundselbone++;
                                if (ebone->parent != actbone) allchildbones= 1; 
@@ -2851,7 +2829,7 @@ void make_bone_parent(void)
        else {
                /* loop through all editbones, parenting all selected bones to the active bone */
                for (selbone = G.edbo.first; selbone; selbone=selbone->next) {
-                       if (arm->layer & selbone->layer) {
+                       if (EBONE_VISIBLE(arm, selbone)) {
                                if ((selbone->flag & BONE_SELECTED) && (selbone!=actbone)) {
                                        /* parent selbone to actbone */
                                        bone_connect_to_new_parent(selbone, actbone, val);
@@ -2909,7 +2887,7 @@ void clear_bone_parent(void)
        if (val<1) return;
        
        for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
-               if (arm->layer & ebone->layer) {
+               if (EBONE_VISIBLE(arm, ebone)) {
                        if (ebone->flag & BONE_SELECTED) {
                                if (arm->flag & ARM_MIRROR_EDIT)
                                        flipbone = armature_bone_get_mirrored(ebone);
@@ -2959,7 +2937,7 @@ void unique_editbone_name (ListBase *ebones, char *name)
                }
                
                for (number = 1; number <=999; number++) {
-                       sprintf (tempname, "%s.%03d", name, number);
+                       sprintf(tempname, "%s.%03d", name, number);
                        if (!editbone_name_exists(ebones, tempname)) {
                                BLI_strncpy(name, tempname, 32);
                                return;
@@ -2980,7 +2958,7 @@ void extrude_armature(int forked)
        
        /* since we allow root extrude too, we have to make sure selection is OK */
        for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
-               if (arm->layer & ebone->layer) {
+               if (EBONE_VISIBLE(arm, ebone)) {
                        if (ebone->flag & BONE_ROOTSEL) {
                                if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
                                        if (ebone->parent->flag & BONE_TIPSEL)
@@ -2992,7 +2970,7 @@ void extrude_armature(int forked)
        
        /* Duplicate the necessary bones */
        for (ebone = G.edbo.first; ((ebone) && (ebone!=first)); ebone=ebone->next) {
-               if (arm->layer & ebone->layer) {
+               if (EBONE_VISIBLE(arm, ebone)) {
                        /* we extrude per definition the tip */
                        do_extrude= 0;
                        if (ebone->flag & (BONE_TIPSEL|BONE_SELECTED))
@@ -3006,7 +2984,7 @@ void extrude_armature(int forked)
                        if (do_extrude) {
                                /* we re-use code for mirror editing... */
                                flipbone= NULL;
-                               if(arm->flag & ARM_MIRROR_EDIT) {
+                               if (arm->flag & ARM_MIRROR_EDIT) {
                                        flipbone= armature_bone_get_mirrored(ebone);
                                        if (flipbone) {
                                                forked= 0;      // we extrude 2 different bones
@@ -3036,7 +3014,7 @@ void extrude_armature(int forked)
                                                newbone->parent = ebone;
                                                
                                                newbone->flag = ebone->flag & BONE_TIPSEL;      // copies it, in case mirrored bone
-
+                                               
                                                if (newbone->parent) newbone->flag |= BONE_CONNECTED;
                                        }
                                        else {
@@ -3046,7 +3024,7 @@ void extrude_armature(int forked)
                                                
                                                newbone->flag= BONE_TIPSEL;
                                                
-                                               if (newbone->parent && ebone->flag & BONE_CONNECTED) {
+                                               if (newbone->parent && (ebone->flag & BONE_CONNECTED)) {
                                                        newbone->flag |= BONE_CONNECTED;
                                                }
                                        }
@@ -3065,8 +3043,8 @@ void extrude_armature(int forked)
                                        BLI_strncpy (newbone->name, ebone->name, 32);
                                        
                                        if (flipbone && forked) {       // only set if mirror edit
-                                               if(strlen(newbone->name)<30) {
-                                                       if(a==0) strcat(newbone->name, "_L");
+                                               if (strlen(newbone->name)<30) {
+                                                       if (a==0) strcat(newbone->name, "_L");
                                                        else strcat(newbone->name, "_R");
                                                }
                                        }
@@ -3111,7 +3089,7 @@ void subdivide_armature(int numcuts)
        if (numcuts < 1) return;
 
        for (mbone = G.edbo.last; mbone; mbone= mbone->prev) {
-               if (arm->layer & mbone->layer) {
+               if (EBONE_VISIBLE(arm, mbone)) {
                        if (mbone->flag & BONE_SELECTED) {
                                for (i=numcuts+1; i>1; i--) {
                                        /* compute cut ratio first */
@@ -3176,6 +3154,59 @@ void subdivide_armature(int numcuts)
        else BIF_undo_push("Subdivide multi");
 }
 
+/* switch direction of bone chains */
+void switch_direction_armature (void)
+{
+       bArmature *arm= (G.obedit) ? G.obedit->data : NULL;
+       ListBase chains = {NULL, NULL};
+       LinkData *chain;
+       
+       /* error checking paranoia */
+       if (arm == NULL)
+               return;
+       
+       /* get chains of bones (ends on chains) */
+       chains_find_tips(&chains);
+       if (chains.first == NULL) return;
+       
+       /* loop over chains, only considering selected and visible bones */
+       for (chain= chains.first; chain; chain= chain->next) {
+               EditBone *ebo, *child=NULL, *parent=NULL;
+               
+               /* loop over bones in chain */
+               for (ebo= chain->data; ebo; child= ebo, ebo=parent) {
+                       parent= ebo->parent;
+                       
+                       /* only if selected and editable */
+                       if (EBONE_VISIBLE(arm, ebo) && EBONE_EDITABLE(ebo)) {                           
+                               /* swap head and tail coordinates */
+                               SWAP(float, ebo->head[0], ebo->tail[0]);
+                               SWAP(float, ebo->head[1], ebo->tail[1]);
+                               SWAP(float, ebo->head[2], ebo->tail[2]);
+                               
+                               /* do parent swapping:
+                                *      - use 'child' as new parent
+                                *      - connected flag is only set if points are coincidental
+                                */
+                               ebo->parent= child;
+                               if ((child) && VecEqual(ebo->head, child->tail))
+                                       ebo->flag |= BONE_CONNECTED;
+                               else    
+                                       ebo->flag &= ~BONE_CONNECTED;
+                               
+                               /* FIXME: other things that need fixing?
+                                *              i.e. roll?
+                                */
+                       }
+               }
+       }
+       
+       /* free chains */
+       BLI_freelistN(&chains);
+       
+       BIF_undo_push("Switch Direction");
+}
+
 /* ***************** Pose tools ********************* */
 
 void clear_armature(Object *ob, char mode)
index c7a75b32df16656dc58b4f46bfeb028729d3cc59..6dfbd67720b57356b9e1d7867e221f1504fed026 100644 (file)
@@ -1432,361 +1432,398 @@ int mesh_layers_menu(CustomData *data, int type) {
        return ret;
 }
 
-/* ctrl+c in mesh editmode */
-void mesh_copy_menu(void)
+void EM_mesh_copy_edge(short type) 
 {
        EditMesh *em = G.editMesh;
        EditSelection *ese;
-       short ret, change=0;
+       short change=0;
+       
+       EditEdge *eed, *eed_act;
+       float vec[3], vec_mid[3], eed_len, eed_len_act;
        
        if (!em) return;
        
        ese = em->selected.last;
+       if (!ese) return;
        
-       /* Faces can have a NULL ese, so dont return on a NULL ese here */
+       eed_act = (EditEdge*)ese->data;
        
-       if(ese && ese->type == EDITVERT) {
-               
-               if (!ese) return;
-               /*EditVert *ev, *ev_act = (EditVert*)ese->data;
-               ret= pupmenu("");*/
-       } else if(ese && ese->type == EDITEDGE) {
-               EditEdge *eed, *eed_act;
-               float vec[3], vec_mid[3], eed_len, eed_len_act;
-               
-               if (!ese) return;
-               
-               eed_act = (EditEdge*)ese->data;
-               
-               ret= pupmenu("Copy Active Edge to Selected%t|Crease%x1|Bevel Weight%x2|Length%x3");
-               if (ret<1) return;
-               
-               eed_len_act = VecLenf(eed_act->v1->co, eed_act->v2->co);
-               
-               switch (ret) {
-               case 1: /* copy crease */
-                       for(eed=em->edges.first; eed; eed=eed->next) {
-                               if (eed->f & SELECT && eed != eed_act && eed->crease != eed_act->crease) {
-                                       eed->crease = eed_act->crease;
-                                       change = 1;
-                               }
+       switch (type) {
+       case 1: /* copy crease */
+               for(eed=em->edges.first; eed; eed=eed->next) {
+                       if (eed->f & SELECT && eed != eed_act && eed->crease != eed_act->crease) {
+                               eed->crease = eed_act->crease;
+                               change = 1;
                        }
-                       break;
-               case 2: /* copy bevel weight */
-                       for(eed=em->edges.first; eed; eed=eed->next) {
-                               if (eed->f & SELECT && eed != eed_act && eed->bweight != eed_act->bweight) {
-                                       eed->bweight = eed_act->bweight;
-                                       change = 1;
-                               }
+               }
+               break;
+       case 2: /* copy bevel weight */
+               for(eed=em->edges.first; eed; eed=eed->next) {
+                       if (eed->f & SELECT && eed != eed_act && eed->bweight != eed_act->bweight) {
+                               eed->bweight = eed_act->bweight;
+                               change = 1;
                        }
-                       break;
-                       
-               case 3: /* copy length */
-                       
-                       for(eed=em->edges.first; eed; eed=eed->next) {
-                               if (eed->f & SELECT && eed != eed_act) {
-                                       
-                                       eed_len = VecLenf(eed->v1->co, eed->v2->co);
-                                       
-                                       if (eed_len == eed_len_act) continue;
-                                       /* if this edge is zero length we cont do anything with it*/
-                                       if (eed_len == 0.0f) continue;
-                                       if (eed_len_act == 0.0f) {
-                                               VecAddf(vec_mid, eed->v1->co, eed->v2->co);
-                                               VecMulf(vec_mid, 0.5);
-                                               VECCOPY(eed->v1->co, vec_mid);
-                                               VECCOPY(eed->v2->co, vec_mid);
-                                       } else {
-                                               /* copy the edge length */
-                                               VecAddf(vec_mid, eed->v1->co, eed->v2->co);
-                                               VecMulf(vec_mid, 0.5);
-                                               
-                                               /* SCALE 1 */
-                                               VecSubf(vec, eed->v1->co, vec_mid);
-                                               VecMulf(vec, eed_len_act/eed_len);
-                                               VecAddf(eed->v1->co, vec, vec_mid);
-                                               
-                                               /* SCALE 2 */
-                                               VecSubf(vec, eed->v2->co, vec_mid);
-                                               VecMulf(vec, eed_len_act/eed_len);
-                                               VecAddf(eed->v2->co, vec, vec_mid);
-                                       }
-                                       change = 1;
+               }
+               break;
+
+       case 3: /* copy length */
+               eed_len_act = VecLenf(eed_act->v1->co, eed_act->v2->co);
+               for(eed=em->edges.first; eed; eed=eed->next) {
+                       if (eed->f & SELECT && eed != eed_act) {
+
+                               eed_len = VecLenf(eed->v1->co, eed->v2->co);
+
+                               if (eed_len == eed_len_act) continue;
+                               /* if this edge is zero length we cont do anything with it*/
+                               if (eed_len == 0.0f) continue;
+                               if (eed_len_act == 0.0f) {
+                                       VecAddf(vec_mid, eed->v1->co, eed->v2->co);
+                                       VecMulf(vec_mid, 0.5);
+                                       VECCOPY(eed->v1->co, vec_mid);
+                                       VECCOPY(eed->v2->co, vec_mid);
+                               } else {
+                                       /* copy the edge length */
+                                       VecAddf(vec_mid, eed->v1->co, eed->v2->co);
+                                       VecMulf(vec_mid, 0.5);
+
+                                       /* SCALE 1 */
+                                       VecSubf(vec, eed->v1->co, vec_mid);
+                                       VecMulf(vec, eed_len_act/eed_len);
+                                       VecAddf(eed->v1->co, vec, vec_mid);
+
+                                       /* SCALE 2 */
+                                       VecSubf(vec, eed->v2->co, vec_mid);
+                                       VecMulf(vec, eed_len_act/eed_len);
+                                       VecAddf(eed->v2->co, vec, vec_mid);
                                }
+                               change = 1;
                        }
-                       
-                       if (change)
-                               recalc_editnormals();
-                       
-                       
-                       break;
                }
+
+               if (change)
+                       recalc_editnormals();
+
+               break;
+       }
+       
+       if (change) {
+               DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+               allqueue(REDRAWVIEW3D, 0);
+               allqueue(REDRAWBUTSEDIT, 0);
                
-       } else if(ese==NULL || ese->type == EDITFACE) {
-               EditFace *efa, *efa_act;
-               MTFace *tf, *tf_act = NULL;
-               MCol *mcol, *mcol_act = NULL;
-               
-               efa_act = EM_get_actFace(0);
-               
-               if (efa_act) {
-                       ret= pupmenu(
-                               "Copy Face Selected%t|"
-                               "Active Material%x1|Active Image%x2|Active UV Coords%x3|"
-                               "Active Mode%x4|Active Transp%x5|Active Vertex Colors%x6|%l|"
-                               
-                               "TexFace UVs from layer%x7|"
-                               "TexFace Images from layer%x8|"
-                               "TexFace All from layer%x9|"
-                               "Vertex Colors from layer%x10");
-                       if (ret<1) return;
-                       tf_act =        CustomData_em_get(&em->fdata, efa_act->data, CD_MTFACE);
-                       mcol_act =      CustomData_em_get(&em->fdata, efa_act->data, CD_MCOL);
-               } else {
-                       ret= pupmenu(
-                               "Copy Face Selected%t|"
-                               
-                               /* Make sure these are always the same as above */
-                               "TexFace UVs from layer%x7|"
-                               "TexFace Images from layer%x8|"
-                               "TexFace All from layer%x9|"
-                               "Vertex Colors from layer%x10");
-                       if (ret<1) return;
+               BIF_undo_push("Copy Edge Attribute");
+       }
+}
+
+void EM_mesh_copy_face(short type)
+{
+       EditMesh *em = G.editMesh;
+       short change=0;
+       
+       EditFace *efa, *efa_act;
+       MTFace *tf, *tf_act = NULL;
+       MCol *mcol, *mcol_act = NULL;
+       if (!em) return;
+       efa_act = EM_get_actFace(0);
+       
+       if (!efa_act) return;
+       
+       tf_act =        CustomData_em_get(&em->fdata, efa_act->data, CD_MTFACE);
+       mcol_act =      CustomData_em_get(&em->fdata, efa_act->data, CD_MCOL);
+       
+       switch (type) {
+       case 1: /* copy material */
+               for(efa=em->faces.first; efa; efa=efa->next) {
+                       if (efa->f & SELECT && efa->mat_nr != efa_act->mat_nr) {
+                               efa->mat_nr = efa_act->mat_nr;
+                               change = 1;
+                       }
                }
-               
-               switch (ret) {
-               case 1: /* copy material */
-                       for(efa=em->faces.first; efa; efa=efa->next) {
-                               if (efa->f & SELECT && efa->mat_nr != efa_act->mat_nr) {
-                                       efa->mat_nr = efa_act->mat_nr;
-                                       change = 1;
+               break;
+       case 2: /* copy image */
+               if (!tf_act) {
+                       error("mesh has no uv/image layers");
+                       return;
+               }
+               for(efa=em->faces.first; efa; efa=efa->next) {
+                       if (efa->f & SELECT && efa != efa_act) {
+                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                               if (tf_act->tpage) {
+                                       tf->tpage = tf_act->tpage;
+                                       tf->mode |= TF_TEX;
+                               } else {
+                                       tf->tpage = NULL;
+                                       tf->mode &= ~TF_TEX;
                                }
+                               tf->tile= tf_act->tile;
+                               change = 1;
                        }
-                       break;
-               case 2: /* copy image */
-                       if (!tf_act) {
-                               error("mesh has no uv/image layers");
-                               return;
+               }
+               break;
+
+       case 3: /* copy UV's */
+               if (!tf_act) {
+                       error("mesh has no uv/image layers");
+                       return;
+               }
+               for(efa=em->faces.first; efa; efa=efa->next) {
+                       if (efa->f & SELECT && efa != efa_act) {
+                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                               memcpy(tf->uv, tf_act->uv, sizeof(tf->uv));
+                               change = 1;
                        }
-                       for(efa=em->faces.first; efa; efa=efa->next) {
-                               if (efa->f & SELECT && efa != efa_act) {
-                                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                                       if (tf_act->tpage) {
-                                               tf->tpage = tf_act->tpage;
-                                               tf->mode |= TF_TEX;
-                                       } else {
-                                               tf->tpage = NULL;
-                                               tf->mode &= ~TF_TEX;
-                                       }
-                                       tf->tile= tf_act->tile;
-                                       change = 1;
-                               }
+               }
+               break;
+       case 4: /* mode's */
+               if (!tf_act) {
+                       error("mesh has no uv/image layers");
+                       return;
+               }
+               for(efa=em->faces.first; efa; efa=efa->next) {
+                       if (efa->f & SELECT && efa != efa_act) {
+                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                               tf->mode= tf_act->mode;
+                               change = 1;
                        }
-                       break;
-                       
-               case 3: /* copy UV's */
-                       if (!tf_act) {
-                               error("mesh has no uv/image layers");
-                               return;
+               }
+               break;
+       case 5: /* copy transp's */
+               if (!tf_act) {
+                       error("mesh has no uv/image layers");
+                       return;
+               }
+               for(efa=em->faces.first; efa; efa=efa->next) {
+                       if (efa->f & SELECT && efa != efa_act) {
+                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                               tf->transp= tf_act->transp;
+                               change = 1;
                        }
+               }
+               break;
+
+       case 6: /* copy vcols's */
+               if (!mcol_act) {
+                       error("mesh has no color layers");
+                       return;
+               } else {
+                       /* guess the 4th color if needs be */
+                       float val =- 1;
+
+                       if (!efa_act->v4) {
+                               /* guess the othe vale, we may need to use it
+                                * 
+                                * Modifying the 4th value of the mcol is ok here since its not seen
+                                * on a triangle
+                                * */
+                               val = ((float)(mcol_act->r +  (mcol_act+1)->r + (mcol_act+2)->r)) / 3; CLAMP(val, 0, 255);
+                               (mcol_act+3)->r = (char)val;
+
+                               val = ((float)(mcol_act->g +  (mcol_act+1)->g + (mcol_act+2)->g)) / 3; CLAMP(val, 0, 255);
+                               (mcol_act+3)->g = (char)val;
+
+                               val = ((float)(mcol_act->b +  (mcol_act+1)->b + (mcol_act+2)->b)) / 3; CLAMP(val, 0, 255);
+                               (mcol_act+3)->b = (char)val;
+                       } 
+
+
                        for(efa=em->faces.first; efa; efa=efa->next) {
                                if (efa->f & SELECT && efa != efa_act) {
-                                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                                       memcpy(tf->uv, tf_act->uv, sizeof(tf->uv));
+                                       /* TODO - make copy from tri to quad guess the 4th vert */
+                                       mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
+                                       memcpy(mcol, mcol_act, sizeof(MCol)*4); 
                                        change = 1;
                                }
                        }
-                       break;
-               case 4: /* mode's */
-                       if (!tf_act) {
-                               error("mesh has no uv/image layers");
+               }
+               break;
+       }
+       
+       if (change) {
+               DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+               allqueue(REDRAWVIEW3D, 0);
+               allqueue(REDRAWBUTSEDIT, 0);
+               if (type==3) {
+                       allqueue(REDRAWIMAGE, 0);                       
+               }
+               
+               BIF_undo_push("Copy Face Attribute");
+       }
+}
+
+
+void EM_mesh_copy_face_layer(short type) 
+{
+       EditMesh *em = G.editMesh;
+       short change=0;
+       
+       EditFace *efa;
+       MTFace *tf, *tf_from;
+       MCol *mcol, *mcol_from;
+       
+       if (!em) return;
+       
+       switch(type) {
+       case 7:
+       case 8:
+       case 9:
+               if (CustomData_number_of_layers(&em->fdata, CD_MTFACE)<2) {
+                       error("mesh does not have multiple uv/image layers");
+                       return;
+               } else {
+                       int layer_orig_idx, layer_idx;
+
+                       layer_idx = mesh_layers_menu(&em->fdata, CD_MTFACE);
+                       if (layer_idx<0) return;
+
+                       /* warning, have not updated mesh pointers however this is not needed since we swicth back */
+                       layer_orig_idx = CustomData_get_active_layer(&em->fdata, CD_MTFACE);
+                       if (layer_idx==layer_orig_idx)
                                return;
-                       }
+
+                       /* get the tfaces */
+                       CustomData_set_layer_active(&em->fdata, CD_MTFACE, (int)layer_idx);
+                       /* store the tfaces in our temp */
                        for(efa=em->faces.first; efa; efa=efa->next) {
-                               if (efa->f & SELECT && efa != efa_act) {
-                                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                                       tf->mode= tf_act->mode;
-                                       change = 1;
-                               }
+                               if (efa->f & SELECT) {
+                                       efa->tmp.p = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                               }       
                        }
-                       break;
-               case 5: /* copy transp's */
-                       if (!tf_act) {
-                               error("mesh has no uv/image layers");
+                       CustomData_set_layer_active(&em->fdata, CD_MTFACE, layer_orig_idx);
+               }
+               break;
+
+       case 10: /* select vcol layers - make sure this stays in sync with above code */
+               if (CustomData_number_of_layers(&em->fdata, CD_MCOL)<2) {
+                       error("mesh does not have multiple color layers");
+                       return;
+               } else {
+                       int layer_orig_idx, layer_idx;
+
+                       layer_idx = mesh_layers_menu(&em->fdata, CD_MCOL);
+                       if (layer_idx<0) return;
+
+                       /* warning, have not updated mesh pointers however this is not needed since we swicth back */
+                       layer_orig_idx = CustomData_get_active_layer(&em->fdata, CD_MCOL);
+                       if (layer_idx==layer_orig_idx)
                                return;
-                       }
+
+                       /* get the tfaces */
+                       CustomData_set_layer_active(&em->fdata, CD_MCOL, (int)layer_idx);
+                       /* store the tfaces in our temp */
                        for(efa=em->faces.first; efa; efa=efa->next) {
-                               if (efa->f & SELECT && efa != efa_act) {
-                                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                                       tf->transp= tf_act->transp;
-                                       change = 1;
-                               }
-                       }
-                       break;
-                       
-               case 6: /* copy vcols's */
-                       if (!mcol_act) {
-                               error("mesh has no color layers");
-                               return;
-                       } else {
-                               /* guess the 4th color if needs be */
-                               float val =- 1;
-                               
-                               if (!efa_act->v4) {
-                                       /* guess the othe vale, we may need to use it
-                                        * 
-                                        * Modifying the 4th value of the mcol is ok here since its not seen
-                                        * on a triangle
-                                        * */
-                                       val = ((float)(mcol_act->r +  (mcol_act+1)->r + (mcol_act+2)->r)) / 3; CLAMP(val, 0, 255);
-                                       (mcol_act+3)->r = (char)val;
-                                       
-                                       val = ((float)(mcol_act->g +  (mcol_act+1)->g + (mcol_act+2)->g)) / 3; CLAMP(val, 0, 255);
-                                       (mcol_act+3)->g = (char)val;
-                                       
-                                       val = ((float)(mcol_act->b +  (mcol_act+1)->b + (mcol_act+2)->b)) / 3; CLAMP(val, 0, 255);
-                                       (mcol_act+3)->b = (char)val;
-                               } 
-                               
-                               
-                               for(efa=em->faces.first; efa; efa=efa->next) {
-                                       if (efa->f & SELECT && efa != efa_act) {
-                                               /* TODO - make copy from tri to quad guess the 4th vert */
-                                               mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
-                                               memcpy(mcol, mcol_act, sizeof(MCol)*4); 
-                                               change = 1;
-                                       }
-                               }
-                       }
-                       
-                       break;
-               
-               /* Copy from layer - Warning! tf_act and mcol_act will be NULL here */
-               case 7:
-               case 8:
-               case 9:
-                       if (CustomData_number_of_layers(&em->fdata, CD_MTFACE)<2) {
-                               error("mesh does not have multiple uv/image layers");
-                               return;
-                       } else {
-                               int layer_orig_idx, layer_idx;
-                               
-                               layer_idx = mesh_layers_menu(&em->fdata, CD_MTFACE);
-                               if (layer_idx<0) return;
-                               
-                               /* warning, have not updated mesh pointers however this is not needed since we swicth back */
-                               layer_orig_idx = CustomData_get_active_layer(&em->fdata, CD_MTFACE);
-                               if (layer_idx==layer_orig_idx)
-                                       return;
-                               
-                               /* get the tfaces */
-                               CustomData_set_layer_active(&em->fdata, CD_MTFACE, (int)layer_idx);
-                               /* store the tfaces in our temp */
-                               for(efa=em->faces.first; efa; efa=efa->next) {
-                                       if (efa->f & SELECT) {
-                                               efa->tmp.p = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                                       }       
-                               }
-                               CustomData_set_layer_active(&em->fdata, CD_MTFACE, layer_orig_idx);
-                       }
-                       break;
-                       
-               case 10: /* select vcol layers - make sure this stays in sync with above code */
-                       if (CustomData_number_of_layers(&em->fdata, CD_MCOL)<2) {
-                               error("mesh does not have multiple color layers");
-                               return;
-                       } else {
-                               int layer_orig_idx, layer_idx;
-                               
-                               layer_idx = mesh_layers_menu(&em->fdata, CD_MCOL);
-                               if (layer_idx<0) return;
-                               
-                               /* warning, have not updated mesh pointers however this is not needed since we swicth back */
-                               layer_orig_idx = CustomData_get_active_layer(&em->fdata, CD_MCOL);
-                               if (layer_idx==layer_orig_idx)
-                                       return;
-                               
-                               /* get the tfaces */
-                               CustomData_set_layer_active(&em->fdata, CD_MCOL, (int)layer_idx);
-                               /* store the tfaces in our temp */
-                               for(efa=em->faces.first; efa; efa=efa->next) {
-                                       if (efa->f & SELECT) {
-                                               efa->tmp.p = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
-                                       }       
-                               }
-                               CustomData_set_layer_active(&em->fdata, CD_MCOL, layer_orig_idx);
-                               
+                               if (efa->f & SELECT) {
+                                       efa->tmp.p = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
+                               }       
                        }
-                       break;
+                       CustomData_set_layer_active(&em->fdata, CD_MCOL, layer_orig_idx);
+
                }
-               
-               /* layer copy only - sanity checks done above */
-               switch (ret) {
-               case 7: /* copy UV's only */
-                       for(efa=em->faces.first; efa; efa=efa->next) {
-                               if (efa->f & SELECT) {
-                                       tf_act = (MTFace *)efa->tmp.p; /* not active but easier to use this way */
-                                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                                       memcpy(tf->uv, tf_act->uv, sizeof(tf->uv));
-                                       change = 1;
-                               }
+               break;
+       }
+
+       /* layer copy only - sanity checks done above */
+       switch (type) {
+       case 7: /* copy UV's only */
+               for(efa=em->faces.first; efa; efa=efa->next) {
+                       if (efa->f & SELECT) {
+                               tf_from = (MTFace *)efa->tmp.p; /* not active but easier to use this way */
+                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                               memcpy(tf->uv, tf_from->uv, sizeof(tf->uv));
+                               change = 1;
                        }
-                       break;
-               case 8: /* copy image settings only */
-                       for(efa=em->faces.first; efa; efa=efa->next) {
-                               if (efa->f & SELECT) {
-                                       tf_act = (MTFace *)efa->tmp.p; /* not active but easier to use this way */
-                                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                                       if (tf_act->tpage) {
-                                               tf->tpage = tf_act->tpage;
-                                               tf->mode |= TF_TEX;
-                                       } else {
-                                               tf->tpage = NULL;
-                                               tf->mode &= ~TF_TEX;
-                                       }
-                                       tf->tile= tf_act->tile;
-                                       change = 1;
+               }
+               break;
+       case 8: /* copy image settings only */
+               for(efa=em->faces.first; efa; efa=efa->next) {
+                       if (efa->f & SELECT) {
+                               tf_from = (MTFace *)efa->tmp.p; /* not active but easier to use this way */
+                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                               if (tf_from->tpage) {
+                                       tf->tpage = tf_from->tpage;
+                                       tf->mode |= TF_TEX;
+                               } else {
+                                       tf->tpage = NULL;
+                                       tf->mode &= ~TF_TEX;
                                }
+                               tf->tile= tf_from->tile;
+                               change = 1;
                        }
-                       break;
-               case 9: /* copy all tface info */
-                       for(efa=em->faces.first; efa; efa=efa->next) {
-                               if (efa->f & SELECT) {
-                                       tf_act = (MTFace *)efa->tmp.p; /* not active but easier to use this way */
-                                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                                       memcpy(tf->uv, ((MTFace *)efa->tmp.p)->uv, sizeof(tf->uv));
-                                       tf->tpage = tf_act->tpage;
-                                       tf->mode = tf_act->mode;
-                                       tf->transp = tf_act->transp;
-                                       change = 1;
-                               }
+               }
+               break;
+       case 9: /* copy all tface info */
+               for(efa=em->faces.first; efa; efa=efa->next) {
+                       if (efa->f & SELECT) {
+                               tf_from = (MTFace *)efa->tmp.p; /* not active but easier to use this way */
+                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                               memcpy(tf->uv, ((MTFace *)efa->tmp.p)->uv, sizeof(tf->uv));
+                               tf->tpage = tf_from->tpage;
+                               tf->mode = tf_from->mode;
+                               tf->transp = tf_from->transp;
+                               change = 1;
                        }
-                       break;
-               case 10:
-                       for(efa=em->faces.first; efa; efa=efa->next) {
-                               if (efa->f & SELECT) {
-                                       mcol_act = (MCol *)efa->tmp.p; 
-                                       mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
-                                       memcpy(mcol, mcol_act, sizeof(MCol)*4); 
-                                       change = 1;
-                               }
+               }
+               break;
+       case 10:
+               for(efa=em->faces.first; efa; efa=efa->next) {
+                       if (efa->f & SELECT) {
+                               mcol_from = (MCol *)efa->tmp.p; 
+                               mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
+                               memcpy(mcol, mcol_from, sizeof(MCol)*4);        
+                               change = 1;
                        }
-                       break;
                }
-               
+               break;
        }
-       
+
        if (change) {
                DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
                allqueue(REDRAWVIEW3D, 0);
                allqueue(REDRAWBUTSEDIT, 0);
                
-               if (ese==NULL ||        ese->type == EDITFACE)  BIF_undo_push("Copy Face Attribute");
-               else if (                       ese->type == EDITEDGE)  BIF_undo_push("Copy Edge Attribute");
-               else if (                       ese->type == EDITVERT)  BIF_undo_push("Copy Vert Attribute");
-               
+               BIF_undo_push("Copy Face Layer");
        }
+}
+
+
+/* ctrl+c in mesh editmode */
+void mesh_copy_menu(void)
+{
+       EditMesh *em = G.editMesh;
+       EditSelection *ese;
+       int ret;
+       if (!em) return;
        
+       ese = em->selected.last;
+       
+       /* Faces can have a NULL ese, so dont return on a NULL ese here */
+       
+       if(ese && ese->type == EDITVERT) {
+               /* EditVert *ev, *ev_act = (EditVert*)ese->data;
+               ret= pupmenu(""); */
+       } else if(ese && ese->type == EDITEDGE) {
+               ret= pupmenu("Copy Active Edge to Selected%t|Crease%x1|Bevel Weight%x2|Length%x3");
+               if (ret<1) return;
+               
+               EM_mesh_copy_edge(ret);
+               
+       } else if(ese==NULL || ese->type == EDITFACE) {
+               ret= pupmenu(
+                       "Copy Face Selected%t|"
+                       "Active Material%x1|Active Image%x2|Active UV Coords%x3|"
+                       "Active Mode%x4|Active Transp%x5|Active Vertex Colors%x6|%l|"
+
+                       "TexFace UVs from layer%x7|"
+                       "TexFace Images from layer%x8|"
+                       "TexFace All from layer%x9|"
+                       "Vertex Colors from layer%x10");
+               if (ret<1) return;
+               
+               if (ret<=6) {
+                       EM_mesh_copy_face(ret);
+               } else {
+                       EM_mesh_copy_face_layer(ret);
+               }
+       }
 }
 
 
index cbf7691754dfcd78fa92fd63854fbd2cdfaf4a02..fee967bcd9ad5faf45c85c1dc8807a75d15382f9 100644 (file)
@@ -2760,7 +2760,7 @@ void special_editmenu(void)
                DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
        }
        else if(G.obedit->type==OB_ARMATURE) {
-               nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6|%l|Lock%x7|Unlock%x8");
+               nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Switch Direction%x7|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6");
                if(nr==1)
                        subdivide_armature(1);
                if(nr==2) {
@@ -2773,10 +2773,8 @@ void special_editmenu(void)
                else if(ELEM3(nr, 4, 5, 6)) {
                        armature_autoside_names(nr-4);
                }
-               else if(nr==7)
-                       set_locks_armature_bones(1);
-               else if(nr==8)
-                       set_locks_armature_bones(0);
+               else if(nr == 7)
+                       switch_direction_armature();
        }
        else if(G.obedit->type==OB_LATTICE) {
                static float weight= 1.0f;
index 948023bebfbb80603a2d68860aa27a71213bf2ac..fcf4caf45225c6490b104bbbe022afed40a2086a 100644 (file)
@@ -5139,7 +5139,7 @@ static char *snapmode_pup(void)
        static char string[512];
        char *str = string;
        
-       str += sprintf(str, "%s", "Snap Mode: %t"); 
+       str += sprintf(str, "%s", "Snap Element: %t"); 
        str += sprintf(str, "%s", "|Vertex%x0");
        str += sprintf(str, "%s", "|Edge%x1");
        str += sprintf(str, "%s", "|Face%x2"); 
@@ -5777,7 +5777,7 @@ void view3d_buttons(void)
                                xco+= XIC;
                                uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_VERTEXSEL, snapmode_pup(), xco,0,XIC+10,YIC, &(G.scene->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode");
                                xco+= XIC;
-                               uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,0,70,YIC, &G.scene->snap_target, 0, 0, 0, 0, "Snap Target Mode");
+                               uiDefButS(block, MENU, B_NOP, "Snap Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,0,70,YIC, &G.scene->snap_target, 0, 0, 0, 0, "Snap Target Mode");
                                xco+= 70;
                        } else {
                                uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,0,XIC,YIC, &G.scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)");  
index fb2bfe5b605332a9a618459c2c7df754b453e13c..6aeef7c75c249af9c2f61b9b6ce7c7c89ede510e 100644 (file)
@@ -312,7 +312,7 @@ void poselib_add_current_pose (Object *ob, int val)
        /* mode - add new or replace existing */
        if (val == 0) {
                if ((ob->poselib) && (ob->poselib->markers.first)) {
-                       val= pupmenu("PoseLib Add Current Pose%t|Add New%x1|Replace Existing%x2");
+                       val= pupmenu("PoseLib Add Current Pose%t|Add New%x1|Add New (Current Frame)%x3|Replace Existing%x2");
                        if (val <= 0) return;
                }
                else 
@@ -347,7 +347,10 @@ void poselib_add_current_pose (Object *ob, int val)
                act= poselib_validate(ob);
                
                /* get frame */
-               frame= poselib_get_free_index(act);
+               if (val == 3)
+                       frame= CFRA;
+               else /* if (val == 1) */
+                       frame= poselib_get_free_index(act);
                
                /* add pose to poselib - replaces any existing pose there */
                for (marker= act->markers.first; marker; marker= marker->next) {
index 2431ff5de227814a61a64e46c38c4e4e37269f14..ecd63166792e6d107788106035f5c91a167677b2 100644 (file)
 /* DataToC output of file <splash_jpg> */
 
-int datatoc_splash_jpg_size= 95515;
+int datatoc_splash_jpg_size= 50665;
 char datatoc_splash_jpg[]= {
-255,216,255,224,  0, 16, 74, 70, 73, 70,  0,  1,  2,  0,  0,100,  0,100,  0,  0,255,236,  0, 17, 68,117, 99,
-107,121,  0,  1,  0,  4,  0,  0,  0, 95,  0,  0,255,238,  0, 14, 65,100,111, 98,101,  0,100,192,  0,  0,  0,  1,255,219,  0,132,
-  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  1,  1,  1,  1,  1,  2,  2,  2,  2,
-  2,  2,  2,  2,  2,  2,  2,  2,  3,  2,  2,  2,  3,  3,  3,  3,  3,  3,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
-  5,  1,  1,  1,  1,  2,  1,  2,  3,  2,  2,  3,  4,  4,  3,  4,  4,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
-  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
-  5,  5,255,192,  0, 17,  8,  1, 26,  1,245,  3,  1, 17,  0,  2, 17,  1,  3, 17,  1,255,196,  0,230,  0,  0,  0,  6,  3,  1,  1,
-  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  4,  5,  6,  7,  8,  0,  2,  9,  1, 10, 11,  1,  0,  0,  7,  1,  1,  1,  1,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,&