svn merge -r 30323:30417 https://svn.blender.org/svnroot/bf-blender/trunk/blender
This commit is contained in:
commit
2ffe3e46c5
@ -55,10 +55,6 @@ PROJECT(Blender)
|
||||
SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
|
||||
SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
|
||||
|
||||
# Note! - Could create this from the blender version string
|
||||
# ...but thats quite involved, make sure this matches the blender version.
|
||||
SET(BLENDER_VERSION 2.5)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Load some macros.
|
||||
INCLUDE(build_files/cmake/macros.cmake)
|
||||
@ -66,6 +62,8 @@ INCLUDE(build_files/cmake/macros.cmake)
|
||||
#-----------------------------------------------------------------------------
|
||||
# Set default config options
|
||||
|
||||
GET_BLENDER_VERSION()
|
||||
|
||||
# Blender internal features
|
||||
OPTION(WITH_INTERNATIONAL "Enable I18N (International fonts and text)" ON)
|
||||
OPTION(WITH_LCMS "Enable color correction with lcms" OFF)
|
||||
@ -628,6 +626,12 @@ IF(WIN32)
|
||||
SET(WITH_JACK OFF)
|
||||
ENDIF(WITH_JACK)
|
||||
|
||||
IF(WITH_RAYOPTIMIZATION AND SUPPORT_SSE_BUILD)
|
||||
SET(PLATFORM_CFLAGS " -msse -msse2 ${PLATFORM_CFLAGS}")
|
||||
ADD_DEFINITIONS(-D__SSE__)
|
||||
ADD_DEFINITIONS(-D__MMX__)
|
||||
ENDIF(WITH_RAYOPTIMIZATION AND SUPPORT_SSE_BUILD)
|
||||
|
||||
ENDIF(MSVC)
|
||||
|
||||
ENDIF(WIN32)
|
||||
|
15
SConstruct
15
SConstruct
@ -47,19 +47,18 @@ import re
|
||||
from tempfile import mkdtemp
|
||||
|
||||
# needed for importing tools
|
||||
sys.path.append(os.path.join(".", "build_files", "scons"))
|
||||
sys.path.append(os.path.join(".", "build_files", "scons", "tools"))
|
||||
|
||||
import tools.Blender
|
||||
import tools.btools
|
||||
import tools.bcolors
|
||||
import Blender
|
||||
import btools
|
||||
import bcolors
|
||||
|
||||
EnsureSConsVersion(1,0,0)
|
||||
|
||||
BlenderEnvironment = tools.Blender.BlenderEnvironment
|
||||
btools = tools.btools
|
||||
B = tools.Blender
|
||||
BlenderEnvironment = Blender.BlenderEnvironment
|
||||
B = Blender
|
||||
|
||||
VERSION = tools.btools.VERSION # This is used in creating the local config directories
|
||||
VERSION = btools.VERSION # This is used in creating the local config directories
|
||||
|
||||
### globals ###
|
||||
platform = sys.platform
|
||||
|
37
build_files/cmake/example_scripts/cmake_linux_install.sh
Executable file
37
build_files/cmake/example_scripts/cmake_linux_install.sh
Executable file
@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This shell script checks out and compiles blender, tested on ubuntu 10.04
|
||||
# assumes you have dependancies installed alredy
|
||||
|
||||
# See this page for more info:
|
||||
# http://wiki.blender.org/index.php/Dev:2.5/Doc/Building_Blender/Linux/Generic_Distro/CMake
|
||||
|
||||
# grab blender
|
||||
mkdir ~/blender-svn
|
||||
cd ~/blender-svn
|
||||
svn co https://svn.blender.org/svnroot/bf-blender/trunk/blender
|
||||
|
||||
# create cmake dir
|
||||
mkdir ~/blender-svn/build-cmake
|
||||
cd ~/blender-svn/build-cmake
|
||||
|
||||
# cmake without copying files for fast rebuilds
|
||||
# the files from svn will be used in place
|
||||
cmake ../blender -DWITH_INSTALL:BOOL=FALSE
|
||||
|
||||
# make blender, will take some time
|
||||
make
|
||||
|
||||
# link the binary to blenders source directory to run quickly
|
||||
ln -s ~/blender-svn/build-cmake/bin/blender ~/blender-svn/blender/blender.bin
|
||||
|
||||
# useful info
|
||||
echo ""
|
||||
echo "* Useful Commands *"
|
||||
echo " Run Blender: ~/blender-svn/blender/blender.bin"
|
||||
echo " Update Blender: svn up ~/blender-svn/blender"
|
||||
echo " Reconfigure Blender: cd ~/blender-svn/build-cmake ; cmake ."
|
||||
echo " Build Blender: cd ~/blender-svn/build-cmake ; make"
|
||||
echo ""
|
||||
|
||||
|
@ -198,3 +198,36 @@ MACRO(TEST_SSE_SUPPORT)
|
||||
SUPPORT_SSE_BUILD)
|
||||
ENDMACRO(TEST_SSE_SUPPORT)
|
||||
|
||||
MACRO(GET_BLENDER_VERSION)
|
||||
FILE(READ ${CMAKE_SOURCE_DIR}/source/blender/blenkernel/BKE_blender.h CONTENT)
|
||||
STRING(REGEX REPLACE "\n" ";" CONTENT "${CONTENT}")
|
||||
STRING(REGEX REPLACE "\t" ";" CONTENT "${CONTENT}")
|
||||
STRING(REGEX REPLACE " " ";" CONTENT "${CONTENT}")
|
||||
|
||||
FOREACH(ITEM ${CONTENT})
|
||||
IF(LASTITEM MATCHES "BLENDER_VERSION")
|
||||
MATH(EXPR BLENDER_VERSION_MAJOR "${ITEM} / 100")
|
||||
MATH(EXPR BLENDER_VERSION_MINOR "${ITEM} % 100")
|
||||
SET(BLENDER_VERSION "${BLENDER_VERSION_MAJOR}.${BLENDER_VERSION_MINOR}")
|
||||
ENDIF(LASTITEM MATCHES "BLENDER_VERSION")
|
||||
|
||||
IF(LASTITEM MATCHES "BLENDER_SUBVERSION")
|
||||
SET(BLENDER_SUBVERSION ${ITEM})
|
||||
ENDIF(LASTITEM MATCHES "BLENDER_SUBVERSION")
|
||||
|
||||
IF(LASTITEM MATCHES "BLENDER_MINVERSION")
|
||||
MATH(EXPR BLENDER_MINVERSION_MAJOR "${ITEM} / 100")
|
||||
MATH(EXPR BLENDER_MINVERSION_MINOR "${ITEM} % 100")
|
||||
SET(BLENDER_MINVERSION "${BLENDER_MINVERSION_MAJOR}.${BLENDER_MINVERSION_MINOR}")
|
||||
ENDIF(LASTITEM MATCHES "BLENDER_MINVERSION")
|
||||
|
||||
IF(LASTITEM MATCHES "BLENDER_MINSUBVERSION")
|
||||
SET(BLENDER_MINSUBVERSION ${ITEM})
|
||||
ENDIF(LASTITEM MATCHES "BLENDER_MINSUBVERSION")
|
||||
|
||||
SET(LASTITEM ${ITEM})
|
||||
ENDFOREACH(ITEM ${CONTENT})
|
||||
|
||||
MESSAGE(STATUS "Version major: ${BLENDER_VERSION_MAJOR}, Version minor: ${BLENDER_VERSION_MINOR}, Subversion: ${BLENDER_SUBVERSION}, Version: ${BLENDER_VERSION}")
|
||||
MESSAGE(STATUS "Minversion major: ${BLENDER_MINVERSION_MAJOR}, Minversion minor: ${BLENDER_MINVERSION_MINOR}, MinSubversion: ${BLENDER_MINSUBVERSION}, Minversion: ${BLENDER_MINVERSION}")
|
||||
ENDMACRO(GET_BLENDER_VERSION)
|
||||
|
@ -498,7 +498,9 @@ def AppIt(target=None, source=None, env=None):
|
||||
builddir, b = os.path.split(a)
|
||||
libdir = env['LCGDIR'][1:]
|
||||
osxarch = env['MACOSX_ARCHITECTURE']
|
||||
installdir = env['BF_INSTALLDIR']
|
||||
print("compiled architecture: %s"%(osxarch))
|
||||
print("Installing to %s"%(installdir))
|
||||
if libdir == '../lib/darwin-9.x.universal':
|
||||
python_zip = 'python_' + osxarch + '.zip' # set specific python_arch.zip
|
||||
else:
|
||||
@ -513,45 +515,45 @@ def AppIt(target=None, source=None, env=None):
|
||||
|
||||
sourcedir = bldroot + '/source/darwin/%s.app'%binary
|
||||
sourceinfo = bldroot + "/source/darwin/%s.app/Contents/Info.plist"%binary
|
||||
targetinfo = builddir +'/' + "%s.app/Contents/Info.plist"%binary
|
||||
cmd = builddir + '/' +'%s.app'%binary
|
||||
targetinfo = installdir +'/' + "%s.app/Contents/Info.plist"%binary
|
||||
cmd = installdir + '/' +'%s.app'%binary
|
||||
|
||||
if os.path.isdir(cmd):
|
||||
shutil.rmtree(cmd)
|
||||
shutil.copytree(sourcedir, cmd)
|
||||
cmd = "cat %s | sed s/VERSION/`cat release/VERSION`/ | sed s/DATE/`date +'%%Y-%%b-%%d'`/ > %s"%(sourceinfo,targetinfo)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp %s/%s %s/%s.app/Contents/MacOS/%s'%(builddir, binary,builddir, binary, binary)
|
||||
cmd = 'cp %s/%s %s/%s.app/Contents/MacOS/%s'%(builddir, binary,installdir, binary, binary)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/'%(builddir, binary, VERSION)
|
||||
cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/'%(installdir, binary, VERSION)
|
||||
# print cmd
|
||||
commands.getoutput(cmd)
|
||||
cmd = builddir + '/%s.app/Contents/MacOS/%s'%(binary,VERSION)
|
||||
cmd = installdir + '/%s.app/Contents/MacOS/%s'%(binary,VERSION)
|
||||
shutil.copy(bldroot + '/bin/.blender/.bfont.ttf', cmd)
|
||||
shutil.copy(bldroot + '/bin/.blender/.Blanguages', cmd)
|
||||
cmd = 'cp -R %s/bin/%s/locale %s/%s.app/Contents/Resources/'%(bldroot,VERSION,builddir,binary)
|
||||
cmd = 'cp -R %s/bin/%s/locale %s/%s.app/Contents/Resources/'%(bldroot,VERSION,installdir,binary)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/bin/%s/locale %s/%s.app/Contents/MacOS/%s/'%(bldroot,VERSION,builddir,binary,VERSION)
|
||||
cmd = 'cp -R %s/bin/%s/locale %s/%s.app/Contents/MacOS/%s/'%(bldroot,VERSION,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp %s/bin/%s/.Blanguages %s/%s.app/Contents/Resources/'%(bldroot,VERSION,builddir,binary)
|
||||
cmd = 'cp %s/bin/%s/.Blanguages %s/%s.app/Contents/Resources/'%(bldroot,VERSION,installdir,binary)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/python/'%(builddir,binary, VERSION)
|
||||
cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/python/'%(installdir,binary, VERSION)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'unzip -q %s/release/%s -d %s/%s.app/Contents/MacOS/%s/python/'%(libdir,python_zip,builddir,binary,VERSION)
|
||||
cmd = 'unzip -q %s/release/%s -d %s/%s.app/Contents/MacOS/%s/python/'%(libdir,python_zip,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/%s/'%(bldroot,builddir,binary,VERSION)
|
||||
cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/release/ui %s/%s.app/Contents/MacOS/%s/'%(bldroot,builddir,binary,VERSION)
|
||||
cmd = 'cp -R %s/release/ui %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/release/io %s/%s.app/Contents/MacOS/%s/'%(bldroot,builddir,binary,VERSION)
|
||||
cmd = 'cp -R %s/release/io %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'chmod +x %s/%s.app/Contents/MacOS/%s'%(builddir,binary, binary)
|
||||
cmd = 'chmod +x %s/%s.app/Contents/MacOS/%s'%(installdir,binary, binary)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'find %s/%s.app -name .svn -prune -exec rm -rf {} \;'%(builddir, binary)
|
||||
cmd = 'find %s/%s.app -name .svn -prune -exec rm -rf {} \;'%(installdir, binary)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'find %s/%s.app -name .DS_Store -exec rm -rf {} \;'%(builddir, binary)
|
||||
cmd = 'find %s/%s.app -name .DS_Store -exec rm -rf {} \;'%(installdir, binary)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'find %s/%s.app -name __MACOSX -exec rm -rf {} \;'%(builddir, binary)
|
||||
cmd = 'find %s/%s.app -name __MACOSX -exec rm -rf {} \;'%(installdir, binary)
|
||||
commands.getoutput(cmd)
|
||||
|
||||
# extract copy system python, be sure to update other build systems
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "BLENDER" "1" "June 27, 2010" "Blender Blender 2\&.52 (sub 5) "
|
||||
.TH "BLENDER" "1" "July 15, 2010" "Blender Blender 2\&.52 (sub 5) "
|
||||
|
||||
.SH NAME
|
||||
blender \- a 3D modelling and rendering package
|
||||
@ -317,11 +317,13 @@ Arguments are executed in the order they are given. eg
|
||||
.br
|
||||
.br
|
||||
.SH "ENVIRONMENT VARIABLES"
|
||||
\fIHOME\fR Store files such as .blender/ .B.blend .Bfs .Blog here.
|
||||
\fIBLENDERPATH\fR System directory to use for data files and scripts.
|
||||
For this build of blender the default \fIBLENDERPATH\fR is...
|
||||
"/usr/local/share/blender/2.5"
|
||||
setting the \fIBLENDERPATH\fR will override this
|
||||
\fIBLENDER_USER_CONFIG\fR Directory for user configuration files.
|
||||
\fIBLENDER_SYSTEM_CONFIG\fR Directory for system wide configuration files.
|
||||
\fIBLENDER_USER_SCRIPTS\fR Directory for user scripts.
|
||||
\fIBLENDER_SYSTEM_SCRIPTS\fR Directory for system wide scripts.
|
||||
\fIBLENDER_USER_DATAFILES\fR Directory for user data files (icons, translations, ..).
|
||||
\fIBLENDER_SYSTEM_DATAFILES\fR Directory for system wide data files.
|
||||
\fIBLENDER_SYSTEM_PYTHON\fR Directory for system python libraries.
|
||||
\fITMP\fR or \fITMPDIR\fR Store temporary files here.
|
||||
\fIPYTHONHOME\fR Path to the python directory, eg. /usr/lib/python.
|
||||
.br
|
||||
|
@ -53,7 +53,7 @@ blender_version = blender_version.split("Build")[0]
|
||||
|
||||
date_string = datetime.date.fromtimestamp(time.time()).strftime("%B %d, %Y")
|
||||
|
||||
filepath = __file__.replace(".py", "")
|
||||
filepath = os.path.splitext(__file__)[0]
|
||||
|
||||
file = open(filepath, "w")
|
||||
|
||||
@ -132,3 +132,5 @@ This manpage was written for a Debian GNU/Linux system by Daniel Mester
|
||||
<mester@uni-bremen.de> and updated by Cyril Brulebois
|
||||
<cyril.brulebois@enst-bretagne.fr> and Dan Eicher <dan@trollwerks.org>.
|
||||
''')
|
||||
|
||||
print("written:", filepath)
|
||||
|
@ -85,6 +85,9 @@ ELSEIF(UNIX)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemX11.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowX11.cpp
|
||||
)
|
||||
|
||||
ADD_DEFINITIONS(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
ENDIF(APPLE)
|
||||
|
||||
BLENDERLIB(bf_ghost "${SRC}" "${INC}")
|
||||
|
@ -56,9 +56,8 @@ else:
|
||||
|
||||
if env['BF_GHOST_DEBUG']:
|
||||
defs.append('BF_GHOST_DEBUG')
|
||||
|
||||
|
||||
incs = '. ../string #extern/glew/include #source/blender/imbuf #source/blender/makesdna ' + env['BF_OPENGL_INC']
|
||||
if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
|
||||
incs = env['BF_WINTAB_INC'] + ' ' + incs
|
||||
env.BlenderLib ('bf_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15] )
|
||||
|
||||
|
@ -67,6 +67,10 @@
|
||||
#include <stdio.h> // for fprintf only
|
||||
#include <cstdlib> // for exit
|
||||
|
||||
#ifndef PREFIX
|
||||
# define PREFIX "/usr/local"
|
||||
#endif
|
||||
|
||||
typedef struct NDOFPlatformInfo {
|
||||
Display *display;
|
||||
Window window;
|
||||
@ -1461,7 +1465,7 @@ void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const
|
||||
|
||||
const GHOST_TUns8* GHOST_SystemX11::getSystemDir() const
|
||||
{
|
||||
return (GHOST_TUns8*)"/usr/share";
|
||||
return (GHOST_TUns8*) PREFIX "/share";
|
||||
}
|
||||
|
||||
const GHOST_TUns8* GHOST_SystemX11::getUserDir() const
|
||||
|
@ -42,7 +42,7 @@ AGLContext GHOST_WindowCarbon::s_firstaglCtx = NULL;
|
||||
const GHOST_TInt32 GHOST_WindowCarbon::s_sizeRectSize = 16;
|
||||
#endif //GHOST_DRAW_CARBON_GUTTER
|
||||
|
||||
static const GLint sPreferredFormatWindow[8] = {
|
||||
static const GLint sPreferredFormatWindow[10] = {
|
||||
AGL_RGBA,
|
||||
AGL_DOUBLEBUFFER,
|
||||
AGL_ACCELERATED,
|
||||
@ -50,7 +50,7 @@ AGL_DEPTH_SIZE, 32,
|
||||
AGL_NONE,
|
||||
};
|
||||
|
||||
static const GLint sPreferredFormatFullScreen[9] = {
|
||||
static const GLint sPreferredFormatFullScreen[11] = {
|
||||
AGL_RGBA,
|
||||
AGL_DOUBLEBUFFER,
|
||||
AGL_ACCELERATED,
|
||||
|
@ -348,10 +348,11 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
|
||||
//pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
|
||||
|
||||
|
||||
pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize;
|
||||
pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 32;
|
||||
|
||||
|
||||
if (stereoVisual) pixelFormatAttrsWindow[i++] = NSOpenGLPFAStereo;
|
||||
|
||||
if (numOfAASamples>0) {
|
||||
|
@ -1093,7 +1093,7 @@ static int WeightPixelFormat(PIXELFORMATDESCRIPTOR& pfd) {
|
||||
!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
|
||||
!(pfd.dwFlags & PFD_DOUBLEBUFFER) || /* Blender _needs_ this */
|
||||
( pfd.cDepthBits <= 8 ) ||
|
||||
!(pfd.iPixelType == PFD_TYPE_RGBA) )
|
||||
!(pfd.iPixelType == PFD_TYPE_RGBA))
|
||||
return 0;
|
||||
|
||||
weight = 1; /* it's usable */
|
||||
|
@ -355,10 +355,6 @@
|
||||
Name="datafiles"
|
||||
Filter="c"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\datafiles\B.blend.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\datafiles\Bfont.c"
|
||||
>
|
||||
@ -387,6 +383,10 @@
|
||||
RelativePath="..\..\..\source\blender\editors\datafiles\splash.png.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\datafiles\startup.blend.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="interface"
|
||||
@ -1347,6 +1347,10 @@
|
||||
RelativePath="..\..\..\source\blender\editors\sculpt_paint\sculpt_intern.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\editors\sculpt_paint\sculpt_undo.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="uvedit"
|
||||
|
@ -508,7 +508,7 @@
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\..\source\blender\gpu\gpu_buffers.h"
|
||||
RelativePath="..\..\..\source\blender\gpu\GPU_buffers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
132
release/freedesktop/blender-thumbnailer.py
Executable file
132
release/freedesktop/blender-thumbnailer.py
Executable file
@ -0,0 +1,132 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
"""
|
||||
Thumbnailer runs with python 2.6 and 3.x.
|
||||
To run automatically with nautilus:
|
||||
gconftool --type boolean --set /desktop/gnome/thumbnailers/application@x-blender/enable true
|
||||
gconftool --type string --set /desktop/gnome/thumbnailers/application@x-blender/command "blender-thumbnailer.py %i %o"
|
||||
"""
|
||||
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
|
||||
def blend_extract_thumb(path):
|
||||
# def MAKE_ID(tag): ord(tag[0])<<24 | ord(tag[1])<<16 | ord(tag[2])<<8 | ord(tag[3])
|
||||
REND = 1145980242 # MAKE_ID(b'REND')
|
||||
TEST = 1414743380 # MAKE_ID(b'TEST')
|
||||
|
||||
blendfile = open(path, 'rb')
|
||||
|
||||
head = blendfile.read(7)
|
||||
|
||||
if head[0:2] == b'\x1f\x8b': # gzip magic
|
||||
import gzip
|
||||
blendfile.close()
|
||||
blendfile = gzip.open(path, 'rb')
|
||||
head = blendfile.read(7)
|
||||
|
||||
if head != b'BLENDER':
|
||||
blendfile.close()
|
||||
return None, 0, 0
|
||||
|
||||
is_64_bit = (blendfile.read(1) == b'-')
|
||||
|
||||
# true for PPC, false for X86
|
||||
is_big_endian = (blendfile.read(1) == b'V')
|
||||
|
||||
# Now read the bhead chunk!!!
|
||||
blendfile.read(3) # skip the version
|
||||
|
||||
sizeof_pointer = 8 if is_64_bit else 4
|
||||
|
||||
sizeof_bhead = 24 if is_64_bit else 20
|
||||
|
||||
int_endian = '>i' if is_big_endian else '<i'
|
||||
int_endian_pair = '>ii' if is_big_endian else '<ii'
|
||||
|
||||
while True:
|
||||
try:
|
||||
code, length = struct.unpack(int_endian_pair, blendfile.read(8)) # 8 == sizeof(int) * 2
|
||||
except IOError:
|
||||
return None, 0, 0
|
||||
|
||||
# finally read the rest of the bhead struct, pointer and 2 ints
|
||||
blendfile.seek(sizeof_bhead - 8, os.SEEK_CUR)
|
||||
|
||||
if code == REND:
|
||||
blendfile.seek(length, os.SEEK_CUR)
|
||||
else:
|
||||
break
|
||||
|
||||
if code != TEST:
|
||||
return None, 0, 0
|
||||
|
||||
try:
|
||||
x, y = struct.unpack(int_endian_pair, blendfile.read(8)) # 8 == sizeof(int) * 2
|
||||
except struct.error:
|
||||
return None, 0, 0
|
||||
|
||||
length -= 8 # sizeof(int) * 2
|
||||
|
||||
if length != x * y * 4:
|
||||
return None, 0, 0
|
||||
|
||||
image_buffer = blendfile.read(length)
|
||||
|
||||
if len(image_buffer) != length:
|
||||
return None, 0, 0
|
||||
|
||||
return image_buffer, x, y
|
||||
|
||||
|
||||
def write_png(buf, width, height):
|
||||
import zlib
|
||||
|
||||
# reverse the vertical line order and add null bytes at the start
|
||||
width_byte_4 = width * 4
|
||||
raw_data = b"".join([b'\x00' + buf[span:span + width_byte_4] for span in range((height - 1) * width * 4, -1, - width_byte_4)])
|
||||
|
||||
def png_pack(png_tag, data):
|
||||
chunk_head = png_tag + data
|
||||
return struct.pack("!I", len(data)) + chunk_head + struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head))
|
||||
|
||||
return b"".join([
|
||||
b'\x89PNG\r\n\x1a\n',
|
||||
png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)),
|
||||
png_pack(b'IDAT', zlib.compress(raw_data, 9)),
|
||||
png_pack(b'IEND', b'')])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) < 2:
|
||||
print("Expected 2 arguments <input.blend> <output.png>")
|
||||
else:
|
||||
file_in = sys.argv[-2]
|
||||
|
||||
buf, width, height = blend_extract_thumb(file_in)
|
||||
|
||||
if buf:
|
||||
file_out = sys.argv[-1]
|
||||
|
||||
f = open(file_out, "wb")
|
||||
f.write(write_png(buf, width, height))
|
||||
f.close()
|
@ -3,7 +3,7 @@ Encoding=UTF-8
|
||||
Name=Blender
|
||||
Comment=3D modeling, animation, rendering and post-production
|
||||
Exec=blender
|
||||
Icon=blender.png
|
||||
Icon=blender.svg
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Graphics;3DGraphics;
|
||||
|
@ -347,7 +347,7 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
|
||||
scn = context.scene
|
||||
#XXX scn.objects.selected = []
|
||||
for ob in scn.objects:
|
||||
ob.selected = False
|
||||
ob.select = False
|
||||
|
||||
scn.set_frame(IMPORT_START_FRAME)
|
||||
|
||||
@ -356,7 +356,7 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
|
||||
|
||||
scn.objects.link(arm_ob)
|
||||
|
||||
arm_ob.selected = True
|
||||
arm_ob.select = True
|
||||
scn.objects.active = arm_ob
|
||||
print(scn.objects.active)
|
||||
|
||||
|
@ -360,7 +360,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
vertMappingIndex = 0
|
||||
|
||||
vertsToUse = [i for i in range(len(myContextMesh_vertls)) if faceVertUsers[i]]
|
||||
myVertMapping = dict( [ (ii, i) for i, ii in enumerate(vertsToUse) ] )
|
||||
myVertMapping = {ii: i for i, ii in enumerate(vertsToUse)}
|
||||
|
||||
tempName= '%s_%s' % (contextObName, matName) # matName may be None.
|
||||
bmesh = bpy.data.meshes.new(tempName)
|
||||
|
@ -596,7 +596,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
|
||||
|
||||
if unique_smooth_groups:
|
||||
sharp_edges= {}
|
||||
smooth_group_users= dict([ (context_smooth_group, {}) for context_smooth_group in list(unique_smooth_groups.keys()) ])
|
||||
smooth_group_users = {context_smooth_group: {} for context_smooth_group in list(unique_smooth_groups.keys())}
|
||||
context_smooth_group_old= -1
|
||||
|
||||
# Split fgons into tri's
|
||||
@ -691,7 +691,7 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
|
||||
|
||||
|
||||
# map the material names to an index
|
||||
material_mapping= dict([(name, i) for i, name in enumerate(unique_materials)]) # enumerate over unique_materials keys()
|
||||
material_mapping = {name: i for i, name in enumerate(unique_materials)} # enumerate over unique_materials keys()
|
||||
|
||||
materials= [None] * len(unique_materials)
|
||||
|
||||
|
@ -144,4 +144,4 @@ if __name__ == "__main__":
|
||||
|
||||
process(args)
|
||||
|
||||
bpy.ops.wm.save_as_mainfile(path=new_path, check_existing=False)
|
||||
bpy.ops.wm.save_as_mainfile(filepath=new_path, check_existing=False)
|
||||
|
@ -50,12 +50,12 @@ def add_object_data(context, obdata, operator=None):
|
||||
|
||||
# ugh, could be made nicer
|
||||
for ob in scene.objects:
|
||||
ob.selected = False
|
||||
ob.select = False
|
||||
|
||||
obj_new = bpy.data.objects.new(obdata.name, obdata)
|
||||
|
||||
base = scene.objects.link(obj_new)
|
||||
base.selected = True
|
||||
base.select = True
|
||||
|
||||
if context.space_data and context.space_data.type == 'VIEW_3D':
|
||||
base.layers_from_view(context.space_data)
|
||||
@ -68,7 +68,7 @@ def add_object_data(context, obdata, operator=None):
|
||||
if obj_act and obj_act.mode == 'EDIT' and obj_act.type == obj_new.type:
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
obj_act.selected = True
|
||||
obj_act.select = True
|
||||
scene.update() # apply location
|
||||
#scene.objects.active = obj_new
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
# <pep8 compliant>
|
||||
|
||||
"""
|
||||
This module contains utility functions spesific to blender but
|
||||
This module contains utility functions specific to blender but
|
||||
not assosiated with blenders internal data.
|
||||
"""
|
||||
|
||||
@ -27,7 +27,8 @@ import bpy as _bpy
|
||||
import os as _os
|
||||
import sys as _sys
|
||||
|
||||
from _bpy import home_paths, blend_paths
|
||||
from _bpy import blend_paths
|
||||
from _bpy import script_paths as _bpy_script_paths
|
||||
|
||||
|
||||
def _test_import(module_name, loaded_modules):
|
||||
@ -313,7 +314,7 @@ def script_paths(subdir=None, user=True):
|
||||
else:
|
||||
user_script_path = None
|
||||
|
||||
for path in home_paths("scripts") + (user_script_path, ):
|
||||
for path in _bpy_script_paths() + (user_script_path, ):
|
||||
if path:
|
||||
path = _os.path.normpath(path)
|
||||
if path not in scripts and _os.path.isdir(path):
|
||||
|
@ -444,7 +444,7 @@ class Mesh(bpy_types.ID):
|
||||
if not hasattr(edges, "pop"):
|
||||
edges = edges[:]
|
||||
|
||||
edge_dict = dict((ed.key, ed) for ed in self.edges if ed.selected)
|
||||
edge_dict = {ed.key: ed for ed in self.edges if ed.select}
|
||||
|
||||
while edges:
|
||||
current_edge = edges.pop()
|
||||
|
@ -124,7 +124,7 @@ def get_argspec(func, strip_self=True, doc=None, source=None):
|
||||
if source is None:
|
||||
try:
|
||||
source = inspect.getsource(func)
|
||||
except TypeError:
|
||||
except (TypeError, IOError):
|
||||
source = ''
|
||||
if source:
|
||||
match = re.search(DEF_SOURCE % func_name, source, RE_FLAG)
|
||||
|
@ -191,8 +191,8 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
|
||||
obj.animation_data_clear()
|
||||
|
||||
# Select generated rig object
|
||||
obj_orig.selected = False
|
||||
obj.selected = True
|
||||
obj_orig.select = False
|
||||
obj.select = True
|
||||
scene.objects.active = obj
|
||||
|
||||
# Remove all bones from the generated rig armature.
|
||||
@ -212,9 +212,9 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
|
||||
|
||||
# Select the temp rigs for merging
|
||||
for objt in scene.objects:
|
||||
objt.selected = False # deselect all objects
|
||||
temp_rig_1.selected = True
|
||||
temp_rig_2.selected = True
|
||||
objt.select = False # deselect all objects
|
||||
temp_rig_1.select = True
|
||||
temp_rig_2.select = True
|
||||
scene.objects.active = temp_rig_2
|
||||
|
||||
# Merge the temporary rigs
|
||||
@ -225,8 +225,8 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
|
||||
|
||||
# Select the generated rig
|
||||
for objt in scene.objects:
|
||||
objt.selected = False # deselect all objects
|
||||
obj.selected = True
|
||||
objt.select = False # deselect all objects
|
||||
obj.select = True
|
||||
scene.objects.active = obj
|
||||
|
||||
# Copy over the pose_bone properties
|
||||
@ -464,7 +464,7 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
|
||||
arm.layer = layer_show
|
||||
|
||||
|
||||
# obj.restrict_view = True
|
||||
# obj.hide = True
|
||||
obj.data.draw_axes = False
|
||||
|
||||
bpy.ops.object.mode_set(mode=mode_orig)
|
||||
@ -490,8 +490,8 @@ def generate_test(context, metarig_type="", GENERATE_FINAL=True):
|
||||
scene.objects.link(obj_new)
|
||||
scene.objects.active = obj_new
|
||||
for obj in scene.objects:
|
||||
obj.selected = False
|
||||
obj_new.selected = True
|
||||
obj.select = False
|
||||
obj_new.select = True
|
||||
|
||||
for module_name in get_submodule_types():
|
||||
if (metarig_type and module_name != metarig_type):
|
||||
@ -551,8 +551,8 @@ def generate_test_all(context, GRAPH=False):
|
||||
obj.data.drawtype = 'STICK'
|
||||
obj.location[1] += i
|
||||
obj_new.location[1] += i
|
||||
obj_new.selected = False
|
||||
obj.selected = True
|
||||
obj_new.select = False
|
||||
obj.select = True
|
||||
i += 4
|
||||
|
||||
|
||||
|
@ -137,8 +137,8 @@ def ik(obj, definitions, base_names, options):
|
||||
ik.pole_vis = add_stretch_to(obj, mt.forearm, ik.pole, "VIS-%s_ik" % base_names[mt.forearm])
|
||||
|
||||
ik.update()
|
||||
ik.hand_vis_e.restrict_select = True
|
||||
ik.pole_vis_e.restrict_select = True
|
||||
ik.hand_vis_e.hide_select = True
|
||||
ik.pole_vis_e.hide_select = True
|
||||
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
|
@ -631,8 +631,8 @@ if __name__ == "__main__":
|
||||
props = [(prop.identifier, prop) for prop in v.properties]
|
||||
|
||||
for prop_id, prop in sorted(props):
|
||||
if prop.type == 'boolean':
|
||||
continue
|
||||
# if prop.type == 'boolean':
|
||||
# continue
|
||||
data += "%s.%s -> %s: %s%s %s\n" % (struct_id_str, prop.identifier, prop.identifier, prop.type, ", (read-only)" if prop.is_readonly else "", prop.description)
|
||||
|
||||
if bpy.app.background:
|
||||
|
@ -68,7 +68,7 @@ def get_console(console_id):
|
||||
stderr = io.StringIO()
|
||||
else:
|
||||
namespace = {'__builtins__': __builtins__, 'bpy': bpy}
|
||||
console = InteractiveConsole(namespace)
|
||||
console = InteractiveConsole(locals=namespace, filename="<blender_console>")
|
||||
|
||||
import io
|
||||
stdout = io.StringIO()
|
||||
|
@ -40,7 +40,7 @@ def main(context):
|
||||
|
||||
flist = bpy.context.active_object.animation_data.action.fcurves
|
||||
for f in flist:
|
||||
if f.selected and f.data_path.endswith("rotation_euler"):
|
||||
if f.select and f.data_path.endswith("rotation_euler"):
|
||||
cleanupEulCurve(f)
|
||||
|
||||
class DiscontFilterOp(bpy.types.Operator):
|
||||
|
@ -54,9 +54,9 @@ class MeshSelectInteriorFaces(bpy.types.Operator):
|
||||
|
||||
for index, face in enumerate(face_list):
|
||||
if(test_interior(index)):
|
||||
face.selected = True
|
||||
face.select = True
|
||||
else:
|
||||
face.selected = False
|
||||
face.select = False
|
||||
|
||||
if is_editmode:
|
||||
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||
@ -122,7 +122,7 @@ class MeshMirrorUV(bpy.types.Operator):
|
||||
# as a list
|
||||
faces = mesh.faces[:]
|
||||
|
||||
fuvsel = [(False not in uv.uv_selected) for uv in active_uv_layer]
|
||||
fuvsel = [(False not in uv.select_uv) for uv in active_uv_layer]
|
||||
fcents = [f.center for f in faces]
|
||||
|
||||
# find mirror faces
|
||||
|
@ -100,7 +100,7 @@ def bake(frame_start, frame_end, step=1, only_selected=False):
|
||||
pose_items = pose.bones.items()
|
||||
|
||||
for name, pbone in pose_items:
|
||||
if only_selected and not pbone.selected:
|
||||
if only_selected and not pbone.select:
|
||||
continue
|
||||
|
||||
for f in frame_range:
|
||||
|
@ -52,9 +52,9 @@ class SelectPattern(bpy.types.Operator):
|
||||
# Can be pose bones or objects
|
||||
for item in items:
|
||||
if pattern_match(item.name, self.properties.pattern):
|
||||
item.selected = True
|
||||
item.select = True
|
||||
elif not self.properties.extend:
|
||||
item.selected = False
|
||||
item.select = False
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
@ -90,7 +90,7 @@ class SelectCamera(bpy.types.Operator):
|
||||
self.report({'WARNING'}, "Active camera is not in this scene")
|
||||
|
||||
context.scene.objects.active = camera
|
||||
camera.selected = True
|
||||
camera.select = True
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
@ -121,7 +121,7 @@ class SelectHierarchy(bpy.types.Operator):
|
||||
|
||||
if not self.properties.extend:
|
||||
# for obj in objs:
|
||||
# obj.selected = False
|
||||
# obj.select = False
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
if self.properties.direction == 'PARENT':
|
||||
@ -135,7 +135,7 @@ class SelectHierarchy(bpy.types.Operator):
|
||||
if obj_act == obj:
|
||||
context.scene.objects.active = parent
|
||||
|
||||
parent.selected = True
|
||||
parent.select = True
|
||||
|
||||
if parents:
|
||||
return {'CANCELLED'}
|
||||
@ -145,7 +145,7 @@ class SelectHierarchy(bpy.types.Operator):
|
||||
for obj in objs:
|
||||
children += list(obj.children)
|
||||
for obj_iter in children:
|
||||
obj_iter.selected = True
|
||||
obj_iter.select = True
|
||||
|
||||
children.sort(key=lambda obj_iter: obj_iter.name)
|
||||
context.scene.objects.active = children[0]
|
||||
@ -536,11 +536,11 @@ class IsolateTypeRender(bpy.types.Operator):
|
||||
|
||||
for obj in context.visible_objects:
|
||||
|
||||
if obj.selected:
|
||||
obj.restrict_render = False
|
||||
if obj.select:
|
||||
obj.hide_render = False
|
||||
else:
|
||||
if obj.type == act_type:
|
||||
obj.restrict_render = True
|
||||
obj.hide_render = True
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
@ -40,7 +40,7 @@ class SequencerCrossfadeSounds(bpy.types.Operator):
|
||||
seq1 = None
|
||||
seq2 = None
|
||||
for s in context.scene.sequence_editor.sequences:
|
||||
if s.selected and s.type == 'SOUND':
|
||||
if s.select and s.type == 'SOUND':
|
||||
if seq1 == None:
|
||||
seq1 = s
|
||||
elif seq2 == None:
|
||||
@ -97,13 +97,13 @@ class SequencerCutMulticam(bpy.types.Operator):
|
||||
if s.multicam_source == camera:
|
||||
return {'FINISHED'}
|
||||
|
||||
if not s.selected:
|
||||
s.selected = True
|
||||
if not s.select:
|
||||
s.select = True
|
||||
|
||||
cfra = context.scene.frame_current
|
||||
bpy.ops.sequencer.cut(frame=cfra, type='SOFT', side='RIGHT')
|
||||
for s in context.scene.sequence_editor.sequences_all:
|
||||
if s.selected and s.type == 'MULTICAM' and s.frame_final_start <= cfra and cfra < s.frame_final_end:
|
||||
if s.select and s.type == 'MULTICAM' and s.frame_final_start <= cfra and cfra < s.frame_final_end:
|
||||
context.scene.sequence_editor.active_strip = s
|
||||
|
||||
context.scene.sequence_editor.active_strip.multicam_source = camera
|
||||
@ -125,7 +125,7 @@ class SequencerDeinterlaceSelectedMovies(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
for s in context.scene.sequence_editor.sequences_all:
|
||||
if s.selected and s.type == 'MOVIE':
|
||||
if s.select and s.type == 'MOVIE':
|
||||
s.de_interlace = True
|
||||
|
||||
return {'FINISHED'}
|
||||
|
@ -85,9 +85,9 @@ class ExportUVLayout(bpy.types.Operator):
|
||||
for i in range(uv_layer_len):
|
||||
uv_elem = uv_layer[i]
|
||||
# context checks
|
||||
if faces[i].selected and (local_image is Ellipsis or local_image == uv_elem.image):
|
||||
if faces[i].select and (local_image is Ellipsis or local_image == uv_elem.image):
|
||||
#~ uv = uv_elem.uv
|
||||
#~ if False not in uv_elem.uv_selected[:len(uv)]:
|
||||
#~ if False not in uv_elem.select_uv[:len(uv)]:
|
||||
#~ yield (i, uv)
|
||||
|
||||
# just write what we see.
|
||||
|
@ -65,9 +65,9 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
|
||||
# vertex index is the key, uv is the value
|
||||
|
||||
uvs_vhash_source = dict([(vindex, uvs_source[i]) for i, vindex in enumerate(vidx_source)])
|
||||
uvs_vhash_source = {vindex: uvs_source[i] for i, vindex in enumerate(vidx_source)}
|
||||
|
||||
uvs_vhash_target = dict([(vindex, uvs_target[i]) for i, vindex in enumerate(vidx_target)])
|
||||
uvs_vhash_target = {vindex: uvs_target[i] for i, vindex in enumerate(vidx_target)}
|
||||
|
||||
edge_idxs_source = face_edge_vs(vidx_source)
|
||||
edge_idxs_target = face_edge_vs(vidx_target)
|
||||
@ -146,7 +146,7 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
operator.report({'ERROR'}, "No active face.")
|
||||
return
|
||||
|
||||
face_sel = [f for f in me.faces if len(f.verts) == 4 and f.selected]
|
||||
face_sel = [f for f in me.faces if len(f.verts) == 4 and f.select]
|
||||
|
||||
face_act_local_index = -1
|
||||
for i, f in enumerate(face_sel):
|
||||
|
@ -821,7 +821,7 @@ def main(context, island_margin, projection_limit):
|
||||
#XXX ob = objects.active
|
||||
ob= objects[0]
|
||||
|
||||
if ob and ob.selected == 0 and ob.type == 'MESH':
|
||||
if ob and (not ob.select) and ob.type == 'MESH':
|
||||
# Add to the list
|
||||
obList =[ob]
|
||||
del objects
|
||||
@ -899,7 +899,7 @@ def main(context, island_margin, projection_limit):
|
||||
me_verts = list(me.verts)
|
||||
|
||||
if USER_ONLY_SELECTED_FACES:
|
||||
meshFaces = [thickface(f, uv_layer[i], me_verts) for i, f in enumerate(me.faces) if f.selected]
|
||||
meshFaces = [thickface(f, uv_layer[i], me_verts) for i, f in enumerate(me.faces) if f.select]
|
||||
#else:
|
||||
# meshFaces = map(thickface, me.faces)
|
||||
|
||||
|
@ -127,7 +127,7 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
|
||||
return('CANCELLED', )
|
||||
|
||||
for i, f in enumerate(me.faces):
|
||||
if not me.use_paint_mask or f.selected:
|
||||
if not me.use_paint_mask or f.select:
|
||||
|
||||
f_col = active_col_layer[i]
|
||||
|
||||
|
@ -244,9 +244,9 @@ kmi = km.items.add('object.location_clear', 'G', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.rotation_clear', 'R', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.scale_clear', 'S', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.origin_clear', 'O', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.restrictview_clear', 'H', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.restrictview_set', 'H', 'PRESS')
|
||||
kmi = km.items.add('object.restrictview_set', 'H', 'PRESS', shift=True)
|
||||
kmi = km.items.add('object.hide_clear', 'H', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.hide_set', 'H', 'PRESS')
|
||||
kmi = km.items.add('object.hide_set', 'H', 'PRESS', shift=True)
|
||||
kmi.properties.unselected = True
|
||||
kmi = km.items.add('object.move_to_layer', 'M', 'PRESS')
|
||||
kmi = km.items.add('object.delete', 'X', 'PRESS')
|
||||
|
@ -16,7 +16,7 @@ def main(context):
|
||||
for i, uv in enumerate(mesh.active_uv_texture.data):
|
||||
uvs = uv.uv1, uv.uv2, uv.uv3, uv.uv4
|
||||
for j, v_idx in enumerate(mesh.faces[i].verts):
|
||||
if uv.uv_selected[j]:
|
||||
if uv.select_uv[j]:
|
||||
# apply the location of the vertex as a UV
|
||||
uvs[j][:] = mesh.verts[v_idx].co.xy
|
||||
|
||||
|
@ -81,13 +81,13 @@ class BONE_PT_transform(BoneButtonsPanel):
|
||||
sub.label(text="Roll:")
|
||||
sub.prop(bone, "roll", text="")
|
||||
sub.label()
|
||||
sub.prop(bone, "locked")
|
||||
sub.prop(bone, "lock")
|
||||
else:
|
||||
col = layout.column()
|
||||
col.prop(bone, "head")
|
||||
col.prop(bone, "tail")
|
||||
col.prop(bone, "roll")
|
||||
col.prop(bone, "locked")
|
||||
col.prop(bone, "lock")
|
||||
|
||||
else:
|
||||
pchan = ob.pose.bones[context.bone.name]
|
||||
@ -231,7 +231,7 @@ class BONE_PT_display(BoneButtonsPanel):
|
||||
|
||||
col = split.column()
|
||||
col.prop(bone, "draw_wire", text="Wireframe")
|
||||
col.prop(bone, "hidden", text="Hide")
|
||||
col.prop(bone, "hide", text="Hide")
|
||||
|
||||
if wide_ui:
|
||||
col = split.column()
|
||||
|
@ -437,6 +437,7 @@ class DATA_PT_modifiers(DataButtonsPanel):
|
||||
col.prop(md, "levels", text="Preview")
|
||||
col.prop(md, "sculpt_levels", text="Sculpt")
|
||||
col.prop(md, "render_levels", text="Render")
|
||||
col.prop(bpy.context.tool_settings.sculpt, "fast_navigate")
|
||||
|
||||
if wide_ui:
|
||||
col = split.column()
|
||||
|
@ -58,7 +58,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel):
|
||||
col = split.column()
|
||||
col.prop(game, "actor")
|
||||
col.prop(game, "ghost")
|
||||
col.prop(ob, "restrict_render", text="Invisible") # out of place but useful
|
||||
col.prop(ob, "hide_render", text="Invisible") # out of place but useful
|
||||
|
||||
if wide_ui:
|
||||
col = split.column()
|
||||
@ -120,7 +120,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel):
|
||||
col = layout.column()
|
||||
col.prop(game, "actor")
|
||||
col.prop(game, "ghost")
|
||||
col.prop(ob, "restrict_render", text="Invisible")
|
||||
col.prop(ob, "hide_render", text="Invisible")
|
||||
|
||||
layout.separator()
|
||||
|
||||
@ -156,10 +156,10 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel):
|
||||
col = layout.column()
|
||||
col.prop(game, "actor")
|
||||
col.prop(game, "ghost")
|
||||
col.prop(ob, "restrict_render", text="Invisible")
|
||||
col.prop(ob, "hide_render", text="Invisible")
|
||||
|
||||
elif game.physics_type in ('SENSOR', 'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'):
|
||||
layout.prop(ob, "restrict_render", text="Invisible")
|
||||
layout.prop(ob, "hide_render", text="Invisible")
|
||||
|
||||
|
||||
class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel):
|
||||
|
@ -523,7 +523,7 @@ class ConstraintButtonsPanel(bpy.types.Panel):
|
||||
row = layout.row()
|
||||
if wide_ui:
|
||||
row.label(text="Lock:")
|
||||
row.prop(con, "locked", expand=True)
|
||||
row.prop(con, "lock", expand=True)
|
||||
|
||||
def LIMIT_DISTANCE(self, context, layout, con, wide_ui):
|
||||
self.target_template(layout, con, wide_ui)
|
||||
|
@ -275,15 +275,12 @@ class TEXTURE_PT_mapping(TextureSlotPanel):
|
||||
|
||||
if type(idblock) == bpy.types.Brush:
|
||||
if context.sculpt_object:
|
||||
layout.label(text="Brush Mapping:")
|
||||
layout.prop(tex, "map_mode", expand=True)
|
||||
|
||||
row = layout.row()
|
||||
row.active = tex.map_mode in ('FIXED', 'TILED')
|
||||
row.prop(tex, "angle")
|
||||
|
||||
row = layout.row()
|
||||
row.active = tex.map_mode in ('TILED', '3D')
|
||||
row.column().prop(tex, "size")
|
||||
else:
|
||||
if type(idblock) == bpy.types.Material:
|
||||
split = layout.split(percentage=0.3)
|
||||
@ -307,15 +304,17 @@ class TEXTURE_PT_mapping(TextureSlotPanel):
|
||||
row.prop(tex, "y_mapping", text="")
|
||||
row.prop(tex, "z_mapping", text="")
|
||||
|
||||
# any non brush
|
||||
split = layout.split()
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop(tex, "offset")
|
||||
|
||||
if wide_ui:
|
||||
col = split.column()
|
||||
col.prop(tex, "offset")
|
||||
else:
|
||||
col.separator()
|
||||
|
||||
if wide_ui:
|
||||
col = split.column()
|
||||
col.prop(tex, "size")
|
||||
col.prop(tex, "size")
|
||||
|
||||
|
||||
class TEXTURE_PT_influence(TextureSlotPanel):
|
||||
|
@ -141,7 +141,7 @@ class TIME_MT_frame(bpy.types.Menu):
|
||||
|
||||
# it was ok for riscos... ok TODO, operator
|
||||
for marker in context.scene.timeline_markers:
|
||||
if marker.selected:
|
||||
if marker.select:
|
||||
layout.separator()
|
||||
layout.prop(marker, "name", text="", icon='MARKER_HLT')
|
||||
break
|
||||
|
@ -327,7 +327,21 @@ class USERPREF_PT_edit(bpy.types.Panel):
|
||||
row.separator()
|
||||
row.separator()
|
||||
|
||||
sculpt = context.tool_settings.sculpt
|
||||
col = row.column()
|
||||
col.label(text="Paint and Sculpt:")
|
||||
col.prop(edit, "sculpt_paint_use_unified_size", text="Unify Size")
|
||||
col.prop(edit, "sculpt_paint_use_unified_strength", text="Unify Strength")
|
||||
row = col.row(align=True)
|
||||
row.label("Overlay Color:")
|
||||
row.prop(edit, "sculpt_paint_overlay_col", text="")
|
||||
col.prop(sculpt, "use_openmp", text="Threaded Sculpt")
|
||||
col.prop(sculpt, "show_brush")
|
||||
|
||||
col.separator()
|
||||
col.separator()
|
||||
col.separator()
|
||||
|
||||
col.label(text="Duplicate Data:")
|
||||
col.prop(edit, "duplicate_mesh", text="Mesh")
|
||||
col.prop(edit, "duplicate_surface", text="Surface")
|
||||
|
@ -859,9 +859,9 @@ class VIEW3D_MT_object_showhide(bpy.types.Menu):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("object.restrictview_clear", text="Show Hidden")
|
||||
layout.operator("object.restrictview_set", text="Hide Selected")
|
||||
layout.operator("object.restrictview_set", text="Hide Unselected").unselected = True
|
||||
layout.operator("object.hide_view_clear", text="Show Hidden")
|
||||
layout.operator("object.hide_view_set", text="Hide Selected")
|
||||
layout.operator("object.hide_view_set", text="Hide Unselected").unselected = True
|
||||
|
||||
|
||||
class VIEW3D_MT_make_single_user(bpy.types.Menu):
|
||||
|
@ -19,6 +19,7 @@
|
||||
# <pep8 compliant>
|
||||
import bpy
|
||||
|
||||
narrowui = bpy.context.user_preferences.view.properties_width_check
|
||||
|
||||
class View3DPanel(bpy.types.Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
@ -503,18 +504,26 @@ class VIEW3D_PT_tools_brush(PaintPanel):
|
||||
|
||||
if not context.particle_edit_object:
|
||||
col = layout.split().column()
|
||||
row = col.row()
|
||||
|
||||
if context.sculpt_object and brush:
|
||||
defaultbrushes = 8
|
||||
elif context.texture_paint_object and brush:
|
||||
defaultbrushes = 4
|
||||
if context.sculpt_object and context.tool_settings.sculpt:
|
||||
col.template_ID_preview(settings, "brush", new="brush.add", filter="is_sculpt_brush", rows=3, cols=8)
|
||||
elif context.texture_paint_object and context.tool_settings.image_paint:
|
||||
col.template_ID_preview(settings, "brush", new="brush.add", filter="is_imapaint_brush", rows=3, cols=8)
|
||||
elif context.vertex_paint_object and context.tool_settings.vertex_paint:
|
||||
col.template_ID_preview(settings, "brush", new="brush.add", filter="is_vpaint_brush", rows=3, cols=8)
|
||||
elif context.weight_paint_object and context.tool_settings.weight_paint:
|
||||
col.template_ID_preview(settings, "brush", new="brush.add", filter="is_wpaint_brush", rows=3, cols=8)
|
||||
else:
|
||||
defaultbrushes = 7
|
||||
row = col.row()
|
||||
|
||||
row.template_list(settings, "brushes", settings, "active_brush_index", rows=2, maxrows=defaultbrushes)
|
||||
if context.sculpt_object and brush:
|
||||
defaultbrushes = 8
|
||||
elif context.texture_paint_object and brush:
|
||||
defaultbrushes = 4
|
||||
else:
|
||||
defaultbrushes = 7
|
||||
|
||||
col.template_ID(settings, "brush", new="brush.add")
|
||||
row.template_list(settings, "brushes", settings, "active_brush_index", rows=2, maxrows=defaultbrushes)
|
||||
|
||||
# Particle Mode #
|
||||
|
||||
@ -546,44 +555,152 @@ class VIEW3D_PT_tools_brush(PaintPanel):
|
||||
# Sculpt Mode #
|
||||
|
||||
elif context.sculpt_object and brush:
|
||||
edit = context.user_preferences.edit
|
||||
|
||||
col = layout.column()
|
||||
|
||||
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "size", slider=True)
|
||||
|
||||
if brush.sculpt_tool != 'GRAB':
|
||||
row.prop(brush, "use_size_pressure", toggle=True, text="")
|
||||
if edit.sculpt_paint_use_unified_size:
|
||||
if edit.sculpt_paint_unified_lock_brush_size:
|
||||
row.prop(edit, "sculpt_paint_unified_lock_brush_size", toggle=True, text="", icon='LOCKED')
|
||||
row.prop(edit, "sculpt_paint_unified_unprojected_radius", text="Unified Radius", slider=True)
|
||||
else:
|
||||
row.prop(edit, "sculpt_paint_unified_lock_brush_size", toggle=True, text="", icon='UNLOCKED')
|
||||
row.prop(edit, "sculpt_paint_unified_size", text="Unified Radius", slider=True)
|
||||
|
||||
else:
|
||||
if brush.lock_brush_size:
|
||||
row.prop(brush, "lock_brush_size", toggle=True, text="", icon='LOCKED')
|
||||
row.prop(brush, "unprojected_radius", text="Radius", slider=True)
|
||||
else:
|
||||
row.prop(brush, "lock_brush_size", toggle=True, text="", icon='UNLOCKED')
|
||||
row.prop(brush, "size", text="Radius", slider=True)
|
||||
|
||||
row.prop(brush, "use_size_pressure", toggle=True, text="")
|
||||
|
||||
|
||||
if brush.sculpt_tool not in ('SNAKE_HOOK', 'GRAB', 'ROTATE'):
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "strength", slider=True)
|
||||
|
||||
if brush.use_space and brush.sculpt_tool not in ('SMOOTH'):
|
||||
if brush.use_space_atten:
|
||||
row.prop(brush, "use_space_atten", toggle=True, text="", icon='LOCKED')
|
||||
else:
|
||||
row.prop(brush, "use_space_atten", toggle=True, text="", icon='UNLOCKED')
|
||||
|
||||
if edit.sculpt_paint_use_unified_strength:
|
||||
row.prop(edit, "sculpt_paint_unified_strength", text="Unified Strength", slider=True)
|
||||
else:
|
||||
row.prop(brush, "strength", text="Strength", slider=True)
|
||||
|
||||
row.prop(brush, "use_strength_pressure", text="")
|
||||
|
||||
# XXX - TODO
|
||||
#row = col.row(align=True)
|
||||
#row.prop(brush, "jitter", slider=True)
|
||||
#row.prop(brush, "use_jitter_pressure", toggle=True, text="")
|
||||
|
||||
col = layout.column()
|
||||
|
||||
if brush.sculpt_tool in ('DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'):
|
||||
col.row().prop(brush, "direction", expand=True)
|
||||
if brush.sculpt_tool not in ('SMOOTH'):
|
||||
col.separator()
|
||||
|
||||
if brush.sculpt_tool in ('DRAW', 'INFLATE', 'LAYER'):
|
||||
col.prop(brush, "use_accumulate")
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "autosmooth_factor", slider=True)
|
||||
row.prop(brush, "use_inverse_smooth_pressure", toggle=True, text="")
|
||||
|
||||
if brush.sculpt_tool == 'LAYER':
|
||||
ob = context.sculpt_object
|
||||
do_persistent = True
|
||||
|
||||
# not supported yet for this case
|
||||
for md in ob.modifiers:
|
||||
if md.type == 'MULTIRES':
|
||||
do_persistent = False
|
||||
|
||||
if do_persistent:
|
||||
col.prop(brush, "use_persistent")
|
||||
col.operator("sculpt.set_persistent_base")
|
||||
if brush.sculpt_tool in ('GRAB', 'SNAKE_HOOK'):
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "normal_weight", slider=True)
|
||||
|
||||
|
||||
|
||||
if brush.sculpt_tool in ('CREASE', 'BLOB'):
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "crease_pinch_factor", slider=True, text="Pinch")
|
||||
|
||||
if brush.sculpt_tool not in ('PINCH', 'INFLATE', 'SMOOTH'):
|
||||
row = col.row(align=True)
|
||||
|
||||
col.separator()
|
||||
|
||||
if brush.use_original_normal:
|
||||
row.prop(brush, "use_original_normal", toggle=True, text="", icon='LOCKED')
|
||||
else:
|
||||
row.prop(brush, "use_original_normal", toggle=True, text="", icon='UNLOCKED')
|
||||
|
||||
row.prop(brush, "sculpt_plane", text="")
|
||||
|
||||
#if brush.sculpt_tool in ('CLAY', 'CLAY_TUBES', 'FLATTEN', 'FILL', 'SCRAPE'):
|
||||
if brush.sculpt_tool in ('CLAY', 'FLATTEN', 'FILL', 'SCRAPE'):
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "plane_offset", slider=True)
|
||||
row.prop(brush, "use_offset_pressure", text="")
|
||||
|
||||
col.separator()
|
||||
|
||||
row= col.row()
|
||||
row.prop(brush, "use_plane_trim", text="Trim")
|
||||
row= col.row()
|
||||
row.active=brush.use_plane_trim
|
||||
row.prop(brush, "plane_trim", slider=True, text="Distance")
|
||||
|
||||
col.separator()
|
||||
|
||||
row= col.row()
|
||||
row.prop(brush, "use_frontface", text="Front Faces Only")
|
||||
|
||||
#if brush.sculpt_tool in ('DRAW', 'CREASE', 'BLOB', 'LAYER', 'CLAY', 'CLAY_TUBES'):
|
||||
if brush.sculpt_tool in ('DRAW', 'CREASE', 'BLOB', 'LAYER', 'CLAY'):
|
||||
col.separator()
|
||||
col.row().prop(brush, "direction", expand=True)
|
||||
elif brush.sculpt_tool in ('FLATTEN'):
|
||||
col.separator()
|
||||
col.row().prop(brush, "flatten_contrast", expand=True)
|
||||
elif brush.sculpt_tool in ('FILL'):
|
||||
col.separator()
|
||||
col.row().prop(brush, "fill_deepen", expand=True)
|
||||
elif brush.sculpt_tool in ('SCRAPE'):
|
||||
col.separator()
|
||||
col.row().prop(brush, "scrape_peaks", expand=True)
|
||||
elif brush.sculpt_tool in ('INFLATE'):
|
||||
col.separator()
|
||||
col.row().prop(brush, "inflate_deflate", expand=True)
|
||||
elif brush.sculpt_tool in ('PINCH'):
|
||||
col.separator()
|
||||
col.row().prop(brush, "pinch_magnify", expand=True)
|
||||
|
||||
|
||||
|
||||
#if brush.sculpt_tool in ('DRAW', 'CREASE', 'BLOB', 'INFLATE', 'LAYER', 'CLAY', 'CLAY_TUBES'):
|
||||
if brush.sculpt_tool in ('DRAW', 'CREASE', 'BLOB', 'INFLATE', 'LAYER', 'CLAY'):
|
||||
col.separator()
|
||||
|
||||
col.prop(brush, "use_accumulate")
|
||||
|
||||
|
||||
|
||||
if brush.sculpt_tool == 'LAYER':
|
||||
col.separator()
|
||||
|
||||
ob = context.sculpt_object
|
||||
do_persistent = True
|
||||
|
||||
# not supported yet for this case
|
||||
for md in ob.modifiers:
|
||||
if md.type == 'MULTIRES':
|
||||
do_persistent = False
|
||||
|
||||
if do_persistent:
|
||||
col.prop(brush, "use_persistent")
|
||||
col.operator("sculpt.set_persistent_base")
|
||||
|
||||
# Texture Paint Mode #
|
||||
|
||||
@ -669,10 +786,88 @@ class VIEW3D_PT_tools_brush_texture(PaintPanel):
|
||||
|
||||
col = layout.column()
|
||||
|
||||
col.template_ID_preview(brush, "texture", new="texture.new", rows=2, cols=4)
|
||||
col.template_ID_preview(brush, "texture", new="texture.new", rows=3, cols=8)
|
||||
|
||||
if context.sculpt_object:
|
||||
col.row().prop(tex_slot, "map_mode", expand=True)
|
||||
#XXX duplicated from properties_texture.py
|
||||
|
||||
wide_ui = context.region.width > narrowui
|
||||
|
||||
|
||||
col.separator()
|
||||
|
||||
|
||||
col.label(text="Brush Mapping:")
|
||||
row = col.row(align=True)
|
||||
row.prop(tex_slot, "map_mode", expand=True)
|
||||
|
||||
col.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.active = tex_slot.map_mode in ('FIXED')
|
||||
col.label(text="Angle:")
|
||||
|
||||
col = layout.column()
|
||||
if not brush.use_anchor and brush.sculpt_tool not in ('GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE') and tex_slot.map_mode in ('FIXED'):
|
||||
col.prop(brush, "texture_angle_source", text="")
|
||||
else:
|
||||
col.prop(brush, "texture_angle_source_no_random", text="")
|
||||
|
||||
#row = col.row(align=True)
|
||||
#row.label(text="Angle:")
|
||||
#row.active = tex_slot.map_mode in ('FIXED', 'TILED')
|
||||
|
||||
#row = col.row(align=True)
|
||||
|
||||
#col = row.column()
|
||||
#col.active = tex_slot.map_mode in ('FIXED')
|
||||
#col.prop(brush, "use_rake", toggle=True, icon='PARTICLEMODE', text="")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(tex_slot, "angle", text="")
|
||||
col.active = tex_slot.map_mode in ('FIXED', 'TILED')
|
||||
|
||||
#col = layout.column()
|
||||
#col.prop(brush, "use_random_rotation")
|
||||
#col.active = (not brush.use_rake) and (not brush.use_anchor) and brush.sculpt_tool not in ('GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE') and tex_slot.map_mode in ('FIXED')
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop(tex_slot, "offset")
|
||||
|
||||
if wide_ui:
|
||||
col = split.column()
|
||||
else:
|
||||
col.separator()
|
||||
|
||||
col.prop(tex_slot, "size")
|
||||
|
||||
col = layout.column()
|
||||
|
||||
row = col.row(align=True)
|
||||
row.label(text="Sample Bias:")
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "texture_sample_bias", slider=True, text="")
|
||||
|
||||
row = col.row(align=True)
|
||||
row.label(text="Overlay:")
|
||||
row.active = tex_slot.map_mode in ('FIXED', 'TILED')
|
||||
|
||||
row = col.row(align=True)
|
||||
|
||||
col = row.column()
|
||||
|
||||
if brush.use_texture_overlay:
|
||||
col.prop(brush, "use_texture_overlay", toggle=True, text="", icon='MUTE_IPO_OFF')
|
||||
else:
|
||||
col.prop(brush, "use_texture_overlay", toggle=True, text="", icon='MUTE_IPO_ON')
|
||||
|
||||
col.active = tex_slot.map_mode in ('FIXED', 'TILED')
|
||||
|
||||
col = row.column()
|
||||
col.prop(brush, "texture_overlay_alpha", text="Alpha")
|
||||
col.active = tex_slot.map_mode in ('FIXED', 'TILED') and brush.use_texture_overlay
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_brush_tool(PaintPanel):
|
||||
@ -696,15 +891,11 @@ class VIEW3D_PT_tools_brush_tool(PaintPanel):
|
||||
col = layout.column(align=True)
|
||||
|
||||
if context.sculpt_object:
|
||||
col.prop(brush, "sculpt_tool", expand=True)
|
||||
col.prop(brush, "sculpt_tool", expand=False, text="")
|
||||
elif context.texture_paint_object:
|
||||
col.prop(brush, "imagepaint_tool", expand=True)
|
||||
#col.prop_enum(settings, "tool", 'DRAW')
|
||||
#col.prop_enum(settings, "tool", 'SOFTEN')
|
||||
#col.prop_enum(settings, "tool", 'CLONE')
|
||||
#col.prop_enum(settings, "tool", 'SMEAR')
|
||||
col.prop(brush, "imagepaint_tool", expand=False, text="")
|
||||
elif context.vertex_paint_object or context.weight_paint_object:
|
||||
col.prop(brush, "vertexpaint_tool", expand=True)
|
||||
col.prop(brush, "vertexpaint_tool", expand=False, text="")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_brush_stroke(PaintPanel):
|
||||
@ -725,29 +916,83 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel):
|
||||
brush = settings.brush
|
||||
texture_paint = context.texture_paint_object
|
||||
|
||||
if context.sculpt_object:
|
||||
if brush.sculpt_tool != 'LAYER':
|
||||
layout.prop(brush, "use_anchor")
|
||||
layout.prop(brush, "use_rake")
|
||||
|
||||
layout.prop(brush, "use_airbrush")
|
||||
col = layout.column()
|
||||
col.active = brush.use_airbrush
|
||||
col.prop(brush, "rate", slider=True)
|
||||
|
||||
if not texture_paint:
|
||||
layout.prop(brush, "use_smooth_stroke")
|
||||
if context.sculpt_object:
|
||||
col.label(text="Stroke Method:")
|
||||
col.prop(brush, "stroke_method", text="")
|
||||
|
||||
if brush.use_anchor:
|
||||
col.separator()
|
||||
row = col.row()
|
||||
row.prop(brush, "edge_to_edge", "Edge To Edge")
|
||||
|
||||
if brush.use_airbrush:
|
||||
col.separator()
|
||||
row = col.row()
|
||||
row.prop(brush, "rate", text="Rate", slider=True)
|
||||
|
||||
if brush.use_space:
|
||||
col.separator()
|
||||
row = col.row()
|
||||
row.active = brush.use_space
|
||||
row.prop(brush, "spacing", text="Spacing")
|
||||
|
||||
if brush.sculpt_tool not in ('GRAB', 'THUMB', 'SNAKE_HOOK', 'ROTATE') and (not brush.use_anchor) and (not brush.restore_mesh):
|
||||
col = layout.column()
|
||||
col.separator()
|
||||
|
||||
col.prop(brush, "use_smooth_stroke")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = brush.use_smooth_stroke
|
||||
sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
row.prop(brush, "use_jitter_pressure", toggle=True, text="")
|
||||
|
||||
else:
|
||||
row = col.row()
|
||||
row.prop(brush, "use_airbrush")
|
||||
|
||||
row = col.row()
|
||||
row.active = brush.use_airbrush and (not brush.use_space) and (not brush.use_anchor)
|
||||
row.prop(brush, "rate", slider=True)
|
||||
|
||||
col.separator()
|
||||
|
||||
if not texture_paint:
|
||||
row = col.row()
|
||||
row.prop(brush, "use_smooth_stroke")
|
||||
|
||||
col = layout.column()
|
||||
col.active = brush.use_smooth_stroke
|
||||
col.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
col.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
|
||||
col.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.active = brush.use_smooth_stroke
|
||||
col.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
col.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
col.active = (not brush.use_anchor) and (brush.sculpt_tool not in ('GRAB', 'THUMB', 'ROTATE', 'SNAKE_HOOK'))
|
||||
|
||||
layout.prop(brush, "use_space")
|
||||
row = layout.row(align=True)
|
||||
row.active = brush.use_space
|
||||
row.prop(brush, "spacing", text="Distance", slider=True)
|
||||
if texture_paint:
|
||||
row.prop(brush, "use_spacing_pressure", toggle=True, text="")
|
||||
row = col.row()
|
||||
row.prop(brush, "use_space")
|
||||
|
||||
row = col.row()
|
||||
row.active = brush.use_space
|
||||
row.prop(brush, "spacing", text="Spacing")
|
||||
|
||||
#col.prop(brush, "use_space_atten", text="Adaptive Strength")
|
||||
#col.prop(brush, "use_adaptive_space", text="Adaptive Spacing")
|
||||
|
||||
#col.separator()
|
||||
|
||||
#if texture_paint:
|
||||
# row.prop(brush, "use_spacing_pressure", toggle=True, text="")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_brush_curve(PaintPanel):
|
||||
@ -767,13 +1012,17 @@ class VIEW3D_PT_tools_brush_curve(PaintPanel):
|
||||
layout.template_curve_mapping(brush, "curve", brush=True)
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.operator("brush.curve_preset", text="Sharp").shape = 'SHARP'
|
||||
row.operator("brush.curve_preset", text="Smooth").shape = 'SMOOTH'
|
||||
row.operator("brush.curve_preset", text="Max").shape = 'MAX'
|
||||
|
||||
row.operator("brush.curve_preset", icon="SMOOTHCURVE", text="").shape = 'SMOOTH'
|
||||
row.operator("brush.curve_preset", icon="SPHERECURVE", text="").shape = 'ROUND'
|
||||
row.operator("brush.curve_preset", icon="ROOTCURVE", text="").shape = 'ROOT'
|
||||
row.operator("brush.curve_preset", icon="SHARPCURVE", text="").shape = 'SHARP'
|
||||
row.operator("brush.curve_preset", icon="LINCURVE", text="").shape = 'LINE'
|
||||
row.operator("brush.curve_preset", icon="NOCURVE", text="").shape = 'MAX'
|
||||
row.operator("brush.curve_preset", icon="RNDCURVE", text="").shape = 'MID9'
|
||||
|
||||
class VIEW3D_PT_sculpt_options(PaintPanel):
|
||||
bl_label = "Options"
|
||||
bl_default_closed = True
|
||||
|
||||
def poll(self, context):
|
||||
return (context.sculpt_object and context.tool_settings.sculpt)
|
||||
@ -781,25 +1030,100 @@ class VIEW3D_PT_sculpt_options(PaintPanel):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
wide_ui = context.region.width > narrowui
|
||||
|
||||
sculpt = context.tool_settings.sculpt
|
||||
settings = self.paint_settings(context)
|
||||
brush = settings.brush
|
||||
|
||||
col = layout.column()
|
||||
col.prop(sculpt, "show_brush")
|
||||
col.prop(sculpt, "fast_navigate")
|
||||
|
||||
split = self.layout.split()
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Symmetry:")
|
||||
|
||||
edit = context.user_preferences.edit
|
||||
col.label(text="Unified Settings:")
|
||||
col.prop(edit, "sculpt_paint_use_unified_size", text="Size")
|
||||
col.prop(edit, "sculpt_paint_use_unified_strength", text="Strength")
|
||||
|
||||
if wide_ui:
|
||||
col = split.column()
|
||||
else:
|
||||
col.separator()
|
||||
|
||||
col.label(text="Lock:")
|
||||
row = col.row(align=True)
|
||||
row.prop(sculpt, "lock_x", text="X", toggle=True)
|
||||
row.prop(sculpt, "lock_y", text="Y", toggle=True)
|
||||
row.prop(sculpt, "lock_z", text="Z", toggle=True)
|
||||
|
||||
class VIEW3D_PT_sculpt_symmetry(PaintPanel):
|
||||
bl_label = "Symmetry"
|
||||
bl_default_closed = True
|
||||
|
||||
def poll(self, context):
|
||||
return (context.sculpt_object and context.tool_settings.sculpt)
|
||||
|
||||
def draw(self, context):
|
||||
wide_ui = context.region.width > narrowui
|
||||
|
||||
layout = self.layout
|
||||
|
||||
sculpt = context.tool_settings.sculpt
|
||||
settings = self.paint_settings(context)
|
||||
brush = settings.brush
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
|
||||
col.label(text="Mirror:")
|
||||
col.prop(sculpt, "symmetry_x", text="X")
|
||||
col.prop(sculpt, "symmetry_y", text="Y")
|
||||
col.prop(sculpt, "symmetry_z", text="Z")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Lock:")
|
||||
col.prop(sculpt, "lock_x", text="X")
|
||||
col.prop(sculpt, "lock_y", text="Y")
|
||||
col.prop(sculpt, "lock_z", text="Z")
|
||||
if wide_ui:
|
||||
col = split.column()
|
||||
else:
|
||||
col.separator()
|
||||
|
||||
col.prop(sculpt, "radial_symm", text="Radial")
|
||||
|
||||
col = layout.column()
|
||||
|
||||
col.separator()
|
||||
|
||||
col.prop(sculpt, "use_symmetry_feather", text="Feather")
|
||||
|
||||
class VIEW3D_PT_tools_brush_appearance(PaintPanel):
|
||||
bl_label = "Appearance"
|
||||
bl_default_closed = True
|
||||
|
||||
def poll(self, context):
|
||||
return (context.sculpt_object and context.tool_settings.sculpt) or (context.vertex_paint_object and context.tool_settings.vertex_paint) or (context.weight_paint_object and context.tool_settings.weight_paint) or (context.texture_paint_object and context.tool_settings.image_paint)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
sculpt = context.tool_settings.sculpt
|
||||
settings = self.paint_settings(context)
|
||||
brush = settings.brush
|
||||
|
||||
col = layout.column();
|
||||
|
||||
if context.sculpt_object and context.tool_settings.sculpt:
|
||||
#if brush.sculpt_tool in ('DRAW', 'INFLATE', 'CLAY', 'CLAY_TUBES', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN'):
|
||||
if brush.sculpt_tool in ('DRAW', 'INFLATE', 'CLAY', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN'):
|
||||
col.prop(brush, "add_col", text="Add Color")
|
||||
col.prop(brush, "sub_col", text="Substract Color")
|
||||
else:
|
||||
col.prop(brush, "add_col", text="Color")
|
||||
|
||||
col.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="Icon:")
|
||||
#col.template_ID_preview(brush, "image_icon", open="image.open", filter="is_image_icon", rows=3, cols=8)
|
||||
col.template_ID_preview(brush, "image_icon", open="image.open", rows=3, cols=8)
|
||||
|
||||
# ********** default tools for weightpaint ****************
|
||||
|
||||
@ -1049,9 +1373,11 @@ classes = [
|
||||
VIEW3D_PT_tools_posemode_options,
|
||||
VIEW3D_PT_tools_brush,
|
||||
VIEW3D_PT_tools_brush_texture,
|
||||
VIEW3D_PT_tools_brush_tool,
|
||||
VIEW3D_PT_tools_brush_stroke,
|
||||
VIEW3D_PT_tools_brush_curve,
|
||||
VIEW3D_PT_tools_brush_appearance,
|
||||
VIEW3D_PT_tools_brush_tool,
|
||||
VIEW3D_PT_sculpt_symmetry,
|
||||
VIEW3D_PT_sculpt_options,
|
||||
VIEW3D_PT_tools_vertexpaint,
|
||||
VIEW3D_PT_tools_weightpaint_options,
|
||||
|
@ -43,7 +43,7 @@ struct bContext;
|
||||
struct ReportList;
|
||||
struct Scene;
|
||||
struct Main;
|
||||
|
||||
|
||||
#define BLENDER_VERSION 252
|
||||
#define BLENDER_SUBVERSION 5
|
||||
|
||||
|
@ -84,5 +84,15 @@ unsigned int *brush_gen_texture_cache(struct Brush *br, int half_side);
|
||||
void brush_radial_control_invoke(struct wmOperator *op, struct Brush *br, float size_weight);
|
||||
int brush_radial_control_exec(struct wmOperator *op, struct Brush *br, float size_weight);
|
||||
|
||||
/* unified strength and size */
|
||||
int sculpt_get_brush_size(struct Brush *brush);
|
||||
void sculpt_set_brush_size(struct Brush *brush, int size);
|
||||
int sculpt_get_lock_brush_size(struct Brush *brush);
|
||||
float sculpt_get_brush_unprojected_radius(struct Brush *brush);
|
||||
void sculpt_set_brush_unprojected_radius(struct Brush *brush, float unprojected_radius);
|
||||
float sculpt_get_brush_alpha(struct Brush *brush);
|
||||
void sculpt_set_brush_alpha(struct Brush *brush, float alpha);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -28,6 +28,8 @@
|
||||
#ifndef BKE_PAINT_H
|
||||
#define BKE_PAINT_H
|
||||
|
||||
#include "DNA_vec_types.h"
|
||||
|
||||
struct Brush;
|
||||
struct MFace;
|
||||
struct MultireModifierData;
|
||||
@ -96,6 +98,8 @@ typedef struct SculptSession {
|
||||
struct GPUDrawObject *drawobject;
|
||||
|
||||
int modifiers_active;
|
||||
|
||||
rcti previous_r;
|
||||
} SculptSession;
|
||||
|
||||
void free_sculptsession(struct Object *ob);
|
||||
|
@ -53,8 +53,7 @@
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_texture.h"
|
||||
|
||||
|
||||
#include "BKE_icons.h"
|
||||
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
@ -70,29 +69,59 @@ Brush *add_brush(const char *name)
|
||||
|
||||
brush= alloc_libblock(&G.main->brush, ID_BR, name);
|
||||
|
||||
brush->rgb[0]= 1.0f;
|
||||
/* BRUSH SCULPT TOOL SETTINGS */
|
||||
brush->sculpt_tool = SCULPT_TOOL_DRAW; /* sculpting defaults to the draw tool for new brushes */
|
||||
brush->size= 35; /* radius of the brush in pixels */
|
||||
brush->alpha= 0.5f; /* brush strength/intensity probably variable should be renamed? */
|
||||
brush->autosmooth_factor= 0.0f;
|
||||
brush->crease_pinch_factor= 0.5f;
|
||||
brush->sculpt_plane = SCULPT_DISP_DIR_VIEW;
|
||||
brush->plane_offset= 0.0f; /* how far above or below the plane that is found by averaging the faces */
|
||||
brush->plane_trim= 0.5f;
|
||||
brush->clone.alpha= 0.5f;
|
||||
brush->normal_weight= 0.0f;
|
||||
|
||||
/* BRUSH PAINT TOOL SETTINGS */
|
||||
brush->rgb[0]= 1.0f; /* default rgb color of the brush when painting - white */
|
||||
brush->rgb[1]= 1.0f;
|
||||
brush->rgb[2]= 1.0f;
|
||||
brush->alpha= 0.2f;
|
||||
brush->size= 25;
|
||||
brush->spacing= 3.5f;
|
||||
brush->smooth_stroke_radius= 75;
|
||||
brush->smooth_stroke_factor= 0.9;
|
||||
brush->rate= 0.1f;
|
||||
brush->jitter= 0.0f;
|
||||
brush->clone.alpha= 0.5;
|
||||
brush->sculpt_tool = SCULPT_TOOL_DRAW;
|
||||
brush->flag |= BRUSH_SPACE;
|
||||
|
||||
brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
|
||||
|
||||
/* BRUSH STROKE SETTINGS */
|
||||
brush->flag |= (BRUSH_SPACE|BRUSH_SPACE_ATTEN);
|
||||
brush->spacing= 10; /* how far each brush dot should be spaced as a percentage of brush diameter */
|
||||
|
||||
brush->smooth_stroke_radius= 75;
|
||||
brush->smooth_stroke_factor= 0.9f;
|
||||
|
||||
brush->rate= 0.1f; /* time delay between dots of paint or sculpting when doing airbrush mode */
|
||||
|
||||
brush->jitter= 0.0f;
|
||||
|
||||
/* BRUSH TEXTURE SETTINGS */
|
||||
default_mtex(&brush->mtex);
|
||||
|
||||
brush->texture_sample_bias= 0; /* value to added to texture samples */
|
||||
|
||||
/* brush appearance */
|
||||
|
||||
brush->image_icon= NULL;
|
||||
|
||||
brush->add_col[0]= 1.00; /* add mode color is light red */
|
||||
brush->add_col[1]= 0.39;
|
||||
brush->add_col[2]= 0.39;
|
||||
|
||||
brush->sub_col[0]= 0.39; /* subtract mode color is light blue */
|
||||
brush->sub_col[1]= 0.39;
|
||||
brush->sub_col[2]= 1.00;
|
||||
|
||||
/* the default alpha falloff curve */
|
||||
brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
|
||||
|
||||
/* enable fake user by default */
|
||||
brush->id.flag |= LIB_FAKEUSER;
|
||||
brush_toggled_fake_user(brush);
|
||||
|
||||
return brush;
|
||||
|
||||
return brush;
|
||||
}
|
||||
|
||||
Brush *copy_brush(Brush *brush)
|
||||
@ -118,7 +147,7 @@ Brush *copy_brush(Brush *brush)
|
||||
void free_brush(Brush *brush)
|
||||
{
|
||||
if(brush->mtex.tex) brush->mtex.tex->id.us--;
|
||||
|
||||
|
||||
curvemapping_free(brush->curve);
|
||||
}
|
||||
|
||||
@ -731,11 +760,19 @@ static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pres
|
||||
brush->spacing = MAX2(1.0, painter->startspacing*(1.5f-pressure));
|
||||
}
|
||||
|
||||
static void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos)
|
||||
void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos)
|
||||
{
|
||||
if(brush->jitter){
|
||||
jitterpos[0] = pos[0] + ((BLI_frand()-0.5f) * brush->size * brush->jitter * 2);
|
||||
jitterpos[1] = pos[1] + ((BLI_frand()-0.5f) * brush->size * brush->jitter * 2);
|
||||
float rand_pos[2];
|
||||
|
||||
// find random position within a circle of diameter 1
|
||||
do {
|
||||
rand_pos[0] = BLI_frand()-0.5f;
|
||||
rand_pos[1] = BLI_frand()-0.5f;
|
||||
} while (len_v2(rand_pos) > 0.5f);
|
||||
|
||||
jitterpos[0] = pos[0] + 2*rand_pos[0]*brush->size*brush->jitter;
|
||||
jitterpos[1] = pos[1] + 2*rand_pos[1]*brush->size*brush->jitter;
|
||||
}
|
||||
else {
|
||||
VECCOPY2D(jitterpos, pos);
|
||||
@ -887,7 +924,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
|
||||
/* Uses the brush curve control to find a strength value between 0 and 1 */
|
||||
float brush_curve_strength_clamp(Brush *br, float p, const float len)
|
||||
{
|
||||
if(p >= len) p= 1.0f;
|
||||
if(p >= len) return 0;
|
||||
else p= p/len;
|
||||
|
||||
p= curvemapping_evaluateF(br->curve, 0, p);
|
||||
@ -899,9 +936,12 @@ float brush_curve_strength_clamp(Brush *br, float p, const float len)
|
||||
* used for sculpt only */
|
||||
float brush_curve_strength(Brush *br, float p, const float len)
|
||||
{
|
||||
if(p >= len) p= 1.0f;
|
||||
else p= p/len;
|
||||
return curvemapping_evaluateF(br->curve, 0, p);
|
||||
if(p >= len)
|
||||
p= 1.0f;
|
||||
else
|
||||
p= p/len;
|
||||
|
||||
return curvemapping_evaluateF(br->curve, 0, p);
|
||||
}
|
||||
|
||||
/* TODO: should probably be unified with BrushPainter stuff? */
|
||||
@ -915,7 +955,7 @@ unsigned int *brush_gen_texture_cache(Brush *br, int half_side)
|
||||
|
||||
memset(&texres, 0, sizeof(TexResult));
|
||||
|
||||
if(mtex && mtex->tex) {
|
||||
if(mtex->tex) {
|
||||
float x, y, step = 2.0 / side, co[3];
|
||||
|
||||
texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
|
||||
@ -993,9 +1033,9 @@ void brush_radial_control_invoke(wmOperator *op, Brush *br, float size_weight)
|
||||
float original_value= 0;
|
||||
|
||||
if(mode == WM_RADIALCONTROL_SIZE)
|
||||
original_value = br->size * size_weight;
|
||||
original_value = sculpt_get_brush_size(br) * size_weight;
|
||||
else if(mode == WM_RADIALCONTROL_STRENGTH)
|
||||
original_value = br->alpha;
|
||||
original_value = sculpt_get_brush_alpha(br);
|
||||
else if(mode == WM_RADIALCONTROL_ANGLE) {
|
||||
MTex *mtex = brush_active_texture(br);
|
||||
if(mtex)
|
||||
@ -1013,9 +1053,15 @@ int brush_radial_control_exec(wmOperator *op, Brush *br, float size_weight)
|
||||
const float conv = 0.017453293;
|
||||
|
||||
if(mode == WM_RADIALCONTROL_SIZE)
|
||||
br->size = new_value * size_weight;
|
||||
if (sculpt_get_lock_brush_size(br)) {
|
||||
float initial_value = RNA_float_get(op->ptr, "initial_value");
|
||||
const float unprojected_radius = sculpt_get_brush_unprojected_radius(br);
|
||||
sculpt_set_brush_unprojected_radius(br, unprojected_radius * new_value/initial_value * size_weight);
|
||||
}
|
||||
else
|
||||
sculpt_set_brush_size(br, new_value * size_weight);
|
||||
else if(mode == WM_RADIALCONTROL_STRENGTH)
|
||||
br->alpha = new_value;
|
||||
sculpt_set_brush_alpha(br, new_value);
|
||||
else if(mode == WM_RADIALCONTROL_ANGLE) {
|
||||
MTex *mtex = brush_active_texture(br);
|
||||
if(mtex)
|
||||
|
@ -126,6 +126,9 @@ CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, floa
|
||||
cumap->cm[a].curve[1].x= maxx;
|
||||
cumap->cm[a].curve[1].y= maxy;
|
||||
}
|
||||
|
||||
cumap->changed_timestamp = 0;
|
||||
|
||||
return cumap;
|
||||
}
|
||||
|
||||
@ -240,10 +243,12 @@ void curvemap_reset(CurveMap *cuma, rctf *clipr, int preset)
|
||||
|
||||
switch(preset) {
|
||||
case CURVE_PRESET_LINE: cuma->totpoint= 2; break;
|
||||
case CURVE_PRESET_SHARP: cuma->totpoint= 3; break;
|
||||
case CURVE_PRESET_SHARP: cuma->totpoint= 4; break;
|
||||
case CURVE_PRESET_SMOOTH: cuma->totpoint= 4; break;
|
||||
case CURVE_PRESET_MAX: cuma->totpoint= 2; break;
|
||||
case CURVE_PRESET_MID9: cuma->totpoint= 9;
|
||||
case CURVE_PRESET_MID9: cuma->totpoint= 9; break;
|
||||
case CURVE_PRESET_ROUND: cuma->totpoint= 4; break;
|
||||
case CURVE_PRESET_ROOT: cuma->totpoint= 4; break;
|
||||
}
|
||||
|
||||
cuma->curve= MEM_callocN(cuma->totpoint*sizeof(CurveMapPoint), "curve points");
|
||||
@ -251,27 +256,29 @@ void curvemap_reset(CurveMap *cuma, rctf *clipr, int preset)
|
||||
switch(preset) {
|
||||
case CURVE_PRESET_LINE:
|
||||
cuma->curve[0].x= clipr->xmin;
|
||||
cuma->curve[0].y= clipr->ymin;
|
||||
cuma->curve[0].y= clipr->ymax;
|
||||
cuma->curve[0].flag= 0;
|
||||
cuma->curve[1].x= clipr->xmax;
|
||||
cuma->curve[1].y= clipr->ymax;
|
||||
cuma->curve[1].y= clipr->ymin;
|
||||
cuma->curve[1].flag= 0;
|
||||
break;
|
||||
case CURVE_PRESET_SHARP:
|
||||
cuma->curve[0].x= 0;
|
||||
cuma->curve[0].y= 1;
|
||||
cuma->curve[1].x= 0.33;
|
||||
cuma->curve[1].y= 0.33;
|
||||
cuma->curve[2].x= 1;
|
||||
cuma->curve[2].y= 0;
|
||||
cuma->curve[1].x= 0.25;
|
||||
cuma->curve[1].y= 0.50;
|
||||
cuma->curve[2].x= 0.75;
|
||||
cuma->curve[2].y= 0.04;
|
||||
cuma->curve[3].x= 1;
|
||||
cuma->curve[3].y= 0;
|
||||
break;
|
||||
case CURVE_PRESET_SMOOTH:
|
||||
cuma->curve[0].x= 0;
|
||||
cuma->curve[0].y= 1;
|
||||
cuma->curve[1].x= 0.25;
|
||||
cuma->curve[1].y= 0.92;
|
||||
cuma->curve[1].y= 0.94;
|
||||
cuma->curve[2].x= 0.75;
|
||||
cuma->curve[2].y= 0.08;
|
||||
cuma->curve[2].y= 0.06;
|
||||
cuma->curve[3].x= 1;
|
||||
cuma->curve[3].y= 0;
|
||||
break;
|
||||
@ -290,8 +297,29 @@ void curvemap_reset(CurveMap *cuma, rctf *clipr, int preset)
|
||||
cuma->curve[i].y= 0.5;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CURVE_PRESET_ROUND:
|
||||
cuma->curve[0].x= 0;
|
||||
cuma->curve[0].y= 1;
|
||||
cuma->curve[1].x= 0.5;
|
||||
cuma->curve[1].y= 0.90;
|
||||
cuma->curve[2].x= 0.86;
|
||||
cuma->curve[2].y= 0.5;
|
||||
cuma->curve[3].x= 1;
|
||||
cuma->curve[3].y= 0;
|
||||
break;
|
||||
case CURVE_PRESET_ROOT:
|
||||
cuma->curve[0].x= 0;
|
||||
cuma->curve[0].y= 1;
|
||||
cuma->curve[1].x= 0.25;
|
||||
cuma->curve[1].y= 0.95;
|
||||
cuma->curve[2].x= 0.75;
|
||||
cuma->curve[2].y= 0.44;
|
||||
cuma->curve[3].x= 1;
|
||||
cuma->curve[3].y= 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(cuma->table) {
|
||||
MEM_freeN(cuma->table);
|
||||
cuma->table= NULL;
|
||||
@ -619,7 +647,9 @@ void curvemapping_changed(CurveMapping *cumap, int rem_doubles)
|
||||
float thresh= 0.01f*(clipr->xmax - clipr->xmin);
|
||||
float dx= 0.0f, dy= 0.0f;
|
||||
int a;
|
||||
|
||||
|
||||
cumap->changed_timestamp++;
|
||||
|
||||
/* clamp with clip */
|
||||
if(cumap->flag & CUMA_DO_CLIP) {
|
||||
for(a=0; a<cuma->totpoint; a++) {
|
||||
@ -701,7 +731,7 @@ float curvemapping_evaluateF(CurveMapping *cumap, int cur, float value)
|
||||
if(cuma->table==NULL) {
|
||||
curvemap_make_table(cuma, &cumap->clipr);
|
||||
if(cuma->table==NULL)
|
||||
return value;
|
||||
return 1.0f-value;
|
||||
}
|
||||
return curvemap_evaluateF(cuma, value);
|
||||
}
|
||||
|
@ -1318,30 +1318,33 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp, int forRender)
|
||||
short dnr;
|
||||
|
||||
/* bevel now in three parts, for proper vertex normals */
|
||||
/* part 1 */
|
||||
dnr= nr= 2+ cu->bevresol;
|
||||
if( (cu->flag & (CU_FRONT|CU_BACK))==0)
|
||||
nr= 3+ 2*cu->bevresol;
|
||||
|
||||
dl= MEM_callocN(sizeof(DispList), "makebevelcurve p1");
|
||||
dl->verts= MEM_mallocN(nr*3*sizeof(float), "makebevelcurve p1");
|
||||
BLI_addtail(disp, dl);
|
||||
dl->type= DL_SEGM;
|
||||
dl->parts= 1;
|
||||
dl->flag= DL_BACK_CURVE;
|
||||
dl->nr= nr;
|
||||
/* part 1, back */
|
||||
|
||||
/* half a circle */
|
||||
fp= dl->verts;
|
||||
dangle= (0.5*M_PI/(dnr-1));
|
||||
angle= -(nr-1)*dangle;
|
||||
|
||||
for(a=0; a<nr; a++) {
|
||||
fp[0]= 0.0;
|
||||
fp[1]= (float)(cos(angle)*(cu->ext2));
|
||||
fp[2]= (float)(sin(angle)*(cu->ext2)) - cu->ext1;
|
||||
angle+= dangle;
|
||||
fp+= 3;
|
||||
if((cu->flag & CU_BACK) || !(cu->flag & CU_FRONT)) {
|
||||
dnr= nr= 2+ cu->bevresol;
|
||||
if( (cu->flag & (CU_FRONT|CU_BACK))==0)
|
||||
nr= 3+ 2*cu->bevresol;
|
||||
|
||||
dl= MEM_callocN(sizeof(DispList), "makebevelcurve p1");
|
||||
dl->verts= MEM_mallocN(nr*3*sizeof(float), "makebevelcurve p1");
|
||||
BLI_addtail(disp, dl);
|
||||
dl->type= DL_SEGM;
|
||||
dl->parts= 1;
|
||||
dl->flag= DL_BACK_CURVE;
|
||||
dl->nr= nr;
|
||||
|
||||
/* half a circle */
|
||||
fp= dl->verts;
|
||||
dangle= (0.5*M_PI/(dnr-1));
|
||||
angle= -(nr-1)*dangle;
|
||||
|
||||
for(a=0; a<nr; a++) {
|
||||
fp[0]= 0.0;
|
||||
fp[1]= (float)(cos(angle)*(cu->ext2));
|
||||
fp[2]= (float)(sin(angle)*(cu->ext2)) - cu->ext1;
|
||||
angle+= dangle;
|
||||
fp+= 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* part 2, sidefaces */
|
||||
@ -1374,30 +1377,32 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp, int forRender)
|
||||
}
|
||||
}
|
||||
|
||||
/* part 3 */
|
||||
dnr= nr= 2+ cu->bevresol;
|
||||
if( (cu->flag & (CU_FRONT|CU_BACK))==0)
|
||||
nr= 3+ 2*cu->bevresol;
|
||||
|
||||
dl= MEM_callocN(sizeof(DispList), "makebevelcurve p3");
|
||||
dl->verts= MEM_mallocN(nr*3*sizeof(float), "makebevelcurve p3");
|
||||
BLI_addtail(disp, dl);
|
||||
dl->type= DL_SEGM;
|
||||
dl->flag= DL_FRONT_CURVE;
|
||||
dl->parts= 1;
|
||||
dl->nr= nr;
|
||||
|
||||
/* half a circle */
|
||||
fp= dl->verts;
|
||||
angle= 0.0;
|
||||
dangle= (0.5*M_PI/(dnr-1));
|
||||
|
||||
for(a=0; a<nr; a++) {
|
||||
fp[0]= 0.0;
|
||||
fp[1]= (float)(cos(angle)*(cu->ext2));
|
||||
fp[2]= (float)(sin(angle)*(cu->ext2)) + cu->ext1;
|
||||
angle+= dangle;
|
||||
fp+= 3;
|
||||
/* part 3, front */
|
||||
if((cu->flag & CU_FRONT) || !(cu->flag & CU_BACK)) {
|
||||
dnr= nr= 2+ cu->bevresol;
|
||||
if( (cu->flag & (CU_FRONT|CU_BACK))==0)
|
||||
nr= 3+ 2*cu->bevresol;
|
||||
|
||||
dl= MEM_callocN(sizeof(DispList), "makebevelcurve p3");
|
||||
dl->verts= MEM_mallocN(nr*3*sizeof(float), "makebevelcurve p3");
|
||||
BLI_addtail(disp, dl);
|
||||
dl->type= DL_SEGM;
|
||||
dl->flag= DL_FRONT_CURVE;
|
||||
dl->parts= 1;
|
||||
dl->nr= nr;
|
||||
|
||||
/* half a circle */
|
||||
fp= dl->verts;
|
||||
angle= 0.0;
|
||||
dangle= (0.5*M_PI/(dnr-1));
|
||||
|
||||
for(a=0; a<nr; a++) {
|
||||
fp[0]= 0.0;
|
||||
fp[1]= (float)(cos(angle)*(cu->ext2));
|
||||
fp[2]= (float)(sin(angle)*(cu->ext2)) + cu->ext1;
|
||||
angle+= dangle;
|
||||
fp+= 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3073,7 +3078,7 @@ int clamp_nurb_order_u( struct Nurb *nu )
|
||||
nu->orderu= nu->pntsu;
|
||||
change= 1;
|
||||
}
|
||||
if(((nu->flag & CU_NURB_CYCLIC)==0) && (nu->flagu & CU_NURB_BEZIER)) {
|
||||
if(((nu->flagu & CU_NURB_CYCLIC)==0) && (nu->flagu & CU_NURB_BEZIER)) {
|
||||
CLAMP(nu->orderu, 3,4);
|
||||
change= 1;
|
||||
}
|
||||
@ -3087,7 +3092,7 @@ int clamp_nurb_order_v( struct Nurb *nu)
|
||||
nu->orderv= nu->pntsv;
|
||||
change= 1;
|
||||
}
|
||||
if(((nu->flag & CU_NURB_CYCLIC)==0) && (nu->flagv & CU_NURB_BEZIER)) {
|
||||
if(((nu->flagv & CU_NURB_CYCLIC)==0) && (nu->flagv & CU_NURB_BEZIER)) {
|
||||
CLAMP(nu->orderv, 3,4);
|
||||
change= 1;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
#include "DNA_world_types.h"
|
||||
#include "DNA_brush_types.h"
|
||||
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
@ -120,6 +121,7 @@ struct PreviewImage* BKE_previewimg_create()
|
||||
|
||||
for (i=0; i<PREVIEW_MIPMAPS; ++i) {
|
||||
prv_img->changed[i] = 1;
|
||||
prv_img->changed_timestamp[i] = 0;
|
||||
}
|
||||
return prv_img;
|
||||
}
|
||||
@ -202,7 +204,7 @@ PreviewImage* BKE_previewimg_get(ID *id)
|
||||
Image *img = (Image*)id;
|
||||
if (!img->preview) img->preview = BKE_previewimg_create();
|
||||
prv_img = img->preview;
|
||||
}
|
||||
}
|
||||
|
||||
return prv_img;
|
||||
}
|
||||
@ -224,6 +226,7 @@ void BKE_icon_changed(int id)
|
||||
int i;
|
||||
for (i=0; i<PREVIEW_MIPMAPS; ++i) {
|
||||
prv->changed[i] = 1;
|
||||
prv->changed_timestamp[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,9 +200,9 @@ void free_image(Image *ima)
|
||||
}
|
||||
BKE_icon_delete(&ima->id);
|
||||
ima->id.icon_id = 0;
|
||||
if (ima->preview) {
|
||||
BKE_previewimg_free(&ima->preview);
|
||||
}
|
||||
|
||||
BKE_previewimg_free(&ima->preview);
|
||||
|
||||
for(a=0; a<IMA_MAX_RENDER_SLOT; a++) {
|
||||
if(ima->renders[a]) {
|
||||
RE_FreeRenderResult(ima->renders[a]);
|
||||
|
@ -1800,6 +1800,10 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
|
||||
if(seq->flag & SEQ_FLIPX) {
|
||||
IMB_flipx(se->ibuf);
|
||||
}
|
||||
|
||||
if(seq->flag & SEQ_FLIPY) {
|
||||
IMB_flipy(se->ibuf);
|
||||
}
|
||||
|
||||
if(seq->sat != 1.0f) {
|
||||
/* inline for now, could become an imbuf function */
|
||||
@ -2279,6 +2283,13 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
|
||||
addzbuffloatImBuf(se->ibuf);
|
||||
memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
|
||||
}
|
||||
|
||||
/* {
|
||||
ImBuf *imb= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
|
||||
IMB_saveiff(imb, "/tmp/foo.image", IB_rect | IB_metadata);
|
||||
IMB_freeImBuf(imb);
|
||||
} */
|
||||
|
||||
} else if (rres.rect32) {
|
||||
se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
|
||||
memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
|
||||
|
@ -40,39 +40,14 @@ extern "C" {
|
||||
struct ListBase;
|
||||
struct direntry;
|
||||
|
||||
char *BLI_gethome(void);
|
||||
char *BLI_gethome_folder(char *folder_name, int flag);
|
||||
|
||||
/* BLI_gethome_folder flag */
|
||||
#define BLI_GETHOME_LOCAL 1<<1 /* relative location for portable binaries */
|
||||
#define BLI_GETHOME_SYSTEM 1<<2 /* system location, or set from the BLENDERPATH env variable (UNIX only) */
|
||||
#define BLI_GETHOME_USER 1<<3 /* home folder ~/.blender */
|
||||
#define BLI_GETHOME_ALL (BLI_GETHOME_SYSTEM|BLI_GETHOME_LOCAL|BLI_GETHOME_USER)
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
typedef enum {
|
||||
BasePath_Temporary = 1,
|
||||
BasePath_BlenderShared,
|
||||
BasePath_BlenderUser,
|
||||
BasePath_ApplicationBundle
|
||||
} basePathesTypes;
|
||||
|
||||
/**
|
||||
* Gets the base path. The path may not exist.
|
||||
* Note that return string must be copied as its persistence is not guaranteed
|
||||
*
|
||||
* @return base path of pathType
|
||||
*/
|
||||
const char* BLI_osx_getBasePath(basePathesTypes pathType);
|
||||
#endif
|
||||
char *BLI_getDefaultDocumentFolder(void);
|
||||
|
||||
char *BLI_get_folder(int folder_id, char *subfolder);
|
||||
char *BLI_get_folder_create(int folder_id, char *subfolder);
|
||||
|
||||
/* folder_id */
|
||||
|
||||
/* general, will find baserd on user/local/system priority */
|
||||
/* general, will find based on user/local/system priority */
|
||||
#define BLENDER_CONFIG 1
|
||||
#define BLENDER_DATAFILES 2
|
||||
#define BLENDER_SCRIPTS 3
|
||||
@ -84,6 +59,7 @@ char *BLI_get_folder_create(int folder_id, char *subfolder);
|
||||
#define BLENDER_USER_DATAFILES 32
|
||||
#define BLENDER_USER_SCRIPTS 33
|
||||
#define BLENDER_USER_PLUGINS 34
|
||||
#define BLENDER_USER_AUTOSAVE 35
|
||||
|
||||
/* system */
|
||||
#define BLENDER_SYSTEM_CONFIG 51 /* optional */
|
||||
|
@ -36,12 +36,17 @@ struct ListBase;
|
||||
typedef struct PBVH PBVH;
|
||||
typedef struct PBVHNode PBVHNode;
|
||||
|
||||
typedef struct {
|
||||
float (*co)[3];
|
||||
} PBVHProxyNode;
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
/* returns 1 if the search should continue from this node, 0 otherwise */
|
||||
typedef int (*BLI_pbvh_SearchCallback)(PBVHNode *node, void *data);
|
||||
|
||||
typedef void (*BLI_pbvh_HitCallback)(PBVHNode *node, void *data);
|
||||
typedef void (*BLI_pbvh_HitOccludedCallback)(PBVHNode *node, void *data, float* tmin);
|
||||
|
||||
/* Building */
|
||||
|
||||
@ -70,7 +75,7 @@ void BLI_pbvh_search_gather(PBVH *bvh,
|
||||
it's up to the callback to find the primitive within the leaves that is
|
||||
hit first */
|
||||
|
||||
void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitCallback cb, void *data,
|
||||
void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
|
||||
float ray_start[3], float ray_normal[3], int original);
|
||||
int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
|
||||
float ray_start[3], float ray_normal[3], float *dist);
|
||||
@ -106,6 +111,8 @@ void BLI_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node,
|
||||
void BLI_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3]);
|
||||
void BLI_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max[3]);
|
||||
|
||||
float BLI_pbvh_node_get_tmin(PBVHNode* node);
|
||||
|
||||
/* Update Normals/Bounding Box/Draw Buffers/Redraw and clear flags */
|
||||
|
||||
void BLI_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]);
|
||||
@ -159,13 +166,21 @@ typedef struct PBVHVertexIter {
|
||||
float *fno;
|
||||
} PBVHVertexIter;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable:4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
#define BLI_pbvh_vertex_iter_begin(bvh, node, vi, mode) \
|
||||
{ \
|
||||
struct DMGridData **grids; \
|
||||
struct MVert *verts; \
|
||||
int *grid_indices, totgrid, gridsize, *vert_indices, uniq_verts, totvert; \
|
||||
\
|
||||
memset(&vi, 0, sizeof(PBVHVertexIter)); \
|
||||
vi.grid= 0; \
|
||||
vi.no= 0; \
|
||||
vi.fno= 0; \
|
||||
vi.mvert= 0; \
|
||||
vi.skip= 0; \
|
||||
\
|
||||
BLI_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids, NULL); \
|
||||
BLI_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert); \
|
||||
@ -222,6 +237,13 @@ typedef struct PBVHVertexIter {
|
||||
} \
|
||||
}
|
||||
|
||||
void BLI_pbvh_node_get_proxies(PBVHNode* node, PBVHProxyNode** proxies, int* proxy_count);
|
||||
void BLI_pbvh_node_free_proxies(PBVHNode* node);
|
||||
PBVHProxyNode* BLI_pbvh_node_add_proxy(PBVH* bvh, PBVHNode* node);
|
||||
void BLI_pbvh_gather_proxies(PBVH* pbvh, PBVHNode*** nodes, int* totnode);
|
||||
|
||||
//void BLI_pbvh_node_BB_reset(PBVHNode* node);
|
||||
//void BLI_pbvh_node_BB_expand(PBVHNode* node, float co[3]);
|
||||
|
||||
#endif /* BLI_PBVH_H */
|
||||
|
||||
|
@ -74,10 +74,10 @@ extern "C" {
|
||||
#define MAXPATHLEN MAX_PATH
|
||||
|
||||
#ifndef S_ISREG
|
||||
#define S_ISREG(x) ((x&S_IFMT) == S_IFREG)
|
||||
#define S_ISREG(x) (((x)&_S_IFREG) == _S_IFREG)
|
||||
#endif
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(x) ((x&S_IFMT) == S_IFDIR)
|
||||
#define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
|
||||
#endif
|
||||
|
||||
/* defines for using ISO C++ conformant names */
|
||||
|
@ -205,6 +205,10 @@ int BLI_touch(const char *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BLI_exists(char *file) {
|
||||
return BLI_exist(file);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
static char str[MAXPATHLEN+12];
|
||||
@ -282,10 +286,6 @@ int BLI_link(char *file, char *to) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BLI_exists(char *file) {
|
||||
return (GetFileAttributes(file) != 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void BLI_recurdir_fileops(char *dirname) {
|
||||
char *lslash;
|
||||
char tmp[MAXPATHLEN];
|
||||
@ -326,10 +326,10 @@ int BLI_rename(char *from, char *to) {
|
||||
return rename(from, to);
|
||||
}
|
||||
|
||||
#else /* The sane UNIX world */
|
||||
#else /* The weirdo UNIX world */
|
||||
|
||||
/*
|
||||
* but the sane UNIX world is tied to the interface, and the system
|
||||
* but the UNIX world is tied to the interface, and the system
|
||||
* timer, and... We implement a callback mechanism. The system will
|
||||
* have to initialise the callback before the functions will work!
|
||||
* */
|
||||
@ -374,10 +374,6 @@ int BLI_link(char *file, char *to) {
|
||||
return system(str);
|
||||
}
|
||||
|
||||
int BLI_exists(char *file) {
|
||||
return BLI_exist(file);
|
||||
}
|
||||
|
||||
void BLI_recurdir_fileops(char *dirname) {
|
||||
char *lslash;
|
||||
char tmp[MAXPATHLEN];
|
||||
|
@ -62,6 +62,7 @@ float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const floa
|
||||
n[0]= n1[1]*n2[2]-n1[2]*n2[1];
|
||||
n[1]= n1[2]*n2[0]-n1[0]*n2[2];
|
||||
n[2]= n1[0]*n2[1]-n1[1]*n2[0];
|
||||
|
||||
return normalize_v3(n);
|
||||
}
|
||||
|
||||
@ -401,16 +402,17 @@ int isect_line_tri_v3(float p1[3], float p2[3], float v0[3], float v1[3], float
|
||||
|
||||
sub_v3_v3v3(s, p1, v0);
|
||||
|
||||
cross_v3_v3v3(q, s, e1);
|
||||
*lambda = f * dot_v3v3(e2, q);
|
||||
if ((*lambda < 0.0)||(*lambda > 1.0)) return 0;
|
||||
|
||||
u = f * dot_v3v3(s, p);
|
||||
if ((u < 0.0)||(u > 1.0)) return 0;
|
||||
|
||||
v = f * dot_v3v3(d, q);
|
||||
cross_v3_v3v3(q, s, e1);
|
||||
|
||||
v = f * dot_v3v3(d, q);
|
||||
if ((v < 0.0)||((u + v) > 1.0)) return 0;
|
||||
|
||||
*lambda = f * dot_v3v3(e2, q);
|
||||
if ((*lambda < 0.0)||(*lambda > 1.0)) return 0;
|
||||
|
||||
if(uv) {
|
||||
uv[0]= u;
|
||||
uv[1]= v;
|
||||
@ -440,17 +442,18 @@ int isect_ray_tri_v3(float p1[3], float d[3], float v0[3], float v1[3], float v2
|
||||
|
||||
sub_v3_v3v3(s, p1, v0);
|
||||
|
||||
cross_v3_v3v3(q, s, e1);
|
||||
*lambda = f * dot_v3v3(e2, q);
|
||||
if ((*lambda < 0.0)) return 0;
|
||||
|
||||
u = f * dot_v3v3(s, p);
|
||||
if ((u < 0.0)||(u > 1.0)) return 0;
|
||||
|
||||
cross_v3_v3v3(q, s, e1);
|
||||
|
||||
v = f * dot_v3v3(d, q);
|
||||
if ((v < 0.0)||((u + v) > 1.0)) return 0;
|
||||
|
||||
if(uv) {
|
||||
*lambda = f * dot_v3v3(e2, q);
|
||||
if ((*lambda < 0.0)) return 0;
|
||||
|
||||
if(uv) {
|
||||
uv[0]= u;
|
||||
uv[1]= v;
|
||||
}
|
||||
@ -460,36 +463,36 @@ int isect_ray_tri_v3(float p1[3], float d[3], float v0[3], float v1[3], float v2
|
||||
|
||||
int isect_ray_tri_epsilon_v3(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv, float epsilon)
|
||||
{
|
||||
float p[3], s[3], e1[3], e2[3], q[3];
|
||||
float a, f, u, v;
|
||||
|
||||
sub_v3_v3v3(e1, v1, v0);
|
||||
sub_v3_v3v3(e2, v2, v0);
|
||||
|
||||
cross_v3_v3v3(p, d, e2);
|
||||
a = dot_v3v3(e1, p);
|
||||
if (a == 0.0f) return 0;
|
||||
f = 1.0f/a;
|
||||
|
||||
sub_v3_v3v3(s, p1, v0);
|
||||
|
||||
cross_v3_v3v3(q, s, e1);
|
||||
float p[3], s[3], e1[3], e2[3], q[3];
|
||||
float a, f, u, v;
|
||||
|
||||
u = f * dot_v3v3(s, p);
|
||||
if ((u < -epsilon)||(u > 1.0f+epsilon)) return 0;
|
||||
|
||||
v = f * dot_v3v3(d, q);
|
||||
if ((v < -epsilon)||((u + v) > 1.0f+epsilon)) return 0;
|
||||
sub_v3_v3v3(e1, v1, v0);
|
||||
sub_v3_v3v3(e2, v2, v0);
|
||||
|
||||
*lambda = f * dot_v3v3(e2, q);
|
||||
if ((*lambda < 0.0f)) return 0;
|
||||
cross_v3_v3v3(p, d, e2);
|
||||
a = dot_v3v3(e1, p);
|
||||
if (a == 0.0f) return 0;
|
||||
f = 1.0f/a;
|
||||
|
||||
if(uv) {
|
||||
uv[0]= u;
|
||||
uv[1]= v;
|
||||
}
|
||||
|
||||
return 1;
|
||||
sub_v3_v3v3(s, p1, v0);
|
||||
|
||||
u = f * dot_v3v3(s, p);
|
||||
if ((u < -epsilon)||(u > 1.0f+epsilon)) return 0;
|
||||
|
||||
cross_v3_v3v3(q, s, e1);
|
||||
|
||||
v = f * dot_v3v3(d, q);
|
||||
if ((v < -epsilon)||((u + v) > 1.0f+epsilon)) return 0;
|
||||
|
||||
*lambda = f * dot_v3v3(e2, q);
|
||||
if ((*lambda < 0.0f)) return 0;
|
||||
|
||||
if(uv) {
|
||||
uv[0]= u;
|
||||
uv[1]= v;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int isect_ray_tri_threshold_v3(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv, float threshold)
|
||||
|
@ -364,7 +364,7 @@ void BLI_path_rel(char *file, const char *relfile)
|
||||
if (strlen(relfile) > 2 && relfile[1] != ':') {
|
||||
char* ptemp;
|
||||
/* fix missing volume name in relative base,
|
||||
can happen with old .Blog files */
|
||||
can happen with old recent-files.txt files */
|
||||
get_default_root(temp);
|
||||
ptemp = &temp[2];
|
||||
if (relfile[0] != '\\' && relfile[0] != '/') {
|
||||
@ -732,184 +732,41 @@ void BLI_getlastdir(const char* dir, char *last, int maxlen)
|
||||
}
|
||||
}
|
||||
|
||||
char *BLI_gethome(void) {
|
||||
/* This is now only used to really get the user's default document folder */
|
||||
/* On Windows I chose the 'Users/<MyUserName>/Documents' since it's used
|
||||
as default location to save documents */
|
||||
char *BLI_getDefaultDocumentFolder(void) {
|
||||
#if !defined(WIN32)
|
||||
return getenv("HOME");
|
||||
|
||||
#else /* Windows */
|
||||
char * ret;
|
||||
static char dir[512];
|
||||
static char appdatapath[MAXPATHLEN];
|
||||
static char documentfolder[MAXPATHLEN];
|
||||
HRESULT hResult;
|
||||
|
||||
/* Check for %HOME% env var */
|
||||
|
||||
ret = getenv("HOME");
|
||||
if(ret) {
|
||||
sprintf(dir, "%s\\%s", ret, blender_version_decimal());
|
||||
if (BLI_is_dir(dir)) return dir;
|
||||
if (BLI_is_dir(ret)) return ret;
|
||||
}
|
||||
|
||||
/* else, check install dir (path containing blender.exe) */
|
||||
|
||||
if(BLI_getInstallationDir(dir))
|
||||
{
|
||||
sprintf(dir, "%s", dir, blender_version_decimal());
|
||||
if (BLI_is_dir(dir)) return(dir);
|
||||
}
|
||||
|
||||
|
||||
/* add user profile support for WIN 2K / NT.
|
||||
* This is %APPDATA%, which translates to either
|
||||
* %USERPROFILE%\Application Data or since Vista
|
||||
* to %USERPROFILE%\AppData\Roaming
|
||||
*/
|
||||
hResult = SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdatapath);
|
||||
hResult = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documentfolder);
|
||||
|
||||
if (hResult == S_OK)
|
||||
{
|
||||
if (BLI_is_dir(appdatapath)) { /* from fop, also below... */
|
||||
sprintf(dir, "%s\\Blender Foundation\\Blender", appdatapath);
|
||||
BLI_recurdir_fileops(dir);
|
||||
if (BLI_is_dir(dir)) {
|
||||
sprintf(dir,"%s\\%s", dir, blender_version_decimal());
|
||||
if(BLI_is_dir(dir)) return(dir);
|
||||
}
|
||||
}
|
||||
hResult = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdatapath);
|
||||
if (hResult == S_OK)
|
||||
{
|
||||
if (BLI_is_dir(appdatapath))
|
||||
{ /* from fop, also below... */
|
||||
sprintf(dir, "%s\\Blender Foundation\\Blender", appdatapath);
|
||||
BLI_recurdir_fileops(dir);
|
||||
if (BLI_is_dir(dir)) {
|
||||
sprintf(dir,"%s\\%s", dir, blender_version_decimal());
|
||||
if(BLI_is_dir(dir)) return(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (BLI_is_dir(documentfolder)) return documentfolder;
|
||||
}
|
||||
|
||||
return "C:\\Temp"; /* sheesh! bad, bad, bad! (aphex) */
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* this function returns the path to a blender folder, if it exists
|
||||
* utility functions for BLI_gethome_folder */
|
||||
|
||||
// #define PATH_DEBUG /* for testing paths that are checked */
|
||||
|
||||
static int test_data_path(char *targetpath, char *path_base, char *path_sep, char *folder_name)
|
||||
{
|
||||
char tmppath[FILE_MAXDIR];
|
||||
|
||||
if(path_sep) BLI_join_dirfile(tmppath, path_base, path_sep);
|
||||
else BLI_strncpy(tmppath, path_base, sizeof(tmppath));
|
||||
|
||||
BLI_make_file_string("/", targetpath, tmppath, folder_name);
|
||||
|
||||
if (BLI_is_dir(targetpath)) {
|
||||
#ifdef PATH_DEBUG
|
||||
printf("\tpath found: %s\n", targetpath);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
#ifdef PATH_DEBUG
|
||||
printf("\tpath missing: %s\n", targetpath);
|
||||
#endif
|
||||
targetpath[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int gethome_path_local(char *targetpath, char *folder_name)
|
||||
{
|
||||
extern char bprogname[]; /* argv[0] from creator.c */
|
||||
char bprogdir[FILE_MAXDIR];
|
||||
char cwd[FILE_MAXDIR];
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
#ifdef PATH_DEBUG
|
||||
printf("gethome_path_local...\n");
|
||||
#endif
|
||||
|
||||
/* try release/folder_name (binary relative) */
|
||||
/* use argv[0] (bprogname) to get the path to the executable */
|
||||
s = BLI_last_slash(bprogname);
|
||||
i = s - bprogname + 1;
|
||||
BLI_strncpy(bprogdir, bprogname, i);
|
||||
|
||||
/* try release/folder_name (BIN relative) */
|
||||
if(test_data_path(targetpath, bprogdir, "release", folder_name))
|
||||
return 1;
|
||||
|
||||
/* try release/folder_name (CWD relative) */
|
||||
if(test_data_path(targetpath, BLI_getwdN(cwd), "release", folder_name))
|
||||
return 1;
|
||||
|
||||
/* try ./.blender/folder_name */
|
||||
if(test_data_path(targetpath, bprogdir, ".blender", folder_name))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gethome_path_user(char *targetpath, char *folder_name)
|
||||
{
|
||||
char *home_path= BLI_gethome();
|
||||
|
||||
#ifdef PATH_DEBUG
|
||||
printf("gethome_path_user...\n");
|
||||
#endif
|
||||
|
||||
/* try $HOME/folder_name */
|
||||
return test_data_path(targetpath, home_path, ".blender", folder_name);
|
||||
}
|
||||
|
||||
static int gethome_path_system(char *targetpath, char *folder_name)
|
||||
{
|
||||
extern char blender_path[]; /* unix prefix eg. /usr/share/blender/2.5 creator.c */
|
||||
|
||||
if(!blender_path[0])
|
||||
return 0;
|
||||
|
||||
#ifdef PATH_DEBUG
|
||||
printf("gethome_path_system...\n");
|
||||
#endif
|
||||
|
||||
/* try $BLENDERPATH/folder_name */
|
||||
return test_data_path(targetpath, blender_path, NULL, folder_name);
|
||||
}
|
||||
|
||||
char *BLI_gethome_folder(char *folder_name, int flag)
|
||||
{
|
||||
static char fulldir[FILE_MAXDIR] = "";
|
||||
|
||||
/* first check if this is a redistributable bundle */
|
||||
if(flag & BLI_GETHOME_LOCAL) {
|
||||
if (gethome_path_local(fulldir, folder_name))
|
||||
return fulldir;
|
||||
}
|
||||
|
||||
/* then check if the OS has blender data files installed in a global location */
|
||||
if(flag & BLI_GETHOME_SYSTEM) {
|
||||
if (gethome_path_system(fulldir, folder_name))
|
||||
return fulldir;
|
||||
}
|
||||
|
||||
/* now check the users home dir for data files */
|
||||
if(flag & BLI_GETHOME_USER) {
|
||||
if (gethome_path_user(fulldir, folder_name))
|
||||
return fulldir;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* NEW stuff, to be cleaned up when fully migrated */
|
||||
/* ************************************************************* */
|
||||
/* ************************************************************* */
|
||||
@ -961,10 +818,11 @@ static int test_env_path(char *path, char *envvar)
|
||||
}
|
||||
}
|
||||
|
||||
static int get_path_local(char *targetpath, char *folder_name)
|
||||
static int get_path_local(char *targetpath, char *folder_name, char *subfolder_name)
|
||||
{
|
||||
extern char bprogname[]; /* argv[0] from creator.c */
|
||||
char bprogdir[FILE_MAX];
|
||||
char relfolder[FILE_MAX];
|
||||
char cwd[FILE_MAX];
|
||||
char *s;
|
||||
int i;
|
||||
@ -973,6 +831,11 @@ static int get_path_local(char *targetpath, char *folder_name)
|
||||
printf("get_path_local...\n");
|
||||
#endif
|
||||
|
||||
if (subfolder_name) {
|
||||
BLI_join_dirfile(relfolder, folder_name, subfolder_name);
|
||||
} else {
|
||||
BLI_strncpy(relfolder, folder_name, FILE_MAX);
|
||||
}
|
||||
|
||||
/* use argv[0] (bprogname) to get the path to the executable */
|
||||
s = BLI_last_slash(bprogname);
|
||||
@ -980,38 +843,44 @@ static int get_path_local(char *targetpath, char *folder_name)
|
||||
BLI_strncpy(bprogdir, bprogname, i);
|
||||
|
||||
/* try EXECUTABLE_DIR/folder_name */
|
||||
if(test_path(targetpath, bprogdir, "", folder_name))
|
||||
if(test_path(targetpath, bprogdir, "", relfolder))
|
||||
return 1;
|
||||
|
||||
/* try CWD/release/folder_name */
|
||||
if(test_path(targetpath, BLI_getwdN(cwd), "release", folder_name))
|
||||
if(test_path(targetpath, BLI_getwdN(cwd), "release", relfolder))
|
||||
return 1;
|
||||
|
||||
/* try EXECUTABLE_DIR/release/folder_name */
|
||||
if(test_path(targetpath, bprogdir, "release", folder_name))
|
||||
if(test_path(targetpath, bprogdir, "release", relfolder))
|
||||
return 1;
|
||||
|
||||
/* try EXECUTABLE_DIR/2.5/folder_name - new default directory for local blender installed files */
|
||||
if(test_path(targetpath, bprogdir, blender_version_decimal(), folder_name))
|
||||
if(test_path(targetpath, bprogdir, blender_version_decimal(), relfolder))
|
||||
return 1;
|
||||
|
||||
/* try ./.blender/folder_name -- DEPRECATED, need to update build systems */
|
||||
if(test_path(targetpath, bprogdir, ".blender", folder_name))
|
||||
if(test_path(targetpath, bprogdir, ".blender", relfolder))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_path_user(char *targetpath, char *folder_name, char *envvar)
|
||||
static int get_path_user(char *targetpath, char *folder_name, char *subfolder_name, char *envvar)
|
||||
{
|
||||
char user_path[FILE_MAX];
|
||||
const char *user_base_path;
|
||||
|
||||
user_path[0] = '\0';
|
||||
|
||||
if (test_env_path(targetpath, envvar))
|
||||
return 1;
|
||||
|
||||
if (test_env_path(user_path, envvar)) {
|
||||
if (subfolder_name) {
|
||||
return test_path(targetpath, user_path, NULL, subfolder_name);
|
||||
} else {
|
||||
BLI_strncpy(targetpath, user_path, FILE_MAX);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
user_base_path = (const char *)GHOST_getUserDir();
|
||||
if (user_base_path) {
|
||||
BLI_snprintf(user_path, FILE_MAX, BLENDER_USER_FORMAT, user_base_path, blender_version_decimal());
|
||||
@ -1024,19 +893,30 @@ static int get_path_user(char *targetpath, char *folder_name, char *envvar)
|
||||
printf("get_path_user: %s\n", user_path);
|
||||
#endif
|
||||
|
||||
/* try $HOME/folder_name */
|
||||
return test_path(targetpath, user_path, NULL, folder_name);
|
||||
if (subfolder_name) {
|
||||
/* try $HOME/folder_name/subfolder_name */
|
||||
return test_path(targetpath, user_path, folder_name, subfolder_name);
|
||||
} else {
|
||||
/* try $HOME/folder_name */
|
||||
return test_path(targetpath, user_path, NULL, folder_name);
|
||||
}
|
||||
}
|
||||
|
||||
static int get_path_system(char *targetpath, char *folder_name, char *envvar)
|
||||
static int get_path_system(char *targetpath, char *folder_name, char *subfolder_name, char *envvar)
|
||||
{
|
||||
char system_path[FILE_MAX];
|
||||
const char *system_base_path;
|
||||
|
||||
system_path[0] = '\0';
|
||||
|
||||
if (test_env_path(targetpath, envvar))
|
||||
return 1;
|
||||
if (test_env_path(system_path, envvar)) {
|
||||
if (subfolder_name) {
|
||||
return test_path(targetpath, system_path, NULL, subfolder_name);
|
||||
} else {
|
||||
BLI_strncpy(targetpath, system_path, FILE_MAX);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
system_base_path = (const char *)GHOST_getSystemDir();
|
||||
if (system_base_path) {
|
||||
@ -1050,8 +930,13 @@ static int get_path_system(char *targetpath, char *folder_name, char *envvar)
|
||||
printf("get_path_system: %s\n", system_path);
|
||||
#endif
|
||||
|
||||
/* try $BLENDERPATH/folder_name */
|
||||
return test_path(targetpath, system_path, NULL, folder_name);
|
||||
if (subfolder_name) {
|
||||
/* try $BLENDERPATH/folder_name/subfolder_name */
|
||||
return test_path(targetpath, system_path, folder_name, subfolder_name);
|
||||
} else {
|
||||
/* try $BLENDERPATH/folder_name */
|
||||
return test_path(targetpath, system_path, NULL, folder_name);
|
||||
}
|
||||
}
|
||||
|
||||
/* get a folder out of the 'folder_id' presets for paths */
|
||||
@ -1059,72 +944,65 @@ static int get_path_system(char *targetpath, char *folder_name, char *envvar)
|
||||
char *BLI_get_folder(int folder_id, char *subfolder)
|
||||
{
|
||||
static char path[FILE_MAX] = "";
|
||||
char search_path[FILE_MAX];
|
||||
|
||||
switch (folder_id) {
|
||||
case BLENDER_DATAFILES: /* general case */
|
||||
BLI_join_dirfile(search_path, "datafiles", subfolder);
|
||||
if (get_path_local(path, search_path)) break;
|
||||
if (get_path_user(path, search_path, "BLENDER_USER_DATAFILES")) break;
|
||||
if (get_path_system(path, search_path, "BLENDER_SYSTEM_DATAFILES")) break;
|
||||
if (get_path_local(path, "datafiles", subfolder)) break;
|
||||
if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES")) break;
|
||||
if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES")) break;
|
||||
return NULL;
|
||||
|
||||
case BLENDER_USER_DATAFILES:
|
||||
BLI_join_dirfile(search_path, "datafiles", subfolder);
|
||||
if (get_path_local(path, search_path)) break;
|
||||
if (get_path_user(path, search_path, "BLENDER_USER_DATAFILES")) break;
|
||||
if (get_path_local(path, "datafiles", subfolder)) break;
|
||||
if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES")) break;
|
||||
return NULL;
|
||||
|
||||
case BLENDER_SYSTEM_DATAFILES:
|
||||
BLI_join_dirfile(search_path, "datafiles", subfolder);
|
||||
if (get_path_system(path, search_path, "BLENDER_SYSTEM_DATAFILES")) break;
|
||||
if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES")) break;
|
||||
return NULL;
|
||||
|
||||
case BLENDER_USER_AUTOSAVE:
|
||||
if (get_path_local(path, "autosave", subfolder)) break;
|
||||
if (get_path_user(path, "autosave", subfolder, "BLENDER_USER_DATAFILES")) break;
|
||||
return NULL;
|
||||
|
||||
case BLENDER_CONFIG: /* general case */
|
||||
BLI_join_dirfile(search_path, "config", subfolder);
|
||||
if (get_path_local(path, search_path)) break;
|
||||
if (get_path_user(path, search_path, "BLENDER_USER_CONFIG")) break;
|
||||
if (get_path_system(path, search_path, "BLENDER_SYSTEM_CONFIG")) break;
|
||||
if (get_path_local(path, "config", subfolder)) break;
|
||||
if (get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG")) break;
|
||||
if (get_path_system(path, "config", subfolder, "BLENDER_SYSTEM_CONFIG")) break;
|
||||
return NULL;
|
||||
|
||||
case BLENDER_USER_CONFIG:
|
||||
BLI_join_dirfile(search_path, "config", subfolder);
|
||||
if (get_path_local(path, search_path)) break;
|
||||
if (get_path_user(path, search_path, "BLENDER_USER_CONFIG")) break;
|
||||
if (get_path_local(path, "config", subfolder)) break;
|
||||
if (get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG")) break;
|
||||
return NULL;
|
||||
|
||||
case BLENDER_SYSTEM_CONFIG:
|
||||
BLI_join_dirfile(search_path, "config", subfolder);
|
||||
if (get_path_system(path, search_path, "BLENDER_SYSTEM_CONFIG")) break;
|
||||
if (get_path_system(path, "config", subfolder, "BLENDER_SYSTEM_CONFIG")) break;
|
||||
return NULL;
|
||||
|
||||
case BLENDER_SCRIPTS: /* general case */
|
||||
BLI_join_dirfile(search_path, "scripts", subfolder);
|
||||
if (get_path_local(path, search_path)) break;
|
||||
if (get_path_user(path, search_path, "BLENDER_USER_SCRIPTS")) break;
|
||||
if (get_path_system(path, search_path, "BLENDER_SYSTEM_SCRIPTS")) break;
|
||||
if (get_path_local(path, "scripts", subfolder)) break;
|
||||
if (get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS")) break;
|
||||
if (get_path_system(path, "scripts", subfolder, "BLENDER_SYSTEM_SCRIPTS")) break;
|
||||
return NULL;
|
||||
|
||||
case BLENDER_USER_SCRIPTS:
|
||||
BLI_join_dirfile(search_path, "scripts", subfolder);
|
||||
if (get_path_local(path, search_path)) break;
|
||||
if (get_path_user(path, search_path, "BLENDER_USER_SCRIPTS")) break;
|
||||
if (get_path_local(path, "scripts", subfolder)) break;
|
||||
if (get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS")) break;
|
||||
return NULL;
|
||||
|
||||
case BLENDER_SYSTEM_SCRIPTS:
|
||||
BLI_join_dirfile(search_path, "scripts", subfolder);
|
||||
if (get_path_system(path, search_path, "BLENDER_SYSTEM_SCRIPTS")) break;
|
||||
if (get_path_system(path, "scripts", subfolder, "BLENDER_SYSTEM_SCRIPTS")) break;
|
||||
return NULL;
|
||||
|
||||
case BLENDER_PYTHON: /* general case */
|
||||
BLI_join_dirfile(search_path, "python", subfolder);
|
||||
if (get_path_local(path, search_path)) break;
|
||||
if (get_path_system(path, search_path, "BLENDER_SYSTEM_PYTHON")) break;
|
||||
if (get_path_local(path, "python", subfolder)) break;
|
||||
if (get_path_system(path, "python", subfolder, "BLENDER_SYSTEM_PYTHON")) break;
|
||||
return NULL;
|
||||
|
||||
case BLENDER_SYSTEM_PYTHON:
|
||||
BLI_join_dirfile(search_path, "python", subfolder);
|
||||
if (get_path_system(path, search_path, "BLENDER_SYSTEM_PYTHON")) break;
|
||||
if (get_path_system(path, "python", subfolder, "BLENDER_SYSTEM_PYTHON")) break;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1134,16 +1012,16 @@ char *BLI_get_folder(int folder_id, char *subfolder)
|
||||
static char *BLI_get_user_folder_notest(int folder_id, char *subfolder)
|
||||
{
|
||||
static char path[FILE_MAX] = "";
|
||||
char search_path[FILE_MAX];
|
||||
|
||||
switch (folder_id) {
|
||||
case BLENDER_USER_DATAFILES:
|
||||
BLI_join_dirfile(search_path, "datafiles", subfolder);
|
||||
get_path_user(path, search_path, "BLENDER_USER_DATAFILES");
|
||||
get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES");
|
||||
break;
|
||||
case BLENDER_USER_CONFIG:
|
||||
BLI_join_dirfile(search_path, "config", subfolder);
|
||||
get_path_user(path, search_path, "BLENDER_USER_CONFIG");
|
||||
get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG");
|
||||
break;
|
||||
case BLENDER_USER_AUTOSAVE:
|
||||
get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE");
|
||||
break;
|
||||
}
|
||||
if ('\0' == path[0]) {
|
||||
@ -1157,7 +1035,7 @@ char *BLI_get_folder_create(int folder_id, char *subfolder)
|
||||
char *path;
|
||||
|
||||
/* only for user folders */
|
||||
if (!ELEM(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG))
|
||||
if (!ELEM3(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_AUTOSAVE))
|
||||
return NULL;
|
||||
|
||||
path = BLI_get_folder(folder_id, subfolder);
|
||||
|
@ -92,6 +92,11 @@ struct PBVHNode {
|
||||
unsigned int uniq_verts, face_verts;
|
||||
|
||||
char flag;
|
||||
|
||||
float tmin; // used for raycasting, is how close bb is to the ray point
|
||||
|
||||
int proxy_count;
|
||||
PBVHProxyNode* proxies;
|
||||
};
|
||||
|
||||
struct PBVH {
|
||||
@ -227,6 +232,17 @@ static void update_node_vb(PBVH *bvh, PBVHNode *node)
|
||||
node->vb= vb;
|
||||
}
|
||||
|
||||
//void BLI_pbvh_node_BB_reset(PBVHNode* node)
|
||||
//{
|
||||
// BB_reset(&node->vb);
|
||||
//}
|
||||
//
|
||||
//void BLI_pbvh_node_BB_expand(PBVHNode* node, float co[3])
|
||||
//{
|
||||
// BB_expand(&node->vb, co);
|
||||
//}
|
||||
|
||||
|
||||
/* Adapted from BLI_kdopbvh.c */
|
||||
/* Returns the index of the first element on the right of the partition */
|
||||
static int partition_indices(int *prim_indices, int lo, int hi, int axis,
|
||||
@ -354,10 +370,10 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
|
||||
if(!G.background) {
|
||||
node->draw_buffers =
|
||||
GPU_build_mesh_buffers(map, bvh->verts, bvh->faces,
|
||||
node->prim_indices,
|
||||
node->totprim, node->vert_indices,
|
||||
node->uniq_verts,
|
||||
node->uniq_verts + node->face_verts);
|
||||
node->prim_indices,
|
||||
node->totprim, node->vert_indices,
|
||||
node->uniq_verts,
|
||||
node->uniq_verts + node->face_verts);
|
||||
}
|
||||
|
||||
node->flag |= PBVH_UpdateDrawBuffers;
|
||||
@ -641,13 +657,12 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter)
|
||||
{
|
||||
PBVHNode *node;
|
||||
int revisiting;
|
||||
void *search_data;
|
||||
|
||||
/* purpose here is to traverse tree, visiting child nodes before their
|
||||
parents, this order is necessary for e.g. computing bounding boxes */
|
||||
|
||||
while(iter->stacksize) {
|
||||
/* pop node */
|
||||
/* pop node */
|
||||
iter->stacksize--;
|
||||
node= iter->stack[iter->stacksize].node;
|
||||
|
||||
@ -662,10 +677,7 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter)
|
||||
if(revisiting)
|
||||
return node;
|
||||
|
||||
/* check search callback */
|
||||
search_data= iter->search_data;
|
||||
|
||||
if(iter->scb && !iter->scb(node, search_data))
|
||||
if(iter->scb && !iter->scb(node, iter->search_data))
|
||||
continue; /* don't traverse, outside of search zone */
|
||||
|
||||
if(node->flag & PBVH_Leaf) {
|
||||
@ -685,6 +697,34 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
|
||||
{
|
||||
PBVHNode *node;
|
||||
|
||||
while(iter->stacksize) {
|
||||
/* pop node */
|
||||
iter->stacksize--;
|
||||
node= iter->stack[iter->stacksize].node;
|
||||
|
||||
/* on a mesh with no faces this can happen
|
||||
* can remove this check if we know meshes have at least 1 face */
|
||||
if(node==NULL) return NULL;
|
||||
|
||||
if(iter->scb && !iter->scb(node, iter->search_data)) continue; /* don't traverse, outside of search zone */
|
||||
|
||||
if(node->flag & PBVH_Leaf) {
|
||||
/* immediately hit leaf node */
|
||||
return node;
|
||||
}
|
||||
else {
|
||||
pbvh_stack_push(iter, iter->bvh->nodes+node->children_offset+1, 0);
|
||||
pbvh_stack_push(iter, iter->bvh->nodes+node->children_offset, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void BLI_pbvh_search_gather(PBVH *bvh,
|
||||
BLI_pbvh_SearchCallback scb, void *search_data,
|
||||
PBVHNode ***r_array, int *r_tot)
|
||||
@ -736,12 +776,105 @@ void BLI_pbvh_search_callback(PBVH *bvh,
|
||||
pbvh_iter_begin(&iter, bvh, scb, search_data);
|
||||
|
||||
while((node=pbvh_iter_next(&iter)))
|
||||
if(node->flag & PBVH_Leaf)
|
||||
if (node->flag & PBVH_Leaf)
|
||||
hcb(node, hit_data);
|
||||
|
||||
pbvh_iter_end(&iter);
|
||||
}
|
||||
|
||||
typedef struct node_tree {
|
||||
PBVHNode* data;
|
||||
|
||||
struct node_tree* left;
|
||||
struct node_tree* right;
|
||||
} node_tree;
|
||||
|
||||
static void node_tree_insert(node_tree* tree, node_tree* new_node)
|
||||
{
|
||||
if (new_node->data->tmin < tree->data->tmin) {
|
||||
if (tree->left) {
|
||||
node_tree_insert(tree->left, new_node);
|
||||
}
|
||||
else {
|
||||
tree->left = new_node;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tree->right) {
|
||||
node_tree_insert(tree->right, new_node);
|
||||
}
|
||||
else {
|
||||
tree->right = new_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void traverse_tree(node_tree* tree, BLI_pbvh_HitOccludedCallback hcb, void* hit_data, float* tmin)
|
||||
{
|
||||
if (tree->left) traverse_tree(tree->left, hcb, hit_data, tmin);
|
||||
|
||||
hcb(tree->data, hit_data, tmin);
|
||||
|
||||
if (tree->right) traverse_tree(tree->right, hcb, hit_data, tmin);
|
||||
}
|
||||
|
||||
static void free_tree(node_tree* tree)
|
||||
{
|
||||
if (tree->left) {
|
||||
free_tree(tree->left);
|
||||
tree->left = 0;
|
||||
}
|
||||
|
||||
if (tree->right) {
|
||||
free_tree(tree->right);
|
||||
tree->right = 0;
|
||||
}
|
||||
|
||||
free(tree);
|
||||
}
|
||||
|
||||
float BLI_pbvh_node_get_tmin(PBVHNode* node)
|
||||
{
|
||||
return node->tmin;
|
||||
}
|
||||
|
||||
void BLI_pbvh_search_callback_occluded(PBVH *bvh,
|
||||
BLI_pbvh_SearchCallback scb, void *search_data,
|
||||
BLI_pbvh_HitOccludedCallback hcb, void *hit_data)
|
||||
{
|
||||
PBVHIter iter;
|
||||
PBVHNode *node;
|
||||
node_tree *tree = 0;
|
||||
|
||||
pbvh_iter_begin(&iter, bvh, scb, search_data);
|
||||
|
||||
while((node=pbvh_iter_next_occluded(&iter))) {
|
||||
if(node->flag & PBVH_Leaf) {
|
||||
node_tree* new_node = malloc(sizeof(node_tree));
|
||||
|
||||
new_node->data = node;
|
||||
|
||||
new_node->left = NULL;
|
||||
new_node->right = NULL;
|
||||
|
||||
if (tree) {
|
||||
node_tree_insert(tree, new_node);
|
||||
}
|
||||
else {
|
||||
tree = new_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pbvh_iter_end(&iter);
|
||||
|
||||
if (tree) {
|
||||
float tmin = FLT_MAX;
|
||||
traverse_tree(tree, hcb, hit_data, &tmin);
|
||||
free_tree(tree);
|
||||
}
|
||||
}
|
||||
|
||||
static int update_search_cb(PBVHNode *node, void *data_v)
|
||||
{
|
||||
int flag= GET_INT_FROM_POINTER(data_v);
|
||||
@ -985,7 +1118,8 @@ void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *tot
|
||||
GHashIterator *hiter;
|
||||
GHash *map;
|
||||
void *face, **faces;
|
||||
int i, tot;
|
||||
unsigned i;
|
||||
int tot;
|
||||
|
||||
map = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "pbvh_get_grid_updates gh");
|
||||
|
||||
@ -1086,6 +1220,18 @@ void BLI_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max
|
||||
copy_v3_v3(bb_max, node->orig_vb.bmax);
|
||||
}
|
||||
|
||||
void BLI_pbvh_node_get_proxies(PBVHNode* node, PBVHProxyNode** proxies, int* proxy_count)
|
||||
{
|
||||
if (node->proxy_count > 0) {
|
||||
if (proxies) *proxies = node->proxies;
|
||||
if (proxy_count) *proxy_count = node->proxy_count;
|
||||
}
|
||||
else {
|
||||
if (proxies) *proxies = 0;
|
||||
if (proxy_count) *proxy_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************* Raycast ***********************************/
|
||||
|
||||
typedef struct {
|
||||
@ -1100,16 +1246,13 @@ typedef struct {
|
||||
static int ray_aabb_intersect(PBVHNode *node, void *data_v)
|
||||
{
|
||||
RaycastData *ray = data_v;
|
||||
float bb_min[3], bb_max[3], bbox[2][3];
|
||||
float bbox[2][3];
|
||||
float tmin, tmax, tymin, tymax, tzmin, tzmax;
|
||||
|
||||
if(ray->original)
|
||||
BLI_pbvh_node_get_original_BB(node, bb_min, bb_max);
|
||||
BLI_pbvh_node_get_original_BB(node, bbox[0], bbox[1]);
|
||||
else
|
||||
BLI_pbvh_node_get_BB(node, bb_min, bb_max);
|
||||
|
||||
copy_v3_v3(bbox[0], bb_min);
|
||||
copy_v3_v3(bbox[1], bb_max);
|
||||
BLI_pbvh_node_get_BB(node, bbox[0], bbox[1]);
|
||||
|
||||
tmin = (bbox[ray->sign[0]][0] - ray->start[0]) * ray->inv_dir[0];
|
||||
tmax = (bbox[1-ray->sign[0]][0] - ray->start[0]) * ray->inv_dir[0];
|
||||
@ -1119,8 +1262,10 @@ static int ray_aabb_intersect(PBVHNode *node, void *data_v)
|
||||
|
||||
if((tmin > tymax) || (tymin > tmax))
|
||||
return 0;
|
||||
|
||||
if(tymin > tmin)
|
||||
tmin = tymin;
|
||||
|
||||
if(tymax < tmax)
|
||||
tmax = tymax;
|
||||
|
||||
@ -1129,20 +1274,20 @@ static int ray_aabb_intersect(PBVHNode *node, void *data_v)
|
||||
|
||||
if((tmin > tzmax) || (tzmin > tmax))
|
||||
return 0;
|
||||
|
||||
|
||||
if(tzmin > tmin)
|
||||
tmin = tzmin;
|
||||
|
||||
// XXX jwilkins: tmax does not need to be updated since we don't use it
|
||||
// keeping this here for future reference
|
||||
//if(tzmax < tmax) tmax = tzmax;
|
||||
|
||||
node->tmin = tmin;
|
||||
|
||||
return 1;
|
||||
|
||||
/* XXX: Not sure about this?
|
||||
if(tzmin > tmin)
|
||||
tmin = tzmin;
|
||||
if(tzmax < tmax)
|
||||
tmax = tzmax;
|
||||
return ((tmin < t1) && (tmax > t0));
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitCallback cb, void *data,
|
||||
void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
|
||||
float ray_start[3], float ray_normal[3], int original)
|
||||
{
|
||||
RaycastData rcd;
|
||||
@ -1156,37 +1301,24 @@ void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitCallback cb, void *data,
|
||||
rcd.sign[2] = rcd.inv_dir[2] < 0;
|
||||
rcd.original = original;
|
||||
|
||||
BLI_pbvh_search_callback(bvh, ray_aabb_intersect, &rcd, cb, data);
|
||||
BLI_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
|
||||
}
|
||||
|
||||
/* XXX: Code largely copied from bvhutils.c, could be unified */
|
||||
/* Returns 1 if a better intersection has been found */
|
||||
static int ray_face_intersection(float ray_start[3], float ray_normal[3],
|
||||
float *t0, float *t1, float *t2, float *t3,
|
||||
float *fdist)
|
||||
{
|
||||
int hit = 0;
|
||||
float dist;
|
||||
|
||||
do
|
||||
{
|
||||
float dist = FLT_MAX;
|
||||
|
||||
if(!isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2,
|
||||
&dist, NULL, 0.1f))
|
||||
dist = FLT_MAX;
|
||||
|
||||
if(dist >= 0 && dist < *fdist) {
|
||||
hit = 1;
|
||||
*fdist = dist;
|
||||
}
|
||||
|
||||
t1 = t2;
|
||||
t2 = t3;
|
||||
t3 = NULL;
|
||||
|
||||
} while(t2);
|
||||
|
||||
return hit;
|
||||
if ((isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2, &dist, NULL, 0.1f) && dist < *fdist) ||
|
||||
(t3 && isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist, NULL, 0.1f) && dist < *fdist))
|
||||
{
|
||||
*fdist = dist;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
|
||||
@ -1399,3 +1531,86 @@ int BLI_pbvh_isDeformed(PBVH *pbvh)
|
||||
{
|
||||
return pbvh->deformed;
|
||||
}
|
||||
/* Proxies */
|
||||
|
||||
PBVHProxyNode* BLI_pbvh_node_add_proxy(PBVH* bvh, PBVHNode* node)
|
||||
{
|
||||
int index, totverts;
|
||||
|
||||
#pragma omp critical
|
||||
{
|
||||
|
||||
index = node->proxy_count;
|
||||
|
||||
node->proxy_count++;
|
||||
|
||||
if (node->proxies)
|
||||
node->proxies= MEM_reallocN(node->proxies, node->proxy_count*sizeof(PBVHProxyNode));
|
||||
else
|
||||
node->proxies= MEM_mallocN(sizeof(PBVHProxyNode), "PBVHNodeProxy");
|
||||
|
||||
if (bvh->grids)
|
||||
totverts = node->totprim*bvh->gridsize*bvh->gridsize;
|
||||
else
|
||||
totverts = node->uniq_verts;
|
||||
|
||||
node->proxies[index].co= MEM_callocN(sizeof(float[3])*totverts, "PBVHNodeProxy.co");
|
||||
}
|
||||
|
||||
return node->proxies + index;
|
||||
}
|
||||
|
||||
void BLI_pbvh_node_free_proxies(PBVHNode* node)
|
||||
{
|
||||
#pragma omp critical
|
||||
{
|
||||
int p;
|
||||
|
||||
for (p= 0; p < node->proxy_count; p++) {
|
||||
MEM_freeN(node->proxies[p].co);
|
||||
node->proxies[p].co= 0;
|
||||
}
|
||||
|
||||
MEM_freeN(node->proxies);
|
||||
node->proxies = 0;
|
||||
|
||||
node->proxy_count= 0;
|
||||
}
|
||||
}
|
||||
|
||||
void BLI_pbvh_gather_proxies(PBVH* pbvh, PBVHNode*** r_array, int* r_tot)
|
||||
{
|
||||
PBVHNode **array= NULL, **newarray, *node;
|
||||
int tot= 0, space= 0;
|
||||
int n;
|
||||
|
||||
for (n= 0; n < pbvh->totnode; n++) {
|
||||
node = pbvh->nodes + n;
|
||||
|
||||
if(node->proxy_count > 0) {
|
||||
if(tot == space) {
|
||||
/* resize array if needed */
|
||||
space= (tot == 0)? 32: space*2;
|
||||
newarray= MEM_callocN(sizeof(PBVHNode)*space, "BLI_pbvh_gather_proxies");
|
||||
|
||||
if (array) {
|
||||
memcpy(newarray, array, sizeof(PBVHNode)*tot);
|
||||
MEM_freeN(array);
|
||||
}
|
||||
|
||||
array= newarray;
|
||||
}
|
||||
|
||||
array[tot]= node;
|
||||
tot++;
|
||||
}
|
||||
}
|
||||
|
||||
if(tot == 0 && array) {
|
||||
MEM_freeN(array);
|
||||
array= NULL;
|
||||
}
|
||||
|
||||
*r_array= array;
|
||||
*r_tot= tot;
|
||||
}
|
||||
|
@ -29,6 +29,11 @@
|
||||
* Some really low-level file thingies.
|
||||
*/
|
||||
|
||||
/* needed for mingw & _stat64i32 */
|
||||
#ifdef FREE_WINDOWS
|
||||
# define __MSVCRT_VERSION__ 0x0800
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -76,7 +81,6 @@
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <sys/types.h>
|
||||
#include <io.h>
|
||||
#include <direct.h>
|
||||
#include "BLI_winstuff.h"
|
||||
@ -433,18 +437,20 @@ int BLI_filepathsize(const char *path)
|
||||
|
||||
int BLI_exist(char *name)
|
||||
{
|
||||
struct stat st;
|
||||
#ifdef WIN32
|
||||
struct _stat64i32 st;
|
||||
/* in Windows stat doesn't recognize dir ending on a slash
|
||||
To not break code where the ending slash is expected we
|
||||
don't mess with the argument name directly here - elubie */
|
||||
char tmp[FILE_MAXDIR+FILE_MAXFILE];
|
||||
int len;
|
||||
int len, res;
|
||||
BLI_strncpy(tmp, name, FILE_MAXDIR+FILE_MAXFILE);
|
||||
len = strlen(tmp);
|
||||
if (len > 3 && ( tmp[len-1]=='\\' || tmp[len-1]=='/') ) tmp[len-1] = '\0';
|
||||
if (stat(tmp,&st)) return(0);
|
||||
res = _stat(tmp, &st);
|
||||
if (res == -1) return(0);
|
||||
#else
|
||||
struct stat st;
|
||||
if (stat(name,&st)) return(0);
|
||||
#endif
|
||||
return(st.st_mode);
|
||||
|
@ -174,7 +174,7 @@ READ
|
||||
- read associated 'direct data'
|
||||
- link direct data (internal and to LibBlock)
|
||||
- read FileGlobal
|
||||
- read USER data, only when indicated (file is ~/.B.blend or .B25.blend)
|
||||
- read USER data, only when indicated (file is ~/X.XX/startup.blend)
|
||||
- free file
|
||||
- per Library (per Main)
|
||||
- read file
|
||||
@ -1539,6 +1539,7 @@ static void lib_link_brush(FileData *fd, Main *main)
|
||||
brush->id.flag -= LIB_NEEDLINK;
|
||||
|
||||
brush->mtex.tex= newlibadr_us(fd, brush->id.lib, brush->mtex.tex);
|
||||
brush->image_icon= newlibadr_us(fd, brush->id.lib, brush->image_icon);
|
||||
brush->clone.image= newlibadr_us(fd, brush->id.lib, brush->clone.image);
|
||||
}
|
||||
}
|
||||
@ -10971,6 +10972,82 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/* GSOC 2010 Sculpt - New settings for Brush */
|
||||
|
||||
Brush *brush;
|
||||
for (brush= main->brush.first; brush; brush= brush->id.next) {
|
||||
/* Sanity Check */
|
||||
|
||||
// infinite number of dabs
|
||||
if (brush->spacing == 0)
|
||||
brush->spacing = 10;
|
||||
|
||||
// will have no effect
|
||||
if (brush->alpha == 0)
|
||||
brush->alpha = 0.5f;
|
||||
|
||||
// bad radius
|
||||
if (brush->unprojected_radius == 0)
|
||||
brush->unprojected_radius = 0.125;
|
||||
|
||||
// unusable size
|
||||
if (brush->size == 0)
|
||||
brush->size = 35;
|
||||
|
||||
// can't see overlay
|
||||
if (brush->texture_overlay_alpha == 0)
|
||||
brush->texture_overlay_alpha = 33;
|
||||
|
||||
// same as draw brush
|
||||
if (brush->crease_pinch_factor == 0)
|
||||
brush->crease_pinch_factor = 0.5f;
|
||||
|
||||
// will sculpt no vertexes
|
||||
if (brush->plane_trim == 0)
|
||||
brush->plane_trim = 0.5f;
|
||||
|
||||
// same as smooth stroke off
|
||||
if (brush->smooth_stroke_radius == 0)
|
||||
brush->smooth_stroke_radius= 75;
|
||||
|
||||
// will keep cursor in one spot
|
||||
if (brush->smooth_stroke_radius == 1)
|
||||
brush->smooth_stroke_factor= 0.9f;
|
||||
|
||||
// same as dots
|
||||
if (brush->rate == 0)
|
||||
brush->rate = 0.1f;
|
||||
|
||||
/* New Settings */
|
||||
if (main->versionfile < 252 || (main->versionfile == 252 && main->subversionfile < 5)) {
|
||||
brush->flag |= BRUSH_SPACE_ATTEN; // explicitly enable adaptive space
|
||||
|
||||
// spacing was originally in pixels, convert it to percentage for new version
|
||||
// size should not be zero due to sanity check above
|
||||
brush->spacing = (int)(100*((float)brush->spacing) / ((float)brush->size));
|
||||
|
||||
if (brush->add_col[0] == 0 &&
|
||||
brush->add_col[1] == 0 &&
|
||||
brush->add_col[2] == 0)
|
||||
{
|
||||
brush->add_col[0] = 1.00;
|
||||
brush->add_col[1] = 0.39;
|
||||
brush->add_col[2] = 0.39;
|
||||
}
|
||||
|
||||
if (brush->sub_col[0] == 0 &&
|
||||
brush->sub_col[1] == 0 &&
|
||||
brush->sub_col[2] == 0)
|
||||
{
|
||||
brush->sub_col[0] = 0.39;
|
||||
brush->sub_col[1] = 0.39;
|
||||
brush->sub_col[2] = 1.00;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
|
||||
/* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */
|
||||
|
||||
|
@ -65,7 +65,7 @@ Any case: direct data is ALWAYS after the lib block
|
||||
- write TEST (128x128, blend file preview, optional)
|
||||
- write FileGlobal (some global vars)
|
||||
- write SDNA
|
||||
- write USER if filename is ~/.B.blend
|
||||
- write USER if filename is ~/X.XX/config/startup.blend
|
||||
*/
|
||||
|
||||
|
||||
@ -2481,7 +2481,7 @@ int BLO_write_file(Main *mainvar, char *dir, int write_flags, ReportList *report
|
||||
|
||||
file = open(tempname,O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
|
||||
if(file == -1) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Can't open file for writing: %s.", strerror(errno));
|
||||
BKE_reportf(reports, RPT_ERROR, "Can't open file %s for writing: %s.", tempname, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -633,7 +633,7 @@ void ANIM_uiTemplate_fmodifier_draw (uiLayout *layout, ID *id, ListBase *modifie
|
||||
|
||||
|
||||
/* 'mute' button */
|
||||
uiItemR(subrow, &ptr, "muted", UI_ITEM_R_ICON_ONLY, "", 0);
|
||||
uiItemR(subrow, &ptr, "mute", UI_ITEM_R_ICON_ONLY, "", 0);
|
||||
|
||||
uiBlockSetEmboss(block, UI_EMBOSSN);
|
||||
|
||||
|
@ -4737,7 +4737,7 @@ static int delete_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
void CURVE_OT_delete(wmOperatorType *ot)
|
||||
{
|
||||
static EnumPropertyItem type_items[] = {
|
||||
{0, "SELECTED", 0, "Selected", ""},
|
||||
{0, "SELECTED", 0, "Select", ""},
|
||||
{1, "SEGMENT", 0, "Segment", ""},
|
||||
{2, "ALL", 0, "All", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
@ -126,7 +126,7 @@ static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl)
|
||||
|
||||
/* locked */
|
||||
icon= (gpl->flag & GP_LAYER_LOCKED) ? ICON_LOCKED : ICON_UNLOCKED;
|
||||
uiItemR(subrow, &ptr, "locked", 0, "", icon);
|
||||
uiItemR(subrow, &ptr, "lock", 0, "", icon);
|
||||
|
||||
/* when layer is locked or hidden, only draw header */
|
||||
if (gpl->flag & (GP_LAYER_LOCKED|GP_LAYER_HIDE)) {
|
||||
@ -243,7 +243,7 @@ static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, Poi
|
||||
col= uiLayoutColumn(layout, 0);
|
||||
/* current Grease Pencil block */
|
||||
// TODO: show some info about who owns this?
|
||||
uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", NULL, "GPENCIL_OT_data_unlink");
|
||||
uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", NULL, "GPENCIL_OT_data_unlink", NULL);
|
||||
|
||||
/* add new layer button - can be used even when no data, since it can add a new block too */
|
||||
uiItemO(col, NULL, 0, "GPENCIL_OT_layer_add");
|
||||
|
@ -669,11 +669,11 @@ uiBlock *uiLayoutAbsoluteBlock(uiLayout *layout);
|
||||
void uiTemplateHeader(uiLayout *layout, struct bContext *C, int menus);
|
||||
void uiTemplateDopeSheetFilter(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
|
||||
void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
|
||||
char *newop, char *openop, char *unlinkop);
|
||||
char *newop, char *openop, char *unlinkop, char *filterop);
|
||||
void uiTemplateIDBrowse(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
|
||||
char *newop, char *openop, char *unlinkop);
|
||||
char *newop, char *openop, char *unlinkop, char *filterop);
|
||||
void uiTemplateIDPreview(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
|
||||
char *newop, char *openop, char *unlinkop, int rows, int cols);
|
||||
char *newop, char *openop, char *unlinkop, char *filterop, int rows, int cols);
|
||||
void uiTemplateAnyID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
|
||||
char *proptypename, char *text);
|
||||
void uiTemplatePathBuilder(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
|
||||
|
@ -46,6 +46,7 @@
|
||||
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
#include "DNA_brush_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
@ -762,6 +763,7 @@ static void icon_create_mipmap(struct PreviewImage* prv_img, int miplevel)
|
||||
prv_img->w[miplevel] = size;
|
||||
prv_img->h[miplevel] = size;
|
||||
prv_img->changed[miplevel] = 1;
|
||||
prv_img->changed_timestamp[miplevel] = 0;
|
||||
prv_img->rect[miplevel] = MEM_callocN(size*size*sizeof(unsigned int), "prv_rect");
|
||||
}
|
||||
}
|
||||
@ -976,6 +978,16 @@ int ui_id_icon_get(bContext *C, ID *id, int preview)
|
||||
/* checks if not exists, or changed */
|
||||
ui_id_icon_render(C, id, preview);
|
||||
break;
|
||||
case ID_BR:
|
||||
{ /* use the image in the brush as the icon */
|
||||
/* XXX redundancy here can be reduced be rewriting this switch as an if */
|
||||
ID* ima_id = (ID*)((Brush*)id)->image_icon;
|
||||
id = ima_id ? ima_id : id;
|
||||
iconid= BKE_icon_getid(id);
|
||||
/* checks if not exists, or changed */
|
||||
ui_id_icon_render(C, id, preview);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1745,11 +1745,11 @@ static void circle_picker(uiBlock *block, PointerRNA *ptr, const char *propname)
|
||||
uiBut *bt;
|
||||
|
||||
/* HS circle */
|
||||
bt= uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, propname, 0, 0.0, 0.0, 0, 0, "");
|
||||
bt= uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, propname, 0, 0.0, 0.0, 0, 0, "Color");
|
||||
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
|
||||
|
||||
/* value */
|
||||
bt= uiDefButR(block, HSVCUBE, 0, "", PICKER_W+PICKER_SPACE,0,PICKER_BAR,PICKER_H, ptr, propname, 0, 0.0, 0.0, UI_GRAD_V_ALT, 0, "");
|
||||
bt= uiDefButR(block, HSVCUBE, 0, "", PICKER_W+PICKER_SPACE,0,PICKER_BAR,PICKER_H, ptr, propname, 0, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value");
|
||||
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
|
||||
}
|
||||
|
||||
@ -1760,11 +1760,11 @@ static void square_picker(uiBlock *block, PointerRNA *ptr, const char *propname,
|
||||
int bartype = type + 3;
|
||||
|
||||
/* HS square */
|
||||
bt= uiDefButR(block, HSVCUBE, 0, "", 0, PICKER_BAR+PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, propname, 0, 0.0, 0.0, type, 0, "");
|
||||
bt= uiDefButR(block, HSVCUBE, 0, "", 0, PICKER_BAR+PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, propname, 0, 0.0, 0.0, type, 0, "Color");
|
||||
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
|
||||
|
||||
/* value */
|
||||
bt= uiDefButR(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, propname, 0, 0.0, 0.0, bartype, 0, "");
|
||||
bt= uiDefButR(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, propname, 0, 0.0, 0.0, bartype, 0, "Value");
|
||||
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
|
||||
}
|
||||
|
||||
@ -1832,11 +1832,11 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR
|
||||
|
||||
/* RGB values */
|
||||
uiBlockBeginAlign(block);
|
||||
bt= uiDefButR(block, NUMSLI, 0, "R ", 0, -60, butwidth, UI_UNIT_Y, ptr, propname, 0, 0.0, 0.0, 0, 3, "");
|
||||
bt= uiDefButR(block, NUMSLI, 0, "R ", 0, -60, butwidth, UI_UNIT_Y, ptr, propname, 0, 0.0, 0.0, 0, 3, "Red");
|
||||
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
|
||||
bt= uiDefButR(block, NUMSLI, 0, "G ", 0, -80, butwidth, UI_UNIT_Y, ptr, propname, 1, 0.0, 0.0, 0, 3, "");
|
||||
bt= uiDefButR(block, NUMSLI, 0, "G ", 0, -80, butwidth, UI_UNIT_Y, ptr, propname, 1, 0.0, 0.0, 0, 3, "Green");
|
||||
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
|
||||
bt= uiDefButR(block, NUMSLI, 0, "B ", 0, -100, butwidth, UI_UNIT_Y, ptr, propname, 2, 0.0, 0.0, 0, 3, "");
|
||||
bt= uiDefButR(block, NUMSLI, 0, "B ", 0, -100, butwidth, UI_UNIT_Y, ptr, propname, 2, 0.0, 0.0, 0, 3, "Blue");
|
||||
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
|
||||
|
||||
// could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", 0);
|
||||
@ -1844,16 +1844,16 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR
|
||||
|
||||
/* HSV values */
|
||||
uiBlockBeginAlign(block);
|
||||
bt= uiDefButF(block, NUMSLI, 0, "H ", 0, -60, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, "");
|
||||
bt= uiDefButF(block, NUMSLI, 0, "H ", 0, -60, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, "Hue");
|
||||
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
|
||||
bt= uiDefButF(block, NUMSLI, 0, "S ", 0, -80, butwidth, UI_UNIT_Y, hsv+1, 0.0, 1.0, 10, 3, "");
|
||||
bt= uiDefButF(block, NUMSLI, 0, "S ", 0, -80, butwidth, UI_UNIT_Y, hsv+1, 0.0, 1.0, 10, 3, "Saturation");
|
||||
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
|
||||
bt= uiDefButF(block, NUMSLI, 0, "V ", 0, -100, butwidth, UI_UNIT_Y, hsv+2, 0.0, max, 10, 3, "");
|
||||
bt= uiDefButF(block, NUMSLI, 0, "V ", 0, -100, butwidth, UI_UNIT_Y, hsv+2, 0.0, max, 10, 3, "Value");
|
||||
uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
if(rgb[3] != FLT_MAX) {
|
||||
bt= uiDefButR(block, NUMSLI, 0, "A ", 0, -120, butwidth, UI_UNIT_Y, ptr, propname, 3, 0.0, 0.0, 0, 0, "");
|
||||
bt= uiDefButR(block, NUMSLI, 0, "A ", 0, -120, butwidth, UI_UNIT_Y, ptr, propname, 3, 0.0, 0.0, 0, 0, "Alpha");
|
||||
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
|
||||
}
|
||||
else {
|
||||
|
@ -264,7 +264,7 @@ void UI_DrawString(float x, float y, char *str)
|
||||
|
||||
/* ************** init exit ************************ */
|
||||
|
||||
/* called on each .B.blend read */
|
||||
/* called on each startup.blend read */
|
||||
/* reading without uifont will create one */
|
||||
void uiStyleInit(void)
|
||||
{
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_texture.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
#include "ED_render.h"
|
||||
@ -141,6 +142,8 @@ typedef struct TemplateID {
|
||||
|
||||
ListBase *idlb;
|
||||
int prv_rows, prv_cols;
|
||||
|
||||
char filterop[64];
|
||||
} TemplateID;
|
||||
|
||||
/* Search browse menu, assign */
|
||||
@ -170,15 +173,53 @@ static void id_search_cb(const bContext *C, void *arg_template, char *str, uiSea
|
||||
/* ID listbase */
|
||||
for(id= lb->first; id; id= id->next) {
|
||||
if(!((flag & PROP_ID_SELF_CHECK) && id == id_from)) {
|
||||
int filter_yes;
|
||||
|
||||
/* hide dot-datablocks */
|
||||
if(U.uiflag & USER_HIDE_DOT)
|
||||
filter_yes= 0;
|
||||
|
||||
/* use filter */
|
||||
if (template->filterop[0] != 0) {
|
||||
PointerRNA ptr;
|
||||
ReportList reports;
|
||||
FunctionRNA *func;
|
||||
ParameterList parms;
|
||||
|
||||
RNA_id_pointer_create(id, &ptr);
|
||||
|
||||
BKE_reports_init(&reports, RPT_PRINT);
|
||||
|
||||
func= RNA_struct_find_function(&ptr, template->filterop);
|
||||
|
||||
if (func) {
|
||||
RNA_parameter_list_create(&parms, &ptr, func);
|
||||
|
||||
RNA_parameter_set_lookup(&parms, "context", &C);
|
||||
|
||||
if (RNA_function_call(C, &reports, &ptr, func, &parms) == 0) {
|
||||
int* ret;
|
||||
RNA_parameter_get_lookup(&parms, "ret", (void **)&ret);
|
||||
|
||||
if (!(*ret)) {
|
||||
RNA_parameter_list_free(&parms);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
filter_yes= 1;
|
||||
}
|
||||
}
|
||||
|
||||
RNA_parameter_list_free(&parms);
|
||||
}
|
||||
}
|
||||
|
||||
/* hide dot-datablocks, but only if filter does not force it visible */
|
||||
if(!filter_yes && U.uiflag & USER_HIDE_DOT)
|
||||
if ((id->name[2]=='.') && (str[0] != '.'))
|
||||
continue;
|
||||
|
||||
if(BLI_strcasestr(id->name+2, str)) {
|
||||
iconid= ui_id_icon_get((bContext*)C, id, 1);
|
||||
|
||||
|
||||
if(!uiSearchItemAdd(items, id->name+2, id, iconid))
|
||||
break;
|
||||
}
|
||||
@ -340,7 +381,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
|
||||
}
|
||||
}
|
||||
|
||||
static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, int flag, char *newop, char *openop, char *unlinkop)
|
||||
static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, int flag, char *newop, char *openop, char *unlinkop, char *filterop)
|
||||
{
|
||||
uiBut *but;
|
||||
uiBlock *block;
|
||||
@ -480,7 +521,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
|
||||
static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop, int flag, int prv_rows, int prv_cols)
|
||||
static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop, char* filterop, int flag, int prv_rows, int prv_cols)
|
||||
{
|
||||
TemplateID *template;
|
||||
PropertyRNA *prop;
|
||||
@ -498,7 +539,12 @@ static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, char
|
||||
template->prop= prop;
|
||||
template->prv_rows = prv_rows;
|
||||
template->prv_cols = prv_cols;
|
||||
|
||||
|
||||
if (filterop)
|
||||
BLI_strncpy(template->filterop, filterop, sizeof(template->filterop));
|
||||
else
|
||||
template->filterop[0] = 0;
|
||||
|
||||
if(newop)
|
||||
flag |= UI_ID_ADD_NEW;
|
||||
if(openop)
|
||||
@ -512,26 +558,25 @@ static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, char
|
||||
*/
|
||||
if(template->idlb) {
|
||||
uiLayoutRow(layout, 1);
|
||||
template_ID(C, layout, template, type, flag, newop, openop, unlinkop);
|
||||
template_ID(C, layout, template, type, flag, newop, openop, unlinkop, filterop);
|
||||
}
|
||||
|
||||
MEM_freeN(template);
|
||||
|
||||
}
|
||||
|
||||
void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop)
|
||||
void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop, char *filterop)
|
||||
{
|
||||
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_DELETE, 0, 0);
|
||||
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, filterop, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_DELETE, 0, 0);
|
||||
}
|
||||
|
||||
void uiTemplateIDBrowse(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop)
|
||||
void uiTemplateIDBrowse(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop, char *filterop)
|
||||
{
|
||||
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE|UI_ID_RENAME, 0, 0);
|
||||
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, filterop, UI_ID_BROWSE|UI_ID_RENAME, 0, 0);
|
||||
}
|
||||
|
||||
void uiTemplateIDPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop, int rows, int cols)
|
||||
void uiTemplateIDPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop, char *filterop, int rows, int cols)
|
||||
{
|
||||
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_DELETE|UI_ID_PREVIEWS, rows, cols);
|
||||
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, filterop, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_DELETE|UI_ID_PREVIEWS, rows, cols);
|
||||
}
|
||||
|
||||
/************************ ID Chooser Template ***************************/
|
||||
@ -2004,7 +2049,7 @@ void uiTemplateTriColorSet(uiLayout *layout, PointerRNA *ptr, char *propname)
|
||||
csPtr= RNA_property_pointer_get(ptr, prop);
|
||||
|
||||
uiItemR(row, &csPtr, "normal", 0, "", 0);
|
||||
uiItemR(row, &csPtr, "selected", 0, "", 0);
|
||||
uiItemR(row, &csPtr, "select", 0, "", 0);
|
||||
uiItemR(row, &csPtr, "active", 0, "", 0);
|
||||
}
|
||||
|
||||
|
@ -999,7 +999,7 @@ void init_userdef_do_versions(void)
|
||||
}
|
||||
if (U.savetime <= 0) {
|
||||
U.savetime = 1;
|
||||
// XXX error(".B.blend is buggy, please consider removing it.\n");
|
||||
// XXX error("startup.blend is buggy, please consider removing it.\n");
|
||||
}
|
||||
/* transform widget settings */
|
||||
if(U.tw_hotspot==0) {
|
||||
@ -1138,7 +1138,7 @@ void init_userdef_do_versions(void)
|
||||
}
|
||||
|
||||
/* set defaults for 3D View rotating axis indicator */
|
||||
/* since size can't be set to 0, this indicates it's not saved in .B.blend */
|
||||
/* since size can't be set to 0, this indicates it's not saved in startup.blend */
|
||||
if (U.rvisize == 0) {
|
||||
U.rvisize = 15;
|
||||
U.rvibright = 8;
|
||||
@ -1463,7 +1463,7 @@ void init_userdef_do_versions(void)
|
||||
SETCOL(btheme->tv3d.lastsel_point, 0xff, 0xff, 0xff, 255);
|
||||
}
|
||||
}
|
||||
if (G.main->versionfile <= 252 || (G.main->versionfile == 252 && G.main->subversionfile < 5)) {
|
||||
if (G.main->versionfile < 252 || (G.main->versionfile == 252 && G.main->subversionfile < 5)) {
|
||||
bTheme *btheme;
|
||||
|
||||
/* interface_widgets.c */
|
||||
@ -1521,7 +1521,14 @@ void init_userdef_do_versions(void)
|
||||
/* this timer uses U */
|
||||
// XXX reset_autosave();
|
||||
|
||||
/* GSOC Sculpt 2010 - Sanity check on Sculpt/Paint settings */
|
||||
|
||||
if (U.sculpt_paint_unified_alpha == 0)
|
||||
U.sculpt_paint_unified_alpha = 0.5f;
|
||||
|
||||
if (U.sculpt_paint_unified_unprojected_radius == 0)
|
||||
U.sculpt_paint_unified_unprojected_radius = 0.125f;
|
||||
|
||||
if (U.sculpt_paint_unified_size == 0)
|
||||
U.sculpt_paint_unified_size = 35;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -135,7 +135,7 @@ Object *ED_object_active_context(bContext *C)
|
||||
|
||||
|
||||
/* ********* clear/set restrict view *********/
|
||||
static int object_restrictview_clear_exec(bContext *C, wmOperator *op)
|
||||
static int object_hide_view_clear_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
View3D *v3d= sa->spacedata.first;
|
||||
@ -160,23 +160,23 @@ static int object_restrictview_clear_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_restrictview_clear(wmOperatorType *ot)
|
||||
void OBJECT_OT_hide_view_clear(wmOperatorType *ot)
|
||||
{
|
||||
|
||||
/* identifiers */
|
||||
ot->name= "Clear Restrict View";
|
||||
ot->description = "Reveal the object by setting the restrictview flag";
|
||||
ot->idname= "OBJECT_OT_restrictview_clear";
|
||||
ot->description = "Reveal the object by setting the hide flag";
|
||||
ot->idname= "OBJECT_OT_hide_view_clear";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= object_restrictview_clear_exec;
|
||||
ot->exec= object_hide_view_clear_exec;
|
||||
ot->poll= ED_operator_view3d_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int object_restrictview_set_exec(bContext *C, wmOperator *op)
|
||||
static int object_hide_view_set_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
short changed = 0;
|
||||
@ -213,15 +213,15 @@ static int object_restrictview_set_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_restrictview_set(wmOperatorType *ot)
|
||||
void OBJECT_OT_hide_view_set(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Set Restrict View";
|
||||
ot->description = "Hide the object by setting the restrictview flag";
|
||||
ot->idname= "OBJECT_OT_restrictview_set";
|
||||
ot->description = "Hide the object by setting the hide flag";
|
||||
ot->idname= "OBJECT_OT_hide_view_set";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= object_restrictview_set_exec;
|
||||
ot->exec= object_hide_view_set_exec;
|
||||
ot->poll= ED_operator_view3d_active;
|
||||
|
||||
/* flags */
|
||||
@ -232,7 +232,7 @@ void OBJECT_OT_restrictview_set(wmOperatorType *ot)
|
||||
}
|
||||
|
||||
/* 99% same as above except no need for scene refreshing (TODO, update render preview) */
|
||||
static int object_restrictrender_clear_exec(bContext *C, wmOperator *op)
|
||||
static int object_hide_render_clear_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
short changed= 0;
|
||||
|
||||
@ -251,23 +251,23 @@ static int object_restrictrender_clear_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_restrictrender_clear(wmOperatorType *ot)
|
||||
void OBJECT_OT_hide_render_clear(wmOperatorType *ot)
|
||||
{
|
||||
|
||||
/* identifiers */
|
||||
ot->name= "Clear Restrict Render";
|
||||
ot->description = "Reveal the render object by setting the restrictrender flag";
|
||||
ot->idname= "OBJECT_OT_restrictrender_clear";
|
||||
ot->description = "Reveal the render object by setting the hide render flag";
|
||||
ot->idname= "OBJECT_OT_hide_render_clear";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= object_restrictrender_clear_exec;
|
||||
ot->exec= object_hide_render_clear_exec;
|
||||
ot->poll= ED_operator_view3d_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int object_restrictrender_set_exec(bContext *C, wmOperator *op)
|
||||
static int object_hide_render_set_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
int unselected= RNA_boolean_get(op->ptr, "unselected");
|
||||
|
||||
@ -288,15 +288,15 @@ static int object_restrictrender_set_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_restrictrender_set(wmOperatorType *ot)
|
||||
void OBJECT_OT_hide_render_set(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Set Restrict Render";
|
||||
ot->description = "Hide the render object by setting the restrictrender flag";
|
||||
ot->idname= "OBJECT_OT_restrictrender_set";
|
||||
ot->description = "Hide the render object by setting the hide render flag";
|
||||
ot->idname= "OBJECT_OT_hide_render_set";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= object_restrictrender_set_exec;
|
||||
ot->exec= object_hide_render_set_exec;
|
||||
ot->poll= ED_operator_view3d_active;
|
||||
|
||||
/* flags */
|
||||
|
@ -75,10 +75,10 @@ void OBJECT_OT_drop_named_material(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_mode_set(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_editmode_toggle(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_posemode_toggle(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_restrictview_set(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_restrictview_clear(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_restrictrender_set(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_restrictrender_clear(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_hide_view_set(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_hide_view_clear(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_hide_render_set(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_hide_render_clear(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_proxy_make(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_shade_smooth(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_shade_flat(struct wmOperatorType *ot);
|
||||
|
@ -72,10 +72,10 @@ void ED_operatortypes_object(void)
|
||||
WM_operatortype_append(OBJECT_OT_editmode_toggle);
|
||||
WM_operatortype_append(OBJECT_OT_posemode_toggle);
|
||||
WM_operatortype_append(OBJECT_OT_proxy_make);
|
||||
WM_operatortype_append(OBJECT_OT_restrictview_clear);
|
||||
WM_operatortype_append(OBJECT_OT_restrictview_set);
|
||||
WM_operatortype_append(OBJECT_OT_restrictrender_clear);
|
||||
WM_operatortype_append(OBJECT_OT_restrictrender_set);
|
||||
WM_operatortype_append(OBJECT_OT_hide_view_clear);
|
||||
WM_operatortype_append(OBJECT_OT_hide_view_set);
|
||||
WM_operatortype_append(OBJECT_OT_hide_render_clear);
|
||||
WM_operatortype_append(OBJECT_OT_hide_render_set);
|
||||
WM_operatortype_append(OBJECT_OT_shade_smooth);
|
||||
WM_operatortype_append(OBJECT_OT_shade_flat);
|
||||
WM_operatortype_append(OBJECT_OT_paths_calculate);
|
||||
@ -318,14 +318,14 @@ void ED_keymap_object(wmKeyConfig *keyconf)
|
||||
WM_keymap_verify_item(keymap, "OBJECT_OT_scale_clear", SKEY, KM_PRESS, KM_ALT, 0);
|
||||
WM_keymap_verify_item(keymap, "OBJECT_OT_origin_clear", OKEY, KM_PRESS, KM_ALT, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_restrictview_clear", HKEY, KM_PRESS, KM_ALT, 0);
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_restrictview_set", HKEY, KM_PRESS, 0, 0);
|
||||
RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_restrictview_set", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1);
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
|
||||
RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1);
|
||||
|
||||
/* same as above but for rendering */
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_restrictrender_clear", HKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_restrictrender_set", HKEY, KM_PRESS, KM_CTRL, 0);
|
||||
// RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_restrictrender_set", HKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "unselected", 1); // conflicts, removing
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_clear", HKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_set", HKEY, KM_PRESS, KM_CTRL, 0);
|
||||
// RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_hide_render_set", HKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "unselected", 1); // conflicts, removing
|
||||
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_move_to_layer", MKEY, KM_PRESS, 0, 0);
|
||||
|
||||
|
@ -3,6 +3,8 @@ Import ('env')
|
||||
|
||||
sources = env.Glob('*.c')
|
||||
|
||||
defs = []
|
||||
|
||||
incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
|
||||
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
|
||||
incs += ' ../../render/extern/include'
|
||||
@ -12,7 +14,11 @@ if env['OURPLATFORM'] == 'linux2':
|
||||
cflags='-pthread'
|
||||
incs += ' ../../../extern/binreloc/include'
|
||||
|
||||
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
|
||||
incs += ' ' + env['BF_PTHREADS_INC']
|
||||
if env['OURPLATFORM'] == 'linuxcross':
|
||||
if env['WITH_BF_OPENMP']:
|
||||
incs += ' ' + env['BF_OPENMP_INC']
|
||||
|
||||
env.BlenderLib ( 'bf_editors_sculpt_paint', sources, Split(incs), [], libtype=['core'], priority=[40] )
|
||||
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
|
||||
incs += ' ' + env['BF_PTHREADS_INC']
|
||||
|
||||
env.BlenderLib ( 'bf_editors_sculpt_paint', sources, Split(incs), defines=defs, libtype=['core'], priority=[40] )
|
||||
|
@ -641,8 +641,8 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float
|
||||
}
|
||||
}
|
||||
else {
|
||||
xi = (uv[0]*ibuf->x) + 0.5f;
|
||||
yi = (uv[1]*ibuf->y) + 0.5f;
|
||||
xi = (int)((uv[0]*ibuf->x) + 0.5f);
|
||||
yi = (int)((uv[1]*ibuf->y) + 0.5f);
|
||||
|
||||
//if (xi<0 || xi>=ibuf->x || yi<0 || yi>=ibuf->y) return 0;
|
||||
|
||||
@ -1053,15 +1053,15 @@ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const fl
|
||||
* This is incorrect. Its already given radians but without it wont work.
|
||||
* need to look into a fix - campbell */
|
||||
if (is_quad) {
|
||||
a1 = shell_angle_to_dist(angle_normalized_v2v2(dir4, dir1) * (M_PI/180.0f));
|
||||
a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * (M_PI/180.0f));
|
||||
a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * (M_PI/180.0f));
|
||||
a4 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir4) * (M_PI/180.0f));
|
||||
a1 = shell_angle_to_dist(angle_normalized_v2v2(dir4, dir1) * ((float)M_PI/180.0f));
|
||||
a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI/180.0f));
|
||||
a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI/180.0f));
|
||||
a4 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir4) * ((float)M_PI/180.0f));
|
||||
}
|
||||
else {
|
||||
a1 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir1) * (M_PI/180.0f));
|
||||
a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * (M_PI/180.0f));
|
||||
a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * (M_PI/180.0f));
|
||||
a1 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir1) * ((float)M_PI/180.0f));
|
||||
a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI/180.0f));
|
||||
a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI/180.0f));
|
||||
}
|
||||
|
||||
if (is_quad) {
|
||||
@ -1197,7 +1197,7 @@ static void screen_px_from_persp(
|
||||
w[2] *= wtot_inv;
|
||||
}
|
||||
else {
|
||||
w[0] = w[1] = w[2] = 1.0/3.0; /* dummy values for zero area face */
|
||||
w[0] = w[1] = w[2] = 1.0f/3.0f; /* dummy values for zero area face */
|
||||
}
|
||||
/* done re-weighting */
|
||||
|
||||
@ -2513,11 +2513,11 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
|
||||
w[0]=w[1]=w[2]= 0.0;
|
||||
if (side) {
|
||||
w[fidx1?fidx1-1:0] = fac;
|
||||
w[fidx2?fidx2-1:0] = 1.0-fac;
|
||||
w[fidx2?fidx2-1:0] = 1.0f-fac;
|
||||
}
|
||||
else {
|
||||
w[fidx1] = fac;
|
||||
w[fidx2] = 1.0-fac;
|
||||
w[fidx2] = 1.0f-fac;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -2571,11 +2571,12 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
|
||||
static void project_paint_bucket_bounds(const ProjPaintState *ps, const float min[2], const float max[2], int bucketMin[2], int bucketMax[2])
|
||||
{
|
||||
/* divide by bucketWidth & bucketHeight so the bounds are offset in bucket grid units */
|
||||
bucketMin[0] = (int)(((float)(min[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 0.5f; /* these offsets of 0.5 and 1.5 seem odd but they are correct */
|
||||
bucketMin[1] = (int)(((float)(min[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 0.5f;
|
||||
/* XXX: the offset of 0.5 is always truncated to zero and the offset of 1.5f is always truncated to 1, is this really correct?? - jwilkins */
|
||||
bucketMin[0] = (int)((int)(((float)(min[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 0.5f); /* these offsets of 0.5 and 1.5 seem odd but they are correct */
|
||||
bucketMin[1] = (int)((int)(((float)(min[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 0.5f);
|
||||
|
||||
bucketMax[0] = (int)(((float)(max[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 1.5f;
|
||||
bucketMax[1] = (int)(((float)(max[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 1.5f;
|
||||
bucketMax[0] = (int)((int)(((float)(max[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 1.5f);
|
||||
bucketMax[1] = (int)((int)(((float)(max[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 1.5f);
|
||||
|
||||
/* incase the rect is outside the mesh 2d bounds */
|
||||
CLAMP(bucketMin[0], 0, ps->buckets_x);
|
||||
@ -3029,19 +3030,19 @@ static void project_paint_begin(ProjPaintState *ps)
|
||||
|
||||
if(ps->source==PROJ_SRC_VIEW) {
|
||||
#ifdef PROJ_DEBUG_WINCLIP
|
||||
CLAMP(ps->screenMin[0], -ps->brush->size, ps->winx + ps->brush->size);
|
||||
CLAMP(ps->screenMax[0], -ps->brush->size, ps->winx + ps->brush->size);
|
||||
CLAMP(ps->screenMin[0], (float)(-ps->brush->size), (float)(ps->winx + ps->brush->size));
|
||||
CLAMP(ps->screenMax[0], (float)(-ps->brush->size), (float)(ps->winx + ps->brush->size));
|
||||
|
||||
CLAMP(ps->screenMin[1], -ps->brush->size, ps->winy + ps->brush->size);
|
||||
CLAMP(ps->screenMax[1], -ps->brush->size, ps->winy + ps->brush->size);
|
||||
CLAMP(ps->screenMin[1], (float)(-ps->brush->size), (float)(ps->winy + ps->brush->size));
|
||||
CLAMP(ps->screenMax[1], (float)(-ps->brush->size), (float)(ps->winy + ps->brush->size));
|
||||
#endif
|
||||
}
|
||||
else { /* reprojection, use bounds */
|
||||
ps->screenMin[0]= 0;
|
||||
ps->screenMax[0]= ps->winx;
|
||||
ps->screenMax[0]= (float)(ps->winx);
|
||||
|
||||
ps->screenMin[1]= 0;
|
||||
ps->screenMax[1]= ps->winy;
|
||||
ps->screenMax[1]= (float)(ps->winy);
|
||||
}
|
||||
|
||||
/* only for convenience */
|
||||
@ -3497,7 +3498,7 @@ static int project_bucket_iter_next(ProjPaintState *ps, int *bucket_index, rctf
|
||||
project_bucket_bounds(ps, ps->context_bucket_x, ps->context_bucket_y, bucket_bounds);
|
||||
|
||||
if ( (ps->source != PROJ_SRC_VIEW) ||
|
||||
project_bucket_isect_circle(ps->context_bucket_x, ps->context_bucket_y, mval, ps->brush->size * ps->brush->size, bucket_bounds)
|
||||
project_bucket_isect_circle(ps->context_bucket_x, ps->context_bucket_y, mval, (float)(ps->brush->size * ps->brush->size), bucket_bounds)
|
||||
) {
|
||||
*bucket_index = ps->context_bucket_x + (ps->context_bucket_y * ps->buckets_x);
|
||||
ps->context_bucket_x++;
|
||||
@ -3545,7 +3546,7 @@ static void blend_color_mix(unsigned char *cp, const unsigned char *cp1, const u
|
||||
|
||||
static void blend_color_mix_float(float *cp, const float *cp1, const float *cp2, const float fac)
|
||||
{
|
||||
const float mfac= 1.0-fac;
|
||||
const float mfac= 1.0f-fac;
|
||||
cp[0]= mfac*cp1[0] + fac*cp2[0];
|
||||
cp[1]= mfac*cp1[1] + fac*cp2[1];
|
||||
cp[2]= mfac*cp1[2] + fac*cp2[2];
|
||||
@ -3712,7 +3713,7 @@ static void *do_projectpaint_thread(void *ph_v)
|
||||
}
|
||||
|
||||
/* avoid a square root with every dist comparison */
|
||||
brush_size_sqared = ps->brush->size * ps->brush->size;
|
||||
brush_size_sqared = (float)(ps->brush->size * ps->brush->size);
|
||||
|
||||
/* printf("brush bounds %d %d %d %d\n", bucketMin[0], bucketMin[1], bucketMax[0], bucketMax[1]); */
|
||||
|
||||
@ -3771,7 +3772,7 @@ static void *do_projectpaint_thread(void *ph_v)
|
||||
falloff = 1.0f - falloff;
|
||||
falloff = 1.0f - (falloff * falloff);
|
||||
|
||||
mask_short = projPixel->mask * (ps->brush->alpha * falloff);
|
||||
mask_short = (unsigned short)(projPixel->mask * (ps->brush->alpha * falloff));
|
||||
if (mask_short > projPixel->mask_max) {
|
||||
mask = ((float)mask_short)/65535.0f;
|
||||
projPixel->mask_max = mask_short;
|
||||
@ -3932,8 +3933,8 @@ static int project_paint_sub_stroke(ProjPaintState *ps, BrushPainter *painter, i
|
||||
/* Use mouse coords as floats for projection painting */
|
||||
float pos[2];
|
||||
|
||||
pos[0] = mval_i[0];
|
||||
pos[1] = mval_i[1];
|
||||
pos[0] = (float)(mval_i[0]);
|
||||
pos[1] = (float)(mval_i[1]);
|
||||
|
||||
// we may want to use this later
|
||||
// brush_painter_require_imbuf(painter, ((ibuf->rect_float)? 1: 0), 0, 0);
|
||||
@ -4057,7 +4058,8 @@ static int imapaint_ibuf_add_if(ImBuf *ibuf, unsigned int x, unsigned int y, flo
|
||||
{
|
||||
float inrgb[3];
|
||||
|
||||
if ((x >= ibuf->x) || (y >= ibuf->y)) {
|
||||
// XXX: signed unsigned mismatch
|
||||
if ((x >= (unsigned int)(ibuf->x)) || (y >= (unsigned int)(ibuf->y))) {
|
||||
if (torus) imapaint_ibuf_get_set_rgb(ibuf, x, y, 1, 0, inrgb);
|
||||
else return 0;
|
||||
}
|
||||
@ -4611,8 +4613,8 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps)
|
||||
ps->normal_angle_inner= ps->normal_angle= settings->imapaint.normal_angle;
|
||||
}
|
||||
|
||||
ps->normal_angle_inner *= M_PI_2 / 90;
|
||||
ps->normal_angle *= M_PI_2 / 90;
|
||||
ps->normal_angle_inner *= (float)(M_PI_2 / 90);
|
||||
ps->normal_angle *= (float)(M_PI_2 / 90);
|
||||
ps->normal_angle_range = ps->normal_angle - ps->normal_angle_inner;
|
||||
|
||||
if(ps->normal_angle_range <= 0.0f)
|
||||
@ -4711,8 +4713,8 @@ static void paint_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
|
||||
int mouse[2], redraw;
|
||||
|
||||
RNA_float_get_array(itemptr, "mouse", mousef);
|
||||
mouse[0] = mousef[0];
|
||||
mouse[1] = mousef[1];
|
||||
mouse[0] = (int)(mousef[0]);
|
||||
mouse[1] = (int)(mousef[1]);
|
||||
time= RNA_float_get(itemptr, "time");
|
||||
pressure= RNA_float_get(itemptr, "pressure");
|
||||
|
||||
@ -4832,8 +4834,8 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
|
||||
/* fill in stroke */
|
||||
RNA_collection_add(op->ptr, "stroke", &itemptr);
|
||||
|
||||
mousef[0] = mouse[0];
|
||||
mousef[1] = mouse[1];
|
||||
mousef[0] = (float)(mouse[0]);
|
||||
mousef[1] = (float)(mouse[1]);
|
||||
RNA_float_set_array(&itemptr, "mouse", mousef);
|
||||
RNA_float_set(&itemptr, "time", (float)(time - pop->starttime));
|
||||
RNA_float_set(&itemptr, "pressure", pressure);
|
||||
@ -4950,7 +4952,7 @@ static void brush_drawcursor(bContext *C, int x, int y, void *customdata)
|
||||
glColor4ub(255, 255, 255, 128);
|
||||
glEnable( GL_LINE_SMOOTH );
|
||||
glEnable(GL_BLEND);
|
||||
glutil_draw_lined_arc(0.0, M_PI*2.0, brush->size*0.5f, 40);
|
||||
glutil_draw_lined_arc(0, (float)(M_PI*2.0), brush->size*0.5f, 40);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable( GL_LINE_SMOOTH );
|
||||
|
||||
@ -4977,7 +4979,7 @@ static int paint_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *eve
|
||||
ToolSettings *ts = CTX_data_scene(C)->toolsettings;
|
||||
get_imapaint_zoom(C, &zoom, &zoom);
|
||||
toggle_paint_cursor(C, !ts->imapaint.paintcursor);
|
||||
brush_radial_control_invoke(op, paint_brush(&ts->imapaint.paint), 0.5 * zoom);
|
||||
brush_radial_control_invoke(op, paint_brush(&ts->imapaint.paint), 0.5f * zoom);
|
||||
return WM_radial_control_invoke(C, op, event);
|
||||
}
|
||||
|
||||
@ -4997,7 +4999,7 @@ static int paint_radial_control_exec(bContext *C, wmOperator *op)
|
||||
int ret;
|
||||
char str[256];
|
||||
get_imapaint_zoom(C, &zoom, &zoom);
|
||||
ret = brush_radial_control_exec(op, brush, 2.0 / zoom);
|
||||
ret = brush_radial_control_exec(op, brush, 2.0f / zoom);
|
||||
WM_radial_control_string(op, str, 256);
|
||||
|
||||
WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, brush);
|
||||
|
@ -110,6 +110,13 @@ void PAINT_OT_face_select_all(struct wmOperatorType *ot);
|
||||
|
||||
int facemask_paint_poll(struct bContext *C);
|
||||
|
||||
/* stroke operator */
|
||||
typedef enum wmBrushStrokeMode {
|
||||
WM_BRUSHSTROKE_NORMAL,
|
||||
WM_BRUSHSTROKE_INVERT,
|
||||
WM_BRUSHSTROKE_SMOOTH,
|
||||
} wmBrushStrokeMode;
|
||||
|
||||
/* paint_undo.c */
|
||||
typedef void (*UndoRestoreCb)(struct bContext *C, struct ListBase *lb);
|
||||
typedef void (*UndoFreeCb)(struct ListBase *lb);
|
||||
|
@ -39,28 +39,25 @@
|
||||
#include "sculpt_intern.h"
|
||||
|
||||
#include <string.h>
|
||||
//#include <stdio.h>
|
||||
|
||||
/* Brush operators */
|
||||
static int brush_add_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
/*int type = RNA_enum_get(op->ptr, "type");*/
|
||||
Brush *br = NULL;
|
||||
Paint *paint = paint_get_active(CTX_data_scene(C));
|
||||
Brush *br = paint_brush(paint);
|
||||
|
||||
br = add_brush("Brush");
|
||||
if (br)
|
||||
br = copy_brush(br);
|
||||
else
|
||||
br = add_brush("Brush");
|
||||
|
||||
if(br)
|
||||
paint_brush_set(paint_get_active(CTX_data_scene(C)), br);
|
||||
paint_brush_set(paint_get_active(CTX_data_scene(C)), br);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static EnumPropertyItem brush_type_items[] = {
|
||||
{OB_MODE_SCULPT, "SCULPT", ICON_SCULPTMODE_HLT, "Sculpt", ""},
|
||||
{OB_MODE_VERTEX_PAINT, "VERTEX_PAINT", ICON_VPAINT_HLT, "Vertex Paint", ""},
|
||||
{OB_MODE_WEIGHT_PAINT, "WEIGHT_PAINT", ICON_WPAINT_HLT, "Weight Paint", ""},
|
||||
{OB_MODE_TEXTURE_PAINT, "TEXTURE_PAINT", ICON_TPAINT_HLT, "Texture Paint", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
void BRUSH_OT_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
@ -72,9 +69,43 @@ void BRUSH_OT_add(wmOperatorType *ot)
|
||||
ot->exec= brush_add_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
ot->flag= OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
RNA_def_enum(ot->srna, "type", brush_type_items, OB_MODE_VERTEX_PAINT, "Type", "Which paint mode to create the brush for.");
|
||||
|
||||
static int brush_scale_size_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
/*int type = RNA_enum_get(op->ptr, "type");*/
|
||||
Paint *paint = paint_get_active(CTX_data_scene(C));
|
||||
Brush *br = paint_brush(paint);
|
||||
float factor = RNA_float_get(op->ptr, "scalar");
|
||||
|
||||
if (br) {
|
||||
if (U.sculpt_paint_settings & SCULPT_PAINT_USE_UNIFIED_SIZE) {
|
||||
U.sculpt_paint_unified_size *= factor;
|
||||
}
|
||||
else {
|
||||
br->size *= factor;
|
||||
}
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void BRUSH_OT_scale_size(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Scale Sculpt/Paint Brush Size";
|
||||
ot->description= "Change brush size by a scalar";
|
||||
ot->idname= "BRUSH_OT_scale_size";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= brush_scale_size_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_UNDO;
|
||||
|
||||
RNA_def_float(ot->srna, "scalar", 1, 0, 2, "Scalar", "Factor to scale brush size by", 0, 2);
|
||||
}
|
||||
|
||||
static int vertex_color_set_exec(bContext *C, wmOperator *op)
|
||||
@ -108,8 +139,10 @@ void ED_operatortypes_paint(void)
|
||||
{
|
||||
/* brush */
|
||||
WM_operatortype_append(BRUSH_OT_add);
|
||||
WM_operatortype_append(BRUSH_OT_scale_size);
|
||||
WM_operatortype_append(BRUSH_OT_curve_preset);
|
||||
|
||||
|
||||
/* image */
|
||||
WM_operatortype_append(PAINT_OT_texture_paint_toggle);
|
||||
WM_operatortype_append(PAINT_OT_texture_paint_radial_control);
|
||||
@ -141,6 +174,7 @@ void ED_operatortypes_paint(void)
|
||||
WM_operatortype_append(PAINT_OT_face_select_all);
|
||||
}
|
||||
|
||||
|
||||
static void ed_keymap_paint_brush_switch(wmKeyMap *keymap, const char *path)
|
||||
{
|
||||
wmKeyMapItem *kmi;
|
||||
@ -180,15 +214,13 @@ static void ed_keymap_paint_brush_switch(wmKeyMap *keymap, const char *path)
|
||||
static void ed_keymap_paint_brush_size(wmKeyMap *keymap, const char *path)
|
||||
{
|
||||
wmKeyMapItem *kmi;
|
||||
|
||||
kmi= WM_keymap_add_item(keymap, "WM_OT_context_scale_int", LEFTBRACKETKEY, KM_PRESS, 0, 0);
|
||||
RNA_string_set(kmi->ptr, "data_path", path);
|
||||
RNA_float_set(kmi->ptr, "value", 0.9);
|
||||
|
||||
kmi= WM_keymap_add_item(keymap, "WM_OT_context_scale_int", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
|
||||
RNA_string_set(kmi->ptr, "data_path", path);
|
||||
RNA_float_set(kmi->ptr, "value", 10.0/9.0); // 1.1111....
|
||||
}
|
||||
|
||||
kmi= WM_keymap_add_item(keymap, "BRUSH_OT_scale_size", LEFTBRACKETKEY, KM_PRESS, 0, 0);
|
||||
RNA_float_set(kmi->ptr, "scalar", 0.9);
|
||||
|
||||
kmi= WM_keymap_add_item(keymap, "BRUSH_OT_scale_size", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
|
||||
RNA_float_set(kmi->ptr, "scalar", 10.0/9.0); // 1.1111....
|
||||
}
|
||||
|
||||
void ED_keymap_paint(wmKeyConfig *keyconf)
|
||||
{
|
||||
@ -200,12 +232,15 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
|
||||
keymap= WM_keymap_find(keyconf, "Sculpt", 0, 0);
|
||||
keymap->poll= sculpt_poll;
|
||||
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_RADIALCONTROL_ANGLE);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_RADIALCONTROL_ANGLE);
|
||||
|
||||
WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "mode", WM_BRUSHSTROKE_NORMAL);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_BRUSHSTROKE_INVERT);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_BRUSHSTROKE_SMOOTH);
|
||||
|
||||
//stroke_mode_modal_keymap(keyconf);
|
||||
|
||||
for(i=0; i<=5; i++)
|
||||
RNA_int_set(WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", ZEROKEY+i, KM_PRESS, KM_CTRL, 0)->ptr, "level", i);
|
||||
@ -221,7 +256,8 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
|
||||
|
||||
ed_keymap_paint_brush_switch(keymap, "tool_settings.sculpt.active_brush_index");
|
||||
ed_keymap_paint_brush_size(keymap, "tool_settings.sculpt.brush.size");
|
||||
|
||||
|
||||
/* */
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", AKEY, KM_PRESS, 0, 0);
|
||||
RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.brush.use_anchor");
|
||||
|
||||
@ -254,11 +290,10 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", LKEY, KM_PRESS, 0, 0);
|
||||
RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.active_brush_name");
|
||||
RNA_string_set(kmi->ptr, "value", "Layer");
|
||||
|
||||
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", TKEY, KM_PRESS, KM_SHIFT, 0); // was just T in 2.4x
|
||||
RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.active_brush_name");
|
||||
RNA_string_set(kmi->ptr, "value", "Flatten");
|
||||
|
||||
|
||||
/* Vertex Paint mode */
|
||||
keymap= WM_keymap_find(keyconf, "Vertex Paint", 0, 0);
|
||||
|
@ -20,7 +20,7 @@
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
* Contributor(s): Jason Wilkins, Tom Musgrove.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*
|
||||
@ -35,6 +35,7 @@
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_brush.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
@ -49,6 +50,9 @@
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "paint_intern.h"
|
||||
#include "sculpt_intern.h" // XXX, for expedience in getting this working, refactor later (or this just shows that this needs unification)
|
||||
|
||||
#include "BKE_image.h"
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
@ -96,54 +100,748 @@ static void paint_draw_smooth_stroke(bContext *C, int x, int y, void *customdata
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
}
|
||||
|
||||
static void paint_draw_cursor(bContext *C, int x, int y, void *customdata)
|
||||
#if 0
|
||||
|
||||
// grid texture for testing
|
||||
|
||||
#define GRID_WIDTH 8
|
||||
#define GRID_LENGTH 8
|
||||
|
||||
#define W (0xFFFFFFFF)
|
||||
#define G (0x00888888)
|
||||
#define E (0xE1E1E1E1)
|
||||
#define C (0xC3C3C3C3)
|
||||
#define O (0xB4B4B4B4)
|
||||
#define Q (0xA9A9A9A9)
|
||||
|
||||
static unsigned grid_texture0[256] =
|
||||
{
|
||||
Paint *paint = paint_get_active(CTX_data_scene(C));
|
||||
Brush *brush = paint_brush(paint);
|
||||
W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,G,G,G,G,G,G,G,G,G,G,G,G,G,G,W,
|
||||
W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,
|
||||
};
|
||||
|
||||
if(!(paint->flags & PAINT_SHOW_BRUSH))
|
||||
return;
|
||||
static unsigned grid_texture1[64] =
|
||||
{
|
||||
C,C,C,C,C,C,C,C,
|
||||
C,G,G,G,G,G,G,C,
|
||||
C,G,G,G,G,G,G,C,
|
||||
C,G,G,G,G,G,G,C,
|
||||
C,G,G,G,G,G,G,C,
|
||||
C,G,G,G,G,G,G,C,
|
||||
C,G,G,G,G,G,G,C,
|
||||
C,C,C,C,C,C,C,C,
|
||||
};
|
||||
|
||||
glColor4ubv(paint_get_active(CTX_data_scene(C))->paint_cursor_col);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
static unsigned grid_texture2[16] =
|
||||
{
|
||||
O,O,O,O,
|
||||
O,G,G,O,
|
||||
O,G,G,O,
|
||||
O,O,O,O,
|
||||
};
|
||||
|
||||
glTranslatef((float)x, (float)y, 0.0f);
|
||||
glutil_draw_lined_arc(0.0, M_PI*2.0, brush->size, 40);
|
||||
glTranslatef((float)-x, (float)-y, 0.0f);
|
||||
static unsigned grid_texture3[4] =
|
||||
{
|
||||
Q,Q,
|
||||
Q,Q,
|
||||
};
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
static unsigned grid_texture4[1] =
|
||||
{
|
||||
Q,
|
||||
};
|
||||
|
||||
#undef W
|
||||
#undef G
|
||||
#undef E
|
||||
#undef C
|
||||
#undef O
|
||||
#undef Q
|
||||
|
||||
static void load_grid()
|
||||
{
|
||||
static GLuint overlay_texture;
|
||||
|
||||
if (!overlay_texture) {
|
||||
//GLfloat largest_supported_anisotropy;
|
||||
|
||||
glGenTextures(1, &overlay_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, overlay_texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, grid_texture0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, grid_texture1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, grid_texture2);
|
||||
glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, grid_texture3);
|
||||
glTexImage2D(GL_TEXTURE_2D, 4, GL_RGB, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, grid_texture4);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
|
||||
//glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
|
||||
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extern float get_tex_pixel(Brush* br, float u, float v);
|
||||
|
||||
typedef struct Snapshot {
|
||||
float size[3];
|
||||
float ofs[3];
|
||||
float rot;
|
||||
int brush_size;
|
||||
int winx;
|
||||
int winy;
|
||||
int brush_map_mode;
|
||||
int curve_changed_timestamp;
|
||||
} Snapshot;
|
||||
|
||||
static int same_snap(Snapshot* snap, Brush* brush, ViewContext* vc)
|
||||
{
|
||||
MTex* mtex = &brush->mtex;
|
||||
|
||||
return
|
||||
(mtex->tex &&
|
||||
mtex->ofs[0] == snap->ofs[0] &&
|
||||
mtex->ofs[1] == snap->ofs[1] &&
|
||||
mtex->ofs[2] == snap->ofs[2] &&
|
||||
mtex->size[0] == snap->size[0] &&
|
||||
mtex->size[1] == snap->size[1] &&
|
||||
mtex->size[2] == snap->size[2] &&
|
||||
mtex->rot == snap->rot) &&
|
||||
((mtex->brush_map_mode == MTEX_MAP_MODE_FIXED && sculpt_get_brush_size(brush) <= snap->brush_size) || (sculpt_get_brush_size(brush) == snap->brush_size)) && // make brush smaller shouldn't cause a resample
|
||||
mtex->brush_map_mode == snap->brush_map_mode &&
|
||||
vc->ar->winx == snap->winx &&
|
||||
vc->ar->winy == snap->winy;
|
||||
}
|
||||
|
||||
static void make_snap(Snapshot* snap, Brush* brush, ViewContext* vc)
|
||||
{
|
||||
if (brush->mtex.tex) {
|
||||
snap->brush_map_mode = brush->mtex.brush_map_mode;
|
||||
copy_v3_v3(snap->ofs, brush->mtex.ofs);
|
||||
copy_v3_v3(snap->size, brush->mtex.size);
|
||||
snap->rot = brush->mtex.rot;
|
||||
}
|
||||
else {
|
||||
snap->brush_map_mode = -1;
|
||||
snap->ofs[0]= snap->ofs[1]= snap->ofs[2]= -1;
|
||||
snap->size[0]= snap->size[1]= snap->size[2]= -1;
|
||||
snap->rot = -1;
|
||||
}
|
||||
|
||||
snap->brush_size = sculpt_get_brush_size(brush);
|
||||
snap->winx = vc->ar->winx;
|
||||
snap->winy = vc->ar->winy;
|
||||
}
|
||||
|
||||
int load_tex(Sculpt *sd, Brush* br, ViewContext* vc)
|
||||
{
|
||||
static GLuint overlay_texture = 0;
|
||||
static int init = 0;
|
||||
static int tex_changed_timestamp = -1;
|
||||
static int curve_changed_timestamp = -1;
|
||||
static Snapshot snap;
|
||||
static int old_size = -1;
|
||||
|
||||
GLubyte* buffer = 0;
|
||||
|
||||
int size;
|
||||
int j;
|
||||
int refresh;
|
||||
|
||||
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED && !br->mtex.tex) return 0;
|
||||
|
||||
refresh =
|
||||
!overlay_texture ||
|
||||
(br->mtex.tex &&
|
||||
(!br->mtex.tex->preview ||
|
||||
br->mtex.tex->preview->changed_timestamp[0] != tex_changed_timestamp)) ||
|
||||
!br->curve ||
|
||||
br->curve->changed_timestamp != curve_changed_timestamp ||
|
||||
!same_snap(&snap, br, vc);
|
||||
|
||||
if (refresh) {
|
||||
if (br->mtex.tex && br->mtex.tex->preview)
|
||||
tex_changed_timestamp = br->mtex.tex->preview->changed_timestamp[0];
|
||||
|
||||
if (br->curve)
|
||||
curve_changed_timestamp = br->curve->changed_timestamp;
|
||||
|
||||
make_snap(&snap, br, vc);
|
||||
|
||||
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) {
|
||||
int s = sculpt_get_brush_size(br);
|
||||
int r = 1;
|
||||
|
||||
for (s >>= 1; s > 0; s >>= 1)
|
||||
r++;
|
||||
|
||||
size = (1<<r);
|
||||
|
||||
if (size < 256)
|
||||
size = 256;
|
||||
|
||||
if (size < old_size)
|
||||
size = old_size;
|
||||
}
|
||||
else
|
||||
size = 512;
|
||||
|
||||
if (old_size != size) {
|
||||
if (overlay_texture) {
|
||||
glDeleteTextures(1, &overlay_texture);
|
||||
overlay_texture = 0;
|
||||
}
|
||||
|
||||
init = 0;
|
||||
|
||||
old_size = size;
|
||||
}
|
||||
|
||||
buffer = MEM_mallocN(sizeof(GLubyte)*size*size, "load_tex");
|
||||
|
||||
#pragma omp parallel for schedule(static) if (sd->flags & SCULPT_USE_OPENMP)
|
||||
for (j= 0; j < size; j++) {
|
||||
int i;
|
||||
float y;
|
||||
float len;
|
||||
|
||||
for (i= 0; i < size; i++) {
|
||||
|
||||
// largely duplicated from tex_strength
|
||||
|
||||
const float rotation = -br->mtex.rot;
|
||||
float diameter = sculpt_get_brush_size(br);
|
||||
int index = j*size + i;
|
||||
float x;
|
||||
float avg;
|
||||
|
||||
x = (float)i/size;
|
||||
y = (float)j/size;
|
||||
|
||||
x -= 0.5f;
|
||||
y -= 0.5f;
|
||||
|
||||
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) {
|
||||
x *= vc->ar->winx / diameter;
|
||||
y *= vc->ar->winy / diameter;
|
||||
}
|
||||
else {
|
||||
x *= 2;
|
||||
y *= 2;
|
||||
}
|
||||
|
||||
len = sqrtf(x*x + y*y);
|
||||
|
||||
if ((br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) || len <= 1) {
|
||||
/* it is probably worth optimizing for those cases where
|
||||
the texture is not rotated by skipping the calls to
|
||||
atan2, sqrtf, sin, and cos. */
|
||||
if (br->mtex.tex && (rotation > 0.001 || rotation < -0.001)) {
|
||||
const float angle = atan2(y, x) + rotation;
|
||||
|
||||
x = len * cos(angle);
|
||||
y = len * sin(angle);
|
||||
}
|
||||
|
||||
x *= br->mtex.size[0];
|
||||
y *= br->mtex.size[1];
|
||||
|
||||
x += br->mtex.ofs[0];
|
||||
y += br->mtex.ofs[1];
|
||||
|
||||
avg = br->mtex.tex ? get_tex_pixel(br, x, y) : 1;
|
||||
|
||||
avg += br->texture_sample_bias;
|
||||
|
||||
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED)
|
||||
avg *= brush_curve_strength(br, len, 1); /* Falloff curve */
|
||||
|
||||
buffer[index] = (GLubyte)(255*avg);
|
||||
}
|
||||
else {
|
||||
buffer[index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!overlay_texture)
|
||||
glGenTextures(1, &overlay_texture);
|
||||
}
|
||||
else {
|
||||
size= old_size;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, overlay_texture);
|
||||
|
||||
if (refresh) {
|
||||
if (!init) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
|
||||
init = 1;
|
||||
}
|
||||
else {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
|
||||
}
|
||||
|
||||
if (buffer)
|
||||
MEM_freeN(buffer);
|
||||
}
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Convert a point in model coordinates to 2D screen coordinates. */
|
||||
// XXX duplicated from sculpt.c, deal with this later.
|
||||
static void projectf(bglMats *mats, const float v[3], float p[2])
|
||||
{
|
||||
double ux, uy, uz;
|
||||
|
||||
gluProject(v[0],v[1],v[2], mats->modelview, mats->projection,
|
||||
(GLint *)mats->viewport, &ux, &uy, &uz);
|
||||
p[0]= ux;
|
||||
p[1]= uy;
|
||||
}
|
||||
|
||||
static int project_brush_radius(RegionView3D* rv3d, float radius, float location[3], bglMats* mats)
|
||||
{
|
||||
float view[3], nonortho[3], ortho[3], offset[3], p1[2], p2[2];
|
||||
|
||||
viewvector(rv3d, location, view);
|
||||
|
||||
// create a vector that is not orthogonal to view
|
||||
|
||||
if (fabsf(view[0]) < 0.1) {
|
||||
nonortho[0] = view[0] + 1;
|
||||
nonortho[1] = view[1];
|
||||
nonortho[2] = view[2];
|
||||
}
|
||||
else if (fabsf(view[1]) < 0.1) {
|
||||
nonortho[0] = view[0];
|
||||
nonortho[1] = view[1] + 1;
|
||||
nonortho[2] = view[2];
|
||||
}
|
||||
else {
|
||||
nonortho[0] = view[0];
|
||||
nonortho[1] = view[1];
|
||||
nonortho[2] = view[2] + 1;
|
||||
}
|
||||
|
||||
// get a vector in the plane of the view
|
||||
cross_v3_v3v3(ortho, nonortho, view);
|
||||
normalize_v3(ortho);
|
||||
|
||||
// make a point on the surface of the brush tagent to the view
|
||||
mul_v3_fl(ortho, radius);
|
||||
add_v3_v3v3(offset, location, ortho);
|
||||
|
||||
// project the center of the brush, and the tagent point to the view onto the screen
|
||||
projectf(mats, location, p1);
|
||||
projectf(mats, offset, p2);
|
||||
|
||||
// the distance between these points is the size of the projected brush in pixels
|
||||
return len_v2v2(p1, p2);
|
||||
}
|
||||
|
||||
int sculpt_get_brush_geometry(bContext* C, int x, int y, int* pixel_radius, float location[3], float modelview[16], float projection[16], int viewport[4])
|
||||
{
|
||||
struct PaintStroke *stroke;
|
||||
float window[2];
|
||||
int hit;
|
||||
|
||||
stroke = paint_stroke_new(C, NULL, NULL, NULL, NULL);
|
||||
|
||||
window[0] = x + stroke->vc.ar->winrct.xmin;
|
||||
window[1] = y + stroke->vc.ar->winrct.ymin;
|
||||
|
||||
memcpy(modelview, stroke->vc.rv3d->viewmat, sizeof(float[16]));
|
||||
memcpy(projection, stroke->vc.rv3d->winmat, sizeof(float[16]));
|
||||
memcpy(viewport, stroke->mats.viewport, sizeof(int[4]));
|
||||
|
||||
if (stroke->vc.obact->sculpt && stroke->vc.obact->sculpt->pbvh && sculpt_stroke_get_location(C, stroke, location, window)) {
|
||||
*pixel_radius = project_brush_radius(stroke->vc.rv3d, sculpt_get_brush_unprojected_radius(stroke->brush), location, &stroke->mats);
|
||||
|
||||
if (*pixel_radius == 0)
|
||||
*pixel_radius = sculpt_get_brush_size(stroke->brush);
|
||||
|
||||
mul_m4_v3(stroke->vc.obact->sculpt->ob->obmat, location);
|
||||
|
||||
hit = 1;
|
||||
}
|
||||
else {
|
||||
Sculpt* sd = CTX_data_tool_settings(C)->sculpt;
|
||||
Brush* brush = paint_brush(&sd->paint);
|
||||
|
||||
*pixel_radius = sculpt_get_brush_size(brush);
|
||||
hit = 0;
|
||||
}
|
||||
|
||||
paint_stroke_free(stroke);
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
// XXX duplicated from sculpt.c
|
||||
float unproject_brush_radius(Object *ob, ViewContext *vc, float center[3], float offset)
|
||||
{
|
||||
float delta[3], scale, loc[3];
|
||||
|
||||
mul_v3_m4v3(loc, ob->obmat, center);
|
||||
|
||||
initgrabz(vc->rv3d, loc[0], loc[1], loc[2]);
|
||||
window_to_3d_delta(vc->ar, delta, offset, 0);
|
||||
|
||||
scale= fabsf(mat4_to_scale(ob->obmat));
|
||||
scale= (scale == 0.0f)? 1.0f: scale;
|
||||
|
||||
return len_v3(delta)/scale;
|
||||
}
|
||||
|
||||
// XXX paint cursor now does a lot of the same work that is needed during a sculpt stroke
|
||||
// problem: all this stuff was not intended to be used at this point, so things feel a
|
||||
// bit hacked. I've put lots of stuff in Brush that probably better goes in Paint
|
||||
// Functions should be refactored so that they can be used between sculpt.c and
|
||||
// paint_stroke.c clearly and optimally and the lines of communication between the
|
||||
// two modules should be more clearly defined.
|
||||
static void paint_draw_cursor(bContext *C, int x, int y, void *unused)
|
||||
{
|
||||
ViewContext vc;
|
||||
|
||||
(void)unused;
|
||||
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
|
||||
if (vc.obact->sculpt) {
|
||||
Paint *paint = paint_get_active(CTX_data_scene(C));
|
||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||
Brush *brush = paint_brush(paint);
|
||||
|
||||
int pixel_radius, viewport[4];
|
||||
float location[3], modelview[16], projection[16];
|
||||
|
||||
int hit;
|
||||
|
||||
int flip;
|
||||
int sign;
|
||||
|
||||
float* col;
|
||||
float alpha;
|
||||
|
||||
float visual_strength = sculpt_get_brush_alpha(brush)*sculpt_get_brush_alpha(brush);
|
||||
|
||||
const float min_alpha = 0.20f;
|
||||
const float max_alpha = 0.80f;
|
||||
|
||||
{
|
||||
const float u = 0.5f;
|
||||
const float v = 1 - u;
|
||||
const float r = 20;
|
||||
|
||||
const float dx = sd->last_x - x;
|
||||
const float dy = sd->last_y - y;
|
||||
|
||||
if (dx*dx + dy*dy >= r*r) {
|
||||
sd->last_angle = atan2(dx, dy);
|
||||
|
||||
sd->last_x = u*sd->last_x + v*x;
|
||||
sd->last_y = u*sd->last_y + v*y;
|
||||
}
|
||||
}
|
||||
|
||||
if(!sculpt_get_lock_brush_size(brush) && !(paint->flags & PAINT_SHOW_BRUSH))
|
||||
return;
|
||||
|
||||
hit = sculpt_get_brush_geometry(C, x, y, &pixel_radius, location, modelview, projection, viewport);
|
||||
|
||||
if (sculpt_get_lock_brush_size(brush))
|
||||
sculpt_set_brush_size(brush, pixel_radius);
|
||||
|
||||
// XXX: no way currently to know state of pen flip or invert key modifier without starting a stroke
|
||||
flip = 1;
|
||||
|
||||
sign = flip * ((brush->flag & BRUSH_DIR_IN)? -1 : 1);
|
||||
|
||||
if (sign < 0 && ELEM4(brush->sculpt_tool, SCULPT_TOOL_DRAW, SCULPT_TOOL_INFLATE, SCULPT_TOOL_CLAY, SCULPT_TOOL_PINCH))
|
||||
col = brush->sub_col;
|
||||
else
|
||||
col = brush->add_col;
|
||||
|
||||
alpha = (paint->flags & PAINT_SHOW_BRUSH_ON_SURFACE) ? min_alpha + (visual_strength*(max_alpha-min_alpha)) : 0.50f;
|
||||
|
||||
if (ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_FIXED, MTEX_MAP_MODE_TILED) && brush->flag & BRUSH_TEXTURE_OVERLAY) {
|
||||
glPushAttrib(
|
||||
GL_COLOR_BUFFER_BIT|
|
||||
GL_CURRENT_BIT|
|
||||
GL_DEPTH_BUFFER_BIT|
|
||||
GL_ENABLE_BIT|
|
||||
GL_LINE_BIT|
|
||||
GL_POLYGON_BIT|
|
||||
GL_STENCIL_BUFFER_BIT|
|
||||
GL_TRANSFORM_BIT|
|
||||
GL_VIEWPORT_BIT|
|
||||
GL_TEXTURE_BIT);
|
||||
|
||||
if (load_tex(sd, brush, &vc)) {
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) {
|
||||
glTranslatef(0.5f, 0.5f, 0);
|
||||
|
||||
if (brush->flag & BRUSH_RAKE) {
|
||||
glRotatef(sd->last_angle*(float)(180.0/M_PI), 0, 0, 1);
|
||||
}
|
||||
else {
|
||||
glRotatef(sd->special_rotation*(float)(180.0/M_PI), 0, 0, 1);
|
||||
}
|
||||
|
||||
glTranslatef(-0.5f, -0.5f, 0);
|
||||
|
||||
if (sd->draw_pressure && (brush->flag & BRUSH_SIZE_PRESSURE)) {
|
||||
glTranslatef(0.5f, 0.5f, 0);
|
||||
glScalef(1.0f/sd->pressure_value, 1.0f/sd->pressure_value, 1);
|
||||
glTranslatef(-0.5f, -0.5f, 0);
|
||||
}
|
||||
}
|
||||
|
||||
glColor4f(
|
||||
U.sculpt_paint_overlay_col[0],
|
||||
U.sculpt_paint_overlay_col[1],
|
||||
U.sculpt_paint_overlay_col[2],
|
||||
brush->texture_overlay_alpha / 100.0f);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) {
|
||||
if (sd->draw_anchored) {
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2f(sd->anchored_initial_mouse[0]-sd->anchored_size - vc.ar->winrct.xmin, sd->anchored_initial_mouse[1]-sd->anchored_size - vc.ar->winrct.ymin);
|
||||
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex2f(sd->anchored_initial_mouse[0]+sd->anchored_size - vc.ar->winrct.xmin, sd->anchored_initial_mouse[1]-sd->anchored_size - vc.ar->winrct.ymin);
|
||||
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex2f(sd->anchored_initial_mouse[0]+sd->anchored_size - vc.ar->winrct.xmin, sd->anchored_initial_mouse[1]+sd->anchored_size - vc.ar->winrct.ymin);
|
||||
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex2f(sd->anchored_initial_mouse[0]-sd->anchored_size - vc.ar->winrct.xmin, sd->anchored_initial_mouse[1]+sd->anchored_size - vc.ar->winrct.ymin);
|
||||
}
|
||||
else {
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2f((float)x-sculpt_get_brush_size(brush), (float)y-sculpt_get_brush_size(brush));
|
||||
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex2f((float)x+sculpt_get_brush_size(brush), (float)y-sculpt_get_brush_size(brush));
|
||||
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex2f((float)x+sculpt_get_brush_size(brush), (float)y+sculpt_get_brush_size(brush));
|
||||
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex2f((float)x-sculpt_get_brush_size(brush), (float)y+sculpt_get_brush_size(brush));
|
||||
}
|
||||
}
|
||||
else {
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2f(0, 0);
|
||||
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex2f(viewport[2], 0);
|
||||
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex2f(viewport[2], viewport[3]);
|
||||
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex2f(0, viewport[3]);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
if (hit) {
|
||||
float unprojected_radius;
|
||||
|
||||
// XXX duplicated from brush_strength & paint_stroke_add_step, refactor later
|
||||
//wmEvent* event = CTX_wm_window(C)->eventstate;
|
||||
|
||||
if (sd->draw_pressure && (brush->flag & BRUSH_ALPHA_PRESSURE))
|
||||
visual_strength *= sd->pressure_value;
|
||||
|
||||
// don't show effect of strength past the soft limit
|
||||
if (visual_strength > 1) visual_strength = 1;
|
||||
|
||||
if (sd->draw_anchored) {
|
||||
unprojected_radius = unproject_brush_radius(CTX_data_active_object(C), &vc, location, sd->anchored_size);
|
||||
}
|
||||
else {
|
||||
if (brush->flag & BRUSH_ANCHORED)
|
||||
unprojected_radius = unproject_brush_radius(CTX_data_active_object(C), &vc, location, 8);
|
||||
else
|
||||
unprojected_radius = unproject_brush_radius(CTX_data_active_object(C), &vc, location, sculpt_get_brush_size(brush));
|
||||
}
|
||||
|
||||
if (sd->draw_pressure && (brush->flag & BRUSH_SIZE_PRESSURE))
|
||||
unprojected_radius *= sd->pressure_value;
|
||||
|
||||
if (!sculpt_get_lock_brush_size(brush))
|
||||
sculpt_set_brush_unprojected_radius(brush, unprojected_radius);
|
||||
|
||||
if(!(paint->flags & PAINT_SHOW_BRUSH))
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
glPushAttrib(
|
||||
GL_COLOR_BUFFER_BIT|
|
||||
GL_CURRENT_BIT|
|
||||
GL_DEPTH_BUFFER_BIT|
|
||||
GL_ENABLE_BIT|
|
||||
GL_LINE_BIT|
|
||||
GL_POLYGON_BIT|
|
||||
GL_STENCIL_BUFFER_BIT|
|
||||
GL_TRANSFORM_BIT|
|
||||
GL_VIEWPORT_BIT|
|
||||
GL_TEXTURE_BIT);
|
||||
|
||||
glColor4f(col[0], col[1], col[2], alpha);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
|
||||
if (sd->draw_anchored) {
|
||||
glTranslatef(sd->anchored_initial_mouse[0] - vc.ar->winrct.xmin, sd->anchored_initial_mouse[1] - vc.ar->winrct.ymin, 0.0f);
|
||||
glutil_draw_lined_arc(0.0, M_PI*2.0, sd->anchored_size, 40);
|
||||
glTranslatef(-sd->anchored_initial_mouse[0] + vc.ar->winrct.xmin, -sd->anchored_initial_mouse[1] + vc.ar->winrct.xmin, 0.0f);
|
||||
}
|
||||
else {
|
||||
glTranslatef((float)x, (float)y, 0.0f);
|
||||
glutil_draw_lined_arc(0.0, M_PI*2.0, sculpt_get_brush_size(brush), 40);
|
||||
glTranslatef(-(float)x, -(float)y, 0.0f);
|
||||
}
|
||||
|
||||
glPopAttrib();
|
||||
}
|
||||
else {
|
||||
Paint *paint = paint_get_active(CTX_data_scene(C));
|
||||
Brush *brush = paint_brush(paint);
|
||||
|
||||
if(!(paint->flags & PAINT_SHOW_BRUSH))
|
||||
return;
|
||||
|
||||
glColor4ubv(paint_get_active(CTX_data_scene(C))->paint_cursor_col);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glTranslatef((float)x, (float)y, 0.0f);
|
||||
glutil_draw_lined_arc(0.0, M_PI*2.0, brush->size, 40); // XXX: for now use the brushes size instead of potentially using the unified size because the feature has been enabled for sculpt
|
||||
glTranslatef((float)-x, (float)-y, 0.0f);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */
|
||||
static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, float mouse[2])
|
||||
static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, float mouse_in[2])
|
||||
{
|
||||
Paint *paint = paint_get_active(CTX_data_scene(C)); // XXX
|
||||
Brush *brush = paint_brush(paint); // XXX
|
||||
|
||||
float mouse[2];
|
||||
|
||||
PointerRNA itemptr;
|
||||
float pressure = 1;
|
||||
float center[3] = {0, 0, 0};
|
||||
int flip= event->shift?1:0;
|
||||
|
||||
float location[3];
|
||||
|
||||
float pressure;
|
||||
int pen_flip;
|
||||
|
||||
ViewContext vc; // XXX
|
||||
|
||||
PaintStroke *stroke = op->customdata;
|
||||
|
||||
/* XXX: can remove the if statement once all modes have this */
|
||||
if(stroke->get_location)
|
||||
stroke->get_location(C, stroke, center, mouse);
|
||||
view3d_set_viewcontext(C, &vc); // XXX
|
||||
|
||||
/* Tablet */
|
||||
if(event->custom == EVT_DATA_TABLET) {
|
||||
wmTabletData *wmtab= event->customdata;
|
||||
if(wmtab->Active != EVT_TABLET_NONE)
|
||||
pressure= wmtab->Pressure;
|
||||
if(wmtab->Active == EVT_TABLET_ERASER)
|
||||
flip = 1;
|
||||
|
||||
pressure = (wmtab->Active != EVT_TABLET_NONE) ? wmtab->Pressure : 1;
|
||||
pen_flip = (wmtab->Active == EVT_TABLET_ERASER);
|
||||
}
|
||||
|
||||
else {
|
||||
pressure = 1;
|
||||
pen_flip = 0;
|
||||
}
|
||||
|
||||
// XXX: temporary check for sculpt mode until things are more unified
|
||||
if (vc.obact->sculpt) {
|
||||
float delta[3];
|
||||
|
||||
brush_jitter_pos(brush, mouse_in, mouse);
|
||||
|
||||
// XXX: meh, this is round about because brush_jitter_pos isn't written in the best way to be reused here
|
||||
if (brush->flag & BRUSH_JITTER_PRESSURE) {
|
||||
sub_v3_v3v3(delta, mouse, mouse_in);
|
||||
mul_v3_fl(delta, pressure);
|
||||
add_v3_v3v3(mouse, mouse_in, delta);
|
||||
}
|
||||
}
|
||||
else
|
||||
copy_v3_v3(mouse, mouse_in);
|
||||
|
||||
/* XXX: can remove the if statement once all modes have this */
|
||||
if(stroke->get_location)
|
||||
stroke->get_location(C, stroke, location, mouse);
|
||||
else
|
||||
zero_v3(location);
|
||||
|
||||
/* Add to stroke */
|
||||
RNA_collection_add(op->ptr, "stroke", &itemptr);
|
||||
RNA_float_set_array(&itemptr, "location", center);
|
||||
RNA_float_set_array(&itemptr, "mouse", mouse);
|
||||
RNA_boolean_set(&itemptr, "flip", flip);
|
||||
RNA_float_set(&itemptr, "pressure", pressure);
|
||||
|
||||
RNA_float_set_array(&itemptr, "location", location);
|
||||
RNA_float_set_array(&itemptr, "mouse", mouse);
|
||||
RNA_boolean_set (&itemptr, "pen_flip", pen_flip);
|
||||
RNA_float_set (&itemptr, "pressure", pressure);
|
||||
|
||||
stroke->last_mouse_position[0] = mouse[0];
|
||||
stroke->last_mouse_position[1] = mouse[1];
|
||||
@ -154,10 +852,14 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev
|
||||
/* Returns zero if no sculpt changes should be made, non-zero otherwise */
|
||||
static int paint_smooth_stroke(PaintStroke *stroke, float output[2], wmEvent *event)
|
||||
{
|
||||
output[0] = event->x;
|
||||
output[0] = event->x;
|
||||
output[1] = event->y;
|
||||
|
||||
if(stroke->brush->flag & BRUSH_SMOOTH_STROKE && stroke->brush->sculpt_tool != SCULPT_TOOL_GRAB) {
|
||||
if ((stroke->brush->flag & BRUSH_SMOOTH_STROKE) &&
|
||||
!ELEM4(stroke->brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_SNAKE_HOOK) &&
|
||||
!(stroke->brush->flag & BRUSH_ANCHORED) &&
|
||||
!(stroke->brush->flag & BRUSH_RESTORE_MESH))
|
||||
{
|
||||
float u = stroke->brush->smooth_stroke_factor, v = 1.0 - u;
|
||||
float dx = stroke->last_mouse_position[0] - event->x, dy = stroke->last_mouse_position[1] - event->y;
|
||||
|
||||
@ -176,7 +878,9 @@ static int paint_smooth_stroke(PaintStroke *stroke, float output[2], wmEvent *ev
|
||||
/* Returns zero if the stroke dots should not be spaced, non-zero otherwise */
|
||||
static int paint_space_stroke_enabled(Brush *br)
|
||||
{
|
||||
return (br->flag & BRUSH_SPACE) && !(br->flag & BRUSH_ANCHORED) && (br->sculpt_tool != SCULPT_TOOL_GRAB);
|
||||
return (br->flag & BRUSH_SPACE) &&
|
||||
!(br->flag & BRUSH_ANCHORED) &&
|
||||
!ELEM4(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_SNAKE_HOOK);
|
||||
}
|
||||
|
||||
/* For brushes with stroke spacing enabled, moves mouse in steps
|
||||
@ -187,23 +891,34 @@ static int paint_space_stroke(bContext *C, wmOperator *op, wmEvent *event, const
|
||||
int cnt = 0;
|
||||
|
||||
if(paint_space_stroke_enabled(stroke->brush)) {
|
||||
float mouse[2] = {stroke->last_mouse_position[0], stroke->last_mouse_position[1]};
|
||||
float vec[2] = {final_mouse[0] - mouse[0], final_mouse[1] - mouse[1]};
|
||||
float mouse[2];
|
||||
float vec[2];
|
||||
float length, scale;
|
||||
int steps = 0, i;
|
||||
|
||||
/* Normalize the vector between the last stroke dot and the goal */
|
||||
length = sqrt(vec[0]*vec[0] + vec[1]*vec[1]);
|
||||
copy_v2_v2(mouse, stroke->last_mouse_position);
|
||||
sub_v2_v2v2(vec, final_mouse, mouse);
|
||||
|
||||
length = len_v2(vec);
|
||||
|
||||
if(length > FLT_EPSILON) {
|
||||
scale = stroke->brush->spacing / length;
|
||||
vec[0] *= scale;
|
||||
vec[1] *= scale;
|
||||
int steps;
|
||||
int i;
|
||||
float pressure = 1;
|
||||
|
||||
// XXX duplicate code
|
||||
if(event->custom == EVT_DATA_TABLET) {
|
||||
wmTabletData *wmtab= event->customdata;
|
||||
if(wmtab->Active != EVT_TABLET_NONE)
|
||||
pressure = stroke->brush->flag & BRUSH_SIZE_PRESSURE ? wmtab->Pressure : 1;
|
||||
}
|
||||
|
||||
scale = (sculpt_get_brush_size(stroke->brush)*pressure*stroke->brush->spacing/50.0f) / length;
|
||||
mul_v2_fl(vec, scale);
|
||||
|
||||
steps = (int)(1.0f / scale);
|
||||
|
||||
steps = (int)(length / stroke->brush->spacing);
|
||||
for(i = 0; i < steps; ++i, ++cnt) {
|
||||
mouse[0] += vec[0];
|
||||
mouse[1] += vec[1];
|
||||
add_v2_v2(mouse, vec);
|
||||
paint_brush_stroke_add_step(C, op, event, mouse);
|
||||
}
|
||||
}
|
||||
@ -283,14 +998,25 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
|
||||
//ED_region_tag_redraw(ar);
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
paint_brush_stroke_add_step(C, op, event, mouse);
|
||||
}
|
||||
}
|
||||
else
|
||||
;//ED_region_tag_redraw(ar);
|
||||
}
|
||||
}
|
||||
|
||||
/* we want the stroke to have the first daub at the start location instead of waiting till we have moved the space distance */
|
||||
if(first &&
|
||||
stroke->stroke_started &&
|
||||
paint_space_stroke_enabled(stroke->brush) &&
|
||||
!(stroke->brush->flag & BRUSH_ANCHORED) &&
|
||||
!(stroke->brush->flag & BRUSH_SMOOTH_STROKE))
|
||||
{
|
||||
paint_brush_stroke_add_step(C, op, event, mouse);
|
||||
}
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
|
@ -216,6 +216,10 @@ void BRUSH_OT_curve_preset(wmOperatorType *ot)
|
||||
{CURVE_PRESET_SHARP, "SHARP", 0, "Sharp", ""},
|
||||
{CURVE_PRESET_SMOOTH, "SMOOTH", 0, "Smooth", ""},
|
||||
{CURVE_PRESET_MAX, "MAX", 0, "Max", ""},
|
||||
{CURVE_PRESET_MID9, "MID9", 0, "Mid9", ""},
|
||||
{CURVE_PRESET_LINE, "LINE", 0, "Line", ""},
|
||||
{CURVE_PRESET_ROUND, "ROUND", 0, "Round", ""},
|
||||
{CURVE_PRESET_ROOT, "ROOT", 0, "Root", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
ot->name= "Preset";
|
||||
@ -225,7 +229,7 @@ void BRUSH_OT_curve_preset(wmOperatorType *ot)
|
||||
ot->exec= brush_curve_preset_exec;
|
||||
ot->poll= brush_curve_preset_poll;
|
||||
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
ot->flag= OPTYPE_UNDO;
|
||||
|
||||
RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", "");
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -32,6 +32,9 @@
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_vec_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
|
||||
#include "BLI_pbvh.h"
|
||||
|
||||
struct bContext;
|
||||
struct Brush;
|
||||
@ -65,8 +68,49 @@ void sculpt_stroke_free(struct SculptStroke *);
|
||||
void sculpt_stroke_add_point(struct SculptStroke *, const short x, const short y);
|
||||
void sculpt_stroke_apply(struct Sculpt *sd, struct SculptStroke *);
|
||||
void sculpt_stroke_apply_all(struct Sculpt *sd, struct SculptStroke *);
|
||||
int sculpt_stroke_get_location(bContext *C, struct PaintStroke *stroke, float out[3], float mouse[2]);
|
||||
|
||||
/* Partial Mesh Visibility */
|
||||
void sculptmode_pmv(int mode);
|
||||
|
||||
/* Undo */
|
||||
|
||||
typedef struct SculptUndoNode {
|
||||
struct SculptUndoNode *next, *prev;
|
||||
|
||||
char idname[MAX_ID_NAME]; /* name instead of pointer*/
|
||||
void *node; /* only during push, not valid afterwards! */
|
||||
|
||||
float (*co)[3];
|
||||
short (*no)[3];
|
||||
int totvert;
|
||||
|
||||
/* non-multires */
|
||||
int maxvert; /* to verify if totvert it still the same */
|
||||
int *index; /* to restore into right location */
|
||||
|
||||
/* multires */
|
||||
int maxgrid; /* same for grid */
|
||||
int gridsize; /* same for grid */
|
||||
int totgrid; /* to restore into right location */
|
||||
int *grids; /* to restore into right location */
|
||||
|
||||
/* layer brush */
|
||||
float *layer_disp;
|
||||
|
||||
/* shape keys */
|
||||
char *shapeName[32]; /* keep size in sync with keyblock dna */
|
||||
} SculptUndoNode;
|
||||
|
||||
SculptUndoNode *sculpt_undo_push_node(SculptSession *ss, PBVHNode *node);
|
||||
SculptUndoNode *sculpt_undo_get_node(PBVHNode *node);
|
||||
void sculpt_undo_push_begin(char *name);
|
||||
void sculpt_undo_push_end(void);
|
||||
|
||||
struct MultiresModifierData *sculpt_multires_active(struct Scene *scene, struct Object *ob);
|
||||
int sculpt_modifiers_active(Scene *scene, Object *ob);
|
||||
void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]);
|
||||
|
||||
void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos);
|
||||
|
||||
#endif
|
||||
|
302
source/blender/editors/sculpt_paint/sculpt_undo.c
Normal file
302
source/blender/editors/sculpt_paint/sculpt_undo.c
Normal file
@ -0,0 +1,302 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2006 by Nicholas Bishop
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*
|
||||
* Implements the Sculpt Mode tools
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_multires.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_key.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "ED_sculpt.h"
|
||||
#include "paint_intern.h"
|
||||
#include "sculpt_intern.h"
|
||||
|
||||
/************************** Undo *************************/
|
||||
|
||||
static void update_cb(PBVHNode *node, void *unused)
|
||||
{
|
||||
(void)unused;
|
||||
BLI_pbvh_node_mark_update(node);
|
||||
}
|
||||
|
||||
static void sculpt_undo_restore(bContext *C, ListBase *lb)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
DerivedMesh *dm = mesh_get_derived_final(scene, ob, 0);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
SculptUndoNode *unode;
|
||||
MVert *mvert;
|
||||
MultiresModifierData *mmd;
|
||||
int *index;
|
||||
int i, j, update= 0;
|
||||
|
||||
sculpt_update_mesh_elements(scene, ob, 0);
|
||||
|
||||
for(unode=lb->first; unode; unode=unode->next) {
|
||||
if(!(strcmp(unode->idname, ob->id.name)==0))
|
||||
continue;
|
||||
|
||||
if(unode->maxvert) {
|
||||
char *shapeName= (char*)unode->shapeName;
|
||||
|
||||
/* regular mesh restore */
|
||||
if(ss->totvert != unode->maxvert)
|
||||
continue;
|
||||
|
||||
if (ss->kb && strcmp(ss->kb->name, shapeName)) {
|
||||
/* shape key has been changed before calling undo operator */
|
||||
|
||||
Key *key= ob_get_key(ob);
|
||||
KeyBlock *kb= key_get_named_keyblock(key, shapeName);
|
||||
|
||||
if (kb) {
|
||||
ob->shapenr= BLI_findindex(&key->block, kb) + 1;
|
||||
ob->shapeflag|= OB_SHAPE_LOCK;
|
||||
|
||||
sculpt_update_mesh_elements(scene, ob, 0);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_DATA, ob);
|
||||
} else {
|
||||
/* key has been removed -- skip this undo node */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
index= unode->index;
|
||||
mvert= ss->mvert;
|
||||
|
||||
if (ss->kb) {
|
||||
float (*vertCos)[3];
|
||||
vertCos= key_to_vertcos(ob, ss->kb);
|
||||
|
||||
for(i=0; i<unode->totvert; i++)
|
||||
swap_v3_v3(vertCos[index[i]], unode->co[i]);
|
||||
|
||||
/* propagate new coords to keyblock */
|
||||
sculpt_vertcos_to_key(ob, ss->kb, vertCos);
|
||||
|
||||
/* pbvh uses it's own mvert array, so coords should be */
|
||||
/* propagated to pbvh here */
|
||||
BLI_pbvh_apply_vertCos(ss->pbvh, vertCos);
|
||||
|
||||
MEM_freeN(vertCos);
|
||||
} else {
|
||||
for(i=0; i<unode->totvert; i++) {
|
||||
swap_v3_v3(mvert[index[i]].co, unode->co[i]);
|
||||
mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(unode->maxgrid && dm->getGridData) {
|
||||
/* multires restore */
|
||||
DMGridData **grids, *grid;
|
||||
float (*co)[3];
|
||||
int gridsize;
|
||||
|
||||
if(dm->getNumGrids(dm) != unode->maxgrid)
|
||||
continue;
|
||||
if(dm->getGridSize(dm) != unode->gridsize)
|
||||
continue;
|
||||
|
||||
grids= dm->getGridData(dm);
|
||||
gridsize= dm->getGridSize(dm);
|
||||
|
||||
co = unode->co;
|
||||
for(j=0; j<unode->totgrid; j++) {
|
||||
grid= grids[unode->grids[j]];
|
||||
|
||||
for(i=0; i<gridsize*gridsize; i++, co++)
|
||||
swap_v3_v3(grid[i].co, co[0]);
|
||||
}
|
||||
}
|
||||
|
||||
update= 1;
|
||||
}
|
||||
|
||||
if(update) {
|
||||
/* we update all nodes still, should be more clever, but also
|
||||
needs to work correct when exiting/entering sculpt mode and
|
||||
the nodes get recreated, though in that case it could do all */
|
||||
BLI_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, NULL);
|
||||
BLI_pbvh_update(ss->pbvh, PBVH_UpdateBB|PBVH_UpdateOriginalBB|PBVH_UpdateRedraw, NULL);
|
||||
|
||||
if((mmd=sculpt_multires_active(scene, ob)))
|
||||
multires_mark_as_modified(ob);
|
||||
|
||||
if(ss->modifiers_active || ((Mesh*)ob->data)->id.us > 1)
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
static void sculpt_undo_free(ListBase *lb)
|
||||
{
|
||||
SculptUndoNode *unode;
|
||||
|
||||
for(unode=lb->first; unode; unode=unode->next) {
|
||||
if(unode->co)
|
||||
MEM_freeN(unode->co);
|
||||
if(unode->no)
|
||||
MEM_freeN(unode->no);
|
||||
if(unode->index)
|
||||
MEM_freeN(unode->index);
|
||||
if(unode->grids)
|
||||
MEM_freeN(unode->grids);
|
||||
if(unode->layer_disp)
|
||||
MEM_freeN(unode->layer_disp);
|
||||
}
|
||||
}
|
||||
|
||||
SculptUndoNode *sculpt_undo_get_node(PBVHNode *node)
|
||||
{
|
||||
ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_MESH);
|
||||
SculptUndoNode *unode;
|
||||
|
||||
if(!lb)
|
||||
return NULL;
|
||||
|
||||
for(unode=lb->first; unode; unode=unode->next)
|
||||
if(unode->node == node)
|
||||
return unode;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SculptUndoNode *sculpt_undo_push_node(SculptSession *ss, PBVHNode *node)
|
||||
{
|
||||
ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_MESH);
|
||||
Object *ob= ss->ob;
|
||||
SculptUndoNode *unode;
|
||||
int totvert, allvert, totgrid, maxgrid, gridsize, *grids;
|
||||
|
||||
/* list is manipulated by multiple threads, so we lock */
|
||||
BLI_lock_thread(LOCK_CUSTOM1);
|
||||
|
||||
if((unode= sculpt_undo_get_node(node))) {
|
||||
BLI_unlock_thread(LOCK_CUSTOM1);
|
||||
return unode;
|
||||
}
|
||||
|
||||
unode= MEM_callocN(sizeof(SculptUndoNode), "SculptUndoNode");
|
||||
strcpy(unode->idname, ob->id.name);
|
||||
unode->node= node;
|
||||
|
||||
BLI_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert);
|
||||
BLI_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
|
||||
&maxgrid, &gridsize, NULL, NULL);
|
||||
|
||||
unode->totvert= totvert;
|
||||
/* we will use this while sculpting, is mapalloc slow to access then? */
|
||||
unode->co= MEM_mapallocN(sizeof(float)*3*allvert, "SculptUndoNode.co");
|
||||
unode->no= MEM_mapallocN(sizeof(short)*3*allvert, "SculptUndoNode.no");
|
||||
undo_paint_push_count_alloc(UNDO_PAINT_MESH, (sizeof(float)*3 + sizeof(short)*3 + sizeof(int))*allvert);
|
||||
BLI_addtail(lb, unode);
|
||||
|
||||
if(maxgrid) {
|
||||
/* multires */
|
||||
unode->maxgrid= maxgrid;
|
||||
unode->totgrid= totgrid;
|
||||
unode->gridsize= gridsize;
|
||||
unode->grids= MEM_mapallocN(sizeof(int)*totgrid, "SculptUndoNode.grids");
|
||||
}
|
||||
else {
|
||||
/* regular mesh */
|
||||
unode->maxvert= ss->totvert;
|
||||
unode->index= MEM_mapallocN(sizeof(int)*allvert, "SculptUndoNode.index");
|
||||
}
|
||||
|
||||
BLI_unlock_thread(LOCK_CUSTOM1);
|
||||
|
||||
/* copy threaded, hopefully this is the performance critical part */
|
||||
{
|
||||
PBVHVertexIter vd;
|
||||
|
||||
BLI_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) {
|
||||
copy_v3_v3(unode->co[vd.i], vd.co);
|
||||
if(vd.no) VECCOPY(unode->no[vd.i], vd.no)
|
||||
else normal_float_to_short_v3(unode->no[vd.i], vd.fno);
|
||||
if(vd.vert_indices) unode->index[vd.i]= vd.vert_indices[vd.i];
|
||||
}
|
||||
BLI_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
if(unode->grids)
|
||||
memcpy(unode->grids, grids, sizeof(int)*totgrid);
|
||||
|
||||
/* store active shape key */
|
||||
if(ss->kb) BLI_strncpy((char*)unode->shapeName, ss->kb->name, sizeof(ss->kb->name));
|
||||
else unode->shapeName[0]= '\0';
|
||||
|
||||
return unode;
|
||||
}
|
||||
|
||||
void sculpt_undo_push_begin(char *name)
|
||||
{
|
||||
undo_paint_push_begin(UNDO_PAINT_MESH, name,
|
||||
sculpt_undo_restore, sculpt_undo_free);
|
||||
}
|
||||
|
||||
void sculpt_undo_push_end(void)
|
||||
{
|
||||
ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_MESH);
|
||||
SculptUndoNode *unode;
|
||||
|
||||
/* we don't need normals in the undo stack */
|
||||
for(unode=lb->first; unode; unode=unode->next) {
|
||||
if(unode->no) {
|
||||
MEM_freeN(unode->no);
|
||||
unode->no= NULL;
|
||||
}
|
||||
|
||||
if(unode->layer_disp) {
|
||||
MEM_freeN(unode->layer_disp);
|
||||
unode->layer_disp= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
undo_paint_push_end(UNDO_PAINT_MESH);
|
||||
}
|
@ -945,7 +945,7 @@ int file_directory_exec(bContext *C, wmOperator *unused)
|
||||
if ( sfile->params->dir[0] == '~' ) {
|
||||
char tmpstr[sizeof(sfile->params->dir)-1];
|
||||
strncpy(tmpstr, sfile->params->dir+1, sizeof(tmpstr));
|
||||
BLI_join_dirfile(sfile->params->dir, BLI_gethome(), tmpstr);
|
||||
BLI_join_dirfile(sfile->params->dir, BLI_getDefaultDocumentFolder(), tmpstr);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
|
@ -338,7 +338,7 @@ void fsmenu_read_system(struct FSMenu* fsmenu)
|
||||
/* As 10.4 doesn't provide proper API to retrieve the favorite places,
|
||||
assume they are the standard ones
|
||||
TODO : replace hardcoded paths with proper BLI_get_folder calls */
|
||||
home = BLI_gethome();
|
||||
home = getenv("HOME");
|
||||
if(home) {
|
||||
BLI_snprintf(line, 256, "%s/", home);
|
||||
fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, line, 1, 0);
|
||||
@ -458,7 +458,7 @@ void fsmenu_read_system(struct FSMenu* fsmenu)
|
||||
#else
|
||||
/* unix */
|
||||
{
|
||||
char *home= BLI_gethome();
|
||||
char *home= getenv("HOME");
|
||||
|
||||
if(home) {
|
||||
BLI_snprintf(line, FILE_MAXDIR, "%s/", home);
|
||||
|
@ -792,7 +792,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn
|
||||
uiLayoutSetContextPointer(layout, "edit_image", &imaptr);
|
||||
|
||||
if(!compact)
|
||||
uiTemplateID(layout, C, ptr, propname, "IMAGE_OT_new", "IMAGE_OT_open", NULL);
|
||||
uiTemplateID(layout, C, ptr, propname, "IMAGE_OT_new", "IMAGE_OT_open", NULL, NULL);
|
||||
|
||||
// XXX missing: reload, pack
|
||||
|
||||
|
@ -644,17 +644,17 @@ static char *controller_name(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case CONT_LOGIC_AND:
|
||||
return "AND";
|
||||
return "And";
|
||||
case CONT_LOGIC_OR:
|
||||
return "OR";
|
||||
return "Or";
|
||||
case CONT_LOGIC_NAND:
|
||||
return "NAND";
|
||||
return "Nand";
|
||||
case CONT_LOGIC_NOR:
|
||||
return "NOR";
|
||||
return "Nor";
|
||||
case CONT_LOGIC_XOR:
|
||||
return "XOR";
|
||||
return "Xor";
|
||||
case CONT_LOGIC_XNOR:
|
||||
return "XNOR";
|
||||
return "Xnor";
|
||||
case CONT_EXPRESSION:
|
||||
return "Expression";
|
||||
case CONT_PYTHON:
|
||||
@ -3537,7 +3537,8 @@ static void draw_controller_header(uiLayout *layout, PointerRNA *ptr, int xco, i
|
||||
uiLayout *box, *row, *subrow;
|
||||
bController *cont= (bController *)ptr->data;
|
||||
|
||||
char name[3]; //XXX provisorly for state number
|
||||
char state[3];
|
||||
sprintf(state, "%d", RNA_int_get(ptr, "state"));
|
||||
|
||||
box= uiLayoutBox(layout);
|
||||
row= uiLayoutRow(box, 0);
|
||||
@ -3546,15 +3547,14 @@ static void draw_controller_header(uiLayout *layout, PointerRNA *ptr, int xco, i
|
||||
if(RNA_boolean_get(ptr, "expanded")) {
|
||||
uiItemR(row, ptr, "type", 0, "", 0);
|
||||
uiItemR(row, ptr, "name", 0, "", 0);
|
||||
/* XXX provisory for Blender 2.50Beta */
|
||||
uiDefBlockBut(uiLayoutGetBlock(layout), controller_state_mask_menu, cont, state, (short)(xco+width-44), yco, 22+22, UI_UNIT_Y, "Set controller state index (from 1 to 30)");
|
||||
} else {
|
||||
uiItemL(row, controller_name(cont->type), 0);
|
||||
uiItemL(row, cont->name, 0);
|
||||
uiItemL(row, state, 0);
|
||||
}
|
||||
|
||||
/* XXX provisory for Blender 2.50Beta */
|
||||
sprintf(name, "%d", RNA_int_get(ptr, "state"));
|
||||
uiDefBlockBut(uiLayoutGetBlock(layout), controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22+22, UI_UNIT_Y, "Set controller state index (from 1 to 30)");
|
||||
|
||||
uiItemR(row, ptr, "priority", 0, "", 0);
|
||||
|
||||
if(RNA_boolean_get(ptr, "expanded")==0) {
|
||||
@ -4278,7 +4278,7 @@ static void draw_actuator_sound(uiLayout *layout, PointerRNA *ptr, bContext *C)
|
||||
{
|
||||
uiLayout *row, *col;
|
||||
|
||||
uiTemplateID(layout, C, ptr, "sound", NULL, "SOUND_OT_open", NULL);
|
||||
uiTemplateID(layout, C, ptr, "sound", NULL, "SOUND_OT_open", NULL, NULL);
|
||||
if (!RNA_pointer_get(ptr, "sound").data)
|
||||
{
|
||||
uiItemL(layout, "Select a sound from the list or load a new one", 0);
|
||||
|
@ -237,7 +237,7 @@ static void nla_panel_animdata (const bContext *C, Panel *pa)
|
||||
/* Active Action Properties ------------------------------------- */
|
||||
/* action */
|
||||
row= uiLayoutRow(layout, 1);
|
||||
uiTemplateID(row, (bContext *)C, &adt_ptr, "action", "ACTION_OT_new", NULL, NULL /*"ACTION_OT_unlink"*/); // XXX: need to make these operators
|
||||
uiTemplateID(row, (bContext *)C, &adt_ptr, "action", "ACTION_OT_new", NULL, NULL /*"ACTION_OT_unlink"*/, NULL); // XXX: need to make these operators
|
||||
|
||||
/* extrapolation */
|
||||
row= uiLayoutRow(layout, 1);
|
||||
@ -322,7 +322,7 @@ static void nla_panel_properties(const bContext *C, Panel *pa)
|
||||
column= uiLayoutColumn(layout, 1);
|
||||
uiLayoutSetActive(column, !(RNA_boolean_get(&strip_ptr, "animated_influence") || RNA_boolean_get(&strip_ptr, "animated_time")));
|
||||
uiItemL(column, "Playback Settings:", 0);
|
||||
uiItemR(column, &strip_ptr, "muted", 0, NULL, 0);
|
||||
uiItemR(column, &strip_ptr, "mute", 0, NULL, 0);
|
||||
uiItemR(column, &strip_ptr, "reversed", 0, NULL, 0);
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@
|
||||
|
||||
void node_buts_group(uiLayout *layout, bContext *C, PointerRNA *ptr)
|
||||
{
|
||||
uiTemplateIDBrowse(layout, C, ptr, "nodetree", NULL, NULL, "");
|
||||
uiTemplateIDBrowse(layout, C, ptr, "nodetree", NULL, NULL, "", NULL);
|
||||
}
|
||||
|
||||
static void node_buts_value(uiLayout *layout, bContext *C, PointerRNA *ptr)
|
||||
@ -306,7 +306,7 @@ static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA
|
||||
bNode *node= ptr->data;
|
||||
uiLayout *col;
|
||||
|
||||
uiTemplateID(layout, C, ptr, "material", "MATERIAL_OT_new", NULL, NULL);
|
||||
uiTemplateID(layout, C, ptr, "material", "MATERIAL_OT_new", NULL, NULL, NULL);
|
||||
|
||||
if(!node->id) return;
|
||||
|
||||
@ -467,7 +467,7 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *
|
||||
PointerRNA imaptr;
|
||||
PropertyRNA *prop;
|
||||
|
||||
uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
|
||||
uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL, NULL);
|
||||
|
||||
if(!node->id) return;
|
||||
|
||||
@ -504,7 +504,7 @@ static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, Point
|
||||
const char *layer_name;
|
||||
char scene_name[19];
|
||||
|
||||
uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL);
|
||||
uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, NULL);
|
||||
|
||||
if(!node->id) return;
|
||||
|
||||
@ -1204,7 +1204,7 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *C, PointerRNA *pt
|
||||
|
||||
static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
|
||||
{
|
||||
uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
|
||||
uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL, NULL);
|
||||
}
|
||||
|
||||
static void node_texture_buts_output(uiLayout *layout, bContext *C, PointerRNA *ptr)
|
||||
|
@ -5115,17 +5115,17 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
|
||||
uiBlockSetEmboss(block, UI_EMBOSSN);
|
||||
bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF,
|
||||
(int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (short)te->ys, 17, OL_H-1,
|
||||
&ptr, "restrict_view", -1, 0, 0, -1, -1, NULL);
|
||||
&ptr, "hide", -1, 0, 0, -1, -1, NULL);
|
||||
uiButSetFunc(bt, restrictbutton_view_cb, scene, ob);
|
||||
|
||||
bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF,
|
||||
(int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (short)te->ys, 17, OL_H-1,
|
||||
&ptr, "restrict_select", -1, 0, 0, -1, -1, NULL);
|
||||
&ptr, "hide_select", -1, 0, 0, -1, -1, NULL);
|
||||
uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob);
|
||||
|
||||
bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF,
|
||||
(int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (short)te->ys, 17, OL_H-1,
|
||||
&ptr, "restrict_render", -1, 0, 0, -1, -1, NULL);
|
||||
&ptr, "hide_render", -1, 0, 0, -1, -1, NULL);
|
||||
uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob);
|
||||
|
||||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
|
@ -381,6 +381,8 @@ static void draw_seq_extensions(Scene *scene, ARegion *ar, SpaceSeq *sseq, Seque
|
||||
|
||||
pixely = (v2d->cur.ymax - v2d->cur.ymin)/(v2d->mask.ymax - v2d->mask.ymin);
|
||||
|
||||
if(pixely <= 0) return; /* can happen when the view is split/resized */
|
||||
|
||||
blendcol[0] = blendcol[1] = blendcol[2] = 120;
|
||||
|
||||
if(seq->startofs) {
|
||||
|
@ -621,7 +621,7 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen
|
||||
|
||||
for(seq=ed->seqbasep->first; seq; seq=seq->next) {
|
||||
if(seq->flag & SELECT) {
|
||||
if (seq->type == SEQ_SOUND) {
|
||||
if (seq->type == SEQ_SOUND && get_sequence_effect_num_inputs(type) != 0) {
|
||||
*error_str= "Can't apply effects to audio sequence strips";
|
||||
return 0;
|
||||
}
|
||||
@ -2157,7 +2157,7 @@ static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op)
|
||||
float facx= (v2d->mask.xmax - v2d->mask.xmin) / winx;
|
||||
float facy= (v2d->mask.ymax - v2d->mask.ymin) / winy;
|
||||
|
||||
BLI_resize_rctf(&v2d->cur, winx*facx*ratio, winy*facy*ratio);
|
||||
BLI_resize_rctf(&v2d->cur, (int)(winx*facx*ratio) + 1, (int)(winy*facy*ratio) + 1);
|
||||
|
||||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
|
||||
|
@ -490,9 +490,11 @@ void viewrotate_modal_keymap(wmKeyConfig *keyconf)
|
||||
WM_modalkeymap_add_item(keymap, LEFTALTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_ENABLE);
|
||||
WM_modalkeymap_add_item(keymap, LEFTALTKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_AXIS_SNAP_DISABLE);
|
||||
|
||||
/* disabled mode switching for now, can re-implement better, later on
|
||||
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
|
||||
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
|
||||
WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
|
||||
*/
|
||||
|
||||
/* assign map to operators */
|
||||
WM_modalkeymap_assign(keymap, "VIEW3D_OT_rotate");
|
||||
@ -796,9 +798,11 @@ void viewmove_modal_keymap(wmKeyConfig *keyconf)
|
||||
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
|
||||
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
|
||||
|
||||
/* disabled mode switching for now, can re-implement better, later on
|
||||
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
|
||||
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ZOOM);
|
||||
WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
|
||||
*/
|
||||
|
||||
/* assign map to operators */
|
||||
WM_modalkeymap_assign(keymap, "VIEW3D_OT_move");
|
||||
@ -936,9 +940,11 @@ void viewzoom_modal_keymap(wmKeyConfig *keyconf)
|
||||
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, VIEW_MODAL_CONFIRM);
|
||||
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, VIEW_MODAL_CONFIRM);
|
||||
|
||||
/* disabled mode switching for now, can re-implement better, later on
|
||||
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
|
||||
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_RELEASE, KM_ANY, 0, VIEWROT_MODAL_SWITCH_ROTATE);
|
||||
WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, VIEWROT_MODAL_SWITCH_MOVE);
|
||||
*/
|
||||
|
||||
/* assign map to operators */
|
||||
WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom");
|
||||
|
@ -75,17 +75,17 @@ typedef enum GPUDeviceType {
|
||||
} GPUDeviceType;
|
||||
|
||||
typedef enum GPUOSType {
|
||||
GPU_OS_WIN = (1<<16),
|
||||
GPU_OS_MAC = (1<<17),
|
||||
GPU_OS_UNIX = (1<<18),
|
||||
GPU_OS_WIN = (1<<8),
|
||||
GPU_OS_MAC = (1<<9),
|
||||
GPU_OS_UNIX = (1<<10),
|
||||
GPU_OS_ANY = (0xff00)
|
||||
} GPUOSType;
|
||||
|
||||
typedef enum GPUDriverType {
|
||||
GPU_DRIVER_OFFICIAL = (1<<24),
|
||||
GPU_DRIVER_OPENSOURCE = (1<<25),
|
||||
GPU_DRIVER_SOFTWARE = (1<<26),
|
||||
GPU_DRIVER_UNKNOWN = (0xff0000)
|
||||
GPU_DRIVER_OFFICIAL = (1<<16),
|
||||
GPU_DRIVER_OPENSOURCE = (1<<17),
|
||||
GPU_DRIVER_SOFTWARE = (1<<18),
|
||||
GPU_DRIVER_ANY = (0xff0000)
|
||||
} GPUDriverType;
|
||||
|
||||
int GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user