diff --git a/CMakeLists.txt b/CMakeLists.txt index 16d00dd4b54..e2dda8553d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -562,12 +562,12 @@ set(PLATFORM_LINKFLAGS_DEBUG "") if(UNIX AND NOT APPLE) macro(find_package_wrapper) string(TOUPPER ${ARGV0} _NAME_UPPER) - if(${WITH_STATIC_LIBS}) + if(WITH_STATIC_LIBS) set(_cmake_find_library_suffixes_back ${CMAKE_FIND_LIBRARY_SUFFIXES}) set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) endif() find_package(${ARGV}) - if(${WITH_STATIC_LIBS}) + if(WITH_STATIC_LIBS) set(CMAKE_FIND_LIBRARY_SUFFIXES ${_cmake_find_library_suffixes_back}) unset(_cmake_find_library_suffixes_back) endif() @@ -707,7 +707,7 @@ if(UNIX AND NOT APPLE) if(WITH_BOOST) # uses in build instructions to override include and library variables if(NOT BOOST_CUSTOM) - if(${WITH_STATIC_LIBS}) + if(WITH_STATIC_LIBS) set(Boost_USE_STATIC_LIBS ON) endif() set(Boost_USE_MULTITHREADED ON) diff --git a/intern/audaspace/intern/AUD_Sequencer.cpp b/intern/audaspace/intern/AUD_Sequencer.cpp index 58e8f682714..c59c56a4479 100644 --- a/intern/audaspace/intern/AUD_Sequencer.cpp +++ b/intern/audaspace/intern/AUD_Sequencer.cpp @@ -161,7 +161,7 @@ boost::shared_ptr AUD_Sequencer::add(boost::shared_ptr entry = boost::shared_ptr(new AUD_SequencerEntry(sound, begin, end, skip, m_id++)); - m_entries.push_front(entry); + m_entries.push_back(entry); m_entry_status++; return entry; diff --git a/intern/audaspace/intern/AUD_SequencerReader.cpp b/intern/audaspace/intern/AUD_SequencerReader.cpp index d5e14590df5..aef93cd3896 100644 --- a/intern/audaspace/intern/AUD_SequencerReader.cpp +++ b/intern/audaspace/intern/AUD_SequencerReader.cpp @@ -112,7 +112,7 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer) try { handle = boost::shared_ptr(new AUD_SequencerHandle(entry, m_device)); - handles.push_front(handle); + handles.push_back(handle); } catch(AUD_Exception&) { @@ -143,7 +143,7 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer) try { handle = boost::shared_ptr(new AUD_SequencerHandle(*eit, m_device)); - handles.push_front(handle); + handles.push_back(handle); } catch(AUD_Exception&) { diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index a8293ac683c..cc132a2c3b2 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -13,10 +13,14 @@ if(WITH_RAYOPTIMIZATION AND SUPPORT_SSE_BUILD) endif() if(WIN32 AND MSVC) - set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /Ox /GS-") # there is no /arch:SSE3, but intrinsics are available anyway - set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /Ox /GS-") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /EHsc /Ox /GS-") + set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-") + set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-") + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} /Ox") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE} /Ox") elseif(CMAKE_COMPILER_IS_GNUCC) set(CYCLES_SSE2_KERNEL_FLAGS "-ffast-math -msse -msse2 -mfpmath=sse") set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse") diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript index 57f44ae9d52..d1f1b287e00 100644 --- a/intern/cycles/SConscript +++ b/intern/cycles/SConscript @@ -79,12 +79,12 @@ if env['WITH_BF_RAYOPTIMIZATION']: sse3_cxxflags = Split(env['CXXFLAGS']) if env['OURPLATFORM'] == 'win32-vc': - sse2_cxxflags.append('/arch:SSE /arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /Ox /Gs-'.split()) # there is no /arch:SSE3, but intrinsics are available anyway - sse3_cxxflags.append('/arch:SSE /arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /Ox /Gs-'.split()) + sse2_cxxflags.append('/arch:SSE /arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'.split()) + sse3_cxxflags.append('/arch:SSE /arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'.split()) elif env['OURPLATFORM'] == 'win64-vc': - sse2_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /Ox /Gs-'.split()) - sse3_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /Ox /Gs-'.split()) + sse2_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'.split()) + sse3_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'.split()) else: sse2_cxxflags.append('-ffast-math -msse -msse2 -mfpmath=sse'.split()) sse3_cxxflags.append('-ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse'.split()) diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index f32c6dde639..1f96ed0ae83 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -271,11 +271,53 @@ public: return ""; } + int cuda_version = cuCompilerVersion(); + + if(cuda_version == 0) { + cuda_error_message("CUDA nvcc compiler version could not be parsed."); + return ""; + } + + if(cuda_version != 50) + printf("CUDA version %d.%d detected, build may succeed but only CUDA 5.0 is officially supported.\n", cuda_version/10, cuda_version%10); + /* compile */ string kernel = path_join(kernel_path, "kernel.cu"); string include = kernel_path; const int machine = system_cpu_bits(); - const int maxreg = 24; + string arch_flags; + + /* build flags depending on CUDA version and arch */ + if(cuda_version < 50) { + /* CUDA 4.x */ + if(major == 1) { + /* sm_1x */ + arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0"; + } + else if(major == 2) { + /* sm_2x */ + arch_flags = "--maxrregcount=24"; + } + else { + /* sm_3x */ + arch_flags = "--maxrregcount=32"; + } + } + else { + /* CUDA 4.x */ + if(major == 1) { + /* sm_1x */ + arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0 --use_fast_math"; + } + else if(major == 2) { + /* sm_2x */ + arch_flags = "--maxrregcount=32 --use_fast_math"; + } + else { + /* sm_3x */ + arch_flags = "--maxrregcount=32 --use_fast_math"; + } + } double starttime = time_dt(); printf("Compiling CUDA kernel ...\n"); @@ -283,8 +325,10 @@ public: path_create_directories(cubin); string command = string_printf("\"%s\" -arch=sm_%d%d -m%d --cubin \"%s\" " - "-o \"%s\" --ptxas-options=\"-v\" --maxrregcount=%d --opencc-options -OPT:Olimit=0 -I\"%s\" -DNVCC", - nvcc.c_str(), major, minor, machine, kernel.c_str(), cubin.c_str(), maxreg, include.c_str()); + "-o \"%s\" --ptxas-options=\"-v\" %s -I\"%s\" -DNVCC -D__KERNEL_CUDA_VERSION__=%d", + nvcc.c_str(), major, minor, machine, kernel.c_str(), cubin.c_str(), arch_flags.c_str(), include.c_str(), cuda_version); + + printf("%s\n", command.c_str()); if(system(command.c_str()) == -1) { cuda_error_message("Failed to execute compilation command, see console for details."); diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index 0fb5c7abafb..2ee4ffaca17 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -85,7 +85,7 @@ static string opencl_kernel_build_options(const string& platform, const string * string build_options = " -cl-fast-relaxed-math "; if(platform == "NVIDIA CUDA") - build_options += "-D__KERNEL_OPENCL_NVIDIA__ -cl-nv-maxrregcount=24 -cl-nv-verbose "; + build_options += "-D__KERNEL_OPENCL_NVIDIA__ -cl-nv-maxrregcount=32 -cl-nv-verbose "; else if(platform == "Apple") build_options += "-D__KERNEL_OPENCL_APPLE__ -Wno-missing-prototypes "; diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 8b4466863e0..5e9dd15b812 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -117,32 +117,68 @@ set(SRC_UTIL_HEADERS # CUDA module if(WITH_CYCLES_CUDA_BINARIES) + # 32 bit or 64 bit if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") set(CUDA_BITS 64) else() set(CUDA_BITS 32) endif() + # CUDA version + execute_process (COMMAND ${CUDA_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT) + string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\1" CUDA_VERSION_MAJOR ${NVCC_OUT}) + string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR ${NVCC_OUT}) + set(CUDA_VERSION "${CUDA_VERSION_MAJOR}${CUDA_VERSION_MINOR}") + + # build for each arch set(cuda_sources kernel.cu ${SRC_HEADERS} ${SRC_SVM_HEADERS} ${SRC_CLOSURE_HEADERS} ${SRC_UTIL_HEADERS}) set(cuda_cubins) foreach(arch ${CYCLES_CUDA_BINARIES_ARCH}) set(cuda_cubin kernel_${arch}.cubin) - if(${arch} MATCHES "sm_1[0-9]") - # sm_1x - set(cuda_arch_flags "--maxrregcount=24 --opencc-options -OPT:Olimit=0") - elseif(${arch} MATCHES "sm_2[0-9]") - # sm_2x - set(cuda_arch_flags "--maxrregcount=24") + set(cuda_version_flags "-D__KERNEL_CUDA_VERSION__=${CUDA_VERSION}") + + # warn for other versions + if(CUDA_VERSION MATCHES "50") else() - # sm_3x - set(cuda_arch_flags "--maxrregcount=32") + message(STATUS "CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, build may succeed but only CUDA 5.0 is officially supported") + endif() + + # build flags depending on CUDA version and arch + if(CUDA_VERSION LESS 50) + # CUDA 4.x + if(${arch} MATCHES "sm_1[0-9]") + # sm_1x + set(cuda_arch_flags "--maxrregcount=24 --opencc-options -OPT:Olimit=0") + elseif(${arch} MATCHES "sm_2[0-9]") + # sm_2x + set(cuda_arch_flags "--maxrregcount=24") + else() + # sm_3x + set(cuda_arch_flags "--maxrregcount=32") + endif() + + set(cuda_math_flags "") + else() + # CUDA 5.x + if(${arch} MATCHES "sm_1[0-9]") + # sm_1x + set(cuda_arch_flags "--maxrregcount=24 --opencc-options -OPT:Olimit=0") + elseif(${arch} MATCHES "sm_2[0-9]") + # sm_2x + set(cuda_arch_flags "--maxrregcount=32") + else() + # sm_3x + set(cuda_arch_flags "--maxrregcount=32") + endif() + + set(cuda_math_flags "--use_fast_math") endif() add_custom_command( OUTPUT ${cuda_cubin} - COMMAND ${CUDA_NVCC_EXECUTABLE} -arch=${arch} -m${CUDA_BITS} --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cu -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin} --ptxas-options="-v" ${cuda_arch_flags} -I${CMAKE_CURRENT_SOURCE_DIR}/../util -I${CMAKE_CURRENT_SOURCE_DIR}/svm -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC + COMMAND ${CUDA_NVCC_EXECUTABLE} -arch=${arch} -m${CUDA_BITS} --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cu -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin} --ptxas-options="-v" ${cuda_arch_flags} ${cuda_version_flags} ${cuda_math_flags} -I${CMAKE_CURRENT_SOURCE_DIR}/../util -I${CMAKE_CURRENT_SOURCE_DIR}/svm -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC DEPENDS ${cuda_sources}) delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${cuda_cubin}" ${CYCLES_INSTALL_PATH}/lib) diff --git a/intern/cycles/kernel/SConscript b/intern/cycles/kernel/SConscript index 3a46d10dee1..353ec1ce9d8 100644 --- a/intern/cycles/kernel/SConscript +++ b/intern/cycles/kernel/SConscript @@ -25,6 +25,8 @@ # # ***** END GPL LICENSE BLOCK ***** +import re +import subprocess import sys import os import Blender as B @@ -60,10 +62,19 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']: svm_dir = os.path.join(source_dir, "../svm") closure_dir = os.path.join(source_dir, "../closure") + # get CUDA version + nvcc_pipe = subprocess.Popen([nvcc, "--version"],stdout=subprocess.PIPE,stderr=subprocess.PIPE) + output, erroroutput = nvcc_pipe.communicate() + cuda_major_minor = re.findall(r'release (\d+).(\d+)', output)[0] + cuda_version = int(cuda_major_minor[0])*10 + int(cuda_major_minor[1]) + + if cuda_version != 50: + print("CUDA version %d.%d detected, build may succeed but only CUDA 5.0 is officially supported." % (cuda_version/10, cuda_version%10)) + # nvcc flags nvcc_flags = "-m%s" % (bits) - nvcc_flags += " --cubin --ptxas-options=\"-v\" --maxrregcount=24" - nvcc_flags += " --opencc-options -OPT:Olimit=0" + nvcc_flags += " --cubin --ptxas-options=\"-v\"" + nvcc_flags += " -D__KERNEL_CUDA_VERSION__=%d" % (cuda_version) nvcc_flags += " -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC" nvcc_flags += " -I \"%s\" -I \"%s\" -I \"%s\"" % (util_dir, svm_dir, closure_dir) @@ -75,7 +86,31 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']: for arch in cuda_archs: cubin_file = os.path.join(build_dir, "kernel_%s.cubin" % arch) - command = "\"%s\" -arch=%s %s \"%s\" -o \"%s\"" % (nvcc, arch, nvcc_flags, kernel_file, cubin_file) + # build flags depending on CUDA version and arch + if cuda_version < 50: + # CUDA 4.x + if arch.startswith("sm_1"): + # sm_1x + cuda_arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0" + elif arch.startswith("sm_2"): + # sm_2x + cuda_arch_flags = "--maxrregcount=24" + else: + # sm_3x + cuda_arch_flags = "--maxrregcount=32" + else: + # CUDA 5.x + if arch.startswith("sm_1"): + # sm_1x + cuda_arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0 --use_fast_math" + elif arch.startswith("sm_2"): + # sm_2x + cuda_arch_flags = "--maxrregcount=32 --use_fast_math" + else: + # sm_3x + cuda_arch_flags = "--maxrregcount=32 --use_fast_math" + + command = "\"%s\" -arch=%s %s %s \"%s\" -o \"%s\"" % (nvcc, arch, nvcc_flags, cuda_arch_flags, kernel_file, cubin_file) kernel.Command(cubin_file, 'kernel.cu', command) kernel.Depends(cubin_file, dependencies) diff --git a/intern/cycles/kernel/kernel_bvh_traversal.h b/intern/cycles/kernel/kernel_bvh_traversal.h index 900aa7e75fb..8d423b7e7ce 100644 --- a/intern/cycles/kernel/kernel_bvh_traversal.h +++ b/intern/cycles/kernel/kernel_bvh_traversal.h @@ -80,10 +80,10 @@ __device bool BVH_FUNCTION_NAME isect->u = 0.0f; isect->v = 0.0f; -#if defined(__KERNEL_SSSE3__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) - const __m128i shuffle_identity = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); - const __m128i shuffle_swap = _mm_set_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8); - +#if defined(__KERNEL_SSE2__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) + const shuffle_swap_t shuf_identity = shuffle_swap_identity(); + const shuffle_swap_t shuf_swap = shuffle_swap_swap(); + const __m128i pn = _mm_set_epi32(0x80000000, 0x80000000, 0x00000000, 0x00000000); __m128 Psplat[3], idirsplat[3]; @@ -97,9 +97,9 @@ __device bool BVH_FUNCTION_NAME __m128 tsplat = _mm_set_ps(-isect->t, -isect->t, 0.0f, 0.0f); - __m128i shufflex = (idir.x >= 0)? shuffle_identity: shuffle_swap; - __m128i shuffley = (idir.y >= 0)? shuffle_identity: shuffle_swap; - __m128i shufflez = (idir.z >= 0)? shuffle_identity: shuffle_swap; + shuffle_swap_t shufflex = (idir.x >= 0)? shuf_identity: shuf_swap; + shuffle_swap_t shuffley = (idir.y >= 0)? shuf_identity: shuf_swap; + shuffle_swap_t shufflez = (idir.z >= 0)? shuf_identity: shuf_swap; #endif /* traversal loop */ @@ -112,7 +112,7 @@ __device bool BVH_FUNCTION_NAME bool traverseChild0, traverseChild1; int nodeAddrChild1; -#if !defined(__KERNEL_SSSE3__) || FEATURE(BVH_HAIR_MINIMUM_WIDTH) +#if !defined(__KERNEL_SSE2__) || FEATURE(BVH_HAIR_MINIMUM_WIDTH) /* Intersect two child bounding boxes, non-SSE version */ float t = isect->t; @@ -166,20 +166,20 @@ __device bool BVH_FUNCTION_NAME traverseChild1 = (c1max >= c1min); #endif -#else // __KERNEL_SSSE3__ - /* Intersect two child bounding boxes, SSSE3 version adapted from Embree */ +#else // __KERNEL_SSE2__ + /* Intersect two child bounding boxes, SSE3 version adapted from Embree */ /* fetch node data */ __m128 *bvh_nodes = (__m128*)kg->__bvh_nodes.data + nodeAddr*BVH_NODE_SIZE; float4 cnodes = ((float4*)bvh_nodes)[3]; /* intersect ray against child nodes */ - const __m128 tminmaxx = _mm_mul_ps(_mm_sub_ps(shuffle8(bvh_nodes[0], shufflex), Psplat[0]), idirsplat[0]); - const __m128 tminmaxy = _mm_mul_ps(_mm_sub_ps(shuffle8(bvh_nodes[1], shuffley), Psplat[1]), idirsplat[1]); - const __m128 tminmaxz = _mm_mul_ps(_mm_sub_ps(shuffle8(bvh_nodes[2], shufflez), Psplat[2]), idirsplat[2]); + const __m128 tminmaxx = _mm_mul_ps(_mm_sub_ps(shuffle_swap(bvh_nodes[0], shufflex), Psplat[0]), idirsplat[0]); + const __m128 tminmaxy = _mm_mul_ps(_mm_sub_ps(shuffle_swap(bvh_nodes[1], shuffley), Psplat[1]), idirsplat[1]); + const __m128 tminmaxz = _mm_mul_ps(_mm_sub_ps(shuffle_swap(bvh_nodes[2], shufflez), Psplat[2]), idirsplat[2]); const __m128 tminmax = _mm_xor_ps(_mm_max_ps(_mm_max_ps(tminmaxx, tminmaxy), _mm_max_ps(tminmaxz, tsplat)), _mm_castsi128_ps(pn)); - const __m128 lrhit = _mm_cmple_ps(tminmax, shuffle8(tminmax, shuffle_swap)); + const __m128 lrhit = _mm_cmple_ps(tminmax, shuffle_swap(tminmax, shuf_swap)); /* decide which nodes to traverse next */ #ifdef __VISIBILITY_FLAG__ @@ -190,14 +190,14 @@ __device bool BVH_FUNCTION_NAME traverseChild0 = (_mm_movemask_ps(lrhit) & 1); traverseChild1 = (_mm_movemask_ps(lrhit) & 2); #endif -#endif // __KERNEL_SSSE3__ +#endif // __KERNEL_SSE2__ nodeAddr = __float_as_int(cnodes.x); nodeAddrChild1 = __float_as_int(cnodes.y); if(traverseChild0 && traverseChild1) { /* both children were intersected, push the farther one */ -#if !defined(__KERNEL_SSSE3__) || FEATURE(BVH_HAIR_MINIMUM_WIDTH) +#if !defined(__KERNEL_SSE2__) || FEATURE(BVH_HAIR_MINIMUM_WIDTH) bool closestChild1 = (c1min < c0min); #else union { __m128 m128; float v[4]; } uminmax; @@ -244,6 +244,7 @@ __device bool BVH_FUNCTION_NAME /* primitive intersection */ while(primAddr < primAddr2) { bool hit; + #if FEATURE(BVH_SUBSURFACE) /* only primitives from the same object */ uint tri_object = (object == ~0)? kernel_tex_fetch(__prim_object, primAddr): object; @@ -275,14 +276,17 @@ __device bool BVH_FUNCTION_NAME #if FEATURE(BVH_HAIR) if(segment == ~0) #endif + { hit = bvh_triangle_intersect_subsurface(kg, isect, P, idir, object, primAddr, tmax, &num_hits, subsurface_random); + (void)hit; + } } #else hit = bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr); /* shadow ray early termination */ -#if defined(__KERNEL_SSSE3__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) +#if defined(__KERNEL_SSE2__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) if(hit) { if(visibility == PATH_RAY_SHADOW_OPAQUE) return true; @@ -315,7 +319,7 @@ __device bool BVH_FUNCTION_NAME bvh_instance_push(kg, object, ray, &P, &idir, &isect->t, tmax); #endif -#if defined(__KERNEL_SSSE3__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) +#if defined(__KERNEL_SSE2__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) Psplat[0] = _mm_set_ps1(P.x); Psplat[1] = _mm_set_ps1(P.y); Psplat[2] = _mm_set_ps1(P.z); @@ -326,9 +330,9 @@ __device bool BVH_FUNCTION_NAME tsplat = _mm_set_ps(-isect->t, -isect->t, 0.0f, 0.0f); - shufflex = (idir.x >= 0)? shuffle_identity: shuffle_swap; - shuffley = (idir.y >= 0)? shuffle_identity: shuffle_swap; - shufflez = (idir.z >= 0)? shuffle_identity: shuffle_swap; + shufflex = (idir.x >= 0)? shuf_identity: shuf_swap; + shuffley = (idir.y >= 0)? shuf_identity: shuf_swap; + shufflez = (idir.z >= 0)? shuf_identity: shuf_swap; #endif ++stackPtr; @@ -359,7 +363,7 @@ __device bool BVH_FUNCTION_NAME bvh_instance_pop(kg, object, ray, &P, &idir, &isect->t, tmax); #endif -#if defined(__KERNEL_SSSE3__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) +#if defined(__KERNEL_SSE2__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) Psplat[0] = _mm_set_ps1(P.x); Psplat[1] = _mm_set_ps1(P.y); Psplat[2] = _mm_set_ps1(P.z); @@ -370,9 +374,9 @@ __device bool BVH_FUNCTION_NAME tsplat = _mm_set_ps(-isect->t, -isect->t, 0.0f, 0.0f); - shufflex = (idir.x >= 0)? shuffle_identity: shuffle_swap; - shuffley = (idir.y >= 0)? shuffle_identity: shuffle_swap; - shufflez = (idir.z >= 0)? shuffle_identity: shuffle_swap; + shufflex = (idir.x >= 0)? shuf_identity: shuf_swap; + shuffley = (idir.y >= 0)? shuf_identity: shuf_swap; + shufflez = (idir.z >= 0)? shuf_identity: shuf_swap; #endif object = ~0; diff --git a/intern/cycles/kernel/kernel_jitter.h b/intern/cycles/kernel/kernel_jitter.h index 17704b48cee..3e1a18ab469 100644 --- a/intern/cycles/kernel/kernel_jitter.h +++ b/intern/cycles/kernel/kernel_jitter.h @@ -137,7 +137,7 @@ __device_inline float cmj_randfloat(uint i, uint p) } #ifdef __CMJ__ -__device_noinline float cmj_sample_1D(int s, int N, int p) +__device float cmj_sample_1D(int s, int N, int p) { uint x = cmj_permute(s, N, p * 0x68bc21eb); float jx = cmj_randfloat(s, p * 0x967a889b); @@ -146,7 +146,7 @@ __device_noinline float cmj_sample_1D(int s, int N, int p) return (x + jx)*invN; } -__device_noinline void cmj_sample_2D(int s, int N, int p, float *fx, float *fy) +__device void cmj_sample_2D(int s, int N, int p, float *fx, float *fy) { int m = float_to_int(sqrtf(N)); int n = (N + m - 1)/m; diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 7e41ee35ae0..039981a031a 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -38,7 +38,12 @@ CCL_NAMESPACE_BEGIN /* ShaderData setup from incoming ray */ #ifdef __OBJECT_MOTION__ -__device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time) +#if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42 +__device_noinline +#else +__device +#endif +void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time) { /* note that this is a separate non-inlined function to work around crash * on CUDA sm 2.0, otherwise kernel execution crashes (compiler bug?) */ @@ -53,7 +58,12 @@ __device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderD } #endif -__device_noinline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, +#if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42 +__device_noinline +#else +__device +#endif +void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray) { #ifdef __INSTANCING__ @@ -260,7 +270,12 @@ __device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderData /* ShaderData setup from position sampled on mesh */ -__device_noinline void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, +#if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42 +__device_noinline +#else +__device +#endif +void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, const float3 P, const float3 Ng, const float3 I, int shader, int object, int prim, float u, float v, float t, float time, int segment) { diff --git a/intern/cycles/util/util_cuda.cpp b/intern/cycles/util/util_cuda.cpp index 6c9ee7c548f..42ffb04a793 100644 --- a/intern/cycles/util/util_cuda.cpp +++ b/intern/cycles/util/util_cuda.cpp @@ -16,6 +16,8 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include + #include #include @@ -25,6 +27,11 @@ #include "util_path.h" #include "util_string.h" +#ifdef _WIN32 +#define popen _popen +#define pclose _pclose +#endif + /* function defininitions */ tcuInit *cuInit; @@ -399,7 +406,15 @@ string cuCompilerPath() const char *defaultpaths[] = {"C:/CUDA/bin", NULL}; const char *executable = "nvcc.exe"; #else - const char *defaultpaths[] = {"/Developer/NVIDIA/CUDA-4.2/bin", "/usr/local/cuda-4.2/bin", "/usr/local/cuda/bin", NULL}; + const char *defaultpaths[] = { + "/Developer/NVIDIA/CUDA-5.0/bin", + "/usr/local/cuda-5.0/bin", + "/usr/local/cuda/bin", + "/Developer/NVIDIA/CUDA-4.2/bin", + "/usr/local/cuda-4.2/bin", + "/Developer/NVIDIA/CUDA-5.5/bin", + "/usr/local/cuda-5.5/bin", + NULL}; const char *executable = "nvcc"; #endif @@ -437,5 +452,46 @@ string cuCompilerPath() return ""; } +int cuCompilerVersion() +{ + string path = cuCompilerPath(); + if(path == "") + return 0; + + /* get --version output */ + FILE *pipe = popen((path + " --version").c_str(), "r"); + if(!pipe) { + fprintf(stderr, "CUDA: failed to run compiler to retrieve version"); + return 0; + } + + char buf[128]; + string output = ""; + + while(!feof(pipe)) + if(fgets(buf, 128, pipe) != NULL) + output += buf; + + pclose(pipe); + + /* parse version number */ + string marker = "Cuda compilation tools, release "; + size_t offset = output.find(marker); + if(offset == string::npos) { + fprintf(stderr, "CUDA: failed to find version number in:\n\n%s\n", output.c_str()); + return 0; + } + + string versionstr = output.substr(offset + marker.size(), string::npos); + int major, minor; + + if(sscanf(versionstr.c_str(), "%d.%d", &major, &minor) < 2) { + fprintf(stderr, "CUDA: failed to parse version number from:\n\n%s\n", output.c_str()); + return 0; + } + + return 10*major + minor; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_cuda.h b/intern/cycles/util/util_cuda.h index 55feb3f84cb..ba4df0de90a 100644 --- a/intern/cycles/util/util_cuda.h +++ b/intern/cycles/util/util_cuda.h @@ -32,6 +32,7 @@ CCL_NAMESPACE_BEGIN bool cuLibraryInit(); bool cuHavePrecompiledKernels(); string cuCompilerPath(); +int cuCompilerVersion(); CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h index d0116186ee8..4fd1e9d8807 100644 --- a/intern/cycles/util/util_types.h +++ b/intern/cycles/util/util_types.h @@ -76,8 +76,8 @@ #define __KERNEL_SSE2__ #endif -#ifndef __KERNEL_SSSE3__ -#define __KERNEL_SSSE3__ +#ifndef __KERNEL_SSE3__ +#define __KERNEL_SSE3__ #endif #ifndef __KERNEL_SSSE3__ @@ -100,7 +100,7 @@ #include /* SSE 1 */ #include /* SSE 2 */ -#ifdef __KERNEL_SSSE3__ +#ifdef __KERNEL_SSE3__ #include /* SSE 3 */ #endif #ifdef __KERNEL_SSSE3__ @@ -491,15 +491,56 @@ __device_inline int4 make_int4(const float3& f) #endif -#ifdef __KERNEL_SSSE3__ +#ifdef __KERNEL_SSE2__ /* SSE shuffle utility functions */ -__device_inline const __m128 shuffle8(const __m128& a, const __m128i& shuf) +#ifdef __KERNEL_SSSE3__ + +/* faster version for SSSE3 */ +typedef __m128i shuffle_swap_t; + +__device_inline const shuffle_swap_t shuffle_swap_identity(void) +{ + return _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); +} + +__device_inline const shuffle_swap_t shuffle_swap_swap(void) +{ + return _mm_set_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8); +} + +__device_inline const __m128 shuffle_swap(const __m128& a, const shuffle_swap_t& shuf) { return _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(a), shuf)); } +#else + +/* somewhat slower version for SSE3 */ +typedef int shuffle_swap_t; + +__device_inline const shuffle_swap_t shuffle_swap_identity(void) +{ + return 0; +} + +__device_inline const shuffle_swap_t shuffle_swap_swap(void) +{ + return 1; +} + +__device_inline const __m128 shuffle_swap(const __m128& a, shuffle_swap_t shuf) +{ + /* shuffle value must be a constant, so we need to branch */ + if(shuf) + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); + else + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 2, 1, 0)); +} + +#endif + template __device_inline const __m128 shuffle(const __m128& a, const __m128& b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)); diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 868fa2a311c..594f724c6e3 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -68,6 +68,7 @@ _modules = [ "space_nla", "space_node", "space_outliner", + "space_properties", "space_sequencer", "space_text", "space_time", diff --git a/release/scripts/startup/bl_ui/space_properties.py b/release/scripts/startup/bl_ui/space_properties.py new file mode 100644 index 00000000000..758713b5cc4 --- /dev/null +++ b/release/scripts/startup/bl_ui/space_properties.py @@ -0,0 +1,46 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# +import bpy +from bpy.types import Header + + +class PROPERTIES_HT_header(Header): + bl_space_type = 'PROPERTIES' + + def draw(self, context): + layout = self.layout + + view = context.space_data + + row = layout.row() + row.template_header(menus=False) + row.prop(view, "context", expand=True, icon_only=True) + + +def register(): + bpy.utils.register_module(__name__) + + +def unregister(): + bpy.utils.unregister_module(__name__) + + +if __name__ == "__main__": + register() diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index e0449931fc9..cfd8fd2080f 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1801,6 +1801,8 @@ class VIEW3D_MT_edit_mesh(Menu): layout.separator() layout.operator("mesh.symmetrize") + layout.operator("mesh.symmetry_snap") + layout.separator() layout.operator("mesh.duplicate_move") layout.menu("VIEW3D_MT_edit_mesh_extrude") layout.menu("VIEW3D_MT_edit_mesh_delete") diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index c9c33014aa5..96ccc5be8e0 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2085,7 +2085,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D if (mti->applyModifierEM) ndm = modwrap_applyModifierEM(md, ob, em, dm, MOD_APPLY_USECACHE); else - ndm = mti->applyModifier(md, ob, dm, MOD_APPLY_USECACHE); + ndm = modwrap_applyModifier(md, ob, dm, MOD_APPLY_USECACHE); if (ndm) { if (dm && dm != ndm) diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 243276ca552..edfcefe14c7 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1034,7 +1034,9 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba DM_update_tessface_data(dm); } - CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true); + if (dm->type == DM_TYPE_CDDM) { + CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true); + } } (*derivedFinal) = dm; } @@ -1172,7 +1174,7 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFina if (!orcodm) orcodm = create_orco_dm(scene, ob); - ndm = mti->applyModifier(md, ob, orcodm, app_flag); + ndm = modwrap_applyModifier(md, ob, orcodm, app_flag); if (ndm) { /* if the modifier returned a new dm, release the old one */ diff --git a/source/blender/blenkernel/intern/editmesh_bvh.c b/source/blender/blenkernel/intern/editmesh_bvh.c index 979a38f0346..fced3472566 100644 --- a/source/blender/blenkernel/intern/editmesh_bvh.c +++ b/source/blender/blenkernel/intern/editmesh_bvh.c @@ -369,7 +369,7 @@ struct VertSearchUserData { int index_tri; }; -static void bmbvh_find_vert_closest_cb(void *userdata, int index, const float *UNUSED(co), BVHTreeNearest *hit) +static void bmbvh_find_vert_closest_cb(void *userdata, int index, const float co[3], BVHTreeNearest *hit) { struct VertSearchUserData *bmcb_data = userdata; const BMLoop **ltri = bmcb_data->looptris[index]; @@ -382,7 +382,7 @@ static void bmbvh_find_vert_closest_cb(void *userdata, int index, const float *U bmbvh_tri_from_face(tri_cos, ltri, bmcb_data->cos_cage); for (i = 0; i < 3; i++) { - dist = len_v3v3(hit->co, tri_cos[i]); + dist = len_squared_v3v3(co, tri_cos[i]); if (dist < hit->dist && dist < maxdist) { copy_v3_v3(hit->co, tri_cos[i]); /* XXX, normal ignores cage */ @@ -398,20 +398,19 @@ BMVert *BKE_bmbvh_find_vert_closest(BMBVHTree *bmtree, const float co[3], const { BVHTreeNearest hit; struct VertSearchUserData bmcb_data; + const float maxdist_sq = maxdist * maxdist; if (bmtree->cos_cage) BLI_assert(!(bmtree->em->bm->elem_index_dirty & BM_VERT)); - copy_v3_v3(hit.co, co); - /* XXX, why x5, scampbell */ - hit.dist = maxdist * 5; + hit.dist = maxdist_sq; hit.index = -1; bmcb_data.looptris = (const BMLoop *(*)[3])bmtree->em->looptris; bmcb_data.cos_cage = (const float (*)[3])bmtree->cos_cage; - bmcb_data.maxdist = maxdist; + bmcb_data.maxdist = maxdist_sq; BLI_bvhtree_find_nearest(bmtree->tree, co, &hit, bmbvh_find_vert_closest_cb, &bmcb_data); - if (hit.dist != FLT_MAX && hit.index != -1) { + if (hit.index != -1) { BMLoop **ltri = bmtree->em->looptris[hit.index]; return ltri[bmcb_data.index_tri]->v; } diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index a8fdcd56abb..2da36377e55 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -30,6 +30,7 @@ * \ingroup bli */ +#include #include #include "MEM_guardedalloc.h" @@ -207,6 +208,8 @@ void *BLI_heap_popmin(Heap *heap) { void *ptr = heap->tree[0]->ptr; + BLI_assert(heap->size == 0); + heap->tree[0]->ptr = heap->freenodes; heap->freenodes = heap->tree[0]; diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 8d95ab85df8..c92b049eafb 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -290,6 +290,6 @@ extern void bpy_bm_generic_invalidate(struct BPy_BMGeneric *self); * but should not error on valid cases */ #define BM_LOOP_RADIAL_MAX 10000 #define BM_NGON_MAX 100000 -#define BM_OMP_LIMIT 10000 /* setting zero so we can catch bugs in OpenMP/BMesh */ +#define BM_OMP_LIMIT 0 /* 10000 */ /* setting zero so we can catch bugs in OpenMP/BMesh */ #endif /* __BMESH_CLASS_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 2608a79d455..313d76721fa 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -498,6 +498,8 @@ static int bm_mesh_flag_count(BMesh *bm, const char htype, const char hflag, BMIter iter; int tot = 0; + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); + if (htype & BM_VERT) { for (ele = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) { if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue; @@ -803,6 +805,8 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl int i; + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); + if (hflag & BM_ELEM_SELECT) { BM_select_history_clear(bm); } @@ -872,6 +876,8 @@ void BM_mesh_elem_hflag_enable_test(BMesh *bm, const char htype, const char hfla BMElem *ele; int i; + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); + if (hflag & BM_ELEM_SELECT) { BM_select_history_clear(bm); } diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 79dacaad2fa..4027d4b2c19 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -628,6 +628,8 @@ void BM_mesh_elem_index_validate(BMesh *bm, const char *location, const char *fu */ int BM_mesh_elem_count(BMesh *bm, const char htype) { + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); + switch (htype) { case BM_VERT: return bm->totvert; case BM_EDGE: return bm->totedge; diff --git a/source/blender/bmesh/tools/bmesh_path.c b/source/blender/bmesh/tools/bmesh_path.c index eda252f18f5..9fc1996e51a 100644 --- a/source/blender/bmesh/tools/bmesh_path.c +++ b/source/blender/bmesh/tools/bmesh_path.c @@ -144,7 +144,8 @@ LinkNode *BM_mesh_calc_path_vert( BLI_heap_insert(heap, 0.0f, v_src); cost[BM_elem_index_get(v_src)] = 0.0f; - while ((v = BLI_heap_popmin(heap))) { + while (!BLI_heap_is_empty(heap)) { + v = BLI_heap_popmin(heap); if (v == v_dst) break; @@ -261,7 +262,8 @@ LinkNode *BM_mesh_calc_path_edge( BLI_heap_insert(heap, 0.0f, e_src); cost[BM_elem_index_get(e_src)] = 0.0f; - while ((e = BLI_heap_popmin(heap))) { + while (!BLI_heap_is_empty(heap)) { + e = BLI_heap_popmin(heap); if (e == e_dst) break; @@ -386,7 +388,8 @@ LinkNode *BM_mesh_calc_path_face( BLI_heap_insert(heap, 0.0f, f_src); cost[BM_elem_index_get(f_src)] = 0.0f; - while ((f = BLI_heap_popmin(heap))) { + while (!BLI_heap_is_empty(heap)) { + f = BLI_heap_popmin(heap); if (f == f_dst) break; diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 097ea477501..0b25c494ba9 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -76,7 +76,11 @@ struct MeshStatVis; /* editmesh_utils.c */ -void EDBM_verts_mirror_cache_begin(struct BMEditMesh *em, const bool use_self, const bool use_select); +void EDBM_verts_mirror_cache_begin_ex(struct BMEditMesh *em, const int axis, + const bool use_self, const bool use_select, + const bool is_topo, float maxdist, int *r_index); +void EDBM_verts_mirror_cache_begin(struct BMEditMesh *em, const int axis, + const bool use_self, const bool use_select); void EDBM_verts_mirror_apply(struct BMEditMesh *em, const int sel_from, const int sel_to); struct BMVert *EDBM_verts_mirror_get(struct BMEditMesh *em, struct BMVert *v); void EDBM_verts_mirror_cache_clear(struct BMEditMesh *em, struct BMVert *v); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index cb2f3e3286e..86e51b201d9 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -304,7 +304,7 @@ typedef struct uiSearchItems uiSearchItems; typedef void (*uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2); typedef void (*uiButHandleRenameFunc)(struct bContext *C, void *arg, char *origstr); typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2); -typedef void (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg); +typedef bool (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg); typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items); typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event); @@ -644,7 +644,7 @@ typedef struct AutoComplete AutoComplete; AutoComplete *autocomplete_begin(const char *startname, size_t maxlen); void autocomplete_do_name(AutoComplete *autocpl, const char *name); -void autocomplete_end(AutoComplete *autocpl, char *autoname); +bool autocomplete_end(AutoComplete *autocpl, char *autoname); /* Panels * diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 5a1ba8f31f0..19eb978a01e 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -443,17 +443,24 @@ void uiExplicitBoundsBlock(uiBlock *block, int minx, int miny, int maxx, int max static int ui_but_float_precision(uiBut *but, double value) { int prec; + const double pow10_neg[PRECISION_FLOAT_MAX + 1] = {1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001}; /* first check if prec is 0 and fallback to a simple default */ if ((prec = (int)but->a2) == -1) { prec = (but->hardmax < 10.001f) ? 3 : 2; } + BLI_assert(prec <= PRECISION_FLOAT_MAX); + BLI_assert(pow10_neg[prec] == pow(10, -prec)); + /* check on the number of decimal places need to display * the number, this is so 0.00001 is not displayed as 0.00, * _but_, this is only for small values si 10.0001 will not get * the same treatment */ - if (value != 0.0 && (value = ABS(value)) < 0.1) { + value = ABS(value); + if ((value < pow10_neg[prec]) && + (value > (1.0 / PRECISION_FLOAT_MAX_POW))) + { int value_i = (int)((value * PRECISION_FLOAT_MAX_POW) + 0.5); if (value_i != 0) { const int prec_span = 3; /* show: 0.01001, 5 would allow 0.0100001 for eg. */ @@ -3086,16 +3093,21 @@ void autocomplete_do_name(AutoComplete *autocpl, const char *name) } } -void autocomplete_end(AutoComplete *autocpl, char *autoname) +bool autocomplete_end(AutoComplete *autocpl, char *autoname) { - if (autocpl->truncate[0]) + bool change = false; + if (autocpl->truncate[0]) { BLI_strncpy(autoname, autocpl->truncate, autocpl->maxlen); + change = true; + } else { - if (autoname != autocpl->startname) /* don't copy a string over its self */ + if (autoname != autocpl->startname) { /* don't copy a string over its self */ BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen); + } } MEM_freeN(autocpl->truncate); MEM_freeN(autocpl); + return change; } static void ui_check_but_and_iconize(uiBut *but, int icon) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 85a23a9da22..7aee228ddaa 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1828,20 +1828,19 @@ static bool ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directi static bool ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData *data) { char *str; - /* TODO, should return false if it cant autocomp. */ - bool changed = true; + bool change = true; str = data->str; if (data->searchbox) - ui_searchbox_autocomplete(C, data->searchbox, but, data->str); + change = ui_searchbox_autocomplete(C, data->searchbox, but, data->str); else - but->autocomplete_func(C, str, but->autofunc_arg); + change = but->autocomplete_func(C, str, but->autofunc_arg); but->pos = strlen(str); but->selsta = but->selend = but->pos; - return changed; + return change; } /* mode for ui_textedit_copypaste() */ diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 9de608f2730..a6076b8df78 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -471,7 +471,7 @@ ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBu bool ui_searchbox_inside(struct ARegion *ar, int x, int y); int ui_searchbox_find_index(struct ARegion *ar, const char *name); void ui_searchbox_update(struct bContext *C, struct ARegion *ar, uiBut *but, const bool reset); -void ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str); +bool ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str); void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, const struct wmEvent *event); bool ui_searchbox_apply(uiBut *but, struct ARegion *ar); void ui_searchbox_free(struct bContext *C, struct ARegion *ar); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index b6575f4eca0..ef839f1d143 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -525,7 +525,7 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt name = (!uiname || uiname[0]) ? item->name : ""; icon = item->icon; value = item->value; - itemw = ui_text_icon_width(block->curlayout, name, icon, 0); + itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, 0); if (icon && name[0] && !icon_only) but = uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index b764c70b111..1ff46004bdf 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1039,18 +1039,20 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset) ED_region_tag_redraw(ar); } -void ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str) +bool ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str) { uiSearchboxData *data = ar->regiondata; + bool changed = false; if (str[0]) { data->items.autocpl = autocomplete_begin(str, ui_get_but_string_max_length(but)); but->search_func(C, but->search_arg, but->editstr, &data->items); - autocomplete_end(data->items.autocpl, str); + changed = autocomplete_end(data->items.autocpl, str); data->items.autocpl = NULL; } + return changed; } static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index e14dd484ad3..77b91365535 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -92,7 +92,7 @@ void EDBM_select_mirrored(BMEditMesh *em, bool extend, } } - EDBM_verts_mirror_cache_begin(em, true, true); + EDBM_verts_mirror_cache_begin(em, 0, true, true); if (!extend) EDBM_flag_disable_all(em, BM_ELEM_SELECT); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 3581902e29e..bab9a2d8f5a 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1121,7 +1121,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op) /* mirror before smooth */ if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) { - EDBM_verts_mirror_cache_begin(em, false, true); + EDBM_verts_mirror_cache_begin(em, 0, false, true); } /* if there is a mirror modifier with clipping, flag the verts that @@ -1212,7 +1212,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op) /* mirror before smooth */ if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) { - EDBM_verts_mirror_cache_begin(em, false, true); + EDBM_verts_mirror_cache_begin(em, 0, false, true); } repeat = RNA_int_get(op->ptr, "repeat"); @@ -4258,6 +4258,132 @@ void MESH_OT_symmetrize(struct wmOperatorType *ot) "Direction", "Which sides to copy from and to"); } +static int mesh_symmetry_snap_exec(bContext *C, wmOperator *op) +{ + const float eps = 0.00001f; + const float eps_sq = eps * eps; + + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + int *index = MEM_mallocN(bm->totvert * sizeof(*index), __func__); + const bool is_topo = false; + + const float thresh = RNA_float_get(op->ptr, "threshold"); + const float fac = RNA_float_get(op->ptr, "factor"); + const bool use_center = RNA_boolean_get(op->ptr, "use_center"); + + /* stats */ + int totmirr = 0, totfail = 0, totfound = 0; + + /* axix */ + const int axis_dir = RNA_enum_get(op->ptr, "direction"); + int axis = axis_dir % 3; + bool axis_sign = axis != axis_dir; + + /* vertex iter */ + BMIter iter; + BMVert *v; + int i; + + EDBM_verts_mirror_cache_begin_ex(em, axis, true, true, is_topo, thresh, index); + + EDBM_index_arrays_ensure(em, BM_VERT); + + BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false); + + + BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { + if ((BM_elem_flag_test(v, BM_ELEM_SELECT) != false) && + (BM_elem_flag_test(v, BM_ELEM_TAG) == false)) + { + int i_mirr = index[i]; + if (i_mirr != -1) { + + BMVert *v_mirr = EDBM_vert_at_index(em, index[i]); + + if (v != v_mirr) { + float co[3], co_mirr[3]; + + if ((v->co[axis] > v->co[axis]) == axis_sign) { + SWAP(BMVert *, v, v_mirr); + } + + copy_v3_v3(co_mirr, v_mirr->co); + co_mirr[axis] *= -1.0f; + + if (len_squared_v3v3(v->co, co_mirr) > eps_sq) { + totmirr++; + } + + interp_v3_v3v3(co, v->co, co_mirr, fac); + + copy_v3_v3(v->co, co); + + co[axis] *= -1.0f; + copy_v3_v3(v_mirr->co, co); + + BM_elem_flag_enable(v, BM_ELEM_TAG); + BM_elem_flag_enable(v_mirr, BM_ELEM_TAG); + totfound++; + } + else { + if (use_center) { + + if (fabsf(v->co[axis]) > eps) { + totmirr++; + } + + v->co[axis] = 0.0f; + } + BM_elem_flag_enable(v, BM_ELEM_TAG); + totfound++; + } + } + else { + totfail++; + } + } + } + + + if (totfail) { + BKE_reportf(op->reports, RPT_WARNING, "%d already symmetrical, %d pairs mirrored, %d failed", + totfound - totmirr, totmirr, totfail); + } + else { + BKE_reportf(op->reports, RPT_INFO, "%d already symmetrical, %d pairs mirrored", + totfound - totmirr, totmirr); + } + + /* no need to end cache, just free the array */ + MEM_freeN(index); + + return OPERATOR_FINISHED; +} + +void MESH_OT_symmetry_snap(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Snap to Symmetry"; + ot->description = "Snap vertex pairs to their mirrored locations"; + ot->idname = "MESH_OT_symmetry_snap"; + + /* api callbacks */ + ot->exec = mesh_symmetry_snap_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, "direction", symmetrize_direction_items, + BMO_SYMMETRIZE_NEGATIVE_X, + "Direction", "Which sides to copy from and to"); + RNA_def_float(ot->srna, "threshold", 0.05, 0.0, 10.0, "Threshold", "", 0.0001, 1.0); + RNA_def_float(ot->srna, "factor", 0.5f, 0.0, 1.0, "Factor", "", 0.0, 1.0); + RNA_def_boolean(ot->srna, "use_center", true, "Center", "Snap mid verts to the axis center"); +} + #ifdef WITH_FREESTYLE static int edbm_mark_freestyle_edge(bContext *C, wmOperator *op) diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index fa857edb6fc..f3540fe62b7 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -507,17 +507,20 @@ bool EDBM_index_arrays_check(BMEditMesh *em) BMVert *EDBM_vert_at_index(BMEditMesh *em, int index) { - return em->vert_index && index < em->bm->totvert ? em->vert_index[index] : NULL; + BLI_assert((index >= 0) && (index < em->bm->totvert)); + return em->vert_index[index]; } BMEdge *EDBM_edge_at_index(BMEditMesh *em, int index) { - return em->edge_index && index < em->bm->totedge ? em->edge_index[index] : NULL; + BLI_assert((index >= 0) && (index < em->bm->totedge)); + return em->edge_index[index]; } BMFace *EDBM_face_at_index(BMEditMesh *em, int index) { - return (em->face_index && index < em->bm->totface && index >= 0) ? em->face_index[index] : NULL; + BLI_assert((index >= 0) && (index < em->bm->totface)); + return em->face_index[index]; } void EDBM_selectmode_flush_ex(BMEditMesh *em, const short selectmode) @@ -1144,46 +1147,58 @@ static BMVert *cache_mirr_intptr_as_bmvert(intptr_t *index_lookup, int index) * preference */ #define BM_SEARCH_MAXDIST_MIRR 0.00002f #define BM_CD_LAYER_ID "__mirror_index" -void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bool use_select) +/** + * \param em Editmesh. + * \param use_self Allow a vertex to point to its self (middle verts). + * \param use_select Restrict to selected verts. + * \param is_topo Use topology mirror. + * \param maxdist Distance for close point test. + * \param r_index Optional array to write into, as an alternative to a customdata layer (length of total verts). + */ +void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const int axis, const bool use_self, const bool use_select, + /* extra args */ + const bool is_topo, float maxdist, int *r_index) { Mesh *me = (Mesh *)em->ob->data; BMesh *bm = em->bm; BMIter iter; BMVert *v; - bool topo = false; int cd_vmirr_offset; + int i; /* one or the other is used depending if topo is enabled */ struct BMBVHTree *tree = NULL; MirrTopoStore_t mesh_topo_store = {NULL, -1, -1, -1}; - if (me && (me->editflag & ME_EDIT_MIRROR_TOPO)) { - topo = 1; - } - EDBM_index_arrays_ensure(em, BM_VERT); - em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID); - if (em->mirror_cdlayer == -1) { - BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID); - em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID); + if (r_index == NULL) { + const char *layer_id = BM_CD_LAYER_ID; + em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, layer_id); + if (em->mirror_cdlayer == -1) { + BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, layer_id); + em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, layer_id); + } + + cd_vmirr_offset = CustomData_get_n_offset(&bm->vdata, CD_PROP_INT, + em->mirror_cdlayer - CustomData_get_layer_index(&bm->vdata, CD_PROP_INT)); + + bm->vdata.layers[em->mirror_cdlayer].flag |= CD_FLAG_TEMPORARY; } - cd_vmirr_offset = CustomData_get_n_offset(&bm->vdata, CD_PROP_INT, - em->mirror_cdlayer - CustomData_get_layer_index(&bm->vdata, CD_PROP_INT)); - - bm->vdata.layers[em->mirror_cdlayer].flag |= CD_FLAG_TEMPORARY; - BM_mesh_elem_index_ensure(bm, BM_VERT); - if (topo) { + if (is_topo) { ED_mesh_mirrtopo_init(me, -1, &mesh_topo_store, true); } else { tree = BKE_bmbvh_new(em, 0, NULL, false); } - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { +#define VERT_INTPTR(_v, _i) r_index ? &r_index[_i] : BM_ELEM_CD_GET_VOID_P(_v, cd_vmirr_offset); + + BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { + BLI_assert(BM_elem_index_get(v) == i); /* temporary for testing, check for selection */ if (use_select && !BM_elem_flag_test(v, BM_ELEM_SELECT)) { @@ -1191,20 +1206,23 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo } else { BMVert *v_mirr; - int *idx = BM_ELEM_CD_GET_VOID_P(v, cd_vmirr_offset); + int *idx = VERT_INTPTR(v, i); - if (topo) { - v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, BM_elem_index_get(v)); + if (is_topo) { + v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, i); } else { - float co[3] = {-v->co[0], v->co[1], v->co[2]}; - v_mirr = BKE_bmbvh_find_vert_closest(tree, co, BM_SEARCH_MAXDIST_MIRR); + float co[3]; + copy_v3_v3(co, v->co); + co[axis] *= -1.0f; + v_mirr = BKE_bmbvh_find_vert_closest(tree, co, maxdist); } if (v_mirr && (use_self || (v_mirr != v))) { - *idx = BM_elem_index_get(v_mirr); - idx = BM_ELEM_CD_GET_VOID_P(v_mirr, cd_vmirr_offset); - *idx = BM_elem_index_get(v); + const int i_mirr = BM_elem_index_get(v_mirr); + *idx = i_mirr; + idx = VERT_INTPTR(v_mirr, i_mirr); + *idx = i; } else { *idx = -1; @@ -1213,8 +1231,9 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo } +#undef VERT_INTPTR - if (topo) { + if (is_topo) { ED_mesh_mirrtopo_free(&mesh_topo_store); } else { @@ -1222,6 +1241,20 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo } } +void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const int axis, + const bool use_self, const bool use_select) +{ + Mesh *me = (Mesh *)em->ob->data; + bool is_topo; + + is_topo = (me && (me->editflag & ME_EDIT_MIRROR_TOPO)); + + EDBM_verts_mirror_cache_begin_ex(em, axis, + use_self, use_select, + /* extra args */ + is_topo, BM_SEARCH_MAXDIST_MIRR, NULL); +} + BMVert *EDBM_verts_mirror_get(BMEditMesh *em, BMVert *v) { int *mirr = CustomData_bmesh_get_layer_n(&em->bm->vdata, v->head.data, em->mirror_cdlayer); diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index bc74f4a8bf5..e086e11e3bf 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -170,6 +170,7 @@ void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot); void MESH_OT_wireframe(struct wmOperatorType *ot); void MESH_OT_convex_hull(struct wmOperatorType *ot); void MESH_OT_symmetrize(struct wmOperatorType *ot); +void MESH_OT_symmetry_snap(struct wmOperatorType *ot); void MESH_OT_shape_propagate_to_all(struct wmOperatorType *ot); void MESH_OT_blend_from_shape(struct wmOperatorType *ot); void MESH_OT_sort_elements(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 966d5ecb00e..7fe0c3b0344 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -172,6 +172,7 @@ void ED_operatortypes_mesh(void) #endif WM_operatortype_append(MESH_OT_symmetrize); + WM_operatortype_append(MESH_OT_symmetry_snap); #ifdef WITH_GAMEENGINE WM_operatortype_append(MESH_OT_navmesh_make); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 8da953c4f84..80ca0b38f8c 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -976,11 +976,11 @@ static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum) BMEditMesh *em = me->edit_btmesh; const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); /* warning, this lookup is _not_ fast */ - BMVert *eve; - EDBM_index_arrays_ensure(em, BM_VERT); - - if ((cd_dvert_offset != -1) && (eve = EDBM_vert_at_index(em, vertnum))) { + if (cd_dvert_offset != -1) { + BMVert *eve; + EDBM_index_arrays_ensure(em, BM_VERT); + eve = EDBM_vert_at_index(em, vertnum); dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); } else { @@ -2170,7 +2170,7 @@ void ED_vgroup_mirror(Object *ob, goto cleanup; } - EDBM_verts_mirror_cache_begin(em, true, false); + EDBM_verts_mirror_cache_begin(em, 0, true, false); /* Go through the list of editverts and assign them */ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index b20301cfc3b..9e045a39a0c 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -35,7 +35,6 @@ set(INC_SYS set(SRC buttons_context.c - buttons_header.c buttons_ops.c buttons_texture.c space_buttons.c diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c deleted file mode 100644 index 44c76d7a9a2..00000000000 --- a/source/blender/editors/space_buttons/buttons_header.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - * - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_buttons/buttons_header.c - * \ingroup spbuttons - */ - - -#include -#include - -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" - -#include "BLF_translation.h" - -#include "BKE_context.h" -#include "BKE_modifier.h" -#include "BKE_paint.h" -#include "BKE_scene.h" - -#include "ED_buttons.h" -#include "ED_screen.h" -#include "ED_types.h" - -#include "DNA_brush_types.h" -#include "DNA_object_force.h" -#include "DNA_object_types.h" - -#include "UI_interface.h" -#include "UI_resources.h" -#include "UI_view2d.h" - -#include "buttons_intern.h" - - -#define B_CONTEXT_SWITCH 101 - -static void do_buttons_buttons(bContext *C, void *UNUSED(arg), int event) -{ - SpaceButs *sbuts = CTX_wm_space_buts(C); - - if (!sbuts) /* editor type switch */ - return; - - switch (event) { - case B_CONTEXT_SWITCH: - ED_area_tag_redraw(CTX_wm_area(C)); - - sbuts->preview = 1; - break; - } - - sbuts->mainbuser = sbuts->mainb; -} - -#define BUT_UNIT_X (UI_UNIT_X + 2 * U.pixelsize) - -void buttons_header_buttons(const bContext *C, ARegion *ar) -{ - SpaceButs *sbuts = CTX_wm_space_buts(C); - uiBlock *block; - uiBut *but; - int headery = ED_area_headersize(); - int xco, yco = 0.5f * (headery - UI_UNIT_Y); - - buttons_context_compute(C, sbuts); - - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); - uiBlockSetHandleFunc(block, do_buttons_buttons, NULL); - - xco = ED_area_header_switchbutton(C, block, yco); - - uiBlockSetEmboss(block, UI_EMBOSS); - - xco -= UI_UNIT_X; - - /* Default panels */ - - uiBlockBeginAlign(block); - -#define BUTTON_HEADER_CTX(_ctx, _icon, _tip) \ - if (sbuts->pathflag & (1 << _ctx)) { \ - but = uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, _icon, xco += BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, \ - &(sbuts->mainb), 0.0, (float)_ctx, 0, 0, TIP_(_tip)); \ - uiButClearFlag(but, UI_BUT_UNDO); \ - } (void)0 - - BUTTON_HEADER_CTX(BCONTEXT_RENDER, ICON_SCENE, N_("Render")); - BUTTON_HEADER_CTX(BCONTEXT_RENDER_LAYER, ICON_RENDERLAYERS, N_("Render Layers")); - BUTTON_HEADER_CTX(BCONTEXT_SCENE, ICON_SCENE_DATA, N_("Scene")); - BUTTON_HEADER_CTX(BCONTEXT_WORLD, ICON_WORLD, N_("World")); - BUTTON_HEADER_CTX(BCONTEXT_OBJECT, ICON_OBJECT_DATA, N_("Object")); - BUTTON_HEADER_CTX(BCONTEXT_CONSTRAINT, ICON_CONSTRAINT, N_("Object Constraints")); - BUTTON_HEADER_CTX(BCONTEXT_MODIFIER, ICON_MODIFIER, N_("Object Modifiers")); - BUTTON_HEADER_CTX(BCONTEXT_DATA, sbuts->dataicon, N_("Object Data")); - BUTTON_HEADER_CTX(BCONTEXT_BONE, ICON_BONE_DATA, N_("Bone")); - BUTTON_HEADER_CTX(BCONTEXT_BONE_CONSTRAINT, ICON_CONSTRAINT_BONE, N_("Bone Constraints")); - BUTTON_HEADER_CTX(BCONTEXT_MATERIAL, ICON_MATERIAL, N_("Material")); - BUTTON_HEADER_CTX(BCONTEXT_TEXTURE, ICON_TEXTURE, N_("Textures")); - BUTTON_HEADER_CTX(BCONTEXT_PARTICLE, ICON_PARTICLES, N_("Particles")); - BUTTON_HEADER_CTX(BCONTEXT_PHYSICS, ICON_PHYSICS, N_("Physics")); - -#undef BUTTON_HEADER_CTX - - xco += BUT_UNIT_X; - - uiBlockEndAlign(block); - - /* always as last */ - UI_view2d_totRect_set(&ar->v2d, xco + (UI_UNIT_X / 2), BLI_rctf_size_y(&ar->v2d.tot)); - - uiEndBlock(C, block); - uiDrawBlock(C, block); -} - - diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h index 5700d361e15..f294729ae97 100644 --- a/source/blender/editors/space_buttons/buttons_intern.h +++ b/source/blender/editors/space_buttons/buttons_intern.h @@ -97,9 +97,6 @@ typedef struct ButsContextTexture { /* internal exports only */ -/* buttons_header.c */ -void buttons_header_buttons(const struct bContext *C, struct ARegion *ar); - /* buttons_context.c */ void buttons_context_compute(const struct bContext *C, struct SpaceButs *sbuts); int buttons_context(const struct bContext *C, const char *member, struct bContextDataResult *result); diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 02b06e08eed..e6c6df416bf 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -87,7 +87,7 @@ static SpaceLink *buttons_new(const bContext *UNUSED(C)) BLI_addtail(&sbuts->regionbase, ar); ar->regiontype = RGN_TYPE_WINDOW; - + return (SpaceLink *)sbuts; } @@ -200,22 +200,17 @@ static void buttons_keymap(struct wmKeyConfig *keyconf) /* add handlers, stuff you only do once or on area/region changes */ static void buttons_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar) { - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); + ED_region_header_init(ar); } static void buttons_header_area_draw(const bContext *C, ARegion *ar) { - /* clear */ - UI_ThemeClearColor(ED_screen_area_active(C) ? TH_HEADER : TH_HEADERDESEL); - glClear(GL_COLOR_BUFFER_BIT); - - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(&ar->v2d); - - buttons_header_buttons(C, ar); + SpaceButs *sbuts = CTX_wm_space_buts(C); - /* restore view matrix? */ - UI_view2d_view_restore(C); + /* Needed for RNA to get the good values! */ + buttons_context_compute(C, sbuts); + + ED_region_header(C, ar); } /* draw a certain button set only if properties area is currently diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index e5c6a839380..240106d37d5 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -105,8 +105,8 @@ float file_string_width(const char *str); float file_font_pointsize(void); void file_change_dir(bContext *C, int checkdir); int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file); -void autocomplete_directory(struct bContext *C, char *str, void *arg_v); -void autocomplete_file(struct bContext *C, char *str, void *arg_v); +bool autocomplete_directory(struct bContext *C, char *str, void *arg_v); +bool autocomplete_file(struct bContext *C, char *str, void *arg_v); /* file_panels.c */ void file_panels_register(struct ARegionType *art); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 59801796f8c..a31af851575 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -638,9 +638,10 @@ int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matche return match; } -void autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) +bool autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) { SpaceFile *sfile = CTX_wm_space_file(C); + bool change = false; /* search if str matches the beginning of name */ if (str[0] && sfile->files) { @@ -675,20 +676,25 @@ void autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) } closedir(dir); - autocomplete_end(autocpl, str); - if (BLI_exists(str)) { - BLI_add_slash(str); - } - else { - BLI_strncpy(sfile->params->dir, str, sizeof(sfile->params->dir)); + change = autocomplete_end(autocpl, str); + if (change) { + if (BLI_exists(str)) { + BLI_add_slash(str); + } + else { + BLI_strncpy(sfile->params->dir, str, sizeof(sfile->params->dir)); + } } } } + + return change; } -void autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) +bool autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) { SpaceFile *sfile = CTX_wm_space_file(C); + bool change = false; /* search if str matches the beginning of name */ if (str[0] && sfile->files) { @@ -702,8 +708,9 @@ void autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) autocomplete_do_name(autocpl, file->relname); } } - autocomplete_end(autocpl, str); + change = autocomplete_end(autocpl, str); } + return change; } void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile) diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index ade38a4288b..d0a34f20c77 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -567,7 +567,7 @@ static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int index) BMEditMesh *em = data->em; BMFace *efa = EDBM_face_at_index(em, index); - if (efa == NULL || BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { return DM_DRAW_OPTION_SKIP; } else { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index ac0ecaf58dd..ac5deb057b5 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2060,7 +2060,9 @@ static void draw_dm_face_centers__mapFunc(void *userData, int index, const float BMFace *efa = EDBM_face_at_index(((void **)userData)[0], index); const char sel = *(((char **)userData)[1]); - if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && BM_elem_flag_test(efa, BM_ELEM_SELECT) == sel) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && + (BM_elem_flag_test(efa, BM_ELEM_SELECT) == sel)) + { bglVertex3fv(cent); } } @@ -2326,9 +2328,6 @@ static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int { BMEdge *eed = EDBM_edge_at_index(userData, index); - if (!eed) - return DM_DRAW_OPTION_SKIP; - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && draw_dm_test_freestyle_edge_mark(userData, eed)) return DM_DRAW_OPTION_NORMAL; else @@ -2358,9 +2357,6 @@ static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index) BMFace *efa = EDBM_face_at_index(data->em, index); unsigned char *col; - if (!efa) - return DM_DRAW_OPTION_SKIP; - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { if (efa == data->efa_act) { glColor4ubv(data->cols[2]); @@ -2385,6 +2381,7 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int { drawDMFacesSel_userData *data = userData; + int i; BMFace *efa; BMFace *next_efa; @@ -2393,8 +2390,13 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int if (!data->orig_index_mf_to_mpoly) return 0; - efa = EDBM_face_at_index(data->em, DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, index)); - next_efa = EDBM_face_at_index(data->em, DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, next_index)); + i = DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, index); + efa = (i != ORIGINDEX_NONE) ? EDBM_face_at_index(data->em, i) : NULL; + i = DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, next_index); + next_efa = (i != ORIGINDEX_NONE) ? EDBM_face_at_index(data->em, i) : NULL; + + if (ELEM(NULL, efa, next_efa)) + return 0; if (efa == next_efa) return 1; @@ -2473,32 +2475,27 @@ static DMDrawOption draw_dm_bweights__setDrawOptions(void *userData, int index) { BMEditMesh *em = userData; BMEdge *eed = EDBM_edge_at_index(userData, index); - float *bweight = (float *)CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT); - - if (!bweight) - return DM_DRAW_OPTION_SKIP; - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && *bweight != 0.0f) { - UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_SELECT, *bweight); - return DM_DRAW_OPTION_NORMAL; - } - else { - return DM_DRAW_OPTION_SKIP; + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + const float *bweight = (float *)CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT); + if (*bweight != 0.0f) { + UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_SELECT, *bweight); + return DM_DRAW_OPTION_NORMAL; + } } + return DM_DRAW_OPTION_SKIP; } static void draw_dm_bweights__mapFunc(void *userData, int index, const float co[3], const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) { BMEditMesh *em = userData; BMVert *eve = EDBM_vert_at_index(userData, index); - float *bweight = (float *)CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_BWEIGHT); - - if (!bweight) - return; - - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && *bweight != 0.0f) { - UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_SELECT, *bweight); - bglVertex3fv(co); + + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { + const float *bweight = (float *)CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_BWEIGHT); + if (*bweight != 0.0f) { + UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_SELECT, *bweight); + bglVertex3fv(co); + } } } static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) @@ -2506,15 +2503,19 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) ToolSettings *ts = scene->toolsettings; if (ts->selectmode & SCE_SELECT_VERTEX) { - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2); - bglBegin(GL_POINTS); - dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, em); - bglEnd(); + if (CustomData_has_layer(&em->bm->vdata, CD_BWEIGHT)) { + glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2); + bglBegin(GL_POINTS); + dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, em); + bglEnd(); + } } else { - glLineWidth(3.0); - dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, em); - glLineWidth(1.0); + if (CustomData_has_layer(&em->bm->edata, CD_BWEIGHT)) { + glLineWidth(3.0); + dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, em); + glLineWidth(1.0); + } } } @@ -2958,7 +2959,7 @@ static DMDrawOption draw_em_fancy__setFaceOpts(void *userData, int index) { BMFace *efa = EDBM_face_at_index(userData, index); - if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { GPU_enable_material(efa->mat_nr + 1, NULL); return DM_DRAW_OPTION_NORMAL; } @@ -7274,7 +7275,7 @@ static DMDrawOption bbs_mesh_solid__setSolidDrawOptions(void *userData, int inde { BMFace *efa = EDBM_face_at_index(((void **)userData)[0], index); - if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { if (((void **)userData)[1]) { WM_framebuffer_index_set(index + 1); } diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index 9e310c84bd0..180686b4b82 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -237,7 +237,7 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo foreachScreenFace_userData *data = userData; BMFace *efa = EDBM_face_at_index(data->vc.em, index); - if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { float screen_co[2]; if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, data->clip_flag) == V3D_PROJ_RET_OK) { data->func(data->userData, efa, screen_co, index); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 68b93fe6560..7a8d4c6750e 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2181,17 +2181,6 @@ int transformEnd(bContext *C, TransInfo *t) /* send events out for redraws */ viewRedrawPost(C, t); - /* Undo as last, certainly after special_trans_update! */ - - if (t->state == TRANS_CANCEL) { -// if (t->undostr) ED_undo_push(C, t->undostr); - } - else { -// if (t->undostr) ED_undo_push(C, t->undostr); -// else ED_undo_push(C, transform_to_undostr(t)); - } - t->undostr = NULL; - viewRedrawForce(C, t); } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 987180d4efd..2cef3209b4e 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -319,7 +319,6 @@ typedef struct TransInfo { float vec[3]; /* translation, to show for widget */ float mat[3][3]; /* rot/rescale, to show for widget */ - char *undostr; /* if set, uses this string for undo */ float spacemtx[3][3]; /* orientation matrix of the current space */ char spacename[64]; /* name of the current space, MAX_NAME */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index ac5727a116c..d1b57e2e402 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2020,7 +2020,7 @@ static void createTransEditVerts(TransInfo *t) int cd_vert_bweight_offset = -1; if (t->flag & T_MIRROR) { - EDBM_verts_mirror_cache_begin(em, false, true); + EDBM_verts_mirror_cache_begin(em, 0, false, true); mirror = 1; } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 6b529e13aec..4ab2269ff01 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1475,7 +1475,6 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes } for (i = 0; i < totedge; i++) { - BMEdge *eed = NULL; MEdge *e = edges + i; test = 1; /* reset for every vert */ @@ -1492,11 +1491,11 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes test = 0; } else { - eed = EDBM_edge_at_index(em, index); - - if (eed && (BM_elem_flag_test(eed, BM_ELEM_HIDDEN) || - BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || - BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))) + BMEdge *eed = EDBM_edge_at_index(em, index); + + if ((BM_elem_flag_test(eed, BM_ELEM_HIDDEN) || + BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || + BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))) { test = 0; } diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 36da4e3508c..4513694e59d 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -137,6 +137,25 @@ EnumPropertyItem clip_editor_mode_items[] = { {0, NULL, 0, NULL, NULL} }; +/* Actually populated dynamically trough a function, but helps for context-less access (e.g. doc, i18n...). */ +static EnumPropertyItem buttons_context_items[] = { + {BCONTEXT_SCENE, "SCENE", ICON_SCENE_DATA, "Scene", "Scene"}, + {BCONTEXT_RENDER, "RENDER", ICON_SCENE, "Render", "Render"}, + {BCONTEXT_RENDER_LAYER, "RENDER_LAYER", ICON_RENDERLAYERS, "Render Layers", "Render layers"}, + {BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"}, + {BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"}, + {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Object constraints"}, + {BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifiers", "Object modifiers"}, + {BCONTEXT_DATA, "DATA", ICON_NONE, "Data", "Object data"}, + {BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone"}, + {BCONTEXT_BONE_CONSTRAINT, "BONE_CONSTRAINT", ICON_CONSTRAINT, "Bone Constraints", "Bone constraints"}, + {BCONTEXT_MATERIAL, "MATERIAL", ICON_MATERIAL, "Material", "Material"}, + {BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"}, + {BCONTEXT_PARTICLE, "PARTICLES", ICON_PARTICLES, "Particles", "Particle"}, + {BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"}, + {0, NULL, 0, NULL, NULL} +}; + /* Actually populated dynamically trough a function, but helps for context-less access (e.g. doc, i18n...). */ static EnumPropertyItem buttons_texture_context_items[] = { {SB_TEXC_MATERIAL, "MATERIAL", ICON_MATERIAL, "", "Show material textures"}, @@ -831,6 +850,76 @@ static void rna_SpaceProperties_context_set(PointerRNA *ptr, int value) sbuts->mainbuser = value; } +static EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *C, PointerRNA *ptr, + PropertyRNA *UNUSED(prop), int *free) +{ + SpaceButs *sbuts = (SpaceButs *)(ptr->data); + EnumPropertyItem *item = NULL; + int totitem = 0; + + if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_RENDER); + } + + if (sbuts->pathflag & (1 << BCONTEXT_RENDER_LAYER)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_RENDER_LAYER); + } + + if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SCENE); + } + + if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_WORLD); + } + + if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_OBJECT); + } + + if (sbuts->pathflag & (1 << BCONTEXT_CONSTRAINT)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_CONSTRAINT); + } + + if (sbuts->pathflag & (1 << BCONTEXT_MODIFIER)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MODIFIER); + } + + if (sbuts->pathflag & (1 << BCONTEXT_DATA)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_DATA); + (item + totitem - 1)->icon = sbuts->dataicon; + } + + if (sbuts->pathflag & (1 << BCONTEXT_BONE)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE); + } + + if (sbuts->pathflag & (1 << BCONTEXT_BONE_CONSTRAINT)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE_CONSTRAINT); + } + + if (sbuts->pathflag & (1 << BCONTEXT_MATERIAL)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MATERIAL); + } + + if (sbuts->pathflag & (1 << BCONTEXT_TEXTURE)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_TEXTURE); + } + + if (sbuts->pathflag & (1 << BCONTEXT_PARTICLE)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PARTICLE); + } + + if (sbuts->pathflag & (1 << BCONTEXT_PHYSICS)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PHYSICS); + } + + RNA_enum_item_end(&item, &totitem); + *free = 1; + + return item; +} + static void rna_SpaceProperties_align_set(PointerRNA *ptr, int value) { SpaceButs *sbuts = (SpaceButs *)(ptr->data); @@ -2068,24 +2157,6 @@ static void rna_def_space_buttons(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem buttons_context_items[] = { - {BCONTEXT_SCENE, "SCENE", ICON_SCENE, "Scene", "Scene"}, - {BCONTEXT_RENDER, "RENDER", ICON_SCENE_DATA, "Render", "Render"}, - {BCONTEXT_RENDER_LAYER, "RENDER_LAYER", ICON_RENDERLAYERS, "Render Layers", "Render Layers"}, - {BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"}, - {BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"}, - {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Constraints"}, - {BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifiers", "Modifiers"}, - {BCONTEXT_DATA, "DATA", 0, "Data", "Data"}, - {BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone"}, - {BCONTEXT_BONE_CONSTRAINT, "BONE_CONSTRAINT", ICON_CONSTRAINT, "Bone Constraints", "Bone Constraints"}, - {BCONTEXT_MATERIAL, "MATERIAL", ICON_MATERIAL, "Material", "Material"}, - {BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"}, - {BCONTEXT_PARTICLE, "PARTICLES", ICON_PARTICLES, "Particles", "Particle"}, - {BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"}, - {0, NULL, 0, NULL, NULL} - }; - static EnumPropertyItem align_items[] = { {BUT_HORIZONTAL, "HORIZONTAL", 0, "Horizontal", ""}, {BUT_VERTICAL, "VERTICAL", 0, "Vertical", ""}, @@ -2099,7 +2170,7 @@ static void rna_def_space_buttons(BlenderRNA *brna) prop = RNA_def_property(srna, "context", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "mainb"); RNA_def_property_enum_items(prop, buttons_context_items); - RNA_def_property_enum_funcs(prop, NULL, "rna_SpaceProperties_context_set", NULL); + RNA_def_property_enum_funcs(prop, NULL, "rna_SpaceProperties_context_set", "rna_SpaceProperties_context_itemf"); RNA_def_property_ui_text(prop, "Context", "Type of active data to display and edit"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_PROPERTIES, NULL); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index cd0042731c1..e71be6052d0 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -4210,13 +4210,12 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_SELECT); -#if 0 /* Durien guys like this :S */ + /* left mouse shift for deselect too */ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_DESELECT); WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_SHIFT, 0, GESTURE_MODAL_NOP); -#else + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_DESELECT); // default 2.4x WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_NOP); // default 2.4x -#endif WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_NOP); @@ -4284,21 +4283,22 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) /* items for modal map */ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL); + /* Note: cancel only on press otherwise you cannot map this to RMB-gesture */ WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL); - - WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN); - WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT); WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT); -#if 0 /* Durian guys like this */ + /* allow shift leftclick for deselect too */ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_BEGIN); WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_SHIFT, 0, GESTURE_MODAL_DESELECT); -#else + + /* any unhandled leftclick release handles select */ + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN); + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT); + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN); WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_DESELECT); -#endif - + /* assign map to operators */ WM_modalkeymap_assign(keymap, "ACTION_OT_select_border"); WM_modalkeymap_assign(keymap, "ANIM_OT_channels_select_border"); diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 2fb83d4c1fd..ad16c96dc70 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -358,8 +358,9 @@ static std::map create_translate_table() m[F17KEY ] = SCA_IInputDevice::KX_F17KEY; m[F18KEY ] = SCA_IInputDevice::KX_F18KEY; m[F19KEY ] = SCA_IInputDevice::KX_F19KEY; - - + + m[OSKEY ] = SCA_IInputDevice::KX_OSKEY; + m[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY; m[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY; m[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY; diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 8703a545a4f..19287c1fd62 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -170,6 +170,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() delete (*itw).second; itw++; } + m_worldinfos.clear(); vector >::iterator itp = m_polymaterials.begin(); while (itp != m_polymaterials.end()) { @@ -177,6 +178,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() delete (*itp).second; itp++; } + m_polymaterials.clear(); // delete after RAS_IPolyMaterial vector >::iterator itmat = m_materials.begin(); @@ -185,6 +187,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() delete (*itmat).second; itmat++; } + m_materials.clear(); vector >::iterator itm = m_meshobjects.begin(); @@ -192,6 +195,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() delete (*itm).second; itm++; } + m_meshobjects.clear(); #ifdef WITH_BULLET KX_ClearBulletSharedShapes(); diff --git a/source/gameengine/GameLogic/SCA_IInputDevice.h b/source/gameengine/GameLogic/SCA_IInputDevice.h index ceb9c1e1d4f..47fdd45c78b 100644 --- a/source/gameengine/GameLogic/SCA_IInputDevice.h +++ b/source/gameengine/GameLogic/SCA_IInputDevice.h @@ -238,6 +238,8 @@ public: KX_F17KEY, KX_F18KEY, KX_F19KEY, + + KX_OSKEY, KX_PAUSEKEY, KX_INSERTKEY, diff --git a/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.cpp b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.cpp index e8d3441e4ce..53d03c6f479 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.cpp @@ -147,6 +147,8 @@ GPG_KeyboardDevice::GPG_KeyboardDevice(void) m_reverseKeyTranslateTable[GHOST_kKeyLeftBracket ] = KX_LEFTBRACKETKEY ; m_reverseKeyTranslateTable[GHOST_kKeyRightBracket ] = KX_RIGHTBRACKETKEY ; + m_reverseKeyTranslateTable[GHOST_kKeyOS ] = KX_OSKEY ; + // Modifier keys. m_reverseKeyTranslateTable[GHOST_kKeyLeftControl ] = KX_LEFTCTRLKEY ; m_reverseKeyTranslateTable[GHOST_kKeyRightControl ] = KX_RIGHTCTRLKEY ; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index f02e842ad2e..1061e9fd571 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -54,7 +54,6 @@ #include "MT_Transform.h" #include "SCA_IInputDevice.h" #include "KX_Camera.h" -#include "KX_FontObject.h" #include "KX_Dome.h" #include "KX_Light.h" #include "KX_PythonInit.h" @@ -340,7 +339,7 @@ void KX_KetsjiEngine::RenderDome() // do the rendering m_dome->RenderDomeFrame(scene,cam, i); //render all the font objects for this scene - RenderFonts(scene); + scene->RenderFonts(); } list* cameras = scene->GetCameras(); @@ -358,7 +357,7 @@ void KX_KetsjiEngine::RenderDome() // do the rendering m_dome->RenderDomeFrame(scene, (*it),i); //render all the font objects for this scene - RenderFonts(scene); + scene->RenderFonts(); } it++; @@ -1339,23 +1338,12 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); //render all the font objects for this scene - RenderFonts(scene); + scene->RenderFonts(); if (scene->GetPhysicsEnvironment()) scene->GetPhysicsEnvironment()->debugDrawWorld(); } -void KX_KetsjiEngine::RenderFonts(KX_Scene* scene) -{ - list* fonts = scene->GetFonts(); - - list::iterator it = fonts->begin(); - while (it != fonts->end()) { - (*it)->DrawText(); - ++it; - } -} - /* * To run once per scene */ diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 3cba3558db3..4e69c7d35f7 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -205,7 +205,6 @@ private: void RenderDebugProperties(); void RenderShadowBuffers(KX_Scene *scene); void SetBackGround(KX_WorldInfo* worldinfo); - void RenderFonts(KX_Scene* scene); public: KX_KetsjiEngine(class KX_ISystem* system); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 69b37ceae7a..58996f7b86f 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -2415,6 +2415,8 @@ PyObject *initGameKeys() KX_MACRO_addTypesToDict(d, F17KEY, SCA_IInputDevice::KX_F17KEY); KX_MACRO_addTypesToDict(d, F18KEY, SCA_IInputDevice::KX_F18KEY); KX_MACRO_addTypesToDict(d, F19KEY, SCA_IInputDevice::KX_F19KEY); + + KX_MACRO_addTypesToDict(d, OSKEY, SCA_IInputDevice::KX_OSKEY); KX_MACRO_addTypesToDict(d, PAUSEKEY, SCA_IInputDevice::KX_PAUSEKEY); KX_MACRO_addTypesToDict(d, INSERTKEY, SCA_IInputDevice::KX_INSERTKEY); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 8bb9eaeef10..13fb168221d 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -40,6 +40,7 @@ #include "MT_assert.h" #include "KX_KetsjiEngine.h" #include "KX_BlenderMaterial.h" +#include "KX_FontObject.h" #include "RAS_IPolygonMaterial.h" #include "ListValue.h" #include "SCA_LogicManager.h" @@ -352,11 +353,6 @@ list* KX_Scene::GetCameras() return &m_cameras; } -list* KX_Scene::GetFonts() -{ - return &m_fonts; -} - void KX_Scene::SetFramingType(RAS_FrameSettings & frame_settings) { m_frame_settings = frame_settings; @@ -1639,6 +1635,15 @@ void KX_Scene::RenderBuckets(const MT_Transform & cameratransform, KX_BlenderMaterial::EndFrame(); } +void KX_Scene::RenderFonts() +{ + list::iterator it = m_fonts.begin(); + while (it != m_fonts.end()) { + (*it)->DrawText(); + ++it; + } +} + void KX_Scene::UpdateObjectActivity(void) { if (m_activity_culling) { diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 632e1bf9b50..7c3ea946044 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -381,10 +381,6 @@ public: ); /** Font Routines */ - - std::list* - GetFonts( - ); /** Find a font in the scene by pointer. */ KX_FontObject* @@ -398,6 +394,10 @@ public: KX_FontObject* ); + /** Render the fonts in this scene. */ + void + RenderFonts( + ); /** Camera Routines */ diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index d251f4f7bcb..f184ab9bd1d 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -275,6 +275,8 @@ void ImageRender::Render() m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); + m_scene->RenderFonts(); + // restore the canvas area now that the render is completed m_canvas->GetWindowArea() = area; }