Merged changes in the trunk up to revision 52191.

Conflicts resolved:
source/blender/makesdna/DNA_scene_types.h
This commit is contained in:
2012-11-14 02:01:02 +00:00
115 changed files with 1964 additions and 646 deletions
+15 -7
View File
@@ -353,12 +353,20 @@ if(NOT WITH_GAMEENGINE AND WITH_PLAYER)
message(FATAL_ERROR "WITH_PLAYER requires WITH_GAMEENGINE")
endif()
if(NOT WITH_AUDASPACE AND (WITH_OPENAL OR WITH_JACK OR WITH_GAMEENGINE))
message(FATAL_ERROR "WITH_OPENAL/WITH_JACK/WITH_CODEC_FFMPEG/WITH_GAMEENGINE require WITH_AUDASPACE")
if(NOT WITH_AUDASPACE)
if(WITH_OPENAL)
message(FATAL_ERROR "WITH_OPENAL requires WITH_AUDASPACE")
endif()
if(WITH_JACK)
message(FATAL_ERROR "WITH_JACK requires WITH_AUDASPACE")
endif()
if(WITH_GAMEENGINE)
message(FATAL_ERROR "WITH_GAMEENGINE requires WITH_AUDASPACE")
endif()
endif()
if(NOT WITH_SDL AND WITH_GHOST_SDL)
message(FATAL_ERROR "WITH_GHOST_SDL requires WITH_SDL to be ON")
message(FATAL_ERROR "WITH_GHOST_SDL requires WITH_SDL")
endif()
if(WITH_IMAGE_REDCODE AND ((NOT WITH_IMAGE_OPENJPEG) OR (NOT WITH_CODEC_FFMPEG)))
@@ -1297,9 +1305,9 @@ elseif(WIN32)
boost_system-${BOOST_DEBUG_POSTFIX} boost_thread-${BOOST_DEBUG_POSTFIX})
if(WITH_INTERNATIONAL)
set(BOOST_LIBRARIES ${BOOST_LIBRARIES}
optimized libboost_locale-${BOOST_POSTFIX}
debug libboost_locale-${BOOST_DEBUG_POSTFIX})
endif(WITH_CYCLES_OSL)
optimized boost_locale-${BOOST_POSTFIX}
debug boost_locale-${BOOST_DEBUG_POSTFIX})
endif()
set(BOOST_LIBPATH ${BOOST}/lib)
set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB -DBOOST_THREAD_USE_LIB ")
endif()
@@ -1474,7 +1482,7 @@ elseif(APPLE)
endif()
if(WITH_INPUT_NDOF)
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -weak_framework /Library/Frameworks/3DconnexionClient.framework/3DconnexionClient")
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -weak_framework 3DconnexionClient")
endif()
endif()
+28 -15
View File
@@ -173,14 +173,15 @@ help:
@echo " * test_style_osl_qtc - checks OpenShadingLanguage conforms with blenders style guide: http://wiki.blender.org/index.php/Dev:Doc/CodeStyle"
@echo ""
@echo "Static Source Code Checking (not associated with building blender)"
@echo " * check_cppcheck - run blender source through cppcheck (C & C++)"
@echo " * check_clang_array - run blender source through clang array checking script (C & C++)"
@echo " * check_splint - run blenders source through splint (C only)"
@echo " * check_sparse - run blenders source through sparse (C only)"
@echo " * check_smatch - run blenders source through smatch (C only)"
@echo " * check_spelling_c - check for spelling errors (OSL only)"
@echo " * check_spelling_osl - check for spelling errors (C/C++ only)"
@echo " * check_spelling_py - check for spelling errors (Python only)"
@echo " * check_cppcheck - run blender source through cppcheck (C & C++)"
@echo " * check_clang_array - run blender source through clang array checking script (C & C++)"
@echo " * check_splint - run blenders source through splint (C only)"
@echo " * check_sparse - run blenders source through sparse (C only)"
@echo " * check_smatch - run blenders source through smatch (C only)"
@echo " * check_spelling_c - check for spelling errors (OSL only)"
@echo " * check_spelling_c_qtc - same as check_spelling_c but outputs QtCreator tasks format"
@echo " * check_spelling_osl - check for spelling errors (C/C++ only)"
@echo " * check_spelling_py - check for spelling errors (Python only)"
@echo ""
@echo "Utilities (not associated with building blender)"
@echo " * tbz - create a compressed svn export 'blender_archive.tar.bz2'"
@@ -270,29 +271,41 @@ project_eclipse:
check_cppcheck:
$(CMAKE_CONFIG)
cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py
cd $(BUILD_DIR) ; \
python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py
check_clang_array:
$(CMAKE_CONFIG)
cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_clang_array.py
cd $(BUILD_DIR) ; \
python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_clang_array.py
check_splint:
$(CMAKE_CONFIG)
cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py
cd $(BUILD_DIR) ; \
python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py
check_sparse:
$(CMAKE_CONFIG)
cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py
cd $(BUILD_DIR) ; \
python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py
check_smatch:
$(CMAKE_CONFIG)
cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py
cd $(BUILD_DIR) ; \
python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py
check_spelling_py:
cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/release/scripts
cd $(BUILD_DIR) ; \
PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/release/scripts
check_spelling_c:
cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source
cd $(BUILD_DIR) ; \
PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source
check_spelling_c_qtc:
cd $(BUILD_DIR) ; USE_QTC_TASK=1 \
PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source > \
$(BLENDER_DIR)/check_spelling_c.tasks
check_spelling_osl:
cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/intern/cycles/kernel/osl
+12 -6
View File
@@ -422,16 +422,22 @@ if not quickie and do_clean:
# with _any_ library but since we used a fixed python version this tends to
# be most problematic.
if env['WITH_BF_PYTHON']:
py_h = os.path.join(Dir(env.subst('${BF_PYTHON_INC}')).abspath, "Python.h")
found_python_h = found_pyconfig_h = False
for bf_python_inc in env.subst('${BF_PYTHON_INC}').split():
py_h = os.path.join(Dir(bf_python_inc).abspath, "Python.h")
if os.path.exists(py_h):
found_python_h = True
py_h = os.path.join(Dir(bf_python_inc).abspath, "pyconfig.h")
if os.path.exists(py_h):
found_pyconfig_h = True
if not os.path.exists(py_h):
print("\nMissing: \"" + env.subst('${BF_PYTHON_INC}') + os.sep + "Python.h\",\n"
if not (found_python_h and found_pyconfig_h):
print("\nMissing: Python.h and/or pyconfig.h in\"" + env.subst('${BF_PYTHON_INC}') + "\",\n"
" Set 'BF_PYTHON_INC' to point "
"to a valid python include path.\n Containing "
"Python.h for python version \"" + env.subst('${BF_PYTHON_VERSION}') + "\"")
"to valid python include path(s).\n Containing "
"Python.h and pyconfig.h for python version \"" + env.subst('${BF_PYTHON_VERSION}') + "\"")
Exit()
del py_h
if not os.path.isdir ( B.root_build_dir):
+634
View File
@@ -0,0 +1,634 @@
#!/bin/bash
DISTRO=""
SRC="$HOME/src/blender-deps"
CWD=$PWD
THREADS=`cat /proc/cpuinfo | grep cores | uniq | sed -e "s/.*: *\(.*\)/\\1/"`
PYTHON_VERSION="3.3.0"
BOOST_VERSION="1_51_0"
OIIO_VERSION="1.1.0"
OCIO_VERSION="1.0.7"
FFMPEG_VERSION="1.0"
_ffmpeg_list_sep=";"
HASXVID=false
XVIDDEV=""
HASVPX=false
HASMP3LAME=false
HASX264=false
HASOPENJPEG=false
HASSCHRO=false
# Switch to english language, else some things (like check_package_DEB()) won't work!
LANG_BACK=$LANG
LANG=""
export LANG
ERROR() {
echo "${@}"
}
INFO() {
echo "${@}"
}
detect_distro() {
if [ -f /etc/debian_version ]; then
DISTRO="DEB"
elif [ -f /etc/redhat-release ]; then
DISTRO="RPM"
elif [ -f /etc/SuSE-release ]; then
DISTRO="SUSE"
fi
}
prepare_opt() {
INFO "Ensuring /opt/lib exists and writable by us"
sudo mkdir -p /opt/lib
sudo chown $USER /opt/lib
sudo chmod 775 /opt/lib
}
compile_Python() {
if [ ! -d /opt/lib/python-$PYTHON_VERSION ]; then
INFO "Building Python-$PYTHON_VERSION"
prepare_opt
if [ ! -d $SRC/Python-$PYTHON_VERSION ]; then
mkdir -p $SRC
wget -c http://python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tar.bz2 -P $SRC
INFO "Unpacking Python-$PYTHON_VERSION"
tar -C $SRC -xf $SRC/Python-$PYTHON_VERSION.tar.bz2
fi
cd $SRC/Python-$PYTHON_VERSION
./configure --prefix=/opt/lib/python-$PYTHON_VERSION --enable-ipv6 \
--enable-loadable-sqlite-extensions --with-dbmliborder=bdb \
--with-computed-gotos --with-pymalloc
make -j$THREADS
make install
make clean
rm -f /opt/lib/python-3.3
ln -s python-$PYTHON_VERSION /opt/lib/python-3.3
cd $CWD
fi
}
compile_Boost() {
INFO "Building boost"
version_dots=`echo "$BOOST_VERSION" | sed -r 's/_/./g'`
if [ ! -d /opt/lib/boost-$version_dots ]; then
INFO "Building Boost-$version_dots"
prepare_opt
if [ ! -d $SRC/boost_$BOOST_VERSION ]; then
INFO "Downloading Boost-$version_dots"
mkdir -p $SRC
wget -c http://sourceforge.net/projects/boost/files/boost/$version_dots/boost_$BOOST_VERSION.tar.bz2/download \
-O $SRC/boost_$BOOST_VERSION.tar.bz2
tar -C $SRC -xf $SRC/boost_$BOOST_VERSION.tar.bz2
fi
cd $SRC/boost_$BOOST_VERSION
./bootstrap.sh --with-libraries=system,filesystem,thread,regex,locale --prefix=/opt/lib/boost-$version_dots
./b2 install
./b2 --clean
rm -f /opt/lib/boost
ln -s boost-$version_dots /opt/lib/boost
cd $CWD
fi
}
compile_OCIO() {
if [ ! -d /opt/lib/ocio-$OCIO_VERSION ]; then
INFO "Building OpenColorIO-$OCIO_VERSION"
prepare_opt
if [ ! -d $SRC/OpenColorIO-$OCIO_VERSION ]; then
INFO "Downloading OpenColorIO-$OCIO_VERSION"
mkdir -p $SRC
wget -c http://github.com/imageworks/OpenColorIO/tarball/v$OCIO_VERSION \
-O $SRC/OpenColorIO-$OCIO_VERSION.tar.gz
INFO "Unpacking OpenColorIO-$OCIO_VERSION"
tar -C "$SRC" -xf $SRC/OpenColorIO-$OCIO_VERSION.tar.gz
mv $SRC/imageworks-OpenColorIO* $SRC/OpenColorIO-$OCIO_VERSION
fi
cd $SRC/OpenColorIO-$OCIO_VERSION
mkdir build
cd build
if file /bin/cp | grep -q '32-bit'; then
cflags="-fPIC -m32 -march=i686"
else
cflags="-fPIC"
fi
cmake -D CMAKE_BUILD_TYPE=Release \
-D CMAKE_PREFIX_PATH=/opt/lib/ocio-$OCIO_VERSION \
-D CMAKE_INSTALL_PREFIX=/opt/lib/ocio-$OCIO_VERSION \
-D CMAKE_CXX_FLAGS="$cflags" \
-D CMAKE_EXE_LINKER_FLAGS="-lgcc_s -lgcc" \
..
make -j$THREADS
make install
# Force linking against sttaic libs
rm -f /opt/lib/ocio-$OCIO_VERSION/lib/*.so*
# Additional depencencies
cp ext/dist/lib/libtinyxml.a /opt/lib/ocio-$OCIO_VERSION/lib
cp ext/dist/lib/libyaml-cpp.a /opt/lib/ocio-$OCIO_VERSION/lib
make clean
rm -f /opt/lib/ocio
ln -s ocio-$OCIO_VERSION /opt/lib/ocio
cd $CWD
fi
}
compile_OIIO() {
if [ ! -d /opt/lib/oiio-$OIIO_VERSION ]; then
INFO "Building OpenImageIO-$OIIO_VERSION"
prepare_opt
if [ ! -d $SRC/OpenImageIO-$OIIO_VERSION ]; then
wget -c https://github.com/OpenImageIO/oiio/tarball/Release-$OIIO_VERSION \
-O "$SRC/OpenImageIO-$OIIO_VERSION.tar.gz"
INFO "Unpacking OpenImageIO-$OIIO_VERSION"
tar -C $SRC -xf $SRC/OpenImageIO-$OIIO_VERSION.tar.gz
mv $SRC/OpenImageIO-oiio* $SRC/OpenImageIO-$OIIO_VERSION
fi
cd $SRC/OpenImageIO-$OIIO_VERSION
mkdir build
cd build
if [ -d /opt/lib/boost ]; then
boost_root="/opt/lib/boost"
else
boost_root="/usr"
fi
if file /bin/cp | grep -q '32-bit'; then
cflags="-fPIC -m32 -march=i686"
else
cflags="-fPIC"
fi
cmake -D CMAKE_BUILD_TYPE=Release \
-D CMAKE_PREFIX_PATH=/opt/lib/oiio-$OIIO_VERSION \
-D CMAKE_INSTALL_PREFIX=/opt/lib/oiio-$OIIO_VERSION \
-D BUILDSTATIC=ON \
-D CMAKE_CXX_FLAGS="$cflags" \
-D CMAKE_EXE_LINKER_FLAGS="-lgcc_s -lgcc" \
-D BOOST_ROOT="$boost_root" \
../src
make -j$THREADS
make install
make clean
rm -f /opt/lib/oiio
ln -s oiio-$OIIO_VERSION /opt/lib/oiio
cd $CWD
fi
}
compile_FFmpeg() {
if [ ! -d /opt/lib/ffmpeg-$FFMPEG_VERSION ]; then
INFO "Building FFmpeg-$FFMPEG_VERSION"
prepare_opt
if [ ! -d $SRC/ffmpeg-$FFMPEG_VERSION ]; then
INFO "Downloading FFmpeg-$FFMPEG_VERSION"
wget -c http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2 -P $SRC
INFO "Unpacking FFmpeg-$FFMPEG_VERSION"
tar -C $SRC -xf $SRC/ffmpeg-$FFMPEG_VERSION.tar.bz2
fi
cd $SRC/ffmpeg-$FFMPEG_VERSION
extra=""
if $HASXVID; then
extra="$extra --enable-libxvid"
fi
if $HASVPX; then
extra="$extra --enable-libvpx"
fi
if $HASMP3LAME; then
extra="$extra --enable-libmp3lame"
fi
if $HASX264; then
extra="$extra --enable-libx264"
fi
if $HASOPENJPEG; then
extra="$extra --enable-libopenjpeg"
fi
if $HASSCHRO; then
extra="$extra --enable-libschroedinger"
fi
./configure --cc="gcc -Wl,--as-needed" --extra-ldflags="-pthread -static-libgcc" \
--prefix=/opt/lib/ffmpeg-$FFMPEG_VERSION --enable-static --enable-avfilter --disable-vdpau \
--disable-bzlib --disable-libgsm --disable-libspeex --enable-libtheora \
--enable-libvorbis --enable-pthreads --enable-zlib --enable-stripping --enable-runtime-cpudetect \
--disable-vaapi --disable-libfaac --disable-nonfree --enable-gpl \
--disable-postproc --disable-x11grab --disable-librtmp --disable-libopencore-amrnb \
--disable-libopencore-amrwb --disable-libdc1394 --disable-version3 --disable-outdev=sdl \
--disable-outdev=alsa --disable-indev=sdl --disable-indev=alsa --disable-indev=jack \
--disable-indev=lavfi $extra
make -j$THREADS
make install
make clean
rm -f /opt/lib/ffmpeg
ln -s ffmpeg-$FFMPEG_VERSION /opt/lib/ffmpeg
cd $CWD
fi
}
deb_version() {
dpkg-query -W -f '${Version}' $1 | sed -r 's/^([0-9]\.[0-9]+).*/\1/'
}
check_package_DEB() {
r=`apt-cache policy $1 | grep -c 'Candidate:'`
if [ $r -ge 1 ]; then
return 0
else
return 1
fi
}
install_DEB() {
INFO "Installing dependencies for DEB-based distributive"
sudo apt-get update
sudo apt-get -y upgrade
sudo apt-get install -y cmake scons gcc g++ libjpeg-dev libpng-dev libtiff-dev \
libfreetype6-dev libx11-dev libxi-dev wget libsqlite3-dev libbz2-dev libncurses5-dev \
libssl-dev liblzma-dev libreadline-dev libopenjpeg-dev libopenexr-dev libopenal-dev \
libglew-dev yasm libschroedinger-dev libtheora-dev libvorbis-dev libsdl1.2-dev \
libfftw3-dev libjack-dev python-dev patch
HASOPENJPEG=true
HASSCHRO=true
check_package_DEB libxvidcore-dev
if [ $? -eq 0 ]; then
sudo apt-get install -y libxvidcore-dev
HASXVID=true
XVIDDEV="libxvidcore-dev"
fi
check_package_DEB libxvidcore4-dev
if [ $? -eq 0 ]; then
sudo apt-get install -y libxvidcore4-dev
HASXVID=true
XVIDDEV="libxvidcore4-dev"
fi
check_package_DEB libmp3lame-dev
if [ $? -eq 0 ]; then
sudo apt-get install -y libmp3lame-dev
HASMP3LAME=true
fi
check_package_DEB libx264-dev
if [ $? -eq 0 ]; then
sudo apt-get install -y libx264-dev
HASX264=true
fi
check_package_DEB libvpx-dev
if [ $? -eq 0 ]; then
sudo apt-get install -y libvpx-dev
vpx_version=`deb_version libvpx-dev`
if [ ! -z "$vpx_version" ]; then
if dpkg --compare-versions $vpx_version gt 0.9.7; then
HASVPX=true
fi
fi
fi
check_package_DEB libspnav-dev
if [ $? -eq 0 ]; then
sudo apt-get install -y libspnav-dev
fi
check_package_DEB python3.3-dev
if [ $? -eq 0 ]; then
sudo apt-get install -y python3.3-dev
else
compile_Python
fi
check_package_DEB libboost-dev
if [ $? -eq 0 ]; then
sudo apt-get install -y libboost-dev
boost_version=`deb_version libboost-dev`
check_package_DEB libboost-locale$boost_version-dev
if [ $? -eq 0 ]; then
sudo apt-get install -y libboost-locale$boost_version-dev libboost-filesystem$boost_version-dev \
libboost-regex$boost_version-dev libboost-system$boost_version-dev libboost-thread$boost_version-dev
else
compile_Boost
fi
else
compile_Boost
fi
check_package_DEB libopencolorio-dev
if [ $? -eq 0 ]; then
sudo apt-get install -y libopencolorio-dev
else
compile_OCIO
fi
check_package_DEB libopenimageio-dev
if [ $? -eq 0 ]; then
sudo apt-get install -y libopenimageio-dev
else
compile_OIIO
fi
# XXX Debian features libav packages as ffmpeg, those are not really compatible with blender code currently :/
# So for now, always build our own ffmpeg.
# check_package_DEB ffmpeg
# if [ $? -eq 0 ]; then
# sudo apt-get install -y ffmpeg
# ffmpeg_version=`deb_version ffmpeg`
# INFO "ffmpeg version: $ffmpeg_version"
# if [ ! -z "$ffmpeg_version" ]; then
# if dpkg --compare-versions $ffmpeg_version gt 0.7.2; then
# sudo apt-get install -y libavfilter-dev libavcodec-dev libavdevice-dev libavformat-dev libavutil-dev libswscale-dev
# else
# compile_FFmpeg
# fi
# fi
# fi
compile_FFmpeg
}
check_package_RPM() {
r=`yum info $1 | grep -c 'Summary'`
if [ $r -ge 1 ]; then
return 0
else
return 1
fi
}
check_package_version_RPM() {
v=`yum info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'`
# for now major and minor versions only (as if x.y, not x.y.z)
r=`echo $v | grep -c $2`
if [ $r -ge 1 ]; then
return 0
else
return 1
fi
}
install_RPM() {
INFO "Installing dependencies for RPM-based distributive"
sudo yum -y update
sudo yum -y install gcc gcc-c++ cmake scons libpng-devel libtiff-devel \
freetype-devel libX11-devel libXi-devel wget libsqlite3x-devel ncurses-devel \
readline-devel openjpeg-devel openexr-devel openal-soft-devel \
glew-devel yasm schroedinger-devel libtheora-devel libvorbis-devel SDL-devel \
fftw-devel lame-libs jack-audio-connection-kit-devel x264-devel libspnav-devel \
libjpeg-devel patch python-devel
HASOPENJPEG=true
HASSCHRO=true
check_package_version_RPM python-devel 3.3.
if [ $? -eq 0 ]; then
sudo yum install -y python-devel
else
compile_Python
fi
check_package_RPM boost-devel
if [ $? -eq 0 ]; then
sudo yum install -y boost-devel
else
compile_Boost
fi
check_package_RPM OpenColorIO-devel
if [ $? -eq 0 ]; then
sudo yum install -y OpenColorIO-devel
else
compile_OCIO
fi
check_package_RPM OpenImageIO-devel
if [ $? -eq 0 ]; then
sudo yum install -y OpenImageIO-devel
else
compile_OIIO
fi
# Always for now, not sure which packages should be installed
compile_FFmpeg
}
check_package_SUSE() {
r=`zypper info $1 | grep -c 'Summary'`
if [ $r -ge 1 ]; then
return 0
else
return 1
fi
}
check_package_version_SUSE() {
v=`zypper info $1 | grep Version | tail -n 1 | sed -r 's/.*:\s+(([0-9]+\.?)+).*/\1/'`
# for now major and minor versions only (as if x.y, not x.y.z)
r=`echo $v | grep -c $2`
if [ $r -ge 1 ]; then
return 0
else
return 1
fi
}
install_SUSE() {
INFO "Installing dependencies for SuSE-based distributive"
sudo zypper --non-interactive update --auto-agree-with-licenses
sudo zypper --non-interactive install --auto-agree-with-licenses \
gcc gcc-c++ libSDL-devel openal-soft-devel libpng12-devel libjpeg62-devel \
libtiff-devel OpenEXR-devel yasm libtheora-devel libvorbis-devel cmake \
scons patch
check_package_version_SUSE python3-devel 3.3.
if [ $? -eq 0 ]; then
sudo zypper --non-interactive install --auto-agree-with-licenses python3-devel
else
compile_Python
fi
# can not see boost_locale in repo, so let's build own boost
compile_Boost
# this libraries are also missing in the repo
compile_OCIO
compile_OIIO
compile_FFmpeg
}
print_info_ffmpeglink_DEB() {
_packages="libtheora-dev"
if $HASXVID; then
_packages="$_packages $XVIDDEV"
fi
if $HASVPX; then
_packages="$_packages libvpx-dev"
fi
if $HASMP3LAME; then
_packages="$_packages libmp3lame-dev"
fi
if $HASX264; then
_packages="$_packages libx264-dev"
fi
if $HASOPENJPEG; then
_packages="$_packages libopenjpeg-dev"
fi
if $HASSCHRO; then
_packages="$_packages libschroedinger-dev"
fi
dpkg -L $_packages | grep -e ".*\/lib[^\/]\+\.so" | awk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }'
}
print_info_ffmpeglink() {
# This func must only print a ';'-separated list of libs...
if [ -z "$DISTRO" ]; then
ERROR "Failed to detect distribution type"
exit 1
elif [ "$DISTRO" = "DEB" ]; then
print_info_ffmpeglink_DEB
# XXX TODO!
else INFO "<Could not determine additional link libraries needed for ffmpeg, replace this by valid list of libs...>"
# elif [ "$DISTRO" = "RPM" ]; then
# print_info_ffmpeglink_RPM
# elif [ "$DISTRO" = "SUSE" ]; then
# print_info_ffmpeglink_SUSE
fi
}
print_info() {
INFO ""
INFO "If you're using CMake add this to your configuration flags:"
if [ -d /opt/lib/boost ]; then
INFO " -D BOOST_ROOT=/opt/lib/boost"
INFO " -D Boost_NO_SYSTEM_PATHS=ON"
fi
if [ -d /opt/lib/ffmpeg ]; then
INFO " -D WITH_CODEC_FFMPEG=ON"
INFO " -D FFMPEG=/opt/lib/ffmpeg"
INFO " -D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;`print_info_ffmpeglink`'"
fi
INFO ""
INFO "If you're using SCons add this to your user-config:"
if [ -d /opt/lib/python-3.3 ]; then
INFO "BF_PYTHON='/opt/lib/python-3.3'"
INFO "BF_PYTHON_ABI_FLAGS='m'"
fi
if [ -d /opt/lib/ocio ]; then
INFO "BF_OCIO='/opt/lib/ocio'"
fi
if [ -d /opt/lib/oiio ]; then
INFO "BF_OIIO='/opt/lib/oiio'"
fi
if [ -d /opt/lib/boost ]; then
INFO "BF_BOOST='/opt/lib/boost'"
fi
if [ -d /opt/lib/ffmpeg ]; then
INFO "BF_FFMPEG='/opt/lib/ffmpeg'"
_ffmpeg_list_sep=" "
INFO "BF_FFMPEG_LIB='avformat avcodec swscale avutil avdevice `print_info_ffmpeglink`'"
fi
}
# Detect distributive type used on this machine
detect_distro
if [ -z "$DISTRO" ]; then
ERROR "Failed to detect distribution type"
exit 1
elif [ "$DISTRO" = "DEB" ]; then
install_DEB
elif [ "$DISTRO" = "RPM" ]; then
install_RPM
elif [ "$DISTRO" = "SUSE" ]; then
install_SUSE
fi
print_info
# Switch back to user language.
LANG=LANG_BACK
export LANG
@@ -133,7 +133,8 @@ WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/lib/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \
'${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
'${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a \
${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# Ocean Simulation
@@ -132,7 +132,8 @@ WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/lib/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \
'${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
'${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a \
${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# Ocean Simulation
@@ -119,7 +119,7 @@ WITH_BF_BOOST = True
WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# Ocean Simulation
@@ -118,7 +118,7 @@ WITH_BF_BOOST = True
WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# Ocean Simulation
@@ -98,7 +98,8 @@ WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/lib/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \
'${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
'${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a \
${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
@@ -98,7 +98,8 @@ WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/lib/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \
'${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
'${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a \
${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
@@ -94,7 +94,7 @@ WITH_BF_BOOST = True
WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
@@ -94,7 +94,7 @@ WITH_BF_BOOST = True
WITH_BF_STATICBOOST = True
BF_BOOST = '/opt/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# JACK
@@ -39,6 +39,7 @@ SET(_opencolorio_SEARCH_DIRS
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt/lib/ocio
)
FIND_PATH(OPENCOLORIO_INCLUDE_DIR
@@ -33,6 +33,7 @@ SET(_openimageio_SEARCH_DIRS
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt/lib/oiio
)
FIND_PATH(OPENIMAGEIO_INCLUDE_DIR
@@ -78,6 +78,7 @@ IF((NOT _IS_INC_DEF) OR (NOT _IS_INC_CONF_DEF) OR (NOT _IS_LIB_DEF) OR (NOT _IS_
${PYTHON_ROOT_DIR}
"$ENV{HOME}/py${_PYTHON_VERSION_NO_DOTS}"
"/opt/py${_PYTHON_VERSION_NO_DOTS}"
"/opt/lib/python-${PYTHON_VERSION}"
)
FOREACH(_CURRENT_ABI_FLAGS ${_python_ABI_FLAGS})
+1 -2
View File
@@ -292,8 +292,7 @@ WITH_BF_BOOST = True
BF_BOOST = LIBDIR + '/boost'
BF_BOOST_INC = BF_BOOST + '/include'
BF_BOOST_LIB = 'boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt'
if WITH_BF_INTERNATIONAL:
BF_BOOST_LIB += ' boost_locale-mt'
BF_BOOST_LIB_INTERNATIONAL = 'boost_locale-mt'
BF_BOOST_LIBPATH = BF_BOOST + '/lib'
WITH_BF_CYCLES_CUDA_BINARIES = False
+1 -2
View File
@@ -226,8 +226,7 @@ if not os.path.exists(LCGDIR + '/boost'):
BF_BOOST = '/usr'
BF_BOOST_INC = BF_BOOST + '/include'
BF_BOOST_LIB = 'boost_date_time boost_filesystem boost_regex boost_system boost_thread'
if WITH_BF_INTERNATIONAL:
BF_BOOST_LIB += ' boost_locale'
BF_BOOST_LIB_INTERNATIONAL = 'boost_locale'
BF_BOOST_LIBPATH = BF_BOOST + '/lib'
WITH_BF_CYCLES = WITH_BF_OIIO and WITH_BF_BOOST
@@ -164,8 +164,7 @@ WITH_BF_BOOST = True
BF_BOOST = LIBDIR + '/boost'
BF_BOOST_INC = BF_BOOST + '/include'
BF_BOOST_LIB = 'boost_date_time-mgw46-mt-s-1_49 boost_filesystem-mgw46-mt-s-1_49 boost_regex-mgw46-mt-s-1_49 boost_system-mgw46-mt-s-1_49 boost_thread-mgw46-mt-s-1_49'
if WITH_BF_INTERNATIONAL:
BF_BOOST_LIB += ' boost_locale-mgw46-mt-s-1_49'
BF_BOOST_LIB_INTERNATIONAL = 'boost_locale-mgw46-mt-s-1_49'
BF_BOOST_LIBPATH = BF_BOOST + '/lib'
#Ray trace optimization
+1 -2
View File
@@ -166,8 +166,7 @@ WITH_BF_BOOST = True
BF_BOOST = '${LIBDIR}/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49'
if WITH_BF_INTERNATIONAL:
BF_BOOST_LIB += ' libboost_locale-vc90-mt-s-1_49'
BF_BOOST_LIB_INTERNATIONAL = 'libboost_locale-vc90-mt-s-1_49'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#CUDA
@@ -164,8 +164,7 @@ WITH_BF_BOOST = True
BF_BOOST = LIBDIR + '/boost'
BF_BOOST_INC = BF_BOOST + '/include'
BF_BOOST_LIB = 'boost_date_time-mgw47-mt-s-1_49 boost_date_time-mgw47-mt-sd-1_49 boost_filesystem-mgw47-mt-s-1_49 boost_filesystem-mgw47-mt-sd-1_49 boost_regex-mgw47-mt-s-1_49 boost_regex-mgw47-mt-sd-1_49 boost_system-mgw47-mt-s-1_49 boost_system-mgw47-mt-sd-1_49 boost_thread-mgw47-mt-s-1_49 boost_thread-mgw47-mt-sd-1_49'
if WITH_BF_INTERNATIONAL:
BF_BOOST_LIB += ' boost_locale-mgw47-mt-s-1_49 boost_locale-mgw47-mt-sd-1_49'
BF_BOOST_LIB_INTERNATIONAL = ' boost_locale-mgw47-mt-s-1_49 boost_locale-mgw47-mt-sd-1_49'
BF_BOOST_LIBPATH = BF_BOOST + '/lib'
#Ray trace optimization
+1 -2
View File
@@ -164,8 +164,7 @@ WITH_BF_BOOST = True
BF_BOOST = '${LIBDIR}/boost'
BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_49 libboost_filesystem-vc90-mt-s-1_49 libboost_regex-vc90-mt-s-1_49 libboost_system-vc90-mt-s-1_49 libboost_thread-vc90-mt-s-1_49'
if WITH_BF_INTERNATIONAL:
BF_BOOST_LIB += ' libboost_locale-vc90-mt-s-1_49'
BF_BOOST_LIB_INTERNATIONAL = ' libboost_locale-vc90-mt-s-1_49'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#CUDA
+3
View File
@@ -310,6 +310,9 @@ def setup_syslibs(lenv):
if lenv['WITH_BF_BOOST'] and not lenv['WITH_BF_STATICBOOST']:
syslibs += Split(lenv['BF_BOOST_LIB'])
if lenv['WITH_BF_INTERNATIONAL']:
syslibs += Split(lenv['BF_BOOST_LIB_INTERNATIONAL'])
if not lenv['WITH_BF_STATICJPEG']:
syslibs += Split(lenv['BF_JPEG_LIB'])
+2 -1
View File
@@ -163,7 +163,7 @@ def validate_arguments(args, bc):
'WITH_BF_CYCLES', 'WITH_BF_CYCLES_CUDA_BINARIES', 'BF_CYCLES_CUDA_NVCC', 'BF_CYCLES_CUDA_NVCC', 'WITH_BF_CYCLES_CUDA_THREADED_COMPILE',
'WITH_BF_OIIO', 'WITH_BF_STATICOIIO', 'BF_OIIO', 'BF_OIIO_INC', 'BF_OIIO_LIB', 'BF_OIIO_LIB_STATIC', 'BF_OIIO_LIBPATH',
'WITH_BF_OCIO', 'WITH_BF_STATICOCIO', 'BF_OCIO', 'BF_OCIO_INC', 'BF_OCIO_LIB', 'BF_OCIO_LIB_STATIC', 'BF_OCIO_LIBPATH',
'WITH_BF_BOOST', 'WITH_BF_STATICBOOST', 'BF_BOOST', 'BF_BOOST_INC', 'BF_BOOST_LIB', 'BF_BOOST_LIB_STATIC', 'BF_BOOST_LIBPATH',
'WITH_BF_BOOST', 'WITH_BF_STATICBOOST', 'BF_BOOST', 'BF_BOOST_INC', 'BF_BOOST_LIB', 'BF_BOOST_LIB_INTERNATIONAL', 'BF_BOOST_LIB_STATIC', 'BF_BOOST_LIBPATH',
'WITH_BF_LIBMV'
]
@@ -590,6 +590,7 @@ def read_opts(env, cfg, args):
('BF_BOOST', 'Boost root path', ''),
('BF_BOOST_INC', 'Boost include path', ''),
('BF_BOOST_LIB', 'Boost library', ''),
('BF_BOOST_LIB_INTERNATIONAL', 'Boost library', ''),
('BF_BOOST_LIBPATH', 'Boost library path', ''),
('BF_BOOST_LIB_STATIC', 'Boost static library', ''),
+3 -3
View File
@@ -989,13 +989,13 @@ Types
:type: :class:`KX_GameObject` or None
.. attribute:: group_children
.. attribute:: groupMembers
Returns the list of group members if the object is a group object, otherwise None is returned.
:type: :class:`CListValue` of :class:`KX_GameObject` or None
.. attribute:: group_parent
.. attribute:: groupObject
Returns the group object that the object belongs to or None if the object is not part of a group.
@@ -1966,7 +1966,7 @@ Types
:arg matrix: transformation matrix.
:type matrix: 4x4 matrix [[float]]
.. method:: transform_uv(matid, matrix, uv_index=-1, uv_index_from=-1)
.. method:: transformUV(matid, matrix, uv_index=-1, uv_index_from=-1)
Transforms the vertices UV's of a mesh.
+47 -10
View File
@@ -118,18 +118,19 @@ If you insist - yes its possible, but scripts that use this hack wont be conside
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
I can't edit the mesh in edit-mode!
===================================
Modes and Mesh Access
=====================
Blender's EditMesh is an internal data structure (not saved and not exposed to python), this gives the main annoyance that you need to exit edit-mode to edit the mesh from python.
When working with mesh data you may run into the problem where a script fails to run as expected in edit-mode. This is caused by edit-mode having its own data which is only written back to the mesh when exiting edit-mode.
The reason we have not made much attempt to fix this yet is because we
will likely move to BMesh mesh API eventually, so any work on the API now will be wasted effort.
A common example is that exporters may access a mesh through ``obj.data`` (a :class:`bpy.types.Mesh`) but the user is in edit-mode, where the mesh data is available but out of sync with the edit mesh.
With the BMesh API we may expose mesh data to python so we can
write useful tools in python which are also fast to execute while in edit-mode.
In this situation you can...
For the time being this limitation just has to be worked around but we're aware its frustrating needs to be addressed.
* Exit edit-mode before running the tool.
* Explicitly update the mesh by calling :class:`bmesh.types.BMesh.to_mesh`.
* Modify the script to support working on the edit-mode data directly, see: :mod:`bmesh.from_edit_mesh`.
* Report the context as incorrect and only allow the script to run outside edit-mode.
.. _info_gotcha_mesh_faces:
@@ -311,7 +312,7 @@ Naming Limitations
A common mistake is to assume newly created data is given the requested name.
This can cause bugs when you add some data (normally imported) and then reference it later by name.
This can cause bugs when you add some data (normally imported) then reference it later by name.
.. code-block:: python
@@ -557,6 +558,21 @@ This example shows how you can tell undo changes the memory locations.
As suggested above, simply not holding references to data when Blender is used interactively by the user is the only way to ensure the script doesn't become unstable.
Undo & Library Data
^^^^^^^^^^^^^^^^^^^
One of the advantages with Blenders library linking system that undo can skip checking changes in library data since it is assumed to be static.
Tools in Blender are not allowed to modify library data.
Python however does not enforce this restriction.
This can be useful in some cases, using a script to adjust material values for example.
But its also possible to use a script to make library data point to newly created local data, which is not supported since a call to undo will remove the local data but leave the library referencing it and likely crash.
So it's best to consider modifying library data an advanced usage of the API and only to use it when you know what you're doing.
Edit Mode / Memory Access
-------------------------
@@ -616,7 +632,28 @@ Removing Data
**Any** data that you remove shouldn't be modified or accessed afterwards, this includes f-curves, drivers, render layers, timeline markers, modifiers, constraints along with objects, scenes, groups, bones.. etc.
This is a problem in the API at the moment that we should eventually solve.
The ``remove()`` api calls will invalidate the data they free to prevent common mistakes.
The following example shows how this precortion works.
.. code-block:: python
mesh = bpy.data.meshes.new(name="MyMesh")
# normally the script would use the mesh here...
bpy.data.meshes.remove(mesh)
print(mesh.name) # <- give an exception rather then crashing:
# ReferenceError: StructRNA of type Mesh has been removed
But take care because this is limited to scripts accessing the variable which is removed, the next example will still crash.
.. code-block:: python
mesh = bpy.data.meshes.new(name="MyMesh")
vertices = mesh.vertices
bpy.data.meshes.remove(mesh)
print(vertices) # <- this may crash
sys.exit
+4 -4
View File
@@ -64,8 +64,8 @@ public:
* Writes a reader to a writer.
* \param reader The reader to read from.
* \param writer The writer to write to.
* \param length How many samples should be transfered.
* \param buffersize How many samples should be transfered at once.
* \param length How many samples should be transferred.
* \param buffersize How many samples should be transferred at once.
*/
static void writeReader(boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_IWriter> writer, unsigned int length, unsigned int buffersize);
@@ -73,8 +73,8 @@ public:
* Writes a reader to several writers.
* \param reader The reader to read from.
* \param writers The writers to write to.
* \param length How many samples should be transfered.
* \param buffersize How many samples should be transfered at once.
* \param length How many samples should be transferred.
* \param buffersize How many samples should be transferred at once.
*/
static void writeReader(boost::shared_ptr<AUD_IReader> reader, std::vector<boost::shared_ptr<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize);
};
+1 -1
View File
@@ -32,7 +32,7 @@ incs.extend('#source/blender/blenloader ../../source/blender/makesrna/intern'.sp
incs.extend('#extern/glew/include #intern/mikktspace'.split())
incs.append(cycles['BF_OIIO_INC'])
incs.append(cycles['BF_BOOST_INC'])
incs.append(cycles['BF_PYTHON_INC'])
incs.extend(cycles['BF_PYTHON_INC'].split())
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'.split())
+2 -2
View File
@@ -518,8 +518,8 @@ void BlenderSession::get_progress(float& progress, double& total_time)
sample = session->progress.get_sample();
samples_per_tile = session->params.samples;
if(samples_per_tile)
progress = ((float)sample/(float)(tile_total * samples_per_tile));
if(samples_per_tile && tile_total)
progress = ((float)sample / (float)(tile_total * samples_per_tile));
else
progress = 0.0;
}
+1 -1
View File
@@ -757,7 +757,7 @@ void Session::update_status_time(bool show_pause, bool show_done)
if(preview_time == 0.0 && resolution == 1)
preview_time = time_dt();
double tile_time = (tile == 0)? 0.0: (time_dt() - preview_time - paused_time)/(sample);
double tile_time = (tile == 0 || sample == 0)? 0.0: (time_dt() - preview_time - paused_time) / sample;
/* negative can happen when we pause a bit before rendering, can discard that */
if(preview_time < 0.0) preview_time = 0.0;
+1 -1
View File
@@ -256,7 +256,7 @@ createWindow(
window = new GHOST_WindowX11(this, m_display, title,
left, top, width, height,
state, parentWindow, type, stereoVisual);
state, parentWindow, type, stereoVisual, numOfAASamples);
if (window) {
/* Both are now handle in GHOST_WindowX11.cpp
+1 -1
View File
@@ -11,4 +11,4 @@ if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
incs += ' ' + env['BF_BOOST_INC']
env.BlenderLib( 'bf_intern_locale', sources, Split(incs), defs, libtype=['extern','player'], priority=[10, 185])
env.BlenderLib( 'bf_intern_locale', sources, Split(incs), defs, libtype=['intern','player'], priority=[10, 185])
+1 -1
View File
@@ -170,7 +170,7 @@ public :
}
/**
* Assignment operator - ownership is transfered from rhs to lhs.
* Assignment operator - ownership is transferred from rhs to lhs.
* There is an intenional side-effect of function of transferring
* ownership from the const parameter rhs. This is to insure
* the 1-1 relationship.
@@ -40,46 +40,46 @@ LANGUAGES_CATEGORIES = (
)
LANGUAGES = (
# ID, UI english label, ISO code.
( 0, "Default (Default)", "DEFAULT", ""),
( 1, "English (English)", "en_US", "english"),
( 2, "Japanese (日本語)", "ja_JP", "japanese"),
( 3, "Dutch (Nederlandse taal)", "nl_NL", "dutch"),
( 4, "Italian (Italiano)", "it_IT", "italian"),
( 5, "German (Deutsch)", "de_DE", "german"),
( 6, "Finnish (Suomi)", "fi_FI", "finnish"),
( 7, "Swedish (Svenska)", "sv_SE", "swedish"),
( 8, "French (Français)", "fr_FR", "french"),
( 9, "Spanish (Español)", "es", "spanish"),
(10, "Catalan (Català)", "ca_AD", "catalan"),
(11, "Czech (Český)", "cs_CZ", "czech"),
(12, "Portuguese (Português)", "pt_PT", "portuguese_portugal"),
(13, "Simplified Chinese (简体中文)", "zh_CN", "Chinese (Simplified)_China.1252"),
(14, "Traditional Chinese (繁體中文)", "zh_TW", "Chinese (Traditional)_China.1252"),
(15, "Russian (Русский)", "ru_RU", "russian"),
(16, "Croatian (Hrvatski)", "hr_HR", "croatian"),
(17, "Serbian (Српски)", "sr_RS", "serbian"),
(18, "Ukrainian (Український)", "uk_UA", "ukrainian"),
(19, "Polish (Polski)", "pl_PL", "polish"),
(20, "Romanian (Român)", "ro_RO", "romanian"),
( 0, "Default (Default)", "DEFAULT"),
( 1, "English (English)", "en_US"),
( 2, "Japanese (日本語)", "ja_JP"),
( 3, "Dutch (Nederlandse taal)", "nl_NL"),
( 4, "Italian (Italiano)", "it_IT"),
( 5, "German (Deutsch)", "de_DE"),
( 6, "Finnish (Suomi)", "fi_FI"),
( 7, "Swedish (Svenska)", "sv_SE"),
( 8, "French (Français)", "fr_FR"),
( 9, "Spanish (Español)", "es"),
(10, "Catalan (Català)", "ca_AD"),
(11, "Czech (Český)", "cs_CZ"),
(12, "Portuguese (Português)", "pt_PT"),
(13, "Simplified Chinese (简体中文)", "zh_CN"),
(14, "Traditional Chinese (繁體中文)", "zh_TW"),
(15, "Russian (Русский)", "ru_RU"),
(16, "Croatian (Hrvatski)", "hr_HR"),
(17, "Serbian (Српски)", "sr_RS"),
(18, "Ukrainian (Український)", "uk_UA"),
(19, "Polish (Polski)", "pl_PL"),
(20, "Romanian (Român)", "ro_RO"),
# Using the utf8 flipped form of Arabic (العربية).
(21, "Arabic (ﺔﻴﺑﺮﻌﻟﺍ)", "ar_EG", "arabic"),
(22, "Bulgarian (Български)", "bg_BG", "bulgarian"),
(23, "Greek (Ελληνικά)", "el_GR", "greek"),
(24, "Korean (한국 언어)", "ko_KR", "korean"),
(25, "Nepali (नेपाली)", "ne_NP", "nepali"),
(21, "Arabic (ﺔﻴﺑﺮﻌﻟﺍ)", "ar_EG"),
(22, "Bulgarian (Български)", "bg_BG"),
(23, "Greek (Ελληνικά)", "el_GR"),
(24, "Korean (한국 언어)", "ko_KR"),
(25, "Nepali (नेपाली)", "ne_NP"),
# Using the utf8 flipped form of Persian (فارسی).
(26, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR", "farsi"),
(27, "Indonesian (Bahasa indonesia)", "id_ID", "indonesian"),
(28, "Serbian Latin (Srpski latinica)", "sr_RS@latin", "serbian (latin)"),
(29, "Kyrgyz (Кыргыз тили)", "ky_KG", "kyrgyz"),
(30, "Turkish (Türkçe)", "tr_TR", "turkish"),
(31, "Hungarian (Magyar)", "hu_HU", "hungarian"),
(32, "Brazilian Portuguese (Português do Brasil)", "pt_BR", "protuguese_brazil"),
(26, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR"),
(27, "Indonesian (Bahasa indonesia)", "id_ID"),
(28, "Serbian Latin (Srpski latinica)", "sr_RS@latin"),
(29, "Kyrgyz (Кыргыз тили)", "ky_KG"),
(30, "Turkish (Türkçe)", "tr_TR"),
(31, "Hungarian (Magyar)", "hu_HU"),
(32, "Brazilian Portuguese (Português do Brasil)", "pt_BR"),
# Using the utf8 flipped form of Hebrew (עִבְרִית)).
(33, "Hebrew (תירִבְעִ)", "he_IL", "hebrew"),
(34, "Estonian (Eestlane)", "et_EE", "estonian"),
(35, "Esperanto (Esperanto)", "eo", "esperanto"),
(36, "Spanish from Spain (Español de España)", "es_ES", "spanish_spain"),
(33, "Hebrew (תירִבְעִ)", "he_IL"),
(34, "Estonian (Eestlane)", "et_EE"),
(35, "Esperanto (Esperanto)", "eo"),
(36, "Spanish from Spain (Español de España)", "es_ES"),
)
# Name of language file used by Blender to generate translations' menu.
@@ -53,7 +53,7 @@ FLAG_MESSAGES = {
def find_matching_po(languages, stats, forbidden):
"""Match languages defined in LANGUAGES setting to relevant po, if possible!"""
ret = []
for uid, label, org_key, long_loc in languages:
for uid, label, org_key, in languages:
key = org_key
if key not in stats:
# Try to simplify the key (eg from es_ES to es).
@@ -64,11 +64,11 @@ def find_matching_po(languages, stats, forbidden):
key = key + org_key[org_key.index('@'):]
if key in stats:
if key in forbidden:
ret.append((stats[key], uid, label, org_key, long_loc, FORBIDDEN))
ret.append((stats[key], uid, label, org_key, FORBIDDEN))
else:
ret.append((stats[key], uid, label, org_key, long_loc, OK))
ret.append((stats[key], uid, label, org_key, OK))
else:
ret.append((0.0, uid, label, org_key, long_loc, MISSING))
ret.append((0.0, uid, label, org_key, MISSING))
return ret
def main():
@@ -103,14 +103,14 @@ def main():
stats = sorted(stats, key=lambda it: it[0], reverse=True)
langs_cats = [[] for i in range(len(limits))]
highest_uid = 0
for prop, uid, label, key, long_loc, flag in stats:
for prop, uid, label, key, flag in stats:
if prop < limits[idx][0]:
# Sub-sort languages by iso-codes.
langs_cats[idx].sort(key=lambda it: it[2])
idx += 1
if prop < min_trans and flag == OK:
flag = TOOLOW
langs_cats[idx].append((uid, label, key, long_loc, flag))
langs_cats[idx].append((uid, label, key, flag))
if abs(uid) > highest_uid:
highest_uid = abs(uid)
# Sub-sort last group of languages by iso-codes!
@@ -120,7 +120,7 @@ def main():
f.write("# and to generate translation menu.\n")
f.write("#\n")
f.write("# File format:\n")
f.write("# ID:MENULABEL:ISOCODE:WINCODE\n")
f.write("# ID:MENULABEL:ISOCODE\n")
f.write("# ID must be unique, except for 0 value (marks categories for menu).\n")
f.write("# Line starting with a # are comments!\n")
f.write("#\n")
@@ -135,12 +135,12 @@ def main():
# Do not write the category if it has no language!
f.write("# Void category! #0:{}:\n".format(cat[1]))
# ...and all matching language entries!
for uid, label, key, long_loc, flag in langs_cat:
for uid, label, key, flag in langs_cat:
if flag == OK:
f.write("{}:{}:{}:{}\n".format(uid, label, key, long_loc))
f.write("{}:{}:{}\n".format(uid, label, key))
else:
# Non-existing, commented entry!
f.write("# {} #{}:{}:{}:{}\n".format(FLAG_MESSAGES[flag], uid, label, key, long_loc))
f.write("# {} #{}:{}:{}\n".format(FLAG_MESSAGES[flag], uid, label, key))
if __name__ == "__main__":
@@ -554,6 +554,12 @@ class WM_MT_operator_presets(Menu):
def draw(self, context):
self.operator = context.active_operator.bl_idname
# dummy 'default' menu item
layout = self.layout
layout.operator("wm.operator_defaults")
layout.seperator()
Menu.draw_preset(self, context)
@property
@@ -249,6 +249,7 @@ class IMAGE_MT_uvs_weldalign(Menu):
layout = self.layout
layout.operator("uv.weld") # W, 1
layout.operator("uv.remove_doubles")
layout.operator_enum("uv.align", "axis") # W, 2/3/4
+3 -12
View File
@@ -1736,18 +1736,9 @@ class VIEW3D_MT_edit_mesh_select_mode(Menu):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
props = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL')
props.value = "(True, False, False)"
props.data_path = "tool_settings.mesh_select_mode"
props = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL')
props.value = "(False, True, False)"
props.data_path = "tool_settings.mesh_select_mode"
props = layout.operator("wm.context_set_value", text="Face", icon='FACESEL')
props.value = "(False, False, True)"
props.data_path = "tool_settings.mesh_select_mode"
layout.operator("mesh.select_mode", text="Vertex", icon='VERTEXSEL').type = 'VERT'
layout.operator("mesh.select_mode", text="Edge", icon='EDGESEL').type = 'EDGE'
layout.operator("mesh.select_mode", text="Face", icon='FACESEL').type = 'FACE'
class VIEW3D_MT_edit_mesh_extrude(Menu):
+2 -2
View File
@@ -319,8 +319,8 @@ int modifier_dependsOnTime(struct ModifierData *md);
int modifier_supportsMapping(struct ModifierData *md);
int modifier_couldBeCage(struct Scene *scene, struct ModifierData *md);
int modifier_isCorrectableDeformed(struct ModifierData *md);
int modifier_sameTopology(ModifierData *md);
int modifier_nonGeometrical(ModifierData *md);
int modifier_isSameTopology(ModifierData *md);
int modifier_isNonGeometrical(ModifierData *md);
int modifier_isEnabled(struct Scene *scene, struct ModifierData *md, int required_mode);
void modifier_setError(struct ModifierData *md, const char *format, ...)
#ifdef __GNUC__
+1 -1
View File
@@ -248,7 +248,7 @@ void BKE_sequencer_cache_cleanup(void);
struct ImBuf *BKE_sequencer_cache_get(SeqRenderData context, struct Sequence *seq, float cfra, seq_stripelem_ibuf_t type);
/* passed ImBuf is properly refed, so ownership is *not*
* transfered to the cache.
* transferred to the cache.
* you can pass the same ImBuf multiple times to the cache without problems.
*/
+1
View File
@@ -4,6 +4,7 @@ import os
sources = env.Glob('intern/*.c')
sources.remove('intern' + os.sep + 'mask_rasterize.c')
sources.remove('intern' + os.sep + 'mask_evaluate.c')
sources.remove('intern' + os.sep + 'mask.c')
sources_mask = env.Glob('intern/mask*.c')
+26 -13
View File
@@ -1008,8 +1008,8 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *
const ColorManagedDisplaySettings *display_settings)
{
int x, y, c;
unsigned int n, nl;
double div, divl;
unsigned int nl, na, nr, ng, nb;
double divl, diva, divr, divg, divb;
float *rf = NULL;
unsigned char *rc = NULL;
unsigned int *bin_lum, *bin_r, *bin_g, *bin_b, *bin_a;
@@ -1149,24 +1149,37 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *
savedlines += 1;
}
/* test for nicer distribution even - non standard, leave it out for a while */
#if 0
for (x = 0; x < 256; x++) {
bin_lum[x] = sqrt (bin_lum[x]);
bin_r[x] = sqrt(bin_r[x]);
bin_g[x] = sqrt(bin_g[x]);
bin_b[x] = sqrt(bin_b[x]);
bin_a[x] = sqrt(bin_a[x]);
}
#endif
/* convert hist data to float (proportional to max count) */
n = 0;
nl = 0;
nl = na = nr = nb = ng = 0;
for (x = 0; x < 256; x++) {
if (bin_lum[x] > nl) nl = bin_lum[x];
if (bin_r[x] > n) n = bin_r[x];
if (bin_g[x] > n) n = bin_g[x];
if (bin_b[x] > n) n = bin_b[x];
if (bin_a[x] > n) n = bin_a[x];
if (bin_r[x] > nr) nr = bin_r[x];
if (bin_g[x] > ng) ng = bin_g[x];
if (bin_b[x] > nb) nb = bin_b[x];
if (bin_a[x] > na) na = bin_a[x];
}
div = 1.0 / (double)n;
divl = 1.0 / (double)nl;
diva = 1.0 / (double)na;
divr = 1.0 / (double)nr;
divg = 1.0 / (double)ng;
divb = 1.0 / (double)nb;
for (x = 0; x < 256; x++) {
scopes->hist.data_luma[x] = bin_lum[x] * divl;
scopes->hist.data_r[x] = bin_r[x] * div;
scopes->hist.data_g[x] = bin_g[x] * div;
scopes->hist.data_b[x] = bin_b[x] * div;
scopes->hist.data_a[x] = bin_a[x] * div;
scopes->hist.data_r[x] = bin_r[x] * divr;
scopes->hist.data_g[x] = bin_g[x] * divg;
scopes->hist.data_b[x] = bin_b[x] * divb;
scopes->hist.data_a[x] = bin_a[x] * diva;
}
MEM_freeN(bin_lum);
MEM_freeN(bin_r);
+2 -1
View File
@@ -671,8 +671,9 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
}
}
}
else if(ob->type == OB_LAMP)
else if (ob->type == OB_LAMP) {
dag_add_lamp_driver_relations(dag, node, ob->data);
}
/* particles */
psys = ob->particlesystem.first;
+1 -1
View File
@@ -3011,7 +3011,7 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
MLoop *l_iter = loopstart;
float area, polynorm_local[3], (*vertexcos)[3];
const float *no = polynormal ? polynormal : polynorm_local;
BLI_array_fixedstack_declare(vertexcos, BM_NGON_STACK_SIZE, mpoly->totloop, __func__);
BLI_array_fixedstack_declare(vertexcos, BM_DEFAULT_NGON_STACK_SIZE, mpoly->totloop, __func__);
/* pack vertex cos into an array for area_poly_v3 */
for (i = 0; i < mpoly->totloop; i++, l_iter++) {
+2 -2
View File
@@ -249,13 +249,13 @@ int modifier_couldBeCage(struct Scene *scene, ModifierData *md)
modifier_supportsMapping(md));
}
int modifier_sameTopology(ModifierData *md)
int modifier_isSameTopology(ModifierData *md)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
return ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical);
}
int modifier_nonGeometrical(ModifierData *md)
int modifier_isNonGeometrical(ModifierData *md)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
return (mti->type == eModifierTypeType_NonGeometrical);
+10 -8
View File
@@ -198,18 +198,18 @@ int BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
return TRUE;
}
void BKE_object_link_modifiers(struct Object *ob, struct Object *from)
void BKE_object_link_modifiers(struct Object *ob_dst, struct Object *ob_src)
{
ModifierData *md;
BKE_object_free_modifiers(ob);
BKE_object_free_modifiers(ob_dst);
if (!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
if (!ELEM5(ob_dst->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
/* only objects listed above can have modifiers and linking them to objects
* which doesn't have modifiers stack is quite silly */
return;
}
for (md = from->modifiers.first; md; md = md->next) {
for (md = ob_src->modifiers.first; md; md = md->next) {
ModifierData *nmd = NULL;
if (ELEM4(md->type,
@@ -221,16 +221,18 @@ void BKE_object_link_modifiers(struct Object *ob, struct Object *from)
continue;
}
if (!BKE_object_support_modifier_type_check(ob, md->type))
if (!BKE_object_support_modifier_type_check(ob_dst, md->type))
continue;
nmd = modifier_new(md->type);
BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
modifier_copyData(md, nmd);
BLI_addtail(&ob->modifiers, nmd);
BLI_addtail(&ob_dst->modifiers, nmd);
modifier_unique_name(&ob_dst->modifiers, nmd);
}
BKE_object_copy_particlesystems(ob, from);
BKE_object_copy_softbody(ob, from);
BKE_object_copy_particlesystems(ob_dst, ob_src);
BKE_object_copy_softbody(ob_dst, ob_src);
/* TODO: smoke?, cloth? */
}
@@ -139,6 +139,25 @@ MINLINE int power_of_2_min_i(int n)
return n;
}
MINLINE unsigned int highest_order_bit_i(unsigned int n)
{
n |= (n >> 1);
n |= (n >> 2);
n |= (n >> 4);
n |= (n >> 8);
n |= (n >> 16);
return n - (n >> 1);
}
MINLINE unsigned short highest_order_bit_s(unsigned short n)
{
n |= (n >> 1);
n |= (n >> 2);
n |= (n >> 4);
n |= (n >> 8);
return n - (n >> 1);
}
MINLINE float min_ff(float a, float b)
{
return (a < b) ? a : b;
+44 -10
View File
@@ -456,16 +456,50 @@ float BLI_turbulence1(float noisesize, float x, float y, float z, int nr)
/* ********************* FROM PERLIN HIMSELF: ******************** */
static char p[512 + 2] = {
0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D,
0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D,
0xA2, 0xA0
static const char p[512 + 2] = {
0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28,
0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D,
0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8,
0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7,
0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13,
0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB,
0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB,
0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E,
0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C,
0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93,
0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D, 0xBF, 0x33, 0x9C, 0x5F,
0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30,
0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2,
0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9,
0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5,
0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8,
0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4,
0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3,
0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD,
0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75,
0xA4, 0x88, 0xFB, 0x5D, 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE,
0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F,
0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32,
0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83,
0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8,
0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D,
0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50,
0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98,
0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4,
0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA,
0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E,
0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F,
0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0,
0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B,
0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10,
0xB9, 0xCE, 0xC9, 0x8D, 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4,
0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8,
0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0,
0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E,
0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A,
0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D, 0xA2, 0xA0
};
@@ -901,7 +901,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
ob->matbits = MEM_callocN(sizeof(char)*ob->totcol, "ob->matbits");
for (a = 0; a < ob->totcol; a++)
ob->matbits[a] = ob->colbits & (1<<a);
ob->matbits[a] = (ob->colbits & (1<<a)) != 0;
}
}
+8 -2
View File
@@ -244,10 +244,16 @@ enum {
# define BM_FACE_FIRST_LOOP(p) ((p)->l_first)
#endif
/* size to use for static arrays when dealing with NGons,
/**
* size to use for stack arrays when dealing with NGons,
* alloc after this limit is reached.
* this value is rather arbitrary */
#define BM_NGON_STACK_SIZE 32
#define BM_DEFAULT_NGON_STACK_SIZE 32
/**
* size to use for stack arrays dealing with connected mesh data
* verts of faces, edges of vert - etc.
* often used with #BM_iter_as_arrayN() */
#define BM_DEFAULT_ITER_STACK_SIZE 16
/* avoid inf loop, this value is arbitrary
* but should not error on valid cases */
@@ -174,9 +174,9 @@ void BM_face_copy_shared(BMesh *bm, BMFace *f)
BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble)
{
BMEdge **edges2 = NULL;
BLI_array_staticdeclare(edges2, BM_NGON_STACK_SIZE);
BLI_array_staticdeclare(edges2, BM_DEFAULT_NGON_STACK_SIZE);
BMVert **verts = NULL;
BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
BMFace *f = NULL;
BMEdge *e;
BMVert *v, *ev1, *ev2;
+19 -14
View File
@@ -195,8 +195,8 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
{
BMVert **verts = NULL;
BMEdge **edges = NULL;
BLI_array_fixedstack_declare(verts, BM_NGON_STACK_SIZE, f->len, __func__);
BLI_array_fixedstack_declare(edges, BM_NGON_STACK_SIZE, f->len, __func__);
BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
BLI_array_fixedstack_declare(edges, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
BMLoop *l_iter;
BMLoop *l_first;
BMLoop *l_copy;
@@ -558,7 +558,7 @@ static void bm_kill_only_loop(BMesh *bm, BMLoop *l)
void BM_face_edges_kill(BMesh *bm, BMFace *f)
{
BMEdge **edges = NULL;
BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
BMLoop *l_iter;
BMLoop *l_first;
int i;
@@ -582,7 +582,7 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f)
void BM_face_verts_kill(BMesh *bm, BMFace *f)
{
BMVert **verts = NULL;
BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
BMLoop *l_iter;
BMLoop *l_first;
int i;
@@ -734,7 +734,7 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f
const int do_disps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
BMLoop *l_iter, *oldprev, *oldnext;
BMEdge **edar = NULL;
BLI_array_fixedstack_declare(edar, BM_NGON_STACK_SIZE, len, __func__);
BLI_array_fixedstack_declare(edar, BM_DEFAULT_NGON_STACK_SIZE, len, __func__);
int i, j, edok;
for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) {
@@ -937,9 +937,9 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del
BMEdge **edges = NULL;
BMEdge **deledges = NULL;
BMVert **delverts = NULL;
BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
BLI_array_staticdeclare(deledges, BM_NGON_STACK_SIZE);
BLI_array_staticdeclare(delverts, BM_NGON_STACK_SIZE);
BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
BLI_array_staticdeclare(deledges, BM_DEFAULT_NGON_STACK_SIZE);
BLI_array_staticdeclare(delverts, BM_DEFAULT_NGON_STACK_SIZE);
BMVert *v1 = NULL, *v2 = NULL;
const char *err = NULL;
int i, tote = 0;
@@ -1587,7 +1587,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou
if (LIKELY(radlen)) {
BMLoop **loops = NULL;
BLI_array_fixedstack_declare(loops, BM_NGON_STACK_SIZE, radlen, __func__);
BLI_array_fixedstack_declare(loops, BM_DEFAULT_NGON_STACK_SIZE, radlen, __func__);
killoop = ke->l;
@@ -1808,23 +1808,28 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
*/
int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target)
{
BMEdge *e;
void *loops_stack[BM_DEFAULT_ITER_STACK_SIZE];
BMLoop **loops;
int i, loops_tot;
BMEdge *e;
/* verts already spliced */
if (v == v_target) {
return FALSE;
}
/* we can't modify the vert while iterating so first allocate an array of loops */
loops = BM_iter_as_arrayN(bm, BM_LOOPS_OF_VERT, v, &loops_tot);
if (loops) {
loops = BM_iter_as_arrayN(bm, BM_LOOPS_OF_VERT, v, &loops_tot,
loops_stack, BM_DEFAULT_ITER_STACK_SIZE);
if (LIKELY(loops != NULL)) {
for (i = 0; i < loops_tot; i++) {
loops[i]->v = v_target;
}
MEM_freeN(loops);
if (loops != (BMLoop **)loops_stack) {
MEM_freeN(loops);
}
}
/* move all the edges from v's disk to vtarget's disk */
@@ -231,8 +231,8 @@ void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const int do_
int vinput_len;
int einput_len;
BMVert **vinput_arr = BM_iter_as_arrayN(bm, BM_VERTS_OF_MESH, NULL, &vinput_len);
BMEdge **einput_arr = BM_iter_as_arrayN(bm, BM_EDGES_OF_MESH, NULL, &einput_len);
BMVert **vinput_arr = BM_iter_as_arrayN(bm, BM_VERTS_OF_MESH, NULL, &vinput_len, NULL, 0);
BMEdge **einput_arr = BM_iter_as_arrayN(bm, BM_EDGES_OF_MESH, NULL, &einput_len, NULL, 0);
BM_mesh_decimate_dissolve_ex(bm, angle_limit, do_dissolve_boundaries,
vinput_arr, vinput_len,
+10 -10
View File
@@ -174,9 +174,9 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source)
void **blocks = NULL;
float (*cos)[3] = NULL, *w = NULL;
BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(w, BM_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(blocks, BM_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
int i;
BM_elem_attrs_copy(bm, bm, source, target);
@@ -613,10 +613,10 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
void **vblocks = NULL;
float (*cos)[3] = NULL, co[3], *w = NULL;
float cent[3] = {0.0f, 0.0f, 0.0f};
BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(w, BM_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(blocks, BM_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(vblocks, BM_NGON_STACK_SIZE, do_vertex ? source->len : 0, __func__);
BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(vblocks, BM_DEFAULT_NGON_STACK_SIZE, do_vertex ? source->len : 0, __func__);
int i, ax, ay;
BM_elem_attrs_copy(bm, bm, source, target->f);
@@ -689,9 +689,9 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source)
void **blocks = NULL;
float (*cos)[3] = NULL, *w = NULL;
float cent[3] = {0.0f, 0.0f, 0.0f};
BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(w, BM_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(blocks, BM_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__);
int i;
i = 0;
@@ -116,10 +116,14 @@ int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, cons
*
* Caller needs to free the array.
*/
void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len)
void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len,
/* optional args to avoid an alloc (normally stack array) */
void **stack_array, int stack_array_size)
{
BMIter iter;
BLI_assert(stack_array_size == 0 || (stack_array_size && stack_array));
/* we can't rely on coun't being set */
switch (itype) {
case BM_VERTS_OF_MESH:
@@ -137,7 +141,9 @@ void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len)
if (BM_iter_init(&iter, bm, itype, data) && iter.count > 0) {
BMElem *ele;
BMElem **array = MEM_mallocN(sizeof(ele) * iter.count, __func__);
BMElem **array = iter.count > stack_array_size ?
MEM_mallocN(sizeof(ele) * iter.count, __func__) :
stack_array;
int i = 0;
*r_len = iter.count; /* set before iterating */
@@ -125,7 +125,8 @@ __attribute__((warn_unused_result))
#endif
;
int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, const int len);
void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len)
void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len,
void **stack_array, int stack_array_size)
#ifdef __GNUC__
__attribute__((warn_unused_result))
#endif
+3 -3
View File
@@ -162,7 +162,7 @@ float BM_face_calc_area(BMFace *f)
float area;
int i;
BLI_array_fixedstack_declare(verts, BM_NGON_STACK_SIZE, f->len, __func__);
BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__);
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
copy_v3_v3(verts[i], l->v->co);
@@ -965,8 +965,8 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
float fac1 = 1.0000001f, fac2 = 0.9f; //9999f; //0.999f;
int i, j, a = 0, clen;
BLI_array_fixedstack_declare(projverts, BM_NGON_STACK_SIZE, f->len, "projvertsb");
BLI_array_fixedstack_declare(edgeverts, BM_NGON_STACK_SIZE * 2, len * 2, "edgevertsb");
BLI_array_fixedstack_declare(projverts, BM_DEFAULT_NGON_STACK_SIZE, f->len, "projvertsb");
BLI_array_fixedstack_declare(edgeverts, BM_DEFAULT_NGON_STACK_SIZE * 2, len * 2, "edgevertsb");
i = 0;
l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, f);
+36 -1
View File
@@ -1393,7 +1393,7 @@ int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
int BM_face_exists_multi_edge(BMEdge **earr, int len)
{
BMVert **varr;
BLI_array_fixedstack_declare(varr, BM_NGON_STACK_SIZE, len, __func__);
BLI_array_fixedstack_declare(varr, BM_DEFAULT_NGON_STACK_SIZE, len, __func__);
int ok;
int i, i_next;
@@ -1419,3 +1419,38 @@ int BM_face_exists_multi_edge(BMEdge **earr, int len)
return ok;
}
/* convenience functions for checking flags */
int BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag)
{
return (BM_elem_flag_test(e->v1, hflag) ||
BM_elem_flag_test(e->v2, hflag));
}
int BM_face_is_any_vert_flag_test(BMFace *f, const char hflag)
{
BMLoop *l_iter;
BMLoop *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
if (BM_elem_flag_test(l_iter->v, hflag)) {
return TRUE;
}
} while ((l_iter = l_iter->next) != l_first);
return FALSE;
}
int BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
{
BMLoop *l_iter;
BMLoop *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
if (BM_elem_flag_test(l_iter->e, hflag)) {
return TRUE;
}
} while ((l_iter = l_iter->next) != l_first);
return FALSE;
}
@@ -100,4 +100,8 @@ void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2);
void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
BMLoop *edge_loop);
int BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag);
int BM_face_is_any_vert_flag_test(BMFace *f, const char hflag);
int BM_face_is_any_edge_flag_test(BMFace *f, const char hflag);
#endif /* __BMESH_QUERIES_H__ */
+203 -84
View File
@@ -84,6 +84,8 @@ typedef struct VMesh {
M_POLY, /* a simple polygon */
M_ADJ, /* "adjacent edges" mesh pattern */
M_CROSS, /* "cross edges" mesh pattern */
M_TRI_FAN, /* a simple polygon - fan filled */
M_QUAD_STRIP, /* a simple polygon - cut into paralelle strips */
} mesh_kind;
int count; /* number of vertices in the boundary */
int seg; /* common # of segments for segmented edges */
@@ -187,10 +189,10 @@ static EdgeHalf *next_bev(BevVert *bv, EdgeHalf *from_e)
from_e = &bv->edges[bv->edgecount - 1];
e = from_e;
do {
if (e->isbev)
if (e->isbev) {
return e;
e = e->next;
} while (e != from_e);
}
} while ((e = e->next) != from_e);
return NULL;
}
@@ -384,10 +386,9 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, BMVert *v,
madd_v3_v3fl(off2a, norm_perp2, e2->offset);
add_v3_v3v3(off2b, off2a, dir2);
/* intersect the lines; by construction they should be on the same plane and not parallel */
if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) {
BLI_assert(!"offset_meet failure");
copy_v3_v3(meetco, off1a); /* just to do something */
/* lines are parallel; off1a is a good meet point */
copy_v3_v3(meetco, off1a);
}
}
@@ -440,8 +441,7 @@ static void project_to_edge(BMEdge *e, float co_a[3], float co_b[3], float projc
{
float otherco[3];
if (!isect_line_line_v3(e->v1->co, e->v2->co, co_a, co_b,
projco, otherco)) {
if (!isect_line_line_v3(e->v1->co, e->v2->co, co_a, co_b, projco, otherco)) {
BLI_assert(!"project meet failure");
copy_v3_v3(projco, e->v1->co);
}
@@ -537,10 +537,10 @@ static void get_point_on_round_edge(EdgeHalf *e, int i,
get_point_on_round_profile(point, e->offset, i, n, vaadj, vmid, vbadj);
add_v3_v3v3(p2, profileco, dir);
add_v3_v3v3(p2, point, dir);
cross_v3_v3v3(pn, vva, vvb);
if (!isect_line_plane_v3(profileco, point, p2, vmid, pn, 0)) {
BLI_assert(!"bevel: unexpected non-intersection");
/* TODO: track down why this sometimes fails */
copy_v3_v3(profileco, point);
}
}
@@ -639,10 +639,9 @@ static void build_boundary(BevVert *bv)
/* e is not beveled */
if (e->next->isbev) {
/* next iteration will place e between beveled previous and next edges */
e = e->next;
continue;
/* do nothing... */
}
if (e->prev->isbev) {
else if (e->prev->isbev) {
/* on-edge meet between e->prev and e */
offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co);
v = add_new_bound_vert(vm, co);
@@ -663,16 +662,28 @@ static void build_boundary(BevVert *bv)
e->leftv = v;
}
}
e = e->next;
} while (e != efirst);
} while ((e = e->next) != efirst);
BLI_assert(vm->count >= 2);
if (vm->count == 2 && bv->edgecount == 3)
if (vm->count == 2 && bv->edgecount == 3) {
vm->mesh_kind = M_NONE;
else if (efirst->seg == 1 || bv->selcount < 3)
vm->mesh_kind = M_POLY;
else
vm->mesh_kind = M_ADJ;
}
else if (efirst->seg == 1 || bv->selcount == 1) {
if (vm->count == 3 && bv->selcount == 1) {
vm->mesh_kind = M_TRI_FAN;
}
else {
vm->mesh_kind = M_POLY;
}
}
else {
if (bv->selcount == 2) {
vm->mesh_kind = M_QUAD_STRIP;
}
else {
vm->mesh_kind = M_ADJ;
}
}
/* TODO: if vm->count == 4 and bv->selcount == 4, use M_CROSS pattern */
}
@@ -694,8 +705,9 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
ns = vm->seg;
ns2 = ns / 2;
BLI_assert(n > 2 && ns > 1);
/* Make initial rings, going between points on neighbors */
/* Make initial rings, going between points on neighbors.
* After this loop, will have coords for all (i, r, k) where
* BoundVert for i has a bevel, 0 <= r <= ns2, 0 <= k <= ns */
for (ring = 1; ring <= ns2; ring++) {
v = vm->boundstart;
do {
@@ -732,11 +744,15 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co);
}
}
v = v->next;
} while (v != vm->boundstart);
} while ((v = v->next) != vm->boundstart);
}
/* Now make sure cross points of rings share coordinates and vertices */
/* Now make sure cross points of rings share coordinates and vertices.
* After this loop, will have BMVerts for all (i, r, k) where
* i is for a BoundVert that is beveled and has either a predecessor or
* successor BoundVert beveled too, and
* for odd ns: 0 <= r <= ns2, 0 <= k <= ns
* for even ns: 0 <= r < ns2, 0 <= k <= ns except k=ns2 */
v = vm->boundstart;
do {
i = v->index;
@@ -777,11 +793,13 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
}
}
}
v = v->next;
} while (v != vm->boundstart);
} while ((v = v->next) != vm->boundstart);
if (ns % 2 == 0) {
/* do special case center lines */
/* Do special case center lines.
* This loop makes verts for (i, ns2, k) for 1 <= k <= ns-1, k!=ns2
* and for (i, r, ns2) for 1 <= r <= ns2-1,
* whenever i is in a sequence of at least two beveled verts */
v = vm->boundstart;
do {
i = v->index;
@@ -807,17 +825,20 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
copy_v3_v3(nv->co, co);
create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2);
create_mesh_bmvert(bm, vm, i, ns2, ns - k, bv->v);
}
else if (vnext->ebev) {
mid_v3_v3v3(co, nv->co, nvnext->co);
copy_v3_v3(nv->co, co);
create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2);
create_mesh_bmvert(bm, vm, i, ns2, k, bv->v);
}
}
}
v = v->next;
} while (v != vm->boundstart);
} while ((v = v->next) != vm->boundstart);
/* center point need to be average of all centers of rings */
/* TODO: this is wrong if not all verts have ebev: could have
@@ -832,8 +853,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
add_v3_v3(midco, nv->co);
nn++;
}
v = v->next;
} while (v != vm->boundstart);
} while ((v = v->next) != vm->boundstart);
mul_v3_fl(midco, 1.0f / nn);
bmv = BM_vert_create(bm, midco, NULL);
v = vm->boundstart;
@@ -844,8 +864,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
copy_v3_v3(nv->co, midco);
nv->v = bmv;
}
v = v->next;
} while (v != vm->boundstart);
} while ((v = v->next) != vm->boundstart);
}
/* Make the ring quads */
@@ -871,15 +890,19 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
i = v->prev->index;
f = boundvert_rep_face(v->prev);
for (k = ns2 + (ns % 2); k < ns; k++) {
bmv1 = mesh_vert(vm, i, ring + 1, k)->v;
bmv2 = mesh_vert(vm, i, ring, k)->v;
bmv3 = mesh_vert(vm, i, ring, k + 1)->v;
BLI_assert(bmv1 && bmv2 && bmv3);
bev_create_quad_tri(bm, bmv1, bmv2, bmv3, NULL, f);
bmv1 = mesh_vert(vm, i, ring, k)->v;
bmv2 = mesh_vert(vm, i, ring, k + 1)->v;
bmv3 = mesh_vert(vm, i, ring + 1, k + 1)->v;
bmv4 = mesh_vert(vm, i, ring + 1, k)->v;
BLI_assert(bmv1 && bmv2 && bmv3 && bmv4);
if (bmv2 == bmv3) {
bmv3 = bmv4;
bmv4 = NULL;
}
bev_create_quad_tri(bm, bmv1, bmv2, bmv3, bmv4, f);
}
}
v = v->next;
} while (v != vm->boundstart);
} while ((v = v->next) != vm->boundstart);
}
/* Make center ngon if odd number of segments and fully beveled */
@@ -892,8 +915,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
i = v->index;
BLI_assert(v->ebev);
BLI_array_append(vv, mesh_vert(vm, i, ns2, ns2)->v);
v = v->next;
} while (v != vm->boundstart);
} while ((v = v->next) != vm->boundstart);
f = boundvert_rep_face(vm->boundstart);
bev_create_ngon(bm, vv, BLI_array_count(vv), f);
@@ -915,21 +937,30 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
if (!v->prev->ebev) {
for (k = 0; k < ns2; k++) {
bmv1 = mesh_vert(vm, i, ns2, k)->v;
if (!bmv1)
bmv1 = mesh_vert(vm, i, 0, k)->v;
if (!(j > 0 && bmv1 == vv[j - 1])) {
BLI_assert(bmv1 != NULL);
BLI_array_append(vv, bmv1);
j++;
}
}
}
bmv1 = mesh_vert(vm, i, ns2, ns2)->v;
if (!bmv1)
bmv1 = mesh_vert(vm, i, 0, ns2)->v;
if (!(j > 0 && bmv1 == vv[j - 1])) {
BLI_assert(bmv1 != NULL);
BLI_array_append(vv, bmv1);
j++;
}
if (!v->next->ebev) {
for (k = ns - ns2; k < ns; k++) {
bmv1 = mesh_vert(vm, i, ns2, k)->v;
if (!bmv1)
bmv1 = mesh_vert(vm, i, 0, k)->v;
if (!(j > 0 && bmv1 == vv[j - 1])) {
BLI_assert(bmv1 != NULL);
BLI_array_append(vv, bmv1);
j++;
}
@@ -937,11 +968,11 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
}
}
else {
BLI_assert(mesh_vert(vm, i, 0, 0)->v != NULL);
BLI_array_append(vv, mesh_vert(vm, i, 0, 0)->v);
j++;
}
v = v->next;
} while (v != vm->boundstart);
} while ((v = v->next) != vm->boundstart);
if (vv[0] == vv[j - 1])
j--;
bev_create_ngon(bm, vv, j, f);
@@ -950,8 +981,9 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
}
}
static void bevel_build_poly(BMesh *bm, BevVert *bv)
static BMFace *bevel_build_poly_ex(BMesh *bm, BevVert *bv)
{
BMFace *f;
int n, k;
VMesh *vm = bv->vmesh;
BoundVert *v;
@@ -970,11 +1002,91 @@ static void bevel_build_poly(BMesh *bm, BevVert *bv)
n++;
}
}
v = v->next;
} while (v != vm->boundstart);
if (n > 2)
bev_create_ngon(bm, vv, n, boundvert_rep_face(v));
} while ((v = v->next) != vm->boundstart);
if (n > 2) {
f = bev_create_ngon(bm, vv, n, boundvert_rep_face(v));
}
else {
f = NULL;
}
BLI_array_free(vv);
return f;
}
static void bevel_build_poly(BMesh *bm, BevVert *bv)
{
bevel_build_poly_ex(bm, bv);
}
static void bevel_build_trifan(BMesh *bm, BevVert *bv)
{
BMFace *f;
BLI_assert(next_bev(bv, NULL)->seg == 1 || bv->selcount == 1);
f = bevel_build_poly_ex(bm, bv);
if (f) {
/* we have a polygon which we know starts at the previous vertex, make it into a fan */
BMLoop *l_fan = BM_FACE_FIRST_LOOP(f)->prev;
BMVert *v_fan = l_fan->v;
while (f->len > 3) {
BMLoop *l_new;
BMFace *f_new;
BLI_assert(v_fan == l_fan->v);
f_new = BM_face_split(bm, f, l_fan->v, l_fan->next->next->v, &l_new, NULL, FALSE);
if (f_new->len > f->len) {
f = f_new;
if (l_new->v == v_fan) { l_fan = l_new; }
else if (l_new->next->v == v_fan) { l_fan = l_new->next; }
else if (l_new->prev->v == v_fan) { l_fan = l_new->prev; }
else { BLI_assert(0); }
}
else {
if (l_fan->v == v_fan) { l_fan = l_fan; }
else if (l_fan->next->v == v_fan) { l_fan = l_fan->next; }
else if (l_fan->prev->v == v_fan) { l_fan = l_fan->prev; }
else { BLI_assert(0); }
}
}
}
}
static void bevel_build_quadstrip(BMesh *bm, BevVert *bv)
{
BMFace *f;
BLI_assert(bv->selcount == 2);
f = bevel_build_poly_ex(bm, bv);
if (f) {
/* we have a polygon which we know starts at this vertex, make it into strips */
BMVert *v_first = bv->vmesh->boundstart->efirst->next->next->leftv->nv.v; /* magic? */
//BMLoop *l_start = BM_FACE_FIRST_LOOP(f);
BMLoop *l_start = BM_face_vert_share_loop(f, v_first);
BMLoop *l_a = l_start->prev, *l_a_step;
BMLoop *l_b = l_start->next, *l_b_step;
while (f->len > 4) {
// BMLoop *l_new;
BMFace *f_new;
BLI_assert(l_a->f == f);
BLI_assert(l_b->f == f);
l_a_step = l_a->prev;
l_b_step = l_b->next;
f_new = BM_face_split(bm, f, l_a->v, l_b->v, NULL, NULL, FALSE);
if (f_new->len > f->len) {
f = f_new;
}
l_a = l_a_step;
l_b = l_b_step;
}
}
}
/* Given that the boundary is built, now make the actual BMVerts
@@ -1009,8 +1121,7 @@ static void build_vmesh(BMesh *bm, BevVert *bv)
else
weld2 = v;
}
v = v->next;
} while (v != vm->boundstart);
} while ((v = v->next) != vm->boundstart);
/* copy other ends to (i, 0, ns) for all i, and fill in profiles for beveled edges */
v = vm->boundstart;
@@ -1028,13 +1139,14 @@ static void build_vmesh(BMesh *bm, BevVert *bv)
create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
}
}
v = v->next;
} while (v != vm->boundstart);
} while ((v = v->next) != vm->boundstart);
if (weld) {
vm->mesh_kind = M_NONE;
for (k = 1; k < ns; k++) {
mid_v3_v3v3(co, mesh_vert(vm, weld1->index, 0, k)->co,
mesh_vert(vm, weld2->index, 0, ns - k)->co);
va = mesh_vert(vm, weld1->index, 0, k)->co;
vb = mesh_vert(vm, weld2->index, 0, ns - k)->co;
mid_v3_v3v3(co, va, vb);
copy_v3_v3(mesh_vert(vm, weld1->index, 0, k)->co, co);
create_mesh_bmvert(bm, vm, weld1->index, 0, k, bv->v);
}
@@ -1046,6 +1158,10 @@ static void build_vmesh(BMesh *bm, BevVert *bv)
bevel_build_rings(bm, bv);
else if (vm->mesh_kind == M_POLY)
bevel_build_poly(bm, bv);
else if (vm->mesh_kind == M_TRI_FAN)
bevel_build_trifan(bm, bv);
else if (vm->mesh_kind == M_QUAD_STRIP)
bevel_build_quadstrip(bm, bv);
}
/*
@@ -1065,10 +1181,14 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMOperator *op, BMV
int nsel = 0;
/* Gather input selected edges.
* Only bevel selected edges that have exactly two incident faces. */
* Only bevel selected edges that have exactly two incident faces.
*
* TODO, optimization - we could tag edges in 'geom'
* and then just iterate edges-of-vert, checking tags.
*/
BMO_ITER (bme, &siter, bm, op, "geom", BM_EDGE) {
if ((bme->v1 == v) || (BM_edge_other_vert(bme, bme->v1) == v)) {
if (BM_edge_face_count(bme) == 2) {
if (BM_vert_in_edge(bme, v)) {
if (BM_edge_is_manifold(bme)) {
BMO_elem_flag_enable(bm, bme, EDGE_SELECTED);
nsel++;
}
@@ -1236,19 +1356,21 @@ static void rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
/* All polygons touching v need rebuilding because beveling v has made new vertices */
static void bevel_rebuild_existing_polygons(BMesh *bm, BevelParams *bp, BMVert *v)
{
BMFace *f;
BMIter iter;
void *faces_stack[BM_DEFAULT_ITER_STACK_SIZE];
int faces_len, f_index;
BMFace **faces = BM_iter_as_arrayN(bm, BM_FACES_OF_VERT, v, &faces_len,
faces_stack, BM_DEFAULT_ITER_STACK_SIZE);
/* TODO: don't iterate through all faces, but just local geometry around v */
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
BMLoop *l = f->l_first;
do {
if (l->v == v) {
rebuild_polygon(bm, bp, f);
BM_face_kill(bm, f);
}
l = l->next;
} while (l != f->l_first);
if (LIKELY(faces != NULL)) {
for (f_index = 0; f_index < faces_len; f_index++) {
BMFace *f = faces[f_index];
rebuild_polygon(bm, bp, f);
BM_face_kill(bm, f);
}
if (faces != (BMFace **)faces_stack) {
MEM_freeN(faces);
}
}
}
@@ -1266,7 +1388,7 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
BMFace *f1, *f2, *f;
int k, nseg, i1, i2;
if (BM_edge_face_count(bme) != 2)
if (!BM_edge_is_manifold(bme))
return;
bv1 = find_bevvert(bp, bme->v1);
@@ -1279,12 +1401,12 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
BLI_assert(e1 && e2);
/* v4 v3
* \ /
* e->v1 - e->v2
* / \
* v1 v2 */
/* v4 v3
* \ /
* e->v1 - e->v2
* / \
* v1 v2
*/
nseg = e1->seg;
BLI_assert(nseg > 0 && nseg == e2->seg);
@@ -1334,8 +1456,7 @@ static void free_bevel_params(BevelParams *bp)
do {
vnext = v->next;
MEM_freeN(v);
v = vnext;
} while (v != vm->boundstart);
} while ((v = vnext) != vm->boundstart);
}
if (vm->mesh)
MEM_freeN(vm->mesh);
@@ -1349,15 +1470,13 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
BMOIter siter;
BMVert *v;
BMEdge *e;
BevelParams bp;
BevelParams bp = {{NULL}};
bp.offset = BMO_slot_float_get(op, "offset");
bp.op = op;
bp.seg = BMO_slot_int_get(op, "segments");
if (bp.offset > 0) {
bp.vertList.first = bp.vertList.last = NULL;
/* The analysis of the input vertices and execution additional constructions */
BMO_ITER (v, &siter, bm, op, "geom", BM_VERT) {
bevel_vert_construct(bm, &bp, op, v);
@@ -1563,7 +1682,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_disable(bm, e->v2, BEVEL_DEL);
}
#if 0
if (BM_edge_face_count(e) == 0) {
if (BM_edge_is_wire(e)) {
BMVert *verts[2] = {e->v1, e->v2};
BMEdge *edges[2] = {e, BM_edge_create(bm, e->v1, e->v2, e, 0)};
+3 -3
View File
@@ -168,7 +168,7 @@ static void rotsys_reverse(BMEdge *UNUSED(e), BMVert *v, EdgeData *edata, VertDa
BMEdge **edges = NULL;
BMEdge *e_first;
BMEdge *e;
BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
int i, totedge;
e = e_first = vdata[BM_elem_index_get(v)].e;
@@ -359,10 +359,10 @@ static void init_rotsys(BMesh *bm, EdgeData *edata, VertData *vdata)
BMIter iter;
BMEdge *e;
BMEdge **edges = NULL;
BLI_array_staticdeclare(edges, BM_NGON_STACK_SIZE);
BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
BMVert *v;
/* BMVert **verts = NULL; */
/* BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE); */ /* UNUSE */
/* BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE); */ /* UNUSE */
int i;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+2 -2
View File
@@ -595,10 +595,10 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
/* array for passing verts to angle_poly_v3 */
float **verts = NULL;
BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE);
/* array for receiving angles from angle_poly_v3 */
float *face_angles = NULL;
BLI_array_staticdeclare(face_angles, BM_NGON_STACK_SIZE);
BLI_array_staticdeclare(face_angles, BM_DEFAULT_NGON_STACK_SIZE);
BM_mesh_elem_index_ensure(bm, BM_VERT);
+1 -1
View File
@@ -385,7 +385,7 @@ static void hull_tag_holes(BMesh *bm, BMOperator *op)
BMO_ITER (f, &oiter, bm, op, "input", BM_FACE) {
if (BMO_elem_flag_test(bm, f, HULL_FLAG_HOLE)) {
BM_ITER_ELEM (e, &iter, f, BM_EDGES_OF_FACE) {
if (BM_edge_face_count(e) == 1) {
if (BM_edge_is_boundary(e)) {
BMO_elem_flag_disable(bm, f, HULL_FLAG_HOLE);
break;
}
@@ -165,7 +165,7 @@ static void alter_co(BMesh *bm, BMVert *v, BMEdge *UNUSED(origed), const SubDPar
}
/* apply the new difference to the rest of the shape keys,
* note that this doent take rotations into account, we _could_ support
* note that this dosn't take rotations into account, we _could_ support
* this by getting the normals and coords for each shape key and
* re-calculate the smooth value for each but this is quite involved.
* for now its ok to simply apply the difference IMHO - campbell */
@@ -617,7 +617,7 @@ static void symm_kill_unused(Symm *symm)
!symmetric)
{
/* The edge might be used by a face outside the input set */
if (BM_edge_face_count(e) == 0)
if (BM_edge_is_wire(e))
BM_edge_kill(symm->bm, e);
}
}
+1 -1
View File
@@ -844,7 +844,7 @@ void AnimationImporter::apply_matrix_curves(Object *ob, std::vector<FCurve *>& a
* This function returns the aspet ration from the Collada camera.
*
* Note:COLLADA allows to specify either XFov, or YFov alone.
* In tghat case the aspect ratio can be determined from
* In that case the aspect ratio can be determined from
* the viewport aspect ratio (which is 1:1 ?)
* XXX: check this: its probably wrong!
* If both values are specified, then the aspect ration is simply xfov/yfov
@@ -35,7 +35,7 @@
class PixelateOperation : public NodeOperation {
private:
/**
* @brief cached refeerence to the input operation
* @brief cached reference to the input operation
*/
SocketReader *m_inputOperation;
public:
+180 -129
View File
@@ -139,11 +139,11 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
return &sseq->gpd;
}
break;
case SPACE_IMAGE: /* Image/UV Editor */
{
SpaceImage *sima = (SpaceImage *)CTX_wm_space_data(C);
/* for now, Grease Pencil data is associated with the space... */
/* XXX our convention for everything else is to link to data though... */
if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceImageEditor, sima, ptr);
@@ -159,19 +159,19 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
if (clip) {
if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking);
if (!track)
return NULL;
if (ptr)
RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, ptr);
return &track->gpd;
}
else {
if (ptr)
RNA_id_pointer_create(&clip->id, ptr);
return &clip->gpd;
}
}
@@ -471,7 +471,7 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin
mvalf[1] = (float)pt->y / 100.0f * ar->winy;
}
}
/* convert screen coordinate to 3d coordinates
* - method taken from editview.c - mouse_cursor()
*/
@@ -504,19 +504,22 @@ typedef struct tGpTimingData {
double inittime;
} tGpTimingData;
/* init point buffers for timing data */
static void _gp_timing_data_set_nbr(tGpTimingData *gtd, int nbr)
{
float *tmp;
BLI_assert(nbr > gtd->num_points);
/* distances */
tmp = gtd->dists;
gtd->dists = MEM_callocN(sizeof(float) * nbr, __func__);
if (tmp) {
memcpy(gtd->dists, tmp, sizeof(float) * gtd->num_points);
MEM_freeN(tmp);
}
/* times */
tmp = gtd->times;
gtd->times = MEM_callocN(sizeof(float) * nbr, __func__);
if (tmp) {
@@ -527,20 +530,28 @@ static void _gp_timing_data_set_nbr(tGpTimingData *gtd, int nbr)
gtd->num_points = nbr;
}
/* add stroke point to timing buffers */
static void gp_timing_data_add_point(tGpTimingData *gtd, double stroke_inittime, float time, float delta_dist)
{
if (time < 0.0f) {
/* This is a gap, negative value! */
gtd->tot_time = -(gtd->times[gtd->cur_point] = -(((float)(stroke_inittime - gtd->inittime)) + time));
gtd->times[gtd->cur_point] = -(((float)(stroke_inittime - gtd->inittime)) + time);
gtd->tot_time = -gtd->times[gtd->cur_point];
gtd->gap_tot_time += gtd->times[gtd->cur_point] - gtd->times[gtd->cur_point - 1];
}
else
gtd->tot_time = (gtd->times[gtd->cur_point] = (((float)(stroke_inittime - gtd->inittime)) + time));
gtd->dists[gtd->cur_point] = (gtd->tot_dist += delta_dist);
else {
gtd->times[gtd->cur_point] = (((float)(stroke_inittime - gtd->inittime)) + time);
gtd->tot_time = (gtd->times[gtd->cur_point]);
}
gtd->tot_dist += delta_dist;
gtd->dists[gtd->cur_point] = gtd->tot_dist;
gtd->cur_point++;
}
/* In frames! Binary search for FCurve keys have a threshold of 0.01, so we cant set
/* In frames! Binary search for FCurve keys have a threshold of 0.01, so we can't set
* arbitrarily close points - this is esp. important with NoGaps mode!
*/
#define MIN_TIME_DELTA 0.02f
@@ -550,7 +561,7 @@ static int gp_find_end_of_stroke_idx(tGpTimingData *gtd, int idx, int nbr_gaps,
float tot_gaps_time, float delta_time, float *next_delta_time)
{
int j;
for (j = idx + 1; j < gtd->num_points; j++) {
if (gtd->times[j] < 0) {
gtd->times[j] = -gtd->times[j];
@@ -562,20 +573,23 @@ static int gp_find_end_of_stroke_idx(tGpTimingData *gtd, int idx, int nbr_gaps,
/* We want gaps that are in gtd->gap_duration +/- gtd->gap_randomness range,
* and which sum to exactly tot_gaps_time...
*/
int rem_gaps = nbr_gaps - *nbr_done_gaps;
int rem_gaps = nbr_gaps - (*nbr_done_gaps);
if (rem_gaps < 2) {
/* Last gap, just give remaining time! */
*next_delta_time = tot_gaps_time;
}
else {
float delta, min, max;
/* This code ensures that if the first gaps have been shorter than average gap_duration,
* next gaps will tend to be longer (i.e. try to recover the lateness), and vice-versa!
*/
delta = delta_time - (gtd->gap_duration * *nbr_done_gaps);
delta = delta_time - (gtd->gap_duration * (*nbr_done_gaps));
/* Clamp min between [-gap_randomness, 0.0], with lower delta giving higher min */
min = -gtd->gap_randomness - delta;
CLAMP(min, -gtd->gap_randomness, 0.0f);
/* Clamp max between [0.0, gap_randomness], with lower delta giving higher max */
max = gtd->gap_randomness - delta;
CLAMP(max, 0.0f, gtd->gap_randomness);
@@ -655,11 +669,11 @@ static void gp_stroke_path_animation_add_keyframes(ReportList *reports, PointerR
/* This one should *never* be negative! */
end_stroke_time = time_start + ((gtd->times[end_stroke_idx] + delta_time) / gtd->tot_time * time_range);
}
/* Simple proportional stuff... */
cu->ctime = gtd->dists[i] / gtd->tot_dist * cu->pathlen;
cfra = time_start + ((gtd->times[i] + delta_time) / gtd->tot_time * time_range);
/* And now, the checks about timing... */
if (i == start_stroke_idx) {
/* If first point of a stroke, be sure it's enough ahead of last valid keyframe, and
@@ -709,45 +723,44 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
FCurve *fcu;
PointerRNA ptr;
PropertyRNA *prop = NULL;
int nbr_gaps = 0, i;
if (gtd->mode == GP_STROKECONVERT_TIMING_NONE)
return;
/* gap_duration and gap_randomness are in frames, but we need seconds!!! */
gtd->gap_duration = FRA2TIME(gtd->gap_duration);
gtd->gap_randomness = FRA2TIME(gtd->gap_randomness);
/* Enable path! */
cu->flag |= CU_PATH;
cu->pathlen = gtd->frame_range;
/* Get or create default action to add F-Curve+keyframe to */
act = verify_adt_action((ID*)cu, TRUE);
/* Create RNA stuff */
RNA_id_pointer_create((ID*)cu, &ptr);
/* Get RNA pointer to read/write path time values */
RNA_id_pointer_create((ID *)cu, &ptr);
prop = RNA_struct_find_property(&ptr, "eval_time");
/* Get or create fcurve */
/* Ensure we have an F-Curve to add keyframes to */
act = verify_adt_action((ID *)cu, TRUE);
fcu = verify_fcurve(act, NULL, &ptr, "eval_time", 0, TRUE);
if (G.debug & G_DEBUG) {
printf("%s: tot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time);
for (i = 0; i < gtd->num_points; i++) {
printf("\tpoint %d:\t\tlen: %f\t\ttime: %f\n", i, gtd->dists[i], gtd->times[i]);
}
}
if (gtd->mode == GP_STROKECONVERT_TIMING_LINEAR) {
float cfra;
/* Linear extrapolation! */
fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
cu->ctime = 0.0f;
cfra = (float)gtd->start_frame;
insert_keyframe_direct(reports, ptr, prop, fcu, cfra, INSERTKEY_FAST);
cu->ctime = cu->pathlen;
if (gtd->realtime) {
cfra += (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */
@@ -760,34 +773,33 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
else {
/* Use actual recorded timing! */
float time_range;
/* CustomGaps specific */
float tot_gaps_time = 0.0f;
/* Pre-process gaps, in case we don't want to keep their org timing */
/* Pre-process gaps, in case we don't want to keep their original timing */
if (gtd->mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
gp_stroke_path_animation_preprocess_gaps(gtd, &nbr_gaps, &tot_gaps_time);
}
if (gtd->realtime) {
time_range = (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */
}
else {
time_range = (float)(gtd->end_frame - gtd->start_frame);
}
if (G.debug & G_DEBUG) {
printf("Starting keying!\n");
printf("GP Stroke Path Conversion: Starting keying!\n");
}
gp_stroke_path_animation_add_keyframes(reports, ptr, prop, fcu, cu, gtd, time_range,
nbr_gaps, tot_gaps_time);
}
/* As we used INSERTKEY_FAST mode, we need to recompute all curve's handles now */
calchandles_fcurve(fcu);
if (G.debug & G_DEBUG) {
printf("%s: \ntot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time);
for (i = 0; i < gtd->num_points; i++) {
@@ -795,11 +807,11 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
}
printf("\n\n");
}
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
/* send updates */
DAG_id_tag_update((ID*)cu, 0);
DAG_id_tag_update(&cu->id, 0);
}
#undef MIN_TIME_DELTA
@@ -813,14 +825,15 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
float minmax_weights[2], float rad_fac, int stitch, tGpTimingData *gtd)
{
bGPDspoint *pt;
Nurb *nu = curnu ? *curnu : NULL;
Nurb *nu = (curnu) ? *curnu : NULL;
BPoint *bp, *prev_bp = NULL;
int i, old_nbp = 0;
const int do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE);
int i, old_nbp = 0;
/* create new 'nurb' or extend current one within the curve */
if (nu) {
old_nbp = nu->pntsu;
/* If stitch, the first point of this stroke is already present in current nu.
* Else, we have to add to additional points to make the zero-radius link between strokes.
*/
@@ -837,9 +850,9 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
nu->resolu = cu->resolu;
nu->resolv = cu->resolv;
nu->knotsu = NULL;
nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * nu->pntsu, "bpoints");
stitch = FALSE; /* Security! */
}
@@ -861,11 +874,12 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
float delta_time;
prev_bp = NULL;
if (old_nbp > 1 && gps->prev && gps->prev->totpoints > 1) {
if ((old_nbp > 1) && gps->prev && (gps->prev->totpoints > 1)) {
/* Only use last curve segment if previous stroke was not a single-point one! */
prev_bp = nu->bp + old_nbp - 2;
}
bp = nu->bp + old_nbp - 1;
/* XXX We do this twice... Not sure it's worth to bother about this! */
gp_strokepoint_convertcoords(C, gps, gps->points, p, subrect);
if (prev_bp) {
@@ -874,6 +888,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
else {
interp_v3_v3v3(p1, bp->vec, p, GAP_DFAC);
}
if (gps->totpoints > 1) {
/* XXX We do this twice... Not sure it's worth to bother about this! */
gp_strokepoint_convertcoords(C, gps, gps->points + 1, next_p, subrect);
@@ -882,7 +897,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
else {
interp_v3_v3v3(p2, p, bp->vec, GAP_DFAC);
}
/* First point */
bp++;
copy_v3_v3(bp->vec, p1);
@@ -898,7 +913,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
}
gp_timing_data_add_point(gtd, gtd->inittime, delta_time, len_v3v3((bp - 1)->vec, p1));
}
/* Second point */
bp++;
copy_v3_v3(bp->vec, p2);
@@ -915,25 +930,26 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
}
gp_timing_data_add_point(gtd, gps->inittime, delta_time, len_v3v3(p1, p2));
}
old_nbp += 2;
}
if (old_nbp && do_gtd) {
prev_bp = nu->bp + old_nbp - 1;
}
/* add points */
for (i = stitch ? 1 : 0, pt = gps->points + (stitch ? 1 : 0), bp = nu->bp + old_nbp;
for (i = (stitch) ? 1 : 0, pt = gps->points + ((stitch) ? 1 : 0), bp = nu->bp + old_nbp;
i < gps->totpoints;
i++, pt++, bp++)
{
float p3d[3];
float width = pt->pressure * gpl->thickness * WIDTH_CORR_FAC;
/* get coordinates to add at */
gp_strokepoint_convertcoords(C, gps, pt, p3d, subrect);
copy_v3_v3(bp->vec, p3d);
bp->vec[3] = 1.0f;
/* set settings */
bp->f1 = SELECT;
bp->radius = width * rad_fac;
@@ -945,14 +961,14 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
else if (bp->weight > minmax_weights[1]) {
minmax_weights[1] = bp->weight;
}
/* Update timing data */
if (do_gtd) {
gp_timing_data_add_point(gtd, gps->inittime, pt->time, prev_bp ? len_v3v3(prev_bp->vec, p3d) : 0.0f);
gp_timing_data_add_point(gtd, gps->inittime, pt->time, (prev_bp) ? len_v3v3(prev_bp->vec, p3d) : 0.0f);
}
prev_bp = bp;
}
/* add nurb to curve */
if (!curnu || !*curnu) {
BLI_addtail(&cu->nurb, nu);
@@ -960,7 +976,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
if (curnu) {
*curnu = nu;
}
BKE_nurb_knot_calc_u(nu);
}
@@ -968,7 +984,7 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
{
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
if (v3d) {
RegionView3D *rv3d = ar->regiondata;
@@ -979,7 +995,7 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
return 1;
}
}
return 0;
}
@@ -988,12 +1004,12 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
float minmax_weights[2], float rad_fac, int stitch, tGpTimingData *gtd)
{
bGPDspoint *pt;
Nurb *nu = curnu ? *curnu : NULL;
Nurb *nu = (curnu) ? *curnu : NULL;
BezTriple *bezt, *prev_bezt = NULL;
int i, tot, old_nbezt = 0;
float p3d_cur[3], p3d_prev[3], p3d_next[3];
const int do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE);
/* create new 'nurb' or extend current one within the curve */
if (nu) {
old_nbezt = nu->pntsu;
@@ -1001,17 +1017,17 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
* so no need to add it.
* If no stitch, we want to add two additional points to make a "zero-radius" link between both strokes.
*/
BKE_nurb_bezierPoints_add(nu, gps->totpoints + (stitch ? -1 : 2));
BKE_nurb_bezierPoints_add(nu, gps->totpoints + ((stitch) ? -1 : 2));
}
else {
nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_bezier(nurb)");
nu->pntsu = gps->totpoints;
nu->resolu = 12;
nu->resolv = 12;
nu->type = CU_BEZIER;
nu->bezt = (BezTriple *)MEM_callocN(gps->totpoints * sizeof(BezTriple), "bezts");
stitch = FALSE; /* Security! */
}
@@ -1024,9 +1040,9 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
/* get initial coordinates */
pt = gps->points;
if (tot) {
gp_strokepoint_convertcoords(C, gps, pt, stitch ? p3d_prev : p3d_cur, subrect);
gp_strokepoint_convertcoords(C, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect);
if (tot > 1) {
gp_strokepoint_convertcoords(C, gps, pt + 1, stitch ? p3d_cur : p3d_next, subrect);
gp_strokepoint_convertcoords(C, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect);
}
if (stitch && tot > 2) {
gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect);
@@ -1035,7 +1051,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
/* If needed, make the link between both strokes with two zero-radius additional points */
if (curnu && old_nbezt) {
/* Update last point's second handle! */
/* Update last point's second handle */
if (stitch) {
float h2[3];
bezt = nu->bezt + old_nbezt - 1;
@@ -1043,6 +1059,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
copy_v3_v3(bezt->vec[2], h2);
pt++;
}
/* Create "link points" */
/* About "zero-radius" point interpolations:
* - If we have at least two points in current curve (most common case), we linearly extrapolate
@@ -1055,7 +1072,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
else {
float h1[3], h2[3], p1[3], p2[3];
float delta_time;
prev_bezt = NULL;
if (old_nbezt > 1 && gps->prev && gps->prev->totpoints > 1) {
/* Only use last curve segment if previous stroke was not a single-point one! */
@@ -1074,15 +1091,15 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
else {
interp_v3_v3v3(p2, p3d_cur, bezt->vec[1], GAP_DFAC);
}
/* Second handle of last point */
interp_v3_v3v3(h2, bezt->vec[1], p1, BEZT_HANDLE_FAC);
copy_v3_v3(bezt->vec[2], h2);
/* First point */
interp_v3_v3v3(h1, p1, bezt->vec[1], BEZT_HANDLE_FAC);
interp_v3_v3v3(h2, p1, p2, BEZT_HANDLE_FAC);
bezt++;
copy_v3_v3(bezt->vec[0], h1);
copy_v3_v3(bezt->vec[1], p1);
@@ -1090,7 +1107,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
bezt->h1 = bezt->h2 = HD_FREE;
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
minmax_weights[0] = bezt->radius = bezt->weight = 0.0f;
if (do_gtd) {
if (prev_bezt) {
delta_time = gtd->tot_time + (gtd->tot_time - gtd->times[gtd->cur_point - 1]) * GAP_DFAC;
@@ -1100,11 +1117,11 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
}
gp_timing_data_add_point(gtd, gtd->inittime, delta_time, len_v3v3((bezt - 1)->vec[1], p1));
}
/* Second point */
interp_v3_v3v3(h1, p2, p1, BEZT_HANDLE_FAC);
interp_v3_v3v3(h2, p2, p3d_cur, BEZT_HANDLE_FAC);
bezt++;
copy_v3_v3(bezt->vec[0], h1);
copy_v3_v3(bezt->vec[1], p2);
@@ -1112,7 +1129,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
bezt->h1 = bezt->h2 = HD_FREE;
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
minmax_weights[0] = bezt->radius = bezt->weight = 0.0f;
if (do_gtd) {
/* This negative delta_time marks the gap! */
if (tot > 1) {
@@ -1123,7 +1140,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
}
gp_timing_data_add_point(gtd, gps->inittime, delta_time, len_v3v3(p1, p2));
}
old_nbezt += 2;
copy_v3_v3(p3d_prev, p2);
}
@@ -1131,29 +1148,30 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
if (old_nbezt && do_gtd) {
prev_bezt = nu->bezt + old_nbezt - 1;
}
/* add points */
for (i = stitch ? 1 : 0, bezt = nu->bezt + old_nbezt; i < tot; i++, pt++, bezt++) {
float h1[3], h2[3];
float width = pt->pressure * gpl->thickness * WIDTH_CORR_FAC;
if (i || old_nbezt) {
interp_v3_v3v3(h1, p3d_cur, p3d_prev, BEZT_HANDLE_FAC);
}
else {
interp_v3_v3v3(h1, p3d_cur, p3d_next, -BEZT_HANDLE_FAC);
}
if (i < tot - 1) {
interp_v3_v3v3(h2, p3d_cur, p3d_next, BEZT_HANDLE_FAC);
}
else {
interp_v3_v3v3(h2, p3d_cur, p3d_prev, -BEZT_HANDLE_FAC);
}
copy_v3_v3(bezt->vec[0], h1);
copy_v3_v3(bezt->vec[1], p3d_cur);
copy_v3_v3(bezt->vec[2], h2);
/* set settings */
bezt->h1 = bezt->h2 = HD_FREE;
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
@@ -1166,23 +1184,23 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
else if (bezt->weight > minmax_weights[1]) {
minmax_weights[1] = bezt->weight;
}
/* Update timing data */
if (do_gtd) {
gp_timing_data_add_point(gtd, gps->inittime, pt->time, prev_bezt ? len_v3v3(prev_bezt->vec[1], p3d_cur) : 0.0f);
}
/* shift coord vects */
copy_v3_v3(p3d_prev, p3d_cur);
copy_v3_v3(p3d_cur, p3d_next);
if (i + 2 < tot) {
gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect);
}
prev_bezt = bezt;
}
/* must calculate handles or else we crash */
BKE_nurb_handles_calc(nu);
@@ -1200,6 +1218,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
static void gp_stroke_finalize_curve_endpoints(Curve *cu)
{
/* start */
Nurb *nu = cu->nurb.first;
int i = 0;
if (nu->bezt) {
@@ -1214,7 +1233,8 @@ static void gp_stroke_finalize_curve_endpoints(Curve *cu)
bp[i].weight = bp[i].radius = 0.0f;
}
}
/* end */
nu = cu->nurb.last;
i = nu->pntsu - 1;
if (nu->bezt) {
@@ -1237,7 +1257,7 @@ static void gp_stroke_norm_curve_weights(Curve *cu, float minmax_weights[2])
const float delta = minmax_weights[0];
const float fac = 1.0f / (minmax_weights[1] - delta);
int i;
for (nu = cu->nurb.first; nu; nu = nu->next) {
if (nu->bezt) {
BezTriple *bezt = nu->bezt;
@@ -1269,11 +1289,11 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
/* camera framing */
rctf subrect, *subrect_ptr = NULL;
/* error checking */
if (ELEM3(NULL, gpd, gpl, gpf))
return;
/* only convert if there are any strokes on this layer's frame to convert */
if (gpf->strokes.first == NULL)
return;
@@ -1282,7 +1302,7 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
if (gp_camera_view_subrect(C, &subrect)) {
subrect_ptr = &subrect;
}
/* init the curve object (remove rotation and get curve data from it)
* - must clear transforms set on object, as those skew our results
*/
@@ -1291,28 +1311,34 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
zero_v3(ob->rot);
cu = ob->data;
cu->flag |= CU_3D;
/* rename object and curve to layer name */
rename_id((ID *)ob, gpl->info);
rename_id((ID *)cu, gpl->info);
gtd->inittime = ((bGPDstroke*)gpf->strokes.first)->inittime;
gtd->inittime = ((bGPDstroke *)gpf->strokes.first)->inittime;
/* add points to curve */
for (gps = gpf->strokes.first; gps; gps = gps->next) {
/* Detect new strokes created because of GP_STROKE_BUFFER_MAX reached,
* and stitch them to previous one.
*/
int stitch = FALSE;
if (prev_gps) {
bGPDspoint *pt1 = prev_gps->points + prev_gps->totpoints - 1;
bGPDspoint *pt2 = gps->points;
if (pt1->x == pt2->x && pt1->y == pt2->y)
if ((pt1->x == pt2->x) && (pt1->y == pt2->y)) {
stitch = TRUE;
}
}
/* Decide whether we connect this stroke to previous one */
if (!(stitch || link_strokes))
if (!(stitch || link_strokes)) {
nu = NULL;
}
switch (mode) {
case GP_STROKECONVERT_PATH:
gp_stroke_to_path(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, gtd);
@@ -1332,20 +1358,25 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
gp_stroke_finalize_curve_endpoints(cu);
/* Update curve's weights, if needed */
if (norm_weights && (minmax_weights[0] > 0.0f || minmax_weights[1] < 1.0f))
if (norm_weights && ((minmax_weights[0] > 0.0f) || (minmax_weights[1] < 1.0f)))
gp_stroke_norm_curve_weights(cu, minmax_weights);
/* Create the path animation, if needed */
gp_stroke_path_animation(C, reports, cu, gtd);
/* Reset org object as active, else we can't edit operator's settings!!! */
/* Reset original object as active, else we can't edit operator's settings!!! */
/* set layers OK */
newbase = BASACT;
newbase->lay = base->lay;
ob->lay = newbase->lay;
if (base) {
newbase->lay = base->lay;
ob->lay = newbase->lay;
}
/* restore, BKE_object_add sets active */
BASACT = base;
base->flag |= SELECT;
if (base) {
base->flag |= SELECT;
}
}
/* --- */
@@ -1361,13 +1392,14 @@ static int gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOper
bGPDspoint *pt;
double base_time, cur_time, prev_time = -1.0;
int i, valid = TRUE;
do {
base_time = cur_time = gps->inittime;
if (cur_time <= prev_time) {
valid = FALSE;
break;
}
prev_time = cur_time;
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
cur_time = base_time + (double)pt->time;
@@ -1380,11 +1412,12 @@ static int gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOper
}
prev_time = cur_time;
}
if (!valid) {
break;
}
} while ((gps = gps->next));
if (op) {
RNA_boolean_set(op->ptr, "use_timing_data", valid);
}
@@ -1396,6 +1429,7 @@ static void gp_convert_set_end_frame(struct Main *UNUSED(main), struct Scene *UN
{
int start_frame = RNA_int_get(ptr, "start_frame");
int end_frame = RNA_int_get(ptr, "end_frame");
if (end_frame <= start_frame) {
RNA_int_set(ptr, "end_frame", start_frame + 1);
}
@@ -1423,19 +1457,19 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
int link_strokes = RNA_boolean_get(op->ptr, "use_link_strokes");
int valid_timing;
tGpTimingData gtd;
/* check if there's data to work with */
if (gpd == NULL) {
BKE_report(op->reports, RPT_ERROR, "No grease pencil data to work on");
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data to work on");
return OPERATOR_CANCELLED;
}
if (!RNA_property_is_set(op->ptr, prop) && !gp_convert_check_has_valid_timing(C, gpl, op)) {
BKE_report(op->reports, RPT_WARNING,
"Current grease pencil strokes have no valid timing data, most timing options will be hidden!");
"Current Grease Pencil strokes have no valid timing data, most timing options will be hidden!");
}
valid_timing = RNA_property_boolean_get(op->ptr, prop);
gtd.mode = RNA_enum_get(op->ptr, "timing_mode");
/* Check for illegal timing mode! */
if (!valid_timing && !ELEM(gtd.mode, GP_STROKECONVERT_TIMING_NONE, GP_STROKECONVERT_TIMING_LINEAR)) {
@@ -1445,7 +1479,8 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
if (!link_strokes) {
gtd.mode = GP_STROKECONVERT_TIMING_NONE;
}
/* grab all relevant settings */
gtd.frame_range = RNA_int_get(op->ptr, "frame_range");
gtd.start_frame = RNA_int_get(op->ptr, "start_frame");
gtd.realtime = valid_timing ? RNA_boolean_get(op->ptr, "use_realtime") : FALSE;
@@ -1458,13 +1493,24 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
gtd.dists = gtd.times = NULL;
gtd.tot_dist = gtd.tot_time = gtd.gap_tot_time = 0.0f;
gtd.inittime = 0.0;
/* perform conversion */
gp_layer_to_curve(C, op->reports, gpd, gpl, mode, norm_weights, rad_fac, link_strokes, &gtd);
/* free temp memory */
if (gtd.dists) {
MEM_freeN(gtd.dists);
gtd.dists = NULL;
}
if (gtd.times) {
MEM_freeN(gtd.times);
gtd.times = NULL;
}
/* notifiers */
WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
/* done */
return OPERATOR_FINISHED;
}
@@ -1478,7 +1524,7 @@ static int gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
float gap_duration = RNA_float_get(ptr, "gap_duration");
float gap_randomness = RNA_float_get(ptr, "gap_randomness");
int valid_timing = RNA_boolean_get(ptr, "use_timing_data");
/* Always show those props */
if (strcmp(prop_id, "type") == 0 ||
strcmp(prop_id, "use_normalize_weights") == 0 ||
@@ -1487,7 +1533,7 @@ static int gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
{
return TRUE;
}
/* Never show this prop */
if (strcmp(prop_id, "use_timing_data") == 0)
return FALSE;
@@ -1496,7 +1542,7 @@ static int gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
/* Only show when link_stroke is TRUE */
if (strcmp(prop_id, "timing_mode") == 0)
return TRUE;
if (timing_mode != GP_STROKECONVERT_TIMING_NONE) {
/* Only show when link_stroke is TRUE and stroke timing is enabled */
if (strcmp(prop_id, "frame_range") == 0 ||
@@ -1504,26 +1550,26 @@ static int gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
{
return TRUE;
}
/* Only show if we have valid timing data! */
if (valid_timing && strcmp(prop_id, "use_realtime") == 0)
return TRUE;
/* Only show if realtime or valid_timing is FALSE! */
if ((!realtime || !valid_timing) && strcmp(prop_id, "end_frame") == 0)
return TRUE;
if (valid_timing && timing_mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
/* Only show for custom gaps! */
if (strcmp(prop_id, "gap_duration") == 0)
return TRUE;
/* Only show randomness for non-null custom gaps! */
if (strcmp(prop_id, "gap_randomness") == 0 && gap_duration > 0.0f)
if (strcmp(prop_id, "gap_randomness") == 0 && (gap_duration > 0.0f))
return TRUE;
/* Only show seed for randomize action! */
if (strcmp(prop_id, "seed") == 0 && gap_duration > 0.0f && gap_randomness > 0.0f)
if (strcmp(prop_id, "seed") == 0 && (gap_duration > 0.0f) && (gap_randomness > 0.0f))
return TRUE;
}
}
@@ -1565,15 +1611,18 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_convertmodes, 0, "Type", "Which type of curve to convert to");
RNA_def_boolean(ot->srna, "use_normalize_weights", TRUE, "Normalize Weight",
"Normalize weight (set from stroke width)");
RNA_def_float(ot->srna, "radius_multiplier", 1.0f, 0.0f, 1000.0f, "Radius Fac",
"Multiplier for the points' radii (set from stroke width)", 0.0f, 10.0f);
RNA_def_boolean(ot->srna, "use_link_strokes", TRUE, "Link Strokes",
"Whether to link strokes with zero-radius sections of curves");
prop = RNA_def_enum(ot->srna, "timing_mode", prop_gpencil_convert_timingmodes, GP_STROKECONVERT_TIMING_FULL,
"Timing Mode", "How to use timing data stored in strokes");
RNA_def_enum_funcs(prop, rna_GPConvert_mode_items);
RNA_def_int(ot->srna, "frame_range", 100, 1, 10000, "Frame Range",
"The duration of evaluation of the path control curve", 1, 1000);
RNA_def_int(ot->srna, "start_frame", 1, 1, 100000, "Start Frame",
@@ -1583,16 +1632,18 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
prop = RNA_def_int(ot->srna, "end_frame", 250, 1, 100000, "End Frame",
"The end frame of the path control curve (if Realtime is not set)", 1, 100000);
RNA_def_property_update_runtime(prop, gp_convert_set_end_frame);
RNA_def_float(ot->srna, "gap_duration", 0.0f, 0.0f, 10000.0f, "Gap Duration",
"Custom Gap mode: (Average) length of gaps, in frames "
"(note: realtime value, will be scaled if Realtime is not set)", 0.0f, 1000.0f);
"(Note: Realtime value, will be scaled if Realtime is not set)", 0.0f, 1000.0f);
RNA_def_float(ot->srna, "gap_randomness", 0.0f, 0.0f, 10000.0f, "Gap Randomness",
"Custom Gap mode: Number of frames that gap lengths can vary", 0.0f, 1000.0f);
RNA_def_int(ot->srna, "seed", 0, 0, 1000, "Random Seed",
"Custom Gap mode: Random generator seed", 0, 100);
/* Note: Internal use, this one will always be hidden by UI code... */
prop = RNA_def_boolean(ot->srna, "use_timing_data", FALSE, "Has Valid Timing",
"Whether the converted grease pencil layer has valid timing data (internal use)");
"Whether the converted Grease Pencil layer has valid timing data (internal use)");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
+43 -42
View File
@@ -100,8 +100,8 @@ typedef struct tGPsdata {
short radius; /* radius of influence for eraser */
short flags; /* flags that can get set during runtime */
/* Those needs to be doubles, as (at least under unix) they are in seconds since epoch,
/* These need to be doubles, as (at least under unix) they are in seconds since epoch,
* float (and its 7 digits precision) is definitively not enough here!
* double, with its 15 digits precision, ensures us millisecond precision for a few centuries at least.
*/
@@ -110,7 +110,7 @@ typedef struct tGPsdata {
double ocurtime; /* Used when converting to path */
float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space
* to region space */
* to region space */
float custom_color[4]; /* custom color - hack for enforcing a particular color for track/mask editing */
@@ -455,11 +455,13 @@ static void gp_stroke_smooth(tGPsdata *p)
if ((cmx <= 2) || (gpd->sbuffer == NULL))
return;
/* Calculate smoothing coordinates using weighted-averages */
/* XXX DO NOT smooth first and last points! */
/* Calculate smoothing coordinates using weighted-averages
* WARNING: we do NOT smooth first and last points (to avoid shrinkage)
*/
spt = (tGPspoint *)gpd->sbuffer;
/* This small array stores the last two points' org coordinates, we don't want to use already averaged ones!
* Note it is used as a cyclic buffer...
/* This (tmp_spt) small array stores the last two points' original coordinates,
* as we don't want to use already averaged ones! It is used as a cyclic buffer...
*/
tmp_spt[0] = *spt;
for (i = 1, spt++; i < cmx - 1; i++, spt++) {
@@ -469,7 +471,7 @@ static void gp_stroke_smooth(tGPsdata *p)
const tGPspoint *pd = pc + 1;
const tGPspoint *pe = (i + 2 < cmx) ? (pc + 2) : (pd);
/* Store current point's org state for the two next points! */
/* Store current point's original state for the two next points! */
tmp_spt[i % 3] = *spt;
spt->x = (int)(0.1 * pa->x + 0.2 * pb->x + 0.4 * pc->x + 0.2 * pd->x + 0.1 * pe->x);
@@ -588,7 +590,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
return;
}
}
/* allocate memory for a new stroke */
gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
@@ -600,10 +602,10 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* allocate enough memory for a continuous array for storage points */
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
/* set pointer to first non-initialized point */
pt = gps->points + (gps->totpoints - totelem);
/* copy points from the buffer to the stroke */
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
/* straight lines only -> only endpoints */
@@ -722,7 +724,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
if (depth_arr)
MEM_freeN(depth_arr);
}
/* add stroke to frame */
BLI_addtail(&p->gpf->strokes, gps);
gp_stroke_added_enable(p);
@@ -735,7 +737,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
{
bGPDspoint *pt_tmp = gps->points;
bGPDstroke *gsn = NULL;
/* if stroke only had two points, get rid of stroke */
if (gps->totpoints == 2) {
/* free stroke points, then stroke */
@@ -745,7 +747,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
/* nothing left in stroke, so stop */
return 1;
}
/* if last segment, just remove segment from the stroke */
else if (i == gps->totpoints - 2) {
/* allocate new points array, and assign most of the old stroke there */
@@ -759,17 +761,17 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
/* nothing left in stroke, so stop */
return 1;
}
/* if first segment, just remove segment from the stroke */
else if (i == 0) {
/* allocate new points array, and assign most of the old stroke there */
gps->totpoints--;
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
memcpy(gps->points, pt_tmp + 1, sizeof(bGPDspoint) * gps->totpoints);
/* We must adjust timings!
* Each point's timing data is a delta from stroke's inittime, so as we erase the first
* point of the stroke, we have to offset this inittime and all remaing points' delta values.
* point of the stroke, we have to offset this inittime and all remaining points' delta values.
* This way we get a new stroke with exactly the same timing as if user had started drawing from
* the second point...
*/
@@ -777,9 +779,9 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
bGPDspoint *pts;
float delta = pt_tmp[1].time;
int j;
gps->inittime += delta;
gps->inittime += (double)delta;
pts = gps->points;
for (j = 0; j < gps->totpoints; j++, pts++) {
pts->time -= delta;
@@ -792,7 +794,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
/* no break here, as there might still be stuff to remove in this stroke */
return 0;
}
/* segment occurs in 'middle' of stroke, so split */
else {
/* duplicate stroke, and assign 'later' data to that stroke */
@@ -814,15 +816,15 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
bGPDspoint *pts;
float delta = pt_tmp[i].time;
int j;
gsn->inittime += delta;
gsn->inittime += (double)delta;
pts = gsn->points;
for (j = 0; j < gsn->totpoints; j++, pts++) {
pts->time -= delta;
}
}
/* adjust existing stroke */
gps->totpoints = i;
gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
@@ -844,7 +846,7 @@ static short gp_stroke_eraser_strokeinside(const int mval[], const int UNUSED(mv
const float mval_fl[2] = {mval[0], mval[1]};
const float screen_co_a[2] = {x0, y0};
const float screen_co_b[2] = {x1, y1};
if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) {
return TRUE;
}
@@ -904,7 +906,6 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, gps->points, &x0, &y0);
/* do boundbox check first */
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) {
/* only check if point is inside */
if (((x0 - mval[0]) * (x0 - mval[0]) + (y0 - mval[1]) * (y0 - mval[1])) <= rad * rad) {
@@ -922,10 +923,10 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
/* get points to work with */
pt1 = gps->points + i;
pt2 = gps->points + i + 1;
gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt1, &x0, &y0);
gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt2, &x1, &y1);
/* check that point segment of the boundbox of the eraser stroke */
if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) ||
((!ELEM(V2D_IS_CLIPPED, x1, y1)) && BLI_rcti_isect_pt(rect, x1, y1))) {
@@ -1033,7 +1034,7 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
}
}
break;
case SPACE_NODE:
{
/* SpaceNode *snode = curarea->spacedata.first; */
@@ -1554,14 +1555,14 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
PointerRNA itemptr;
float mousef[2];
int tablet = 0;
/* convert from window-space to area-space mouse coordinates
* NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding...
*/
p->mval[0] = event->mval[0] + 1;
p->mval[1] = event->mval[1] + 1;
p->curtime = PIL_check_seconds_timer();
/* handle pressure sensitivity (which is supplied by tablets) */
if (event->custom == EVT_DATA_TABLET) {
wmTabletData *wmtab = event->customdata;
@@ -1592,7 +1593,7 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
p->mvalo[1] = p->mval[1];
p->opressure = p->pressure;
p->inittime = p->ocurtime = p->curtime;
/* special exception here for too high pressure values on first touch in
* windows for some tablets, then we just skip first touch...
*/
@@ -1601,7 +1602,7 @@ static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
}
RNA_float_set(&itemptr, "time", p->curtime - p->inittime);
/* apply the current latest drawing point */
gpencil_draw_apply(op, p);
@@ -1754,7 +1755,7 @@ static int gpencil_area_exists(bContext *C, ScrArea *sa_test)
static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
{
tGPsdata *p = op->customdata;
/* we must check that we're still within the area that we're set up to work from
* otherwise we could crash (see bug #20586)
*/
@@ -1762,20 +1763,20 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
printf("\t\t\tGP - wrong area execution abort!\n");
p->status = GP_STATUS_ERROR;
}
/* printf("\t\tGP - start stroke\n"); */
/* we may need to set up paint env again if we're resuming */
/* XXX: watch it with the paintmode! in future,
* it'd be nice to allow changing paint-mode when in sketching-sessions */
/* XXX: with tablet events, we may event want to check for eraser here, for nicer tablet support */
if (gp_session_initdata(C, p))
gp_paint_initstroke(p, p->paintmode);
if (p->status != GP_STATUS_ERROR)
p->status = GP_STATUS_PAINTING;
return op->customdata;
}
@@ -1800,7 +1801,7 @@ static void gpencil_stroke_end(wmOperator *op)
static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
{
tGPsdata *p = op->customdata;
int estate = OPERATOR_PASS_THROUGH; /* default exit state */
int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through to support MMB view nav, etc. */
/* if (event->type == NDOF_MOTION)
* return OPERATOR_PASS_THROUGH;
@@ -1814,7 +1815,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
* better in tools that immediately apply
* in 3D space.
*/
/* we don't pass on key events, GP is used with key-modifiers - prevents Dkey to insert drivers */
if (ISKEYBOARD(event->type))
estate = OPERATOR_RUNNING_MODAL;
+5
View File
@@ -153,6 +153,11 @@ int EDBM_select_pick(struct bContext *C, const int mval[2], short extend, short
void EDBM_selectmode_set(struct BMEditMesh *em);
void EDBM_selectmode_convert(struct BMEditMesh *em, const short selectmode_old, const short selectmode_new);
/* user access this */
int EDBM_selectmode_toggle(struct bContext *C, const short selectmode_new,
const int action, const int use_extend, const int use_expand);
void EDBM_deselect_by_material(struct BMEditMesh *em, const short index, const short select);
void EDBM_select_toggle_all(struct BMEditMesh *em);
@@ -358,7 +358,7 @@ struct uiBlock {
char color_profile; /* color profile for correcting linear colors for display */
char *display_device; /* display devide name used to display this block,
char *display_device; /* display device name used to display this block,
* used by color widgets to transform colors from/to scene linear
*/
};
@@ -68,6 +68,8 @@
#define EM_SEPR_X 6
#define EM_SEPR_Y 6
// #define USE_OP_RESET_BUT // we may want to make this optional, disable for now.
#define UI_OPERATOR_ERROR_RET(_ot, _opname, return_statement) \
if (ot == NULL) { \
ui_item_disabled(layout, _opname); \
@@ -2840,10 +2842,12 @@ const char *uiLayoutIntrospect(uiLayout *layout)
return str;
}
#ifdef USE_OP_RESET_BUT
static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C), void *op_pt, void *UNUSED(arg_dummy2))
{
WM_operator_properties_reset((wmOperator *)op_pt);
}
#endif
/* this function does not initialize the layout, functions can be called on the layout before and after */
void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
@@ -2911,6 +2915,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
}
}
#ifdef USE_OP_RESET_BUT
/* its possible that reset can do nothing if all have PROP_SKIP_SAVE enabled
* but this is not so important if this button is drawn in those cases
* (which isn't all that likely anyway) - campbell */
@@ -2925,6 +2930,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Reset operator defaults"));
uiButSetFunc(but, ui_layout_operator_buts__reset_cb, op, NULL);
}
#endif
/* set various special settings for buttons */
{
@@ -867,7 +867,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply"), 0, "apply_as", MODIFIER_APPLY_DATA);
if (modifier_sameTopology(md) && !modifier_nonGeometrical(md))
if (modifier_isSameTopology(md) && !modifier_isNonGeometrical(md))
uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply as Shape Key"), 0, "apply_as", MODIFIER_APPLY_SHAPE);
}
+1 -1
View File
@@ -420,7 +420,7 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
if (!view_aligned)
rot[0] += (float)M_PI / 2.0f;
obedit = make_prim_init(C, "Monkey", &dia, mat, &state, loc, rot, layer);
obedit = make_prim_init(C, "Suzanne", &dia, mat, &state, loc, rot, layer);
mat[0][0] *= dia;
mat[1][1] *= dia;
mat[2][2] *= dia;
+2 -2
View File
@@ -157,13 +157,13 @@ BMBVHTree *BMBVH_NewBVH(BMEditMesh *em, int flag, Scene *scene, Object *obedit)
if (flag & BMBVH_RESPECT_SELECT) {
/* note, the arrays wont allign now! take care */
/* note, the arrays wont align now! take care */
if (!BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_SELECT)) {
continue;
}
}
else if (flag & BMBVH_RESPECT_HIDDEN) {
/* note, the arrays wont allign now! take care */
/* note, the arrays wont align now! take care */
if (BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_HIDDEN)) {
continue;
}
+2 -2
View File
@@ -2573,8 +2573,8 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha
int nco = BLI_countlist(chain) - 1;
float (*cos)[3] = NULL;
KnifeVert **kverts;
BLI_array_fixedstack_declare(cos, BM_NGON_STACK_SIZE, nco, __func__);
BLI_array_fixedstack_declare(kverts, BM_NGON_STACK_SIZE, nco, __func__);
BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__);
BLI_array_fixedstack_declare(kverts, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__);
kfe = ((Ref *)chain->first)->ref;
v1 = kfe->v1->v ? kfe->v1->v : kfe->v2->v;
+35 -13
View File
@@ -307,7 +307,8 @@ static void ringsel_find_edge(RingSelOpData *lcd, int cuts)
static void ringsel_finish(bContext *C, wmOperator *op)
{
RingSelOpData *lcd = op->customdata;
int cuts = RNA_int_get(op->ptr, "number_cuts");
const int cuts = RNA_int_get(op->ptr, "number_cuts");
const float smoothness = 0.292f * RNA_float_get(op->ptr, "smoothness");
if (lcd->eed) {
BMEditMesh *em = lcd->em;
@@ -319,7 +320,7 @@ static void ringsel_finish(bContext *C, wmOperator *op)
* Note though that it will break edgeslide in this specific case.
* See [#31939]. */
BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT,
0.0f, 0.0f, 0.0f,
smoothness, 0.0f, 0.0f,
cuts,
SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE, 0);
@@ -413,6 +414,7 @@ static int ringcut_cancel(bContext *C, wmOperator *op)
static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
{
ScrArea *sa = CTX_wm_area(C);
Object *obedit = CTX_data_edit_object(C);
RingSelOpData *lcd;
BMEdge *edge;
@@ -438,13 +440,17 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
lcd->eed = edge;
ringsel_find_edge(lcd, 1);
}
ED_area_headerprint(CTX_wm_area(C), "Select a ring to be cut, use mouse-wheel or page-up/down for number of cuts");
ED_area_headerprint(sa,
"Select a ring to be cut, "
"use mouse-wheel or page-up/down for number of cuts, "
"Hold Alt for smooth");
return OPERATOR_RUNNING_MODAL;
}
static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
{
float smoothness = RNA_float_get(op->ptr, "smoothness");
int cuts = RNA_int_get(op->ptr, "number_cuts");
RingSelOpData *lcd = op->customdata;
int show_cuts = 0;
@@ -491,11 +497,17 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
case WHEELUPMOUSE: /* change number of cuts */
if (event->val == KM_RELEASE)
break;
cuts++;
RNA_int_set(op->ptr, "number_cuts", cuts);
ringsel_find_edge(lcd, cuts);
show_cuts = TRUE;
if (event->alt == 0) {
cuts++;
RNA_int_set(op->ptr, "number_cuts", cuts);
ringsel_find_edge(lcd, cuts);
show_cuts = TRUE;
}
else {
smoothness = min_ff(smoothness + 0.05f, 4.0f);
RNA_float_set(op->ptr, "smoothness", smoothness);
show_cuts = TRUE;
}
ED_region_tag_redraw(lcd->ar);
break;
@@ -505,10 +517,17 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
if (event->val == KM_RELEASE)
break;
cuts = max_ii(cuts - 1, 0);
RNA_int_set(op->ptr, "number_cuts", cuts);
ringsel_find_edge(lcd, cuts);
show_cuts = TRUE;
if (event->alt == 0) {
cuts = max_ii(cuts - 1, 0);
RNA_int_set(op->ptr, "number_cuts", cuts);
ringsel_find_edge(lcd, cuts);
show_cuts = TRUE;
}
else {
smoothness = max_ff(smoothness - 0.05f, 0.0f);
RNA_float_set(op->ptr, "smoothness", smoothness);
show_cuts = TRUE;
}
ED_region_tag_redraw(lcd->ar);
break;
@@ -552,7 +571,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
if (show_cuts) {
char buf[64];
BLI_snprintf(buf, sizeof(buf), "Number of Cuts: %d", cuts);
BLI_snprintf(buf, sizeof(buf), "Number of Cuts: %d, Smooth: %.2f (Alt)", cuts, smoothness);
ED_area_headerprint(CTX_wm_area(C), buf);
}
@@ -604,4 +623,7 @@ void MESH_OT_loopcut(wmOperatorType *ot)
prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, INT_MAX, "Number of Cuts", "", 1, 10);
/* avoid re-using last var because it can cause _very_ high poly meshes and annoy users (or worse crash) */
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_float(ot->srna, "smoothness", 0.0f, 0.0f, FLT_MAX, "Smoothness", "Smoothness factor", 0.0f, 4.0f);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
+188 -28
View File
@@ -56,6 +56,7 @@
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_util.h"
#include "ED_uvedit.h"
#include "ED_object.h"
#include "ED_view3d.h"
@@ -68,6 +69,7 @@
#include "mesh_intern.h"
#include "UI_resources.h"
/* ****************************** MIRROR **************** */
@@ -917,6 +919,74 @@ void MESH_OT_select_similar(wmOperatorType *ot)
RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.0, 1.0);
}
/* **************** Mode Select *************** */
static int edbm_select_mode_exec(bContext *C, wmOperator *op)
{
const int type = RNA_enum_get(op->ptr, "type");
const int action = RNA_enum_get(op->ptr, "action");
const int use_extend = RNA_boolean_get(op->ptr, "use_extend");
const int use_expand = RNA_boolean_get(op->ptr, "use_expand");
if (EDBM_selectmode_toggle(C, type, action, use_extend, use_expand)) {
return OPERATOR_FINISHED;
}
else {
return OPERATOR_CANCELLED;
}
}
static int edbm_select_mode_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
// RNA_enum_set(op->ptr, "type"); /* type must be set already */
RNA_boolean_set(op->ptr, "use_extend", event->shift);
RNA_boolean_set(op->ptr, "use_expand", event->ctrl);
return edbm_select_mode_exec(C, op);
}
void MESH_OT_select_mode(wmOperatorType *ot)
{
PropertyRNA *prop;
static EnumPropertyItem elem_items[] = {
{SCE_SELECT_VERTEX, "VERT", ICON_VERTEXSEL, "Vertices", ""},
{SCE_SELECT_EDGE, "EDGE", ICON_EDGESEL, "Edges", ""},
{SCE_SELECT_FACE, "FACE", ICON_FACESEL, "Faces", ""},
{0, NULL, 0, NULL, NULL},
};
static EnumPropertyItem actions_items[] = {
{0, "DISABLE", 0, "Disable", "Disable selected markers"},
{1, "ENABLE", 0, "Enable", "Enable selected markers"},
{2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"},
{0, NULL, 0, NULL, NULL}
};
/* identifiers */
ot->name = "Select Mode";
ot->idname = "MESH_OT_select_mode";
ot->description = "Change selection mode";
/* api callbacks */
ot->invoke = edbm_select_mode_invoke;
ot->exec = edbm_select_mode_exec;
ot->poll = ED_operator_editmesh;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
prop = RNA_def_boolean(ot->srna, "use_extend", FALSE, "Extend", "");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna, "use_expand", FALSE, "Expand", "");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
ot->prop = prop = RNA_def_enum(ot->srna, "type", elem_items, 0, "Type", "");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
RNA_def_enum(ot->srna, "action", actions_items, 2, "Action", "Selection action to execute");
}
/* ***************************************************** */
/* **************** LOOP SELECTS *************** */
@@ -1891,56 +1961,146 @@ void EDBM_selectmode_convert(BMEditMesh *em, const short selectmode_old, const s
BMFace *efa;
BMIter iter;
/* first tag-to-select, then select --- this avoids a feedback loop */
/* have to find out what the selectionmode was previously */
if (selectmode_old == SCE_SELECT_VERTEX) {
if (selectmode_new == SCE_SELECT_EDGE) {
/* select all edges associated with every selected vertex */
eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
for (; eed; eed = BM_iter_step(&iter)) {
if ((BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)))
{
/* select all edges associated with every selected vert */
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
BM_elem_flag_set(eed, BM_ELEM_TAG, BM_edge_is_any_vert_flag_test(eed, BM_ELEM_SELECT));
}
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_TAG)) {
BM_edge_select_set(em->bm, eed, TRUE);
}
}
}
else if (selectmode_new == SCE_SELECT_FACE) {
BMIter liter;
BMLoop *l;
/* select all faces associated with every selected vert */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_elem_flag_set(efa, BM_ELEM_TAG, BM_face_is_any_vert_flag_test(efa, BM_ELEM_SELECT));
}
/* select all faces associated with every selected vertex */
efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
for (; efa; efa = BM_iter_step(&iter)) {
l = BM_iter_new(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
for (; l; l = BM_iter_step(&liter)) {
if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)) {
BM_face_select_set(em->bm, efa, TRUE);
break;
}
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
BM_face_select_set(em->bm, efa, TRUE);
}
}
}
}
else if (selectmode_old == SCE_SELECT_EDGE) {
if (selectmode_new == SCE_SELECT_FACE) {
BMIter liter;
BMLoop *l;
/* select all faces associated with every selected edge */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_elem_flag_set(efa, BM_ELEM_TAG, BM_face_is_any_edge_flag_test(efa, BM_ELEM_SELECT));
}
/* select all faces associated with every selected vertex */
efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
for (; efa; efa = BM_iter_step(&iter)) {
l = BM_iter_new(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
for (; l; l = BM_iter_step(&liter)) {
if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)) {
BM_face_select_set(em->bm, efa, TRUE);
break;
}
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
BM_face_select_set(em->bm, efa, TRUE);
}
}
}
}
}
/* user facing function, does notification and undo push */
int EDBM_selectmode_toggle(bContext *C, const short selectmode_new,
const int action, const int use_extend, const int use_expand)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = NULL;
int ret = FALSE;
if (obedit && obedit->type == OB_MESH) {
em = BMEdit_FromObject(obedit);
}
if (em == NULL) {
return ret;
}
switch (action) {
case -1:
/* already set */
break;
case 0: /* disable */
/* check we have something to do */
if ((em->selectmode & selectmode_new) == 0) {
return FALSE;
}
em->selectmode &= ~selectmode_new;
break;
case 1: /* enable */
/* check we have something to do */
if ((em->selectmode & selectmode_new) != 0) {
return FALSE;
}
em->selectmode |= selectmode_new;
break;
case 2: /* toggle */
/* can't disable this flag if its the only one set */
if (em->selectmode == selectmode_new) {
return FALSE;
}
em->selectmode ^= selectmode_new;
break;
default:
BLI_assert(0);
}
switch (selectmode_new) {
case SCE_SELECT_VERTEX:
if (use_extend == 0 || em->selectmode == 0)
em->selectmode = SCE_SELECT_VERTEX;
ts->selectmode = em->selectmode;
EDBM_selectmode_set(em);
ret = TRUE;
break;
case SCE_SELECT_EDGE:
if (use_extend == 0 || em->selectmode == 0) {
if (use_expand) {
const short selmode_max = highest_order_bit_s(ts->selectmode);
if (selmode_max == SCE_SELECT_VERTEX) {
EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_EDGE);
}
}
em->selectmode = SCE_SELECT_EDGE;
}
ts->selectmode = em->selectmode;
EDBM_selectmode_set(em);
ret = TRUE;
break;
case SCE_SELECT_FACE:
if (use_extend == 0 || em->selectmode == 0) {
if (use_expand) {
const short selmode_max = highest_order_bit_s(ts->selectmode);
if (ELEM(selmode_max, SCE_SELECT_VERTEX, SCE_SELECT_EDGE)) {
EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_FACE);
}
}
em->selectmode = SCE_SELECT_FACE;
}
ts->selectmode = em->selectmode;
EDBM_selectmode_set(em);
ret = TRUE;
break;
default:
BLI_assert(0);
break;
}
if (ret == TRUE) {
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL);
}
return ret;
}
void EDBM_deselect_by_material(BMEditMesh *em, const short index, const short select)
{
@@ -129,6 +129,7 @@ void MESH_OT_faces_select_linked_flat(struct wmOperatorType *ot);
void MESH_OT_edges_select_sharp(struct wmOperatorType *ot);
void MESH_OT_select_shortest_path(struct wmOperatorType *ot);
void MESH_OT_select_similar(struct wmOperatorType *ot);
void MESH_OT_select_mode(struct wmOperatorType *ot);
void MESH_OT_select_random(struct wmOperatorType *ot);
void MESH_OT_loop_multi_select(struct wmOperatorType *ot);
void MESH_OT_mark_seam(struct wmOperatorType *ot);
+1
View File
@@ -130,6 +130,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_edge_face_add);
WM_operatortype_append(MESH_OT_select_shortest_path);
WM_operatortype_append(MESH_OT_select_similar);
WM_operatortype_append(MESH_OT_select_mode);
WM_operatortype_append(MESH_OT_loop_multi_select);
WM_operatortype_append(MESH_OT_mark_seam);
WM_operatortype_append(MESH_OT_mark_sharp);
@@ -555,7 +555,7 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M
Key *key = me->key;
KeyBlock *kb;
if (!modifier_sameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) {
if (!modifier_isSameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) {
BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to shapes");
return 0;
}
@@ -688,6 +688,13 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
return 0;
}
else if ((ob->mode & OB_MODE_SCULPT) &&
(find_multires_modifier_before(scene, md)) &&
(modifier_isSameTopology(md) == FALSE))
{
BKE_report(reports, RPT_ERROR, "Constructive modifier cannot be applied to multi-res data in sculpt mode");
return 0;
}
if (md != ob->modifiers.first)
BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected");
@@ -1000,7 +1007,7 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
int apply_as = RNA_enum_get(op->ptr, "apply_as");
if (!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
return OPERATOR_CANCELLED;
}
@@ -1225,7 +1225,7 @@ static unsigned int move_to_layer_init(bContext *C, wmOperator *op)
return lay;
}
static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event)
static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
View3D *v3d = CTX_wm_view3d(C);
if (v3d && v3d->localvd) {
@@ -1233,7 +1233,7 @@ static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
else {
move_to_layer_init(C, op);
return WM_operator_props_popup(C, op, event);
return WM_operator_props_dialog_popup(C, op, 260, 30);
}
}
@@ -845,25 +845,26 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum)
static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum)
{
MDeformVert *dv = NULL;
BMVert *eve;
Mesh *me;
/* get the deform vertices corresponding to the vertnum */
if (ob->type == OB_MESH) {
me = ob->data;
Mesh *me = ob->data;
if (me->edit_btmesh) {
eve = BM_vert_at_index(me->edit_btmesh->bm, vertnum);
/* warning, this lookup is _not_ fast */
BMVert *eve = BM_vert_at_index(me->edit_btmesh->bm, vertnum);
if (!eve) {
return 0.0f;
}
dv = CustomData_bmesh_get(&me->edit_btmesh->bm->vdata, eve->head.data, CD_MDEFORMVERT);
}
else {
if (vertnum >= me->totvert) {
return 0.0f;
if (me->dvert) {
if (vertnum >= me->totvert) {
return 0.0f;
}
dv = &me->dvert[vertnum];
}
dv = &me->dvert[vertnum];
}
}
else if (ob->type == OB_LATTICE) {
@@ -248,7 +248,7 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext *
void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts)
{
/* gatheravailable texture users in context. runs on every draw of
/* gather available texture users in context. runs on every draw of
* properties editor, before the buttons are created. */
ButsContextTexture *ct = sbuts->texuser;
Scene *scene = CTX_data_scene(C);
@@ -1497,7 +1497,7 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d)
if (onlyv2d) {
/* if manual calibration is used then grease pencil data is already
* drawed in draw_distortion */
* drawn in draw_distortion */
if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || sc->mode != SC_MODE_DISTORTION) {
glPushMatrix();
glMultMatrixf(sc->unistabmat);
@@ -1686,7 +1686,7 @@ static int sequencer_delete_invoke(bContext *C, wmOperator *op, wmEvent *event)
if (ar->regiontype == RGN_TYPE_WINDOW) {
/* bounding box of 30 pixels is used for markers shortcuts,
* prevent conflict with markers shortcurts here
* prevent conflict with markers shortcuts here
*/
if (event->mval[1] <= 30)
return OPERATOR_PASS_THROUGH;
@@ -945,7 +945,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
ED_region_tag_redraw(ar);
break;
case NC_GPENCIL:
if (wmn->data == ND_DATA || wmn->action == NA_EDITED)
if (wmn->data == ND_DATA || wmn->action == NA_EDITED)
ED_region_tag_redraw(ar);
break;
}
@@ -310,21 +310,14 @@ static char *view3d_modeselect_pup(Scene *scene)
return (string);
}
static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
{
wmWindow *win = CTX_wm_window(C);
ToolSettings *ts = CTX_data_tool_settings(C);
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = NULL;
int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
const int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
PointerRNA props_ptr;
if (obedit && obedit->type == OB_MESH) {
em = BMEdit_FromObject(obedit);
}
/* watch it: if sa->win does not exist, check that when calling direct drawing routines */
switch (event) {
@@ -336,42 +329,17 @@ static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
break;
case B_SEL_VERT:
if (em) {
if (shift == 0 || em->selectmode == 0)
em->selectmode = SCE_SELECT_VERTEX;
ts->selectmode = em->selectmode;
EDBM_selectmode_set(em);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
if (EDBM_selectmode_toggle(C, SCE_SELECT_VERTEX, -1, shift, ctrl)) {
ED_undo_push(C, "Selectmode Set: Vertex");
}
break;
case B_SEL_EDGE:
if (em) {
if (shift == 0 || em->selectmode == 0) {
if ((em->selectmode ^ SCE_SELECT_EDGE) == SCE_SELECT_VERTEX) {
if (ctrl) EDBM_selectmode_convert(em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
}
em->selectmode = SCE_SELECT_EDGE;
}
ts->selectmode = em->selectmode;
EDBM_selectmode_set(em);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
if (EDBM_selectmode_toggle(C, SCE_SELECT_EDGE, -1, shift, ctrl)) {
ED_undo_push(C, "Selectmode Set: Edge");
}
break;
case B_SEL_FACE:
if (em) {
if (shift == 0 || em->selectmode == 0) {
if (((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) ||
((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE))
{
if (ctrl) EDBM_selectmode_convert(em, (ts->selectmode ^ SCE_SELECT_FACE), SCE_SELECT_FACE);
}
em->selectmode = SCE_SELECT_FACE;
}
ts->selectmode = em->selectmode;
EDBM_selectmode_set(em);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
if (EDBM_selectmode_toggle(C, SCE_SELECT_FACE, -1, shift, ctrl)) {
ED_undo_push(C, "Selectmode Set: Face");
}
break;
@@ -430,9 +398,15 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
row = uiLayoutRow(layout, TRUE);
block = uiLayoutGetBlock(row);
uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Vertex select - Shift-Click for multiple modes");
uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Edge select - Shift-Click for multiple modes");
uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Face select - Shift-Click for multiple modes");
uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL,
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
"Vertex select - Shift-Click for multiple modes");
uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL,
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
"Edge select - Shift-Click for multiple modes, Ctrl-Click expands selection");
uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL,
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
"Face select - Shift-Click for multiple modes, Ctrl-Click expands selection");
}
}
+106
View File
@@ -1553,7 +1553,112 @@ static void UV_OT_align(wmOperatorType *ot)
/* properties */
RNA_def_enum(ot->srna, "axis", axis_items, 'a', "Axis", "Axis to align UV locations on");
}
/* ******************** weld near operator **************** */
typedef struct UVvert {
MLoopUV *uv_loop;
int weld;
} UVvert;
static int remove_doubles_exec(bContext *C, wmOperator *op)
{
SpaceImage *sima;
Scene *scene;
Object *obedit;
Image *ima;
BMEditMesh *em;
MTexPoly *tf;
int UV_a;
int UV_b;
float UVp1[2];
float UVp2[2];
float weld_dist;
MLoopUV **loop_arr = NULL;
BLI_array_declare(loop_arr);
UVvert *vert_arr = NULL;
BLI_array_declare(vert_arr);
BMIter iter, liter;
BMFace *efa;
BMLoop *l;
sima = CTX_wm_space_image(C);
scene = CTX_data_scene(C);
obedit = CTX_data_edit_object(C);
em = BMEdit_FromObject(obedit);
ima = CTX_data_edit_image(C);
weld_dist = RNA_float_get(op->ptr, "weld_dist");
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
if (!uvedit_face_visible_test(scene, ima, efa, tf))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l)) {
MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
UVvert vert;
vert.uv_loop = luv;
vert.weld = FALSE;
BLI_array_append(vert_arr, vert);
}
}
}
for (UV_a = 0; UV_a<BLI_array_count(vert_arr); UV_a++){
if (vert_arr[UV_a].weld == FALSE){
float far_UV [2];
float near_UV [2];
BLI_array_empty(loop_arr);
BLI_array_append(loop_arr, vert_arr[UV_a].uv_loop);
copy_v2_v2(UVp1, vert_arr[UV_a].uv_loop->uv);
copy_v2_v2(near_UV, UVp1);
copy_v2_v2(far_UV, UVp1);
vert_arr[UV_a].weld = TRUE;
for (UV_b = 0; UV_b<BLI_array_count(vert_arr); UV_b++){
copy_v2_v2(UVp2, vert_arr[UV_b].uv_loop->uv);
if (UV_b != UV_a && vert_arr[UV_b].weld == FALSE && UVp1[0]-UVp2[0] > -weld_dist && UVp1[0] - UVp2[0] < weld_dist && UVp1[1] - UVp2[1] > -weld_dist && UVp1[1] - UVp2[1] < weld_dist){
minmax_v2v2_v2(near_UV, far_UV, UVp2);
BLI_array_append(loop_arr, vert_arr[UV_b].uv_loop);
vert_arr[UV_b].weld = TRUE;
}
}
for (UV_b = 0; UV_b<BLI_array_count(loop_arr); UV_b++){
mid_v2_v2v2(loop_arr[UV_b]->uv, far_UV, near_UV);
}
}
}
BLI_array_free(loop_arr);
BLI_array_free(vert_arr);
uvedit_live_unwrap_update(sima, scene, obedit);
DAG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
return OPERATOR_FINISHED;
}
static void UV_OT_remove_doubles(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Remove Doubles";
ot->description = "Selected UV vertices that are within a radius of eachother are welded together";
ot->idname = "UV_OT_remove_doubles";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* api callbacks */
ot->exec = remove_doubles_exec;
ot->poll = ED_operator_uvedit;
RNA_def_float(ot->srna, "weld_dist", 0.02f, 0.0f, 1.0f, "Weld Distance", "Maximum distance between welded vertices", 0.001f, 10.0f);
}
/* ******************** weld operator **************** */
static int weld_exec(bContext *C, wmOperator *UNUSED(op))
@@ -3776,6 +3881,7 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_seams_from_islands);
WM_operatortype_append(UV_OT_mark_seam);
WM_operatortype_append(UV_OT_weld);
WM_operatortype_append(UV_OT_remove_doubles);
WM_operatortype_append(UV_OT_pin);
WM_operatortype_append(UV_OT_average_islands_scale);
@@ -1444,18 +1444,22 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
}
case PADENTER:
case RETKEY:
if (stitch_process_data(stitch_state, scene, 1)) {
stitch_exit(C, op, 1);
return OPERATOR_FINISHED;
if (event->val == KM_PRESS) {
if (stitch_process_data(stitch_state, scene, 1)) {
stitch_exit(C, op, 1);
return OPERATOR_FINISHED;
}
else {
return stitch_cancel(C, op);
}
}
else {
return stitch_cancel(C, op);
return OPERATOR_PASS_THROUGH;
}
/* Increase limit */
case PADPLUSKEY:
case WHEELUPMOUSE:
if (event->alt) {
if (event->val == KM_PRESS && event->alt) {
stitch_state->limit_dist += 0.01f;
if (!stitch_process_data(stitch_state, scene, 0)) {
return stitch_cancel(C, op);
@@ -1468,7 +1472,7 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
/* Decrease limit */
case PADMINUS:
case WHEELDOWNMOUSE:
if (event->alt) {
if (event->val == KM_PRESS && event->alt) {
stitch_state->limit_dist -= 0.01f;
stitch_state->limit_dist = MAX2(0.01f, stitch_state->limit_dist);
if (!stitch_process_data(stitch_state, scene, 0)) {
@@ -1414,7 +1414,7 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf))
BMIter liter;
MLoopUV *luv;
float **uvs = NULL;
BLI_array_fixedstack_declare(uvs, BM_NGON_STACK_SIZE, efa->len, __func__);
BLI_array_fixedstack_declare(uvs, BM_DEFAULT_NGON_STACK_SIZE, efa->len, __func__);
float dx;
int i, mi;
@@ -79,12 +79,14 @@ static IKPlugin ikplugin_tab[] = {
itasc_update_param,
itasc_test_constraint,
},
#endif
#endif
{ NULL }
};
static IKPlugin *get_plugin(bPose *pose)
{
if (!pose || pose->iksolver < 0 || pose->iksolver >= (sizeof(ikplugin_tab) / sizeof(IKPlugin)))
if (!pose || pose->iksolver < 0 || pose->iksolver > (sizeof(ikplugin_tab)/sizeof(IKPlugin) - 2))
return NULL;
return &ikplugin_tab[pose->iksolver];
@@ -164,7 +164,7 @@ typedef struct ColormanageProcessor {
* but they holds indexes of all transformations and color spaces, not
* their names.
*
* This helps avoid extra colorsmace / display / view lookup without
* This helps avoid extra colorspace / display / view lookup without
* requiring to pass all variables which affects on display buffer
* to color management cache system and keeps calls small and nice.
*/
+2 -2
View File
@@ -387,8 +387,8 @@ BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val)
/*
* 2048x1080 (2K) at 24 fps or 48 fps, or 4096x2160 (4K) at 24 fps; 3x12 bits per pixel, XYZ color space
*
* - In 2K, for Scope (2.39:1) presentation 2048x858 pixels of the imager is used
* - In 2K, for Flat (1.85:1) presentation 1998x1080 pixels of the imager is used
* - In 2K, for Scope (2.39:1) presentation 2048x858 pixels of the image is used
* - In 2K, for Flat (1.85:1) presentation 1998x1080 pixels of the image is used
*/
/* ****************************** COPIED FROM image_to_j2k.c */
+6 -19
View File
@@ -348,25 +348,12 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla
g = *buffer++;
b = *buffer++;
k = *buffer++;
k = 255 - k;
r -= k;
if (r & 0xffffff00) {
if (r < 0) r = 0;
else r = 255;
}
g -= k;
if (g & 0xffffff00) {
if (g < 0) g = 0;
else g = 255;
}
b -= k;
if (b & 0xffffff00) {
if (b < 0) b = 0;
else b = 255;
}
rect[3] = 255 - k;
r = (r * k) / 255;
g = (g * k) / 255;
b = (b * k) / 255;
rect[3] = 255;
rect[2] = b;
rect[1] = g;
rect[0] = r;
@@ -881,7 +881,7 @@ void IMB_exr_close(void *handle)
/* get a substring from the end of the name, separated by '.' */
static int imb_exr_split_token(const char *str, const char *end, const char **token)
{
int maxlen = end - str;
ptrdiff_t maxlen = end - str;
int len = 0;
while (len < maxlen && *(end - len - 1) != '.') {
len++;
@@ -1183,7 +1183,7 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char
frameBuffer.insert(exr_rgba_channelname(file, "B"),
Slice(Imf::FLOAT, (char *) (first + 2), xstride, ystride));
/* 1.0 is fill value, this still neesd to be assigned even when (is_alpha == 0) */
/* 1.0 is fill value, this still needs to be assigned even when (is_alpha == 0) */
frameBuffer.insert(exr_rgba_channelname(file, "A"),
Slice(Imf::FLOAT, (char *) (first + 3), xstride, ystride, 1, 1, 1.0f));
@@ -35,10 +35,10 @@
/* experiment with more advanced exr api */
/* Note: as for now openexr only supports 32 chars in channel names.
* This api also supports max 8 channels per pass now. easy to fix! */
#define EXR_LAY_MAXNAME 51
#define EXR_PASS_MAXNAME 11
/* XXX layer+pass name max 64? */
/* This api also supports max 8 channels per pass now. easy to fix! */
#define EXR_LAY_MAXNAME 64
#define EXR_PASS_MAXNAME 64
#define EXR_TOT_MAXNAME 64
#define EXR_PASS_MAXCHAN 8
+2 -1
View File
@@ -50,12 +50,13 @@ typedef struct bGPDspoint {
*/
typedef struct bGPDstroke {
struct bGPDstroke *next, *prev;
bGPDspoint *points; /* array of data-points for stroke */
void *pad; /* keep 4 pointers at the beginning, padding for 'inittime' is tricky 64/32bit */
int totpoints; /* number of data-points in array */
short thickness; /* thickness of stroke (currently not used) */
short flag; /* various settings about this stroke */
double inittime; /* Init time of stroke */
} bGPDstroke;
+1 -1
View File
@@ -1201,7 +1201,7 @@ typedef struct Scene {
#define R_NO_OVERWRITE 0x400000 /* skip existing files */
#define R_TOUCH 0x800000 /* touch files before rendering */
#define R_SIMPLIFY 0x1000000
#define R_EDGE_FRS 0x2000000 /* R_EDGE for Freestyle */
#define R_EDGE_FRS 0x2000000 /* R_EDGE reserved for Freestyle */
#define R_PERSISTENT_DATA 0x4000000 /* keep data around for re-render */
/* seq_flag */
+2 -2
View File
@@ -163,7 +163,7 @@ typedef struct MovieTrackingSettings {
/* ** reconstruction settings ** */
int keyframe1 DNA_DEPRECATED,
keyframe2 DNA_DEPRECATED; /* two keyframes for reconstrution initialization
keyframe2 DNA_DEPRECATED; /* two keyframes for reconstruction initialization
* were moved to per-tracking object settings
*/
@@ -228,7 +228,7 @@ typedef struct MovieTrackingObject {
MovieTrackingReconstruction reconstruction; /* reconstruction data for this object */
/* reconstruction options */
int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */
int keyframe1, keyframe2; /* two keyframes for reconstruction initialization */
} MovieTrackingObject;
typedef struct MovieTrackingStats {
+1 -1
View File
@@ -1424,7 +1424,7 @@ static void rna_def_curve(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_map_taper", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_MAP_TAPER);
RNA_def_property_ui_text(prop, "Map Taper", "Map effect of taper object on actually bevelled curve");
RNA_def_property_ui_text(prop, "Map Taper", "Map effect of taper object on actually beveled curve");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
/* texture space */

Some files were not shown because too many files have changed in this diff Show More