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)))
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()
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()
@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'"
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
# 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")
-
- if not os.path.exists(py_h):
- print("\nMissing: \"" + env.subst('${BF_PYTHON_INC}') + os.sep + "Python.h\",\n"
+ 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 (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):
--- /dev/null
+#!/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
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
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
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
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
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
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
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
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
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
+ /opt/lib/ocio
)
FIND_PATH(OPENCOLORIO_INCLUDE_DIR
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
+ /opt/lib/oiio
)
FIND_PATH(OPENIMAGEIO_INCLUDE_DIR
${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})
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
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
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
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
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
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
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'])
'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'
]
('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', ''),
: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.
: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.
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:
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
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
-------------------------
**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
* 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);
* 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);
};
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())
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;
}
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;
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
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])
}
/**
- * 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.
)
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.
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).
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():
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!
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")
# 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__":
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
layout = self.layout
layout.operator("uv.weld") # W, 1
+ layout.operator("uv.remove_doubles")
layout.operator_enum("uv.align", "axis") # W, 2/3/4
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):
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__
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.
*/
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')
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;
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);
}
}
}
- 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;
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++) {
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);
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,
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? */
}
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;
/* ********************* 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
};
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;
}
}
# 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 */
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;
{
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;
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;
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;
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) {
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;
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;
*/
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 */
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,
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);
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);
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;
*
* 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:
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 */
#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
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);
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);
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;
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;
+}
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__ */
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 */
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;
}
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);
}
}
{
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);
}
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);
}
}
/* 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);
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 */
}
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 {
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;
}
}
}
- 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;
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
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;
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 */
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 */
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);
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++;
}
}
}
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);
}
}
-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;
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
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;
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);
}
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);
}
/*
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++;
}
/* 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);
+
+ 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);
+ }
- /* 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 (faces != (BMFace **)faces_stack) {
+ MEM_freeN(faces);
+ }
}
}
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);
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);
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);
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);
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)};
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;
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) {
/* 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);
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;
}
}
/* 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 */
!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);
}
}
* 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
class PixelateOperation : public NodeOperation {
private:
/**
- * @brief cached refeerence to the input operation
+ * @brief cached reference to the input operation
*/
SocketReader *m_inputOperation;
public:
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);
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;
}
}
mvalf[1] = (float)pt->y / 100.0f * ar->winy;
}
}
-
+
/* convert screen coordinate to 3d coordinates
* - method taken from editview.c - mouse_cursor()
*/
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) {
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 can’t 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
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];
/* 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);
/* 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
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 */
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++) {
}
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
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.
*/
nu->resolu = cu->resolu;
nu->resolv = cu->resolv;
nu->knotsu = NULL;
-
+
nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * nu->pntsu, "bpoints");
-
+
stitch = FALSE; /* Security! */
}
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) {
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);
else {
interp_v3_v3v3(p2, p, bp->vec, GAP_DFAC);
}
-
+
/* First point */
bp++;
copy_v3_v3(bp->vec, p1);
}
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);
}
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;
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);
if (curnu) {
*curnu = nu;
}
-
+
BKE_nurb_knot_calc_u(nu);
}
{
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
-
+
if (v3d) {
RegionView3D *rv3d = ar->regiondata;
return 1;
}
}
-
+
return 0;
}
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;
* 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! */
}
/* 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);
/* 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;
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
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! */
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);
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;
}
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);
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) {
}
gp_timing_data_add_point(gtd, gps->inittime, delta_time, len_v3v3(p1, p2));
}
-
+
old_nbezt += 2;
copy_v3_v3(p3d_prev, p2);
}
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;
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);
static void gp_stroke_finalize_curve_endpoints(Curve *cu)
{
+ /* start */
Nurb *nu = cu->nurb.first;
int i = 0;
if (nu->bezt) {
bp[i].weight = bp[i].radius = 0.0f;
}
}
-
+
+ /* end */
nu = cu->nurb.last;
i = nu->pntsu - 1;
if (nu->bezt) {
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;
/* 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;
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
*/
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);
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;
+ }
}
/* --- */
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;
}
prev_time = cur_time;
}
+
if (!valid) {
break;
}
} while ((gps = gps->next));
-
+
if (op) {
RNA_boolean_set(op->ptr, "use_timing_data", valid);
}
{
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);
}
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)) {
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;
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, >d);
-
+
+ /* 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;
}
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 ||
{
return TRUE;
}
-
+
/* Never show this prop */
if (strcmp(prop_id, "use_timing_data") == 0)
return FALSE;
/* 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 ||
{
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;
}
}
/* 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",
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);
}
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.
*/
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 */
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++) {
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);
return;
}
}
-
+
/* allocate memory for a new stroke */
gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
/* 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 */
if (depth_arr)
MEM_freeN(depth_arr);
}
-
+
/* add stroke to frame */
BLI_addtail(&p->gpf->strokes, gps);
gp_stroke_added_enable(p);
{
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 */
/* 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 */
/* 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...
*/
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;
/* 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 */
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");
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;
}
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) {
/* 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))) {
}
}
break;
-
+
case SPACE_NODE:
{
/* SpaceNode *snode = curarea->spacedata.first; */
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;
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...
*/
}
RNA_float_set(&itemptr, "time", p->curtime - p->inittime);
-
+
/* apply the current latest drawing point */
gpencil_draw_apply(op, p);
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)
*/
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;
}
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;
* 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;
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);
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
*/
};
#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); \
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,
}
}
+#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 */
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 */
{
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);
}
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;
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;
}
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;
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;
* 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);
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;
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;
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;
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;
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);
}
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);
}
#include "ED_mesh.h"
#include "ED_screen.h"
+#include "ED_util.h"
#include "ED_uvedit.h"
#include "ED_object.h"
#include "ED_view3d.h"
#include "mesh_intern.h"
+#include "UI_resources.h"
/* ****************************** MIRROR **************** */
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 *************** */
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 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;
- }
+ /* 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));
+ }
+
+ 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 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;
- }
+ /* 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));
+ }
+
+ 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)
{
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);
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);
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;
}
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");
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;
}
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) {
}
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);
}
}
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) {
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);
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);
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;
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;
}
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) {
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;
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");
}
}
/* 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))
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);
}
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);
/* 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)) {
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;
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];
* 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.
*/
/*
* 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 */
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;
/* 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++;
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));
/* 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
*/
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;
#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 */
/* ** 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
*/
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 {
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 */
if (value.data == NULL)
return;
- /* exception: can't set screens inside of area/region handers */
+ /* exception: can't set screens inside of area/region handlers */
win->newscreen = value.data;
}
{
wmWindow *win = (wmWindow *)ptr->data;
- /* exception: can't set screens inside of area/region handers, and must
- * use context so notifier gets to the right window */
+ /* exception: can't set screens inside of area/region handlers,
+ * and must use context so notifier gets to the right window */
if (win->newscreen) {
WM_event_add_notifier(C, NC_SCREEN | ND_SCREENBROWSE, win->newscreen);
win->newscreen = NULL;
/* Note
* Py_TPFLAGS_CHECKTYPES allows us to avoid casting all types to Vector when coercing
* but this means for eg that
- * (vec * mat) and (mat * vec) both get sent to Vector_mul and it neesd to sort out the order
+ * (vec * mat) and (mat * vec) both get sent to Vector_mul and it needs to sort out the order
*/
PyDoc_STRVAR(vector_doc,
#define RE_ENGINE_PREVIEW 2
#define RE_ENGINE_DO_DRAW 4
#define RE_ENGINE_DO_UPDATE 8
+#define RE_ENGINE_RENDERING 16
extern ListBase R_engines;
* eg.: on render code)
*
* 0 means it's reserved and has it own meaning inside each ray acceleration structure
- * (this way each structure can use the allign offset to determine if a node represents a
+ * (this way each structure can use the align offset to determine if a node represents a
* RayObject primitive, which can be used to save memory)
*/
labdao = ddalabda;
- /* traversing ocree nodes need careful detection of smallest values, with proper
+ /* traversing octree nodes need careful detection of smallest values, with proper
* exceptions for equal labdas */
eqval = (labdax == labday);
if (labday == labdaz) eqval += 2;