Merged revision(s) 57587-57670 from trunk/blender into soc-2013-dingto

This commit is contained in:
Thomas Dinges 2013-06-23 18:04:13 +00:00
commit 00234dab2f
124 changed files with 2054 additions and 755 deletions

@ -264,7 +264,7 @@ option(WITH_CYCLES "Enable cycles Render Engine" ON)
option(WITH_CYCLES_TEST "Build cycles test application" OFF)
option(WITH_CYCLES_OSL "Build Cycles with OSL support" OFF)
option(WITH_CYCLES_CUDA_BINARIES "Build cycles CUDA binaries" OFF)
set(CYCLES_CUDA_BINARIES_ARCH sm_20 sm_21 sm_30 CACHE STRING "CUDA architectures to build binaries for")
set(CYCLES_CUDA_BINARIES_ARCH sm_20 sm_21 sm_30 sm_35 CACHE STRING "CUDA architectures to build binaries for")
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
unset(PLATFORM_DEFAULT)

@ -1550,7 +1550,7 @@ compile_OSL() {
tar -C $SRC --transform "s,(.*/?)OpenShadingLanguage-[^/]*(.*),\1OpenShadingLanguage-$OSL_VERSION\2,x" \
-xf $_src.tar.gz
cd $_src
git checkout blender-fixes
#git checkout blender-fixes
cd $CWD
fi
@ -2278,8 +2278,18 @@ install_RPM() {
fi
_suse_rel="`grep VERSION /etc/SuSE-release | gawk '{print $3}'`"
sudo zypper ar -f http://packman.inode.at/suse/openSUSE_$_suse_rel/ packman
INFO ""
INFO "About to add 'packman' repository from http://packman.inode.at/suse/openSUSE_$_suse_rel/"
INFO "This is only needed if you do not already have a packman repository enabled..."
read -p "Do you want to add this repo (Y/n)?"
if [ "$(echo ${REPLY:=Y} | tr [:upper:] [:lower:])" == "y" ]; then
INFO " Installing packman..."
sudo zypper ar --refresh --name 'Packman Repository' http://ftp.gwdg.de/pub/linux/packman/suse/openSUSE_$_suse_rel/ ftp.gwdg.de-suse
INFO " Done."
else
INFO " Skipping packman installation."
fi
sudo zypper --non-interactive --gpg-auto-import-keys update --auto-agree-with-licenses
fi

@ -2,4 +2,4 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-i686'
BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
BF_NUMJOBS = 1
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']

@ -2,4 +2,4 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64'
BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64'
BF_NUMJOBS = 1
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']

@ -55,6 +55,8 @@ WITH_BF_GETTEXT_STATIC = True
WITH_BF_FREETYPE_STATIC = False
WITH_BF_OPENEXR = True
BF_OPENEXR = '/opt/lib/openexr'
BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR ${BF_OPENEXR}/include'
WITH_BF_STATICOPENEXR = True
WITH_BF_TIFF = True

@ -55,6 +55,8 @@ WITH_BF_GETTEXT_STATIC = True
WITH_BF_FREETYPE_STATIC = False
WITH_BF_OPENEXR = True
BF_OPENEXR = '/opt/lib/openexr'
BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR ${BF_OPENEXR}/include'
WITH_BF_STATICOPENEXR = True
WITH_BF_TIFF = True

@ -315,7 +315,7 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
WITH_BF_CYCLES_CUDA_BINARIES = True
BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
#Freestyle
WITH_BF_FREESTYLE = True

@ -315,7 +315,7 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
WITH_BF_CYCLES_CUDA_BINARIES = True
BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
#Freestyle
WITH_BF_FREESTYLE = True

@ -40,6 +40,8 @@ WITH_BF_GETTEXT_STATIC = True
WITH_BF_FREETYPE_STATIC = False
WITH_BF_OPENEXR = True
BF_OPENEXR = '/opt/lib/openexr'
BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR ${BF_OPENEXR}/include'
WITH_BF_STATICOPENEXR = True
WITH_BF_TIFF = True

@ -40,6 +40,8 @@ WITH_BF_GETTEXT_STATIC = True
WITH_BF_FREETYPE_STATIC = False
WITH_BF_OPENEXR = True
BF_OPENEXR = '/opt/lib/openexr'
BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR ${BF_OPENEXR}/include'
WITH_BF_STATICOPENEXR = True
WITH_BF_TIFF = True

@ -155,9 +155,9 @@ else:
scons_options.append('BF_CONFIG=' + os.path.join(config_dir, config))
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
if builder.find('win') != -1:
if not os.path.exists(install_dir):
os.makedirs(install_dir)
if builder.endswith('vc2012'):
dlls = ('msvcp110.dll', 'msvcr110.dll', 'vcomp110.dll')
else:
@ -169,4 +169,6 @@ else:
for dll in dlls:
shutil.copyfile(os.path.join(dlls_path, dll), os.path.join(install_dir, dll))
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
sys.exit(retcode)

@ -401,8 +401,14 @@ macro(TEST_SSE_SUPPORT
set(${_sse_flags} "-msse")
set(${_sse2_flags} "-msse2")
elseif(MSVC)
set(${_sse_flags} "/arch:SSE")
set(${_sse2_flags} "/arch:SSE2")
# x86_64 has this auto enabled
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(${_sse_flags} "")
set(${_sse2_flags} "")
else()
set(${_sse_flags} "/arch:SSE")
set(${_sse2_flags} "/arch:SSE2")
endif()
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
set(${_sse_flags} "") # icc defaults to -msse
set(${_sse2_flags} "-msse2")

@ -315,7 +315,7 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
WITH_BF_CYCLES_CUDA_BINARIES = False
BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
#Freestyle
WITH_BF_FREESTYLE = True

@ -210,7 +210,7 @@ WITH_BF_CYCLES = WITH_BF_OIIO and WITH_BF_BOOST
WITH_BF_CYCLES_CUDA_BINARIES = False
BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
WITH_BF_OPENMP = True

@ -149,7 +149,7 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada'
WITH_BF_CYCLES = True
WITH_BF_CYCLES_CUDA_BINARIES = False
BF_CYCLES_CUDA_NVCC = "" # Path to the NVIDIA CUDA compiler
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
WITH_BF_OIIO = True
BF_OIIO = LIBDIR + '/openimageio'

@ -215,7 +215,7 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#CUDA
WITH_BF_CYCLES_CUDA_BINARIES = False
#BF_CYCLES_CUDA_NVCC = "" # Path to the nvidia compiler
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True

@ -146,7 +146,7 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada'
WITH_BF_CYCLES = True
WITH_BF_CYCLES_CUDA_BINARIES = False
BF_CYCLES_CUDA_NVCC = "" # Path to the NVIDIA CUDA compiler
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
WITH_BF_OIIO = True
BF_OIIO = LIBDIR + '/openimageio'

@ -212,7 +212,7 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#CUDA
WITH_BF_CYCLES_CUDA_BINARIES = False
#BF_CYCLES_CUDA_NVCC = "" # Path to the nvidia compiler
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True

@ -161,7 +161,7 @@ boost::shared_ptr<AUD_SequencerEntry> AUD_Sequencer::add(boost::shared_ptr<AUD_I
boost::shared_ptr<AUD_SequencerEntry> entry = boost::shared_ptr<AUD_SequencerEntry>(new AUD_SequencerEntry(sound, begin, end, skip, m_id++));
m_entries.push_front(entry);
m_entries.push_back(entry);
m_entry_status++;
return entry;

@ -112,7 +112,7 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
try
{
handle = boost::shared_ptr<AUD_SequencerHandle>(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<AUD_SequencerHandle>(new AUD_SequencerHandle(*eit, m_device));
handles.push_front(handle);
handles.push_back(handle);
}
catch(AUD_Exception&)
{

@ -304,7 +304,7 @@ public:
}
}
else {
/* CUDA 4.x */
/* CUDA 5.x */
if(major == 1) {
/* sm_1x */
arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0 --use_fast_math";
@ -704,7 +704,7 @@ public:
CUfunction cuDisplace;
CUdeviceptr d_input = cuda_device_ptr(task.shader_input);
CUdeviceptr d_offset = cuda_device_ptr(task.shader_output);
CUdeviceptr d_output = cuda_device_ptr(task.shader_output);
/* get kernel function */
cuda_assert(cuModuleGetFunction(&cuDisplace, cuModule, "kernel_cuda_shader"))
@ -715,8 +715,8 @@ public:
cuda_assert(cuParamSetv(cuDisplace, offset, &d_input, sizeof(d_input)))
offset += sizeof(d_input);
cuda_assert(cuParamSetv(cuDisplace, offset, &d_offset, sizeof(d_offset)))
offset += sizeof(d_offset);
cuda_assert(cuParamSetv(cuDisplace, offset, &d_output, sizeof(d_output)))
offset += sizeof(d_output);
int shader_eval_type = task.shader_eval_type;
offset = align_up(offset, __alignof(shader_eval_type));

@ -318,6 +318,7 @@ public:
cl_program cpProgram;
cl_kernel ckPathTraceKernel;
cl_kernel ckFilmConvertKernel;
cl_kernel ckShaderKernel;
cl_int ciErr;
typedef map<string, device_vector<uchar>*> ConstMemMap;
@ -427,6 +428,7 @@ public:
cpProgram = NULL;
ckPathTraceKernel = NULL;
ckFilmConvertKernel = NULL;
ckShaderKernel = NULL;
null_mem = 0;
device_initialized = false;
@ -760,6 +762,10 @@ public:
if(opencl_error(ciErr))
return false;
ckShaderKernel = clCreateKernel(cpProgram, "kernel_ocl_shader", &ciErr);
if(opencl_error(ciErr))
return false;
return true;
}
@ -1009,11 +1015,45 @@ public:
enqueue_kernel(ckFilmConvertKernel, d_w, d_h);
}
void shader(DeviceTask& task)
{
/* cast arguments to cl types */
cl_mem d_data = CL_MEM_PTR(const_mem_map["__data"]->device_pointer);
cl_mem d_input = CL_MEM_PTR(task.shader_input);
cl_mem d_output = CL_MEM_PTR(task.shader_output);
cl_int d_shader_eval_type = task.shader_eval_type;
cl_int d_shader_x = task.shader_x;
cl_int d_shader_w = task.shader_w;
/* sample arguments */
cl_uint narg = 0;
ciErr = 0;
ciErr |= clSetKernelArg(ckShaderKernel, narg++, sizeof(d_data), (void*)&d_data);
ciErr |= clSetKernelArg(ckShaderKernel, narg++, sizeof(d_input), (void*)&d_input);
ciErr |= clSetKernelArg(ckShaderKernel, narg++, sizeof(d_output), (void*)&d_output);
#define KERNEL_TEX(type, ttype, name) \
ciErr |= set_kernel_arg_mem(ckShaderKernel, &narg, #name);
#include "kernel_textures.h"
ciErr |= clSetKernelArg(ckShaderKernel, narg++, sizeof(d_shader_eval_type), (void*)&d_shader_eval_type);
ciErr |= clSetKernelArg(ckShaderKernel, narg++, sizeof(d_shader_x), (void*)&d_shader_x);
ciErr |= clSetKernelArg(ckShaderKernel, narg++, sizeof(d_shader_w), (void*)&d_shader_w);
opencl_assert(ciErr);
enqueue_kernel(ckShaderKernel, task.shader_w, 1);
}
void thread_run(DeviceTask *task)
{
if(task->type == DeviceTask::TONEMAP) {
tonemap(*task, task->buffer, task->rgba);
}
else if(task->type == DeviceTask::SHADER) {
shader(*task);
}
else if(task->type == DeviceTask::PATH_TRACE) {
RenderTile tile;

@ -132,6 +132,12 @@ if(WITH_CYCLES_CUDA_BINARIES)
string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR ${NVCC_OUT})
set(CUDA_VERSION "${CUDA_VERSION_MAJOR}${CUDA_VERSION_MINOR}")
# warn for other versions
if(CUDA_VERSION MATCHES "50")
else()
message(WARNING "CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, build may succeed but only CUDA 5.0 is officially supported")
endif()
# build for each arch
set(cuda_sources kernel.cu ${SRC_HEADERS} ${SRC_SVM_HEADERS} ${SRC_CLOSURE_HEADERS} ${SRC_UTIL_HEADERS})
set(cuda_cubins)
@ -141,12 +147,6 @@ if(WITH_CYCLES_CUDA_BINARIES)
set(cuda_version_flags "-D__KERNEL_CUDA_VERSION__=${CUDA_VERSION}")
# warn for other versions
if(CUDA_VERSION MATCHES "50")
else()
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
@ -178,13 +178,17 @@ if(WITH_CYCLES_CUDA_BINARIES)
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} ${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})
if(CUDA_VERSION LESS 50 AND ${arch} MATCHES "sm_35")
message(WARNING "Can't build kernel for CUDA sm_35 architecture, skipping")
else()
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} ${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)
list(APPEND cuda_cubins ${cuda_cubin})
delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${cuda_cubin}" ${CYCLES_INSTALL_PATH}/lib)
list(APPEND cuda_cubins ${cuda_cubin})
endif()
endforeach()
add_custom_target(cycles_kernel_cuda ALL DEPENDS ${cuda_cubins})

@ -88,6 +88,10 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']:
# build flags depending on CUDA version and arch
if cuda_version < 50:
if arch == "sm_35":
print("Can't build kernel for CUDA sm_35 architecture, skipping")
continue
# CUDA 4.x
if arch.startswith("sm_1"):
# sm_1x

@ -25,6 +25,7 @@
#include "kernel_film.h"
#include "kernel_path.h"
#include "kernel_displace.h"
__kernel void kernel_ocl_path_trace(
__constant KernelData *data,
@ -80,10 +81,28 @@ __kernel void kernel_ocl_tonemap(
kernel_film_tonemap(kg, rgba, buffer, sample, x, y, offset, stride);
}
/*__kernel void kernel_ocl_shader(__global uint4 *input, __global float *output, int type, int sx)
__kernel void kernel_ocl_shader(
__constant KernelData *data,
__global uint4 *input,
__global float4 *output,
#define KERNEL_TEX(type, ttype, name) \
__global type *name,
#include "kernel_textures.h"
int type, int sx, int sw)
{
KernelGlobals kglobals, *kg = &kglobals;
kg->data = data;
#define KERNEL_TEX(type, ttype, name) \
kg->name = name;
#include "kernel_textures.h"
int x = sx + get_global_id(0);
kernel_shader_evaluate(input, output, (ShaderEvalType)type, x);
}*/
if(x < sx + sw)
kernel_shader_evaluate(kg, input, output, (ShaderEvalType)type, x);
}

@ -18,7 +18,7 @@
CCL_NAMESPACE_BEGIN
__device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *output, ShaderEvalType type, int i)
__device void kernel_shader_evaluate(KernelGlobals *kg, __global uint4 *input, __global float4 *output, ShaderEvalType type, int i)
{
ShaderData sd;
uint4 in = input[i];

@ -249,7 +249,11 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
#endif
PathState state;
int rng_offset = PRNG_BASE_NUM;
#ifdef __CMJ__
int num_samples = kernel_data.integrator.aa_samples;
#else
int num_samples = 0;
#endif
path_state_init(&state);
@ -765,7 +769,11 @@ __device_noinline void kernel_path_non_progressive_lighting(KernelGlobals *kg, R
float min_ray_pdf, float ray_pdf, PathState state,
int rng_offset, PathRadiance *L, __global float *buffer)
{
#ifdef __CMJ__
int aa_samples = kernel_data.integrator.aa_samples;
#else
int aa_samples = 0;
#endif
#ifdef __AO__
/* ambient occlusion */
@ -964,7 +972,11 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
float ray_pdf = 0.0f;
PathState state;
int rng_offset = PRNG_BASE_NUM;
#ifdef __CMJ__
int aa_samples = kernel_data.integrator.aa_samples;
#else
int aa_samples = 0;
#endif
path_state_init(&state);
@ -1141,7 +1153,11 @@ __device void kernel_path_trace(KernelGlobals *kg,
float filter_u;
float filter_v;
#ifdef __CMJ__
int num_samples = kernel_data.integrator.aa_samples;
#else
int num_samples = 0;
#endif
path_rng_init(kg, rng_state, sample, num_samples, &rng, x, y, &filter_u, &filter_v);

@ -125,9 +125,9 @@ __device_inline float path_rng_1D(KernelGlobals *kg, RNG *rng, int sample, int n
float shift;
if(dimension & 1)
shift = (*rng >> 16)/((float)0xFFFF);
shift = (*rng >> 16) * (1.0f/(float)0xFFFF);
else
shift = (*rng & 0xFFFF)/((float)0xFFFF);
shift = (*rng & 0xFFFF) * (1.0f/(float)0xFFFF);
return r + shift - floorf(r + shift);
#endif

@ -157,10 +157,10 @@ CCL_NAMESPACE_BEGIN
/* Shader Evaluation */
enum ShaderEvalType {
typedef enum ShaderEvalType {
SHADER_EVAL_DISPLACE,
SHADER_EVAL_BACKGROUND
};
} ShaderEvalType;
/* Path Tracing
* note we need to keep the u/v pairs at even values */

@ -52,6 +52,6 @@ surface node_bump(
/* compute and output perturbed normal */
NormalOut = normalize(absdet * NormalIn - dist * sign(det) * surfgrad);
NormalOut = normalize(strength*NormalOut + (1.0 - strength)*NormalIn);
NormalOut = normalize(strength * NormalOut + (1.0 - strength) * NormalIn);
}

@ -50,8 +50,8 @@ color color_scene_linear_to_srgb(color c)
color color_unpremultiply(color c, float alpha)
{
if(alpha != 1.0 && alpha != 0.0)
return c/alpha;
if (alpha != 1.0 && alpha != 0.0)
return c / alpha;
return c;
}

@ -49,6 +49,7 @@ shader node_environment_texture(
string projection = "Equirectangular",
string color_space = "sRGB",
int is_float = 1,
int use_alpha = 1,
output color Color = 0.0,
output float Alpha = 1.0)
{
@ -67,7 +68,7 @@ shader node_environment_texture(
/* todo: use environment for better texture filtering of equirectangular */
Color = (color)texture(filename, p[0], 1.0 - p[1], "wrap", "periodic", "alpha", Alpha);
if (isconnected(Alpha)) {
if (use_alpha) {
Color = color_unpremultiply(Color, Alpha);
if (!is_float)

@ -30,8 +30,9 @@ color image_texture_lookup(string filename, string color_space, float u, float v
rgb = min(rgb, 1.0);
}
if (color_space == "sRGB")
if (color_space == "sRGB") {
rgb = color_srgb_to_scene_linear(rgb);
}
return rgb;
}
@ -45,6 +46,7 @@ shader node_image_texture(
string projection = "Flat",
float projection_blend = 0.0,
int is_float = 1,
int use_alpha = 1,
output color Color = 0.0,
output float Alpha = 1.0)
{
@ -53,8 +55,6 @@ shader node_image_texture(
if (use_mapping)
p = transform(mapping, p);
int use_alpha = isconnected(Alpha);
if (projection == "Flat") {
Color = image_texture_lookup(filename, color_space, p[0], p[1], Alpha, use_alpha, is_float);
}

@ -162,7 +162,7 @@ float safe_noise(point p, int type)
f = noise(p);
/* can happen for big coordinates, things even out to 0.5 then anyway */
if(!isfinite(f))
if (!isfinite(f))
return 0.5;
return f;
@ -254,12 +254,12 @@ float noise_turbulence(point p, string basis, float details, int hard)
if (hard)
t = fabs(2.0 * t - 1.0);
float sum2 = sum + t*amp;
float sum2 = sum + t * amp;
sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
return (1.0 - rmd)*sum + rmd*sum2;
return (1.0 - rmd) * sum + rmd * sum2;
}
else {
sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));

@ -30,7 +30,7 @@
CCL_NAMESPACE_BEGIN
static void dump_background_pixels(Device *device, DeviceScene *dscene, int res, vector<float3>& pixels)
static void shade_background_pixels(Device *device, DeviceScene *dscene, int res, vector<float3>& pixels)
{
/* create input */
int width = res;
@ -433,7 +433,7 @@ void LightManager::device_update_background(Device *device, DeviceScene *dscene,
assert(res > 0);
vector<float3> pixels;
dump_background_pixels(device, dscene, res, pixels);
shade_background_pixels(device, dscene, res, pixels);
if(progress.get_cancel())
return;

@ -237,6 +237,8 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
void ImageTextureNode::compile(OSLCompiler& compiler)
{
ShaderOutput *alpha_out = output("Alpha");
tex_mapping.compile(compiler);
if(is_float == -1)
@ -250,6 +252,7 @@ void ImageTextureNode::compile(OSLCompiler& compiler)
compiler.parameter("projection", projection);
compiler.parameter("projection_blend", projection_blend);
compiler.parameter("is_float", is_float);
compiler.parameter("use_alpha", !alpha_out->links.empty());
compiler.add(this, "node_image_texture");
}
@ -358,6 +361,8 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
void EnvironmentTextureNode::compile(OSLCompiler& compiler)
{
ShaderOutput *alpha_out = output("Alpha");
tex_mapping.compile(compiler);
if(is_float == -1)
@ -370,6 +375,7 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler)
else
compiler.parameter("color_space", "sRGB");
compiler.parameter("is_float", is_float);
compiler.parameter("use_alpha", !alpha_out->links.empty());
compiler.add(this, "node_environment_texture");
}

@ -186,9 +186,6 @@ void OSLShaderManager::shading_system_init()
ss_shared = OSL::ShadingSystem::create(services_shared, ts_shared, &errhandler);
ss_shared->attribute("lockgeom", 1);
ss_shared->attribute("commonspace", "world");
ss_shared->attribute("optimize", 2);
//ss_shared->attribute("debug", 1);
//ss_shared->attribute("statistics:level", 1);
ss_shared->attribute("searchpath:shader", path_get("shader"));
/* our own ray types */

@ -517,7 +517,7 @@ __device_inline const __m128 shuffle_swap(const __m128& a, const shuffle_swap_t&
#else
/* somewhat slower version for SSE3 */
/* somewhat slower version for SSE2 */
typedef int shuffle_swap_t;
__device_inline const shuffle_swap_t shuffle_swap_identity(void)
@ -552,6 +552,30 @@ template<size_t i0, size_t i1, size_t i2, size_t i3> __device_inline const __m12
}
#endif
#ifndef __KERNEL_GPU__
static inline void *malloc_aligned(size_t size, size_t alignment)
{
void *data = (void*)malloc(size + sizeof(void*) + alignment - 1);
union { void *ptr; size_t offset; } u;
u.ptr = (char*)data + sizeof(void*);
u.offset = (u.offset + alignment - 1) & ~(alignment - 1);
*(((void**)u.ptr) - 1) = data;
return u.ptr;
}
static inline void free_aligned(void *ptr)
{
if(ptr) {
void *data = *(((void**)ptr) - 1);
free(data);
}
}
#endif
CCL_NAMESPACE_END
#endif /* __UTIL_TYPES_H__ */

@ -24,18 +24,22 @@
#include <string.h>
#include <vector>
#include "util_types.h"
CCL_NAMESPACE_BEGIN
using std::vector;
/* Array
*
* Simplified version of vector, serving two purposes:
* Simplified version of vector, serving multiple purposes:
* - somewhat faster in that it does not clear memory on resize/alloc,
* this was actually showing up in profiles quite significantly
* - if this is used, we are not tempted to use inefficient operations */
* this was actually showing up in profiles quite significantly. it
* also does not run any constructors/destructors
* - if this is used, we are not tempted to use inefficient operations
* - aligned allocation for SSE data types */
template<typename T>
template<typename T, size_t alignment = 16>
class array
{
public:
@ -52,7 +56,7 @@ public:
datasize = 0;
}
else {
data = new T[newsize];
data = (T*)malloc_aligned(sizeof(T)*newsize, alignment);
datasize = newsize;
}
}
@ -69,7 +73,7 @@ public:
datasize = 0;
}
else {
data = new T[from.datasize];
data = (T*)malloc_aligned(sizeof(T)*from.datasize, alignment);
memcpy(data, from.data, from.datasize*sizeof(T));
datasize = from.datasize;
}
@ -83,7 +87,10 @@ public:
data = NULL;
if(datasize > 0) {
data = new T[datasize];
data = (T*)malloc_aligned(sizeof(T)*datasize, alignment);
memcpy(data, &from[0], datasize*sizeof(T));
free_aligned(data);
data = (T*)malloc_aligned(sizeof(T)*datasize, alignment);
memcpy(data, &from[0], datasize*sizeof(T));
}
@ -92,7 +99,7 @@ public:
~array()
{
delete [] data;
free_aligned(data);
}
void resize(size_t newsize)
@ -100,10 +107,10 @@ public:
if(newsize == 0) {
clear();
}
else {
T *newdata = new T[newsize];
else if(newsize != datasize) {
T *newdata = (T*)malloc_aligned(sizeof(T)*newsize, alignment);
memcpy(newdata, data, ((datasize < newsize)? datasize: newsize)*sizeof(T));
delete [] data;
free_aligned(data);
data = newdata;
datasize = newsize;
@ -112,7 +119,7 @@ public:
void clear()
{
delete [] data;
free_aligned(data);
data = NULL;
datasize = 0;
}

@ -113,8 +113,8 @@ const char *bl_locale_pgettext(const char *msgctxt, const char *msgid)
return r;
return msgid;
}
catch(std::exception const &e) {
catch(std::exception const &) {
// std::cout << "bl_locale_pgettext(" << msgctxt << ", " << msgid << "): " << e.what() << " \n";
return msgid;
}
}
}

@ -250,6 +250,7 @@ class MASK_PT_tools():
col.operator("mask.delete")
col.operator("mask.cyclic_toggle")
col.operator("mask.switch_direction")
col.operator("mask.handle_type_set")
col = layout.column(align=True)
col.label(text="Parenting:")

@ -383,6 +383,8 @@ class IMAGE_HT_header(Header):
if show_uvedit:
sub.menu("IMAGE_MT_select")
if show_maskedit:
sub.menu("MASK_MT_select")
if ima and ima.is_dirty:
sub.menu("IMAGE_MT_image", text="Image*")
@ -391,6 +393,8 @@ class IMAGE_HT_header(Header):
if show_uvedit:
sub.menu("IMAGE_MT_uvs")
if show_maskedit:
sub.menu("MASK_MT_mask")
layout.template_ID(sima, "image", new="image.new")
if not show_render:

@ -734,8 +734,9 @@ class USERPREF_PT_theme(Panel):
padding = subsplit.split(percentage=0.15)
colsub = padding.column()
colsub = padding.column()
colsub.active = False
colsub.row().prop(ui, "icon_file")
# Not working yet.
#~ colsub.active = False
#~ colsub.row().prop(ui, "icon_file")
subsplit = row.split(percentage=0.85)

@ -1800,7 +1800,7 @@ class VIEW3D_MT_edit_mesh(Menu):
layout.menu("VIEW3D_MT_uv_map", text="UV Unwrap...")
layout.separator()
layout.operator("mesh.symmetrize")
layout.operator("mesh.duplicate_move")
layout.menu("VIEW3D_MT_edit_mesh_extrude")
layout.menu("VIEW3D_MT_edit_mesh_delete")
@ -1814,6 +1814,12 @@ class VIEW3D_MT_edit_mesh(Menu):
layout.separator()
layout.operator("mesh.symmetrize")
layout.operator("mesh.symmetry_snap")
layout.operator_menu_enum("mesh.sort_elements", "type", text="Sort Elements...")
layout.separator()
layout.prop(toolsettings, "use_mesh_automerge")
layout.prop_menu_enum(toolsettings, "proportional_edit")
layout.prop_menu_enum(toolsettings, "proportional_edit_falloff")
@ -1869,6 +1875,7 @@ class VIEW3D_MT_edit_mesh_specials(Menu):
layout.operator("mesh.shortest_path_select")
layout.operator("mesh.sort_elements")
layout.operator("mesh.symmetrize")
layout.operator("mesh.symmetry_snap")
class VIEW3D_MT_edit_mesh_select_mode(Menu):
@ -1937,7 +1944,6 @@ class VIEW3D_MT_edit_mesh_vertices(Menu):
layout.operator("mesh.bevel").vertex_only = True
layout.operator("mesh.vertices_smooth")
layout.operator("mesh.remove_doubles")
layout.operator("mesh.sort_elements", text="Sort Vertices").elements = {'VERT'}
layout.operator("mesh.blend_from_shape")
@ -1994,7 +2000,6 @@ class VIEW3D_MT_edit_mesh_edges(Menu):
layout.operator("mesh.bevel").vertex_only = False
layout.operator("mesh.edge_split")
layout.operator("mesh.bridge_edge_loops")
layout.operator("mesh.sort_elements", text="Sort Edges").elements = {'EDGE'}
layout.separator()
@ -2024,7 +2029,6 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
layout.operator("mesh.bevel").vertex_only = False
layout.operator("mesh.solidify")
layout.operator("mesh.wireframe")
layout.operator("mesh.sort_elements", text="Sort Faces").elements = {'FACE'}
layout.separator()

@ -232,7 +232,6 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
mesh = ob.data
col = layout.column(align=True)
col.active = tool_settings.proportional_edit == 'DISABLED'
col.prop(mesh, "use_mirror_x")
row = col.row()

@ -66,7 +66,7 @@ static void free_locales(void)
MEM_freeN((void *)locales_menu[idx].description); /* Also frees locales's relevant value! */
}
MEM_freeN(locales);
MEM_freeN((void *)locales);
locales = NULL;
}
if (locales_menu) {

@ -65,6 +65,8 @@ float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup);
float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup);
void defvert_copy(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src);
void defvert_copy_subset(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src,
const bool *vgroup_subset, const int vgroup_tot);
void defvert_copy_index(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src, const int defgroup);
void defvert_sync(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src, const bool use_verify);
void defvert_sync_mapped(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src,
@ -73,6 +75,8 @@ void defvert_remap(struct MDeformVert *dvert, int *map, const int map_len);
void defvert_flip(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len);
void defvert_flip_merged(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len);
void defvert_normalize(struct MDeformVert *dvert);
void defvert_normalize_subset(struct MDeformVert *dvert,
const bool *vgroup_subset, const int vgroup_tot);
void defvert_normalize_lock_single(struct MDeformVert *dvert, const int def_nr_lock);
void defvert_normalize_lock_map(struct MDeformVert *dvert, const bool *lock_flags, const int defbase_tot);

@ -1474,7 +1474,7 @@ void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3])
theta = angle_normalized_v3v3(target, nor);
/* Make Bone matrix*/
vec_rot_to_mat3(bMatrix, axis, theta);
axis_angle_normalized_to_mat3(bMatrix, axis, theta);
}
else {
/* if nor is a multiple of target ... */
@ -1490,7 +1490,7 @@ void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3])
}
/* Make Roll matrix */
vec_rot_to_mat3(rMatrix, nor, roll);
axis_angle_normalized_to_mat3(rMatrix, nor, roll);
/* Combine and output result */
mul_m3_m3m3(mat, rMatrix, bMatrix);

@ -1823,16 +1823,19 @@ DerivedMesh *CDDM_from_curve(Object *ob)
DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase)
{
Curve *cu = (Curve *) ob->data;
DerivedMesh *dm;
CDDerivedMesh *cddm;
MVert *allvert;
MEdge *alledge;
MLoop *allloop;
MPoly *allpoly;
MLoopUV *alluv = NULL;
int totvert, totedge, totloop, totpoly;
bool use_orco_uv = (cu->flag & CU_UV_ORCO) != 0;
if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge,
&totedge, &allloop, &allpoly, NULL,
&totedge, &allloop, &allpoly, (use_orco_uv) ? &alluv : NULL,
&totloop, &totpoly) != 0)
{
/* Error initializing mdata. This often happens when curve is empty */
@ -1850,6 +1853,12 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase)
memcpy(cddm->mloop, allloop, totloop * sizeof(MLoop));
memcpy(cddm->mpoly, allpoly, totpoly * sizeof(MPoly));
if (alluv) {
const char *uvname = "Orco";
CustomData_add_layer_named(&cddm->dm.polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, totpoly, uvname);
CustomData_add_layer_named(&cddm->dm.loopData, CD_MLOOPUV, CD_ASSIGN, alluv, totloop, uvname);
}
MEM_freeN(allvert);
MEM_freeN(alledge);
MEM_freeN(allloop);

@ -80,7 +80,21 @@ bDeformGroup *defgroup_duplicate(bDeformGroup *ingroup)
return outgroup;
}
/* copy & overwrite weights */
/* overwrite weights filtered by vgroup_subset
* - do nothing if neither are set.
* - add destination weight if needed
*/
void defvert_copy_subset(MDeformVert *dvert_dst, const MDeformVert *dvert_src,
const bool *vgroup_subset, const int vgroup_tot)
{
int defgroup;
for (defgroup=0; defgroup < vgroup_tot; defgroup++) {
if (vgroup_subset[defgroup]) {
defvert_copy_index(dvert_dst, dvert_src, defgroup);
}
}
}
void defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src)
{
if (dvert_dst->totweight == dvert_src->totweight) {
@ -181,6 +195,35 @@ void defvert_remap(MDeformVert *dvert, int *map, const int map_len)
}
}
/**
* Same as #defvert_normalize but takes a bool array.
*/
void defvert_normalize_subset(MDeformVert *dvert,
const bool *vgroup_subset, const int vgroup_tot)
{
MDeformWeight *dw;
unsigned int i;
float tot_weight = 0.0f;
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
tot_weight += dw->weight;
}
}
if (tot_weight > 0.0f) {
float scalar = 1.0f / tot_weight;
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
dw->weight *= scalar;
/* in case of division errors with very low weights */
CLAMP(dw->weight, 0.0f, 1.0f);
}
}
}
}
void defvert_normalize(MDeformVert *dvert)
{
if (dvert->totweight <= 0) {

@ -1040,7 +1040,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;
}

@ -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_squared_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 */
@ -402,7 +402,6 @@ BMVert *BKE_bmbvh_find_vert_closest(BMBVHTree *bmtree, const float co[3], const
if (bmtree->cos_cage) BLI_assert(!(bmtree->em->bm->elem_index_dirty & BM_VERT));
copy_v3_v3(hit.co, co);
hit.dist = maxdist_sq;
hit.index = -1;
@ -411,7 +410,7 @@ BMVert *BKE_bmbvh_find_vert_closest(BMBVHTree *bmtree, const float co[3], const
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;
}

@ -87,6 +87,10 @@
#ifdef __GNUC__
# pragma GCC diagnostic error "-Wsign-conversion"
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 /* gcc4.6+ only */
# pragma GCC diagnostic error "-Wsign-compare"
# pragma GCC diagnostic error "-Wconversion"
# endif
#endif
/* this is rather and annoying hack, use define to isolate it.
@ -335,8 +339,8 @@ static int layer_bucket_isect_test(MaskRasterLayer *layer, unsigned int face_ind
unsigned int *face = layer->face_array[face_index];
float (*cos)[3] = layer->face_coords;
const float xmin = layer->bounds.xmin + (bucket_size_x * bucket_x);
const float ymin = layer->bounds.ymin + (bucket_size_y * bucket_y);
const float xmin = layer->bounds.xmin + (bucket_size_x * (float)bucket_x);
const float ymin = layer->bounds.ymin + (bucket_size_y * (float)bucket_y);
const float xmax = xmin + bucket_size_x;
const float ymax = ymin + bucket_size_y;
@ -417,21 +421,21 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
const float bucket_dim_x = BLI_rctf_size_x(&layer->bounds);
const float bucket_dim_y = BLI_rctf_size_y(&layer->bounds);
layer->buckets_x = (bucket_dim_x / pixel_size) / (float)BUCKET_PIXELS_PER_CELL;
layer->buckets_y = (bucket_dim_y / pixel_size) / (float)BUCKET_PIXELS_PER_CELL;
layer->buckets_x = (unsigned int)((bucket_dim_x / pixel_size) / (float)BUCKET_PIXELS_PER_CELL);
layer->buckets_y = (unsigned int)((bucket_dim_y / pixel_size) / (float)BUCKET_PIXELS_PER_CELL);
// printf("bucket size %ux%u\n", layer->buckets_x, layer->buckets_y);
CLAMP(layer->buckets_x, 8, 512);
CLAMP(layer->buckets_y, 8, 512);
layer->buckets_xy_scalar[0] = (1.0f / (bucket_dim_x + FLT_EPSILON)) * layer->buckets_x;
layer->buckets_xy_scalar[1] = (1.0f / (bucket_dim_y + FLT_EPSILON)) * layer->buckets_y;
layer->buckets_xy_scalar[0] = (1.0f / (bucket_dim_x + FLT_EPSILON)) * (float)layer->buckets_x;
layer->buckets_xy_scalar[1] = (1.0f / (bucket_dim_y + FLT_EPSILON)) * (float)layer->buckets_y;
{
/* width and height of each bucket */
const float bucket_size_x = (bucket_dim_x + FLT_EPSILON) / layer->buckets_x;
const float bucket_size_y = (bucket_dim_y + FLT_EPSILON) / layer->buckets_y;
const float bucket_size_x = (bucket_dim_x + FLT_EPSILON) / (float)layer->buckets_x;
const float bucket_size_y = (bucket_dim_y + FLT_EPSILON) / (float)layer->buckets_y;
const float bucket_max_rad = (max_ff(bucket_size_x, bucket_size_y) * (float)M_SQRT2) + FLT_EPSILON;
const float bucket_max_rad_squared = bucket_max_rad * bucket_max_rad;
@ -641,7 +645,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
if (tot_diff_point > 3) {
ScanFillVert *sf_vert_prev;
int j;
unsigned int j;
float co[3];
co[2] = 0.0f;
@ -650,7 +654,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
if (width != height) {
float *fp;
float *ffp;
int i;
unsigned int i;
float asp;
if (width < height) {
@ -846,15 +850,15 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
fp_turn = diff_feather_points[0];
#define CALC_CAP_RESOL \
clampis_uint((len_v2v2(fp_cent, fp_turn) / (pixel_size * SPLINE_RESOL_CAP_PER_PIXEL)), \
SPLINE_RESOL_CAP_MIN, \
SPLINE_RESOL_CAP_MAX)
clampis_uint((unsigned int )(len_v2v2(fp_cent, fp_turn) / \
(pixel_size * SPLINE_RESOL_CAP_PER_PIXEL)), \
SPLINE_RESOL_CAP_MIN, SPLINE_RESOL_CAP_MAX)
{
const unsigned int vertex_total_cap = CALC_CAP_RESOL;
for (k = 1; k < vertex_total_cap; k++) {
const float angle = (float)k * (1.0f / vertex_total_cap) * (float)M_PI;
const float angle = (float)k * (1.0f / (float)vertex_total_cap) * (float)M_PI;
rotate_point_v2(co_feather, fp_turn, fp_cent, angle, asp_xy);
sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);
@ -874,7 +878,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
const unsigned int vertex_total_cap = CALC_CAP_RESOL;
for (k = 1; k < vertex_total_cap; k++) {
const float angle = (float)k * (1.0f / vertex_total_cap) * (float)M_PI;
const float angle = (float)k * (1.0f / (float)vertex_total_cap) * (float)M_PI;
rotate_point_v2(co_feather, fp_turn, fp_cent, -angle, asp_xy);
sf_vert = BLI_scanfill_vert_add(&sf_ctx, co_feather);

@ -1636,7 +1636,10 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use
void BKE_mesh_from_nurbs(Object *ob)
{
BKE_mesh_from_nurbs_displist(ob, &ob->disp, false);
Curve *cu = (Curve *) ob->data;
bool use_orco_uv = (cu->flag & CU_UV_ORCO) != 0;
BKE_mesh_from_nurbs_displist(ob, &ob->disp, use_orco_uv);
}
typedef struct EdgeLink {

@ -189,6 +189,8 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
return &ts->uvsculpt->paint;
else
return &ts->imapaint.paint;
default:
return &ts->imapaint.paint;
}
}
else {
@ -238,6 +240,8 @@ PaintMode BKE_paintmode_get_active_from_context(const bContext *C)
return PAINT_SCULPT_UV;
else
return PAINT_TEXTURE_2D;
default:
return PAINT_TEXTURE_2D;
}
}
else {

@ -4171,6 +4171,8 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
BKE_sequence_calc_disp(scene, seq);
if (seq_load->name[0] == '\0')
BLI_strncpy(seq_load->name, se->name, sizeof(seq_load->name));
if (seq_load->flag & SEQ_LOAD_MOVIE_SOUND) {
int start_frame_back = seq_load->start_frame;
@ -4182,9 +4184,6 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
seq_load->channel--;
}
if (seq_load->name[0] == '\0')
BLI_strncpy(seq_load->name, se->name, sizeof(seq_load->name));
/* can be NULL */
seq_load_apply(scene, seq, seq_load);

@ -60,7 +60,7 @@ typedef struct GHash {
typedef struct GHashIterator {
GHash *gh;
int curBucket;
unsigned int curBucket;
struct Entry *curEntry;
} GHashIterator;

@ -106,13 +106,6 @@ void mat4_to_axis_angle(float axis[3], float *angle, float M[4][4]);
void single_axis_angle_to_mat3(float R[3][3], const char axis, const float angle);
/****************************** Vector/Rotation ******************************/
/* old axis angle code */
/* TODO: the following calls should probably be deprecated sometime */
/* conversion */
void vec_rot_to_mat3(float mat[3][3], const float vec[3], const float phi);
/******************************** XYZ Eulers *********************************/
void eul_to_quat(float quat[4], const float eul[3]);

@ -56,7 +56,7 @@ typedef struct SmallHash {
typedef struct {
SmallHash *hash;
int i;
unsigned int i;
} SmallHashIter;
#ifdef __GNUC__

@ -28,6 +28,8 @@
/** \file blender/blenlib/intern/BLI_ghash.c
* \ingroup bli
*
* \note edgehash.c is based on this, make sure they stay in sync.
*/
#include <string.h>
@ -44,6 +46,10 @@
#ifdef __GNUC__
# pragma GCC diagnostic error "-Wsign-conversion"
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 /* gcc4.6+ only */
# pragma GCC diagnostic error "-Wsign-compare"
# pragma GCC diagnostic error "-Wconversion"
# endif
#endif
const unsigned int hashsizes[] = {
@ -86,22 +92,21 @@ void BLI_ghash_insert(GHash *gh, void *key, void *val)
e->val = val;
gh->buckets[hash] = e;
if (++gh->nentries > (float)gh->nbuckets / 2) {
if (UNLIKELY(++gh->nentries > gh->nbuckets / 2)) {
Entry **old = gh->buckets;
unsigned int i, nold = gh->nbuckets;
const unsigned nold = gh->nbuckets;
unsigned int i;
gh->nbuckets = hashsizes[++gh->cursize];
gh->buckets = (Entry **)MEM_callocN(gh->nbuckets * sizeof(*gh->buckets), "buckets");
for (i = 0; i < nold; i++) {
for (e = old[i]; e; ) {
Entry *n = e->next;
Entry *e_next;
for (e = old[i]; e; e = e_next) {
e_next = e->next;
hash = gh->hashfp(e->key) % gh->nbuckets;
e->next = gh->buckets[hash];
gh->buckets[hash] = e;
e = n;
}
}
@ -152,7 +157,7 @@ bool BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFr
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
{
int i;
unsigned int i;
if (keyfreefp || valfreefp) {
for (i = 0; i < gh->nbuckets; i++) {
@ -220,7 +225,7 @@ bool BLI_ghash_haskey(GHash *gh, const void *key)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
{
int i;
unsigned int i;
if (keyfreefp || valfreefp) {
for (i = 0; i < gh->nbuckets; i++) {
@ -252,7 +257,7 @@ GHashIterator *BLI_ghashIterator_new(GHash *gh)
GHashIterator *ghi = MEM_mallocN(sizeof(*ghi), "ghash iterator");
ghi->gh = gh;
ghi->curEntry = NULL;
ghi->curBucket = -1;
ghi->curBucket = (unsigned int)-1;
while (!ghi->curEntry) {
ghi->curBucket++;
if (ghi->curBucket == ghi->gh->nbuckets)
@ -265,7 +270,7 @@ void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
{
ghi->gh = gh;
ghi->curEntry = NULL;
ghi->curBucket = -1;
ghi->curBucket = (unsigned int)-1;
while (!ghi->curEntry) {
ghi->curBucket++;
if (ghi->curBucket == ghi->gh->nbuckets)

@ -41,6 +41,10 @@
#ifdef __GNUC__
# pragma GCC diagnostic error "-Wsign-conversion"
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 /* gcc4.6+ only */
# pragma GCC diagnostic error "-Wsign-compare"
# pragma GCC diagnostic error "-Wconversion"
# endif
#endif
/***/
@ -208,7 +212,7 @@ void *BLI_heap_popmin(Heap *heap)
{
void *ptr = heap->tree[0]->ptr;
BLI_assert(heap->size == 0);
BLI_assert(heap->size != 0);
heap->tree[0]->ptr = heap->freenodes;
heap->freenodes = heap->tree[0];

@ -35,6 +35,14 @@
#include "BLI_memarena.h"
#include "BLI_linklist.h"
#ifdef __GNUC__
# pragma GCC diagnostic error "-Wsign-conversion"
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 /* gcc4.6+ only */
# pragma GCC diagnostic error "-Wsign-compare"
# pragma GCC diagnostic error "-Wconversion"
# endif
#endif
struct MemArena {
unsigned char *curbuf;
int bufsize, cursize;
@ -79,7 +87,7 @@ void BLI_memarena_free(MemArena *ma)
}
/* amt must be power of two */
#define PADUP(num, amt) ((num + (amt - 1)) & ~(amt - 1))
#define PADUP(num, amt) (((num) + ((amt) - 1)) & ~((amt) - 1))
void *BLI_memarena_alloc(MemArena *ma, int size)
{
@ -99,15 +107,15 @@ void *BLI_memarena_alloc(MemArena *ma, int size)
ma->cursize = ma->bufsize;
if (ma->use_calloc)
ma->curbuf = MEM_callocN(ma->cursize, ma->name);
ma->curbuf = MEM_callocN((size_t)ma->cursize, ma->name);
else
ma->curbuf = MEM_mallocN(ma->cursize, ma->name);
ma->curbuf = MEM_mallocN((size_t)ma->cursize, ma->name);
BLI_linklist_prepend(&ma->bufs, ma->curbuf);
/* align alloc'ed memory (needed if align > 8) */
tmp = (unsigned char *)PADUP( (intptr_t) ma->curbuf, ma->align);
ma->cursize -= (tmp - ma->curbuf);
ma->cursize -= (int)(tmp - ma->curbuf);
ma->curbuf = tmp;
}
@ -117,4 +125,3 @@ void *BLI_memarena_alloc(MemArena *ma, int size)
return ptr;
}

@ -45,6 +45,10 @@
#ifdef __GNUC__
# pragma GCC diagnostic error "-Wsign-conversion"
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 /* gcc4.6+ only */
# pragma GCC diagnostic error "-Wsign-compare"
# pragma GCC diagnostic error "-Wconversion"
# endif
#endif
/* note: copied from BLO_blend_defs.h, don't use here because we're in BLI */
@ -102,8 +106,8 @@ BLI_mempool *BLI_mempool_create(int esize, int totelem, int pchunk, int flag)
}
/* set the elem size */
if (esize < MEMPOOL_ELEM_SIZE_MIN) {
esize = MEMPOOL_ELEM_SIZE_MIN;
if (esize < (int)MEMPOOL_ELEM_SIZE_MIN) {
esize = (int)MEMPOOL_ELEM_SIZE_MIN;
}
if (flag & BLI_MEMPOOL_ALLOW_ITER) {

@ -28,6 +28,8 @@
/** \file blender/blenlib/intern/edgehash.c
* \ingroup bli
*
* \note Based on 'BLI_ghash.c', make sure these stay in sync.
*/
@ -42,8 +44,11 @@
#include "BLI_mempool.h"
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wstrict-overflow"
# pragma GCC diagnostic error "-Wsign-conversion"
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 /* gcc4.6+ only */
# pragma GCC diagnostic error "-Wsign-compare"
# pragma GCC diagnostic error "-Wconversion"
# endif
#endif
/**************inlined code************/
@ -107,29 +112,27 @@ void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *v
hash = EDGE_HASH(v0, v1) % eh->nbuckets;
e->next = eh->buckets[hash];
e->v0 = v0;
e->v1 = v1;
e->val = val;
e->next = eh->buckets[hash];
eh->buckets[hash] = e;
if (++eh->nentries > eh->nbuckets * 3) {
if (UNLIKELY(++eh->nentries > eh->nbuckets / 2)) {
EdgeEntry **old = eh->buckets;
unsigned int i, nold = eh->nbuckets;
const unsigned int nold = eh->nbuckets;
unsigned int i;
eh->nbuckets = _ehash_hashsizes[++eh->cursize];
eh->buckets = MEM_mallocN(eh->nbuckets * sizeof(*eh->buckets), "eh buckets");
memset(eh->buckets, 0, eh->nbuckets * sizeof(*eh->buckets));
eh->buckets = MEM_callocN(eh->nbuckets * sizeof(*eh->buckets), "eh buckets");
for (i = 0; i < nold; i++) {
for (e = old[i]; e; ) {
EdgeEntry *n = e->next;
EdgeEntry *e_next;
for (e = old[i]; e; e = e_next) {
e_next = e->next;
hash = EDGE_HASH(e->v0, e->v1) % eh->nbuckets;
e->next = eh->buckets[hash];
eh->buckets[hash] = e;
e = n;
}
}
@ -265,4 +268,3 @@ bool BLI_edgehashIterator_isDone(EdgeHashIterator *ehi)
{
return (ehi->curEntry == NULL);
}

@ -3110,7 +3110,7 @@ void accumulate_vertex_normals(float n1[3], float n2[3], float n3[3],
/* Add weighted face normal component into normals of the face vertices.
* Caller must pass pre-allocated vdiffs of nverts length. */
void accumulate_vertex_normals_poly(float **vertnos, const float polyno[3],
const float **vertcos, float vdiffs[][3], int nverts)
const float **vertcos, float vdiffs[][3], const int nverts)
{
int i;

@ -861,35 +861,6 @@ void single_axis_angle_to_mat3(float mat[3][3], const char axis, const float ang
}
}
/****************************** Vector/Rotation ******************************/
/* TODO: the following calls should probably be deprecated sometime */
/* TODO, replace use of this function with axis_angle_to_mat3() */
void vec_rot_to_mat3(float mat[3][3], const float vec[3], const float phi)
{
/* rotation of phi radials around vec */
float vx, vx2, vy, vy2, vz, vz2, co, si;
vx = vec[0];
vy = vec[1];
vz = vec[2];
vx2 = vx * vx;
vy2 = vy * vy;
vz2 = vz * vz;
co = cosf(phi);
si = sinf(phi);
mat[0][0] = vx2 + co * (1.0f - vx2);
mat[0][1] = vx * vy * (1.0f - co) + vz * si;
mat[0][2] = vz * vx * (1.0f - co) - vy * si;
mat[1][0] = vx * vy * (1.0f - co) - vz * si;
mat[1][1] = vy2 + co * (1.0f - vy2);
mat[1][2] = vy * vz * (1.0f - co) + vx * si;
mat[2][0] = vz * vx * (1.0f - co) + vy * si;
mat[2][1] = vy * vz * (1.0f - co) - vx * si;
mat[2][2] = vz2 + co * (1.0f - vz2);
}
/******************************** XYZ Eulers *********************************/
/* XYZ order */

@ -44,8 +44,11 @@
#define SMHASH_CELL_FREE ((void *)0x7FFFFFFD)
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wstrict-overflow"
# pragma GCC diagnostic error "-Wsign-conversion"
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 /* gcc4.6+ only */
# pragma GCC diagnostic error "-Wsign-compare"
# pragma GCC diagnostic error "-Wconversion"
# endif
#endif
/* typically this re-assigns 'h' */
@ -59,7 +62,7 @@ extern unsigned int hashsizes[];
void BLI_smallhash_init(SmallHash *hash)
{
int i;
unsigned int i;
memset(hash, 0, sizeof(*hash));
@ -90,7 +93,7 @@ void BLI_smallhash_insert(SmallHash *hash, uintptr_t key, void *item)
if (hash->size < hash->used * 3) {
unsigned int newsize = hashsizes[++hash->curhash];
SmallHashEntry *tmp;
int i = 0;
unsigned int i = 0;
if (hash->table != hash->stacktable || newsize > SMSTACKSIZE) {
tmp = MEM_callocN(sizeof(*hash->table) * newsize, __func__);

@ -556,7 +556,7 @@ void BLI_timestr(double _time, char *str, size_t maxlen)
}
/* determine the length of a fixed-size string */
size_t BLI_strnlen(const char *s, size_t maxlen)
size_t BLI_strnlen(const char *s, const size_t maxlen)
{
size_t len;

@ -41,7 +41,7 @@
#define WIN32_SKIP_HKEY_PROTECTION // need to use HKEY
#include "BLI_winstuff.h"
#include "BLI_utildefines.h"z
#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_string.h"

@ -43,6 +43,7 @@ set(SRC
operators/bmo_bevel.c
operators/bmo_bridge.c
operators/bmo_connect.c
operators/bmo_connect_pair.c
operators/bmo_create.c
operators/bmo_dissolve.c
operators/bmo_dupe.c

@ -840,6 +840,26 @@ static BMOpDefine bmo_connect_verts_def = {
BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
};
/*
* Connect Verts.
*
* Split faces by adding edges that connect **verts**.
*/
static BMOpDefine bmo_connect_vert_pair_def = {
"connect_vert_pair",
/* slots_in */
{{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
{{'\0'}},
},
/* slots_out */
{{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
{{'\0'}},
},
bmo_connect_vert_pair_exec,
BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
};
/*
* Extrude Faces.
*
@ -1685,6 +1705,7 @@ const BMOpDefine *bmo_opdefines[] = {
&bmo_collapse_def,
&bmo_collapse_uvs_def,
&bmo_connect_verts_def,
&bmo_connect_vert_pair_def,
&bmo_contextual_create_def,
#ifdef WITH_BULLET
&bmo_convex_hull_def,

@ -40,6 +40,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op);
void bmo_collapse_exec(BMesh *bm, BMOperator *op);
void bmo_collapse_uvs_exec(BMesh *bm, BMOperator *op);
void bmo_connect_verts_exec(BMesh *bm, BMOperator *op);
void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op);
void bmo_contextual_create_exec(BMesh *bm, BMOperator *op);
void bmo_convex_hull_exec(BMesh *bm, BMOperator *op);
void bmo_create_circle_exec(BMesh *bm, BMOperator *op);

@ -23,7 +23,7 @@
/** \file blender/bmesh/operators/bmo_connect.c
* \ingroup bmesh
*
* Connect verts across faces (splits faces) and bridge tool.
* Connect verts across faces (splits faces).
*/
#include "MEM_guardedalloc.h"

@ -0,0 +1,548 @@
/*
* ***** 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.
*
* Contributor(s): Campbell Barton.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/bmesh/operators/bmo_connect_pair.c
* \ingroup bmesh
*
* Connect vertex pair across multiple faces (splits faces).
*/
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "bmesh.h"
#include "intern/bmesh_operators_private.h" /* own include */
#include "BLI_mempool.h"
#include "BLI_listbase.h"
/**
* Method for connecting across many faces.
*
* - use the line between both verts and their normal average to construct a matrix.
* - using the matrix, we can find all intersecting verts/edges and build connection data.
* - then walk the connected data and find the shortest path (as we do with other shortest-path functions).
* - if the connection can't be found - fail.
* - with the connection found, split all edges tagging verts (or tag verts that sit on the intersection).
* - run the standard connect operator.
*/
#define CONNECT_EPS 0.0001f
#define VERT_OUT 1
// #define DEBUG_PRINT
typedef struct PathContext {
ListBase state_lb;
float matrix[3][3];
float axis_sep;
BMVert *v_a, *v_b;
BLI_mempool *link_pool;
} PathContext;
/**
* Single linked list where each item contains state and points to previous path item.
*/
typedef struct PathLink {
struct PathLink *next;
BMElem *ele; /* edge or vert */
BMElem *ele_from; /* edge or face we game from (not 'next->ele') */
} PathLink;
typedef struct PathLinkState {
struct PathLinkState *next, *prev;
/* chain of links */
struct PathLink *link_last;
/* length along links */
float dist;
float co_prev[3];
} PathLinkState;
/* only the x axis */
static float mul_v1_m3v3(float M[3][3], const float a[3])
{
return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
}
static int state_isect_co_pair(const PathContext *pc,
const float co_a[3], const float co_b[3])
{
const float diff_a = mul_v1_m3v3((float (*)[3])pc->matrix, co_a) - pc->axis_sep;
const float diff_b = mul_v1_m3v3((float (*)[3])pc->matrix, co_b) - pc->axis_sep;
const int test_a = (fabsf(diff_a) < CONNECT_EPS) ? 0 : (diff_a < 0.0f) ? -1 : 1;
const int test_b = (fabsf(diff_b) < CONNECT_EPS) ? 0 : (diff_b < 0.0f) ? -1 : 1;
if ((test_a && test_b) && (test_a != test_b)) {
return 1; /* on either side */
}
else {
return 0;
}
}
static int state_isect_co_exact(const PathContext *pc,
const float co[3])
{
const float diff = mul_v1_m3v3((float (*)[3])pc->matrix, co) - pc->axis_sep;
return (fabsf(diff) <= CONNECT_EPS);
}
static float state_calc_co_pair_fac(const PathContext *pc,
const float co_a[3], const float co_b[3])
{
float diff_a, diff_b, diff_tot;
diff_a = fabsf(mul_v1_m3v3((float (*)[3])pc->matrix, co_a) - pc->axis_sep);
diff_b = fabsf(mul_v1_m3v3((float (*)[3])pc->matrix, co_b) - pc->axis_sep);
diff_tot = (diff_a + diff_b);
return (diff_tot > FLT_EPSILON) ? (diff_a / diff_tot) : 0.5f;
}
static void state_calc_co_pair(const PathContext *pc,
const float co_a[3], const float co_b[3],
float r_co[3])
{
const float fac = state_calc_co_pair_fac(pc, co_a, co_b);
interp_v3_v3v3(r_co, co_a, co_b, fac);
}
/**
* Ideally we wouldn't need this and for most cases we don't.
* But when a face has vertices that are on the boundary more then once this becomes tricky.
*/
static bool state_link_find(PathLinkState *state, BMElem *ele)
{
PathLink *link = state->link_last;
BLI_assert(ELEM3(ele->head.htype, BM_VERT, BM_EDGE, BM_FACE));
if (link) {
do {
if (link->ele == ele) {
return true;
}
} while ((link = link->next));
}
return false;
}
static void state_link_add(PathContext *pc, PathLinkState *state,
BMElem *ele, BMElem *ele_from)
{
PathLink *step_new = BLI_mempool_alloc(pc->link_pool);
BLI_assert(ele != ele_from);
BLI_assert(state_link_find(state, ele) == false);
#ifdef DEBUG_PRINT
printf("%s: adding to state %p:%d, %.4f - ", __func__, state, BLI_findindex(&pc->state_lb, state), state->dist);
if (ele->head.htype == BM_VERT) {
printf("vert %d, ", BM_elem_index_get(ele));
}
else if (ele->head.htype == BM_EDGE) {
printf("edge %d, ", BM_elem_index_get(ele));
}
else {
BLI_assert(0);
}
if (ele_from == NULL) {
printf("from NULL\n");
}
else if (ele_from->head.htype == BM_EDGE) {
printf("from edge %d\n", BM_elem_index_get(ele_from));
}
else if (ele_from->head.htype == BM_FACE) {
printf("from face %d\n", BM_elem_index_get(ele_from));
}
else {
BLI_assert(0);
}
#endif
/* track distance */
{
float co[3];
if (ele->head.htype == BM_VERT) {
copy_v3_v3(co, ((BMVert *)ele)->co);
}
else if (ele->head.htype == BM_EDGE) {
state_calc_co_pair(pc, ((BMEdge *)ele)->v1->co, ((BMEdge *)ele)->v2->co, co);
}
else {
BLI_assert(0);
}
/* tally distance */
if (ele_from) {
state->dist += len_v3v3(state->co_prev, co);
}
copy_v3_v3(state->co_prev, co);
}
step_new->ele = ele;
step_new->ele_from = ele_from;
step_new->next = state->link_last;
state->link_last = step_new;
}
static PathLinkState *state_dupe_add(PathContext *pc,
PathLinkState *state, const PathLinkState *state_orig)
{
state = MEM_mallocN(sizeof(*state), __func__);
*state = *state_orig;
BLI_addhead(&pc->state_lb, state);
return state;
}
/* walk around the face edges */
static PathLinkState *state_step__face_edges(PathContext *pc,
PathLinkState *state, const PathLinkState *state_orig,
BMLoop *l_iter, BMLoop *l_last)
{
do {
if (state_isect_co_pair(pc, l_iter->v->co, l_iter->next->v->co)) {
BMElem *ele_next = (BMElem *)l_iter->e;
BMElem *ele_next_from = (BMElem *)l_iter->f;
if (state_link_find(state, ele_next) == false) {
if (state_orig->link_last != state->link_last) {
state = state_dupe_add(pc, state, state_orig);
}
state_link_add(pc, state, ele_next, ele_next_from);
}
}
} while ((l_iter = l_iter->next) != l_last);
return state;
}
/* walk around the face verts */
static PathLinkState *state_step__face_verts(PathContext *pc,
PathLinkState *state, const PathLinkState *state_orig,
BMLoop *l_iter, BMLoop *l_last)
{
do {
if (state_isect_co_exact(pc, l_iter->v->co)) {
BMElem *ele_next = (BMElem *)l_iter->v;
BMElem *ele_next_from = (BMElem *)l_iter->f;
if (state_link_find(state, ele_next) == false) {
if (state_orig->link_last != state->link_last) {
state = state_dupe_add(pc, state, state_orig);
}
state_link_add(pc, state, ele_next, ele_next_from);
}
}
} while ((l_iter = l_iter->next) != l_last);
return state;
}
static bool state_step(PathContext *pc, PathLinkState *state)
{
PathLinkState state_orig = *state;
BMElem *ele = state->link_last->ele;
const void *ele_from = state->link_last->ele_from;
if (ele->head.htype == BM_EDGE) {
BMEdge *e = (BMEdge *)ele;
BMIter liter;
BMLoop *l_start;
BM_ITER_ELEM (l_start, &liter, e, BM_LOOPS_OF_EDGE) {
if (l_start->f != ele_from) {
/* very similar to block below */
if (BM_vert_in_face(l_start->f, pc->v_b)) {
if (state_orig.link_last != state->link_last) {
state = state_dupe_add(pc, state, &state_orig);
}
state_link_add(pc, state, (BMElem *)pc->v_b, (BMElem *)l_start->f);
}
else {
state = state_step__face_edges(pc, state, &state_orig,
l_start->next, l_start);
state = state_step__face_verts(pc, state, &state_orig,
l_start->next->next, l_start);
}
}
}
}
else if (ele->head.htype == BM_VERT) {
BMVert *v = (BMVert *)ele;
/* vert loops */
{
BMIter liter;
BMLoop *l_start;
BM_ITER_ELEM (l_start, &liter, v, BM_LOOPS_OF_VERT) {
if (l_start->f != ele_from) {
/* very similar to block above */
if (BM_vert_in_face(l_start->f, pc->v_b)) {
BMElem *ele_next = (BMElem *)pc->v_b;
BMElem *ele_next_from = (BMElem *)l_start->f;
if (state_orig.link_last != state->link_last) {
state = state_dupe_add(pc, state, &state_orig);
}
state_link_add(pc, state, ele_next, ele_next_from);
}
else {
state = state_step__face_edges(pc, state, &state_orig,
l_start->next, l_start->prev);
if (l_start->f->len > 3) {
/* adjacent verts are handled in state_step__vert_edges */
state = state_step__face_verts(pc, state, &state_orig,
l_start->next->next, l_start->prev);
}
}
}
}
}
/* vert edges */
{
BMIter eiter;
BMEdge *e;
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
if ((BMElem *)e != ele_from) {
BMVert *v_other = BM_edge_other_vert(e, v);
if (v_other == pc->v_b) {
BMElem *ele_next = (BMElem *)pc->v_b;
BMElem *ele_next_from = (BMElem *)e;
if (state_orig.link_last != state->link_last) {
state = state_dupe_add(pc, state, &state_orig);
}
state_link_add(pc, state, ele_next, ele_next_from);
}
else {
if (state_isect_co_exact(pc, v_other->co)) {
BMElem *ele_next = (BMElem *)v_other;
BMElem *ele_next_from = (BMElem *)e;
if (state_link_find(state, ele_next) == false) {
if (state_orig.link_last != state->link_last) {
state = state_dupe_add(pc, state, &state_orig);
}
state_link_add(pc, state, ele_next, ele_next_from);
}
}
}
}
}
}
}
else {
BLI_assert(0);
}
return (state_orig.link_last != state->link_last);
}
void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op)
{
BMOpSlot *op_verts_slot = BMO_slot_get(op->slots_in, "verts");
PathContext pc;
bool found_all;
float found_dist_best = -1.0f;
if (op_verts_slot->len != 2) {
/* fail! */
return;
}
pc.v_a = ((BMVert **)op_verts_slot->data.p)[0];
pc.v_b = ((BMVert **)op_verts_slot->data.p)[1];
/* fail! */
if (!(pc.v_a && pc.v_a)) {
return;
}
#ifdef DEBUG_PRINT
printf("%s: v_a: %d\n", __func__, BM_elem_index_get(pc.v_a));
printf("%s: v_b: %d\n", __func__, BM_elem_index_get(pc.v_b));
#endif
/* setup context */
{
pc.state_lb.first = NULL;
pc.state_lb.last = NULL;
pc.link_pool = BLI_mempool_create(sizeof(PathLink), 1, 512, BLI_MEMPOOL_SYSMALLOC);
}
/* calculate matrix */
{
float basis_dir[3];
float basis_tmp[3];
float basis_nor[3];
sub_v3_v3v3(basis_dir, pc.v_a->co, pc.v_b->co);
#if 0
add_v3_v3v3(basis_nor, pc.v_a->no, pc.v_b->no);
cross_v3_v3v3(basis_tmp, basis_nor, basis_dir);
cross_v3_v3v3(basis_nor, basis_tmp, basis_dir);
#else
/* align both normals to the directions before combining */
{
float basis_nor_a[3];
float basis_nor_b[3];
/* align normal to direction */
cross_v3_v3v3(basis_tmp, pc.v_a->no, basis_dir);
cross_v3_v3v3(basis_nor_a, basis_tmp, basis_dir);
cross_v3_v3v3(basis_tmp, pc.v_b->no, basis_dir);
cross_v3_v3v3(basis_nor_b, basis_tmp, basis_dir);
/* combine the normals */
normalize_v3(basis_nor_a);
normalize_v3(basis_nor_b);
/* for flipped faces */
if (dot_v3v3(basis_nor_a, basis_nor_b) < 0.0f) {
negate_v3(basis_nor_b);
}
add_v3_v3v3(basis_nor, basis_nor_a, basis_nor_b);
}
#endif
/* get third axis */
cross_v3_v3v3(basis_tmp, basis_dir, basis_nor);
normalize_v3_v3(pc.matrix[0], basis_tmp);
normalize_v3_v3(pc.matrix[1], basis_dir);
normalize_v3_v3(pc.matrix[2], basis_nor);
invert_m3(pc.matrix);
pc.axis_sep = mul_v1_m3v3(pc.matrix, pc.v_a->co);
}
/* add first vertex */
{
PathLinkState *state;
state = MEM_callocN(sizeof(*state), __func__);
BLI_addtail(&pc.state_lb, state);
state_link_add(&pc, state, (BMElem *)pc.v_a, NULL);
}
found_all = false;
while (pc.state_lb.first) {
PathLinkState *state, *state_next;
found_all = true;
for (state = pc.state_lb.first; state; state = state_next) {
state_next = state->next;
if (state->link_last->ele == (BMElem *)pc.v_b) {
/* pass, wait until all are found */
#ifdef DEBUG_PRINT
printf("%s: state %p loop found %.4f\n", __func__, state, state->dist);
#endif
if ((found_dist_best == -1.0f) || (found_dist_best > state->dist)) {
found_dist_best = state->dist;
}
}
else if (state_step(&pc, state)) {
if ((found_dist_best != -1.0f) && (found_dist_best <= state->dist)) {
BLI_remlink(&pc.state_lb, state);
MEM_freeN(state);
}
else {
found_all = false;
}
}
else {
/* didn't reach the end, remove it,
* links are shared between states so just free the link_pool at the end */
BLI_remlink(&pc.state_lb, state);
MEM_freeN(state);
}
}
if (found_all) {
break;
}
}
if (pc.state_lb.first == NULL) {
found_all = false;
}
if (found_all) {
PathLinkState *state, *state_best = NULL;
PathLink *link;
float state_best_dist = FLT_MAX;
/* find the best state */
for (state = pc.state_lb.first; state; state = state->next) {
if ((state_best == NULL) || (state->dist < state_best_dist)) {
state_best = state;
state_best_dist = state_best->dist;
}
}
link = state_best->link_last;
do {
if (link->ele->head.htype == BM_EDGE) {
BMEdge *e = (BMEdge *)link->ele;
BMVert *v_new;
float e_fac = state_calc_co_pair_fac(&pc, e->v1->co, e->v2->co);
v_new = BM_edge_split(bm, e, e->v1, NULL, e_fac);
BMO_elem_flag_enable(bm, v_new, VERT_OUT);
}
else if (link->ele->head.htype == BM_VERT) {
BMVert *v = (BMVert *)link->ele;
BMO_elem_flag_enable(bm, v, VERT_OUT);
}
else {
BLI_assert(0);
}
} while ((link = link->next));
}
BMO_elem_flag_enable(bm, pc.v_a, VERT_OUT);
BMO_elem_flag_enable(bm, pc.v_b, VERT_OUT);
BLI_mempool_destroy(pc.link_pool);
BLI_freelistN(&pc.state_lb);
#if 1
if (found_all) {
BMOperator op_sub;
BMO_op_initf(bm, &op_sub, 0,
"connect_verts verts=%fv", VERT_OUT);
BMO_op_exec(bm, &op_sub);
BMO_slot_copy(&op_sub, slots_out, "edges.out",
op, slots_out, "edges.out");
BMO_op_finish(bm, &op_sub);
}
#endif
}

@ -76,9 +76,11 @@ struct MeshStatVis;
/* editmesh_utils.c */
void EDBM_verts_mirror_cache_begin_ex(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 bool use_self, const bool use_select);
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);
@ -248,6 +250,7 @@ bool ED_vgroup_object_is_edit_mode(struct Object *ob);
void ED_vgroup_vert_add(struct Object *ob, struct bDeformGroup *dg, int vertnum, float weight, int assignmode);
void ED_vgroup_vert_remove(struct Object *ob, struct bDeformGroup *dg, int vertnum);
float ED_vgroup_vert_weight(struct Object *ob, struct bDeformGroup *dg, int vertnum);
void ED_vgroup_vert_active_mirror(struct Object *ob, int def_nr);
/* mesh_data.c */

@ -65,6 +65,11 @@ struct wmKeyConfig;
struct wmKeyMap;
struct wmOperator;
struct wmOperatorType;
struct PointerRNA;
struct PropertyRNA;
struct EnumPropertyItem;
enum eVGroupSelect;
/* object_edit.c */
struct Object *ED_object_context(struct bContext *C); /* context.object */
@ -200,21 +205,16 @@ int ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v);
/* object_select.c */
void ED_object_select_linked_by_id(struct bContext *C, struct ID *id);
/* object_vgroup.c */
typedef enum eVGroupSelect {
WT_VGROUP_ACTIVE = 1,
WT_VGROUP_BONE_SELECT = 2,
WT_VGROUP_BONE_DEFORM = 3,
WT_VGROUP_ALL = 4,
} eVGroupSelect;
#define WT_VGROUP_MASK_ALL \
((1 << WT_VGROUP_ACTIVE) | \
(1 << WT_VGROUP_BONE_SELECT) | \
(1 << WT_VGROUP_BONE_DEFORM) | \
(1 << WT_VGROUP_ALL))
bool *ED_vgroup_subset_from_select_type(struct Object *ob, enum eVGroupSelect subset_type,
int *r_vgroup_tot, int *r_subset_count);
bool *ED_vgroup_subset_from_select_type(struct Object *ob, eVGroupSelect subset_type, int *r_vgroup_tot, int *r_subset_count);
struct EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(
const struct bContext *C,
struct PointerRNA *ptr,
struct PropertyRNA *prop,
int *free,
const unsigned int selection_mask);
#ifdef __cplusplus
}

@ -1074,6 +1074,7 @@ static int mask_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
BKE_mask_update_display(mask, CFRA);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
return OPERATOR_FINISHED;
}
@ -1140,6 +1141,7 @@ static int mask_normals_make_consistent_exec(bContext *C, wmOperator *UNUSED(op)
BKE_mask_update_display(mask, CFRA);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
return OPERATOR_FINISHED;
}
@ -1172,6 +1174,8 @@ static int set_handle_type_exec(bContext *C, wmOperator *op)
MaskLayer *masklay;
int handle_type = RNA_enum_get(op->ptr, "type");
bool change = false;
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
MaskSpline *spline;
int i;
@ -1188,15 +1192,19 @@ static int set_handle_type_exec(bContext *C, wmOperator *op)
BezTriple *bezt = &point->bezt;
bezt->h1 = bezt->h2 = handle_type;
change = true;
}
}
}
}
WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
DAG_id_tag_update(&mask->id, 0);
if (change) {
WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
DAG_id_tag_update(&mask->id, 0);
return OPERATOR_FINISHED;
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
}
void MASK_OT_handle_type_set(wmOperatorType *ot)

@ -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);

@ -778,13 +778,30 @@ static int edbm_vert_connect(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
BMOperator bmop;
int len = 0;
const bool is_pair = (bm->totvertsel == 2);
int len;
if (!EDBM_op_init(em, &bmop, op, "connect_verts verts=%hv", BM_ELEM_SELECT)) {
return OPERATOR_CANCELLED;
if (is_pair) {
if (!EDBM_op_init(em, &bmop, op, "connect_vert_pair verts=%hv", BM_ELEM_SELECT)) {
return OPERATOR_CANCELLED;
}
}
else {
if (!EDBM_op_init(em, &bmop, op, "connect_verts verts=%hv", BM_ELEM_SELECT)) {
return OPERATOR_CANCELLED;
}
}
BMO_op_exec(bm, &bmop);
len = BMO_slot_get(bmop.slots_out, "edges.out")->len;
if (len) {
if (is_pair) {
/* new verts have been added, we have to select the edges, not just flush */
BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
}
}
if (!EDBM_op_finish(em, &bmop, op, true)) {
return OPERATOR_CANCELLED;
}
@ -1121,7 +1138,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 +1229,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 +4275,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)

@ -1155,7 +1155,7 @@ static BMVert *cache_mirr_intptr_as_bmvert(intptr_t *index_lookup, int index)
* \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 bool use_self, const bool use_select,
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)
{
@ -1212,7 +1212,9 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const bool use_self, const
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]};
float co[3];
copy_v3_v3(co, v->co);
co[axis] *= -1.0f;
v_mirr = BKE_bmbvh_find_vert_closest(tree, co, maxdist);
}
@ -1239,14 +1241,16 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const bool use_self, const
}
}
void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bool use_select)
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, use_self, use_select,
EDBM_verts_mirror_cache_begin_ex(em, axis,
use_self, use_select,
/* extra args */
is_topo, BM_SEARCH_MAXDIST_MIRR, NULL);
}

@ -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);

@ -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);

@ -223,6 +223,11 @@ void OBJECT_OT_vertex_group_mirror(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_sort(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_move(struct wmOperatorType *ot);
void OBJECT_OT_vertex_weight_paste(struct wmOperatorType *ot);
void OBJECT_OT_vertex_weight_delete(struct wmOperatorType *ot);
void OBJECT_OT_vertex_weight_set_active(struct wmOperatorType *ot);
void OBJECT_OT_vertex_weight_normalize_active(struct wmOperatorType *ot);
void OBJECT_OT_vertex_weight_copy(struct wmOperatorType *ot);
/* object_shapekey.c */
void OBJECT_OT_shape_key_add(struct wmOperatorType *ot);

@ -195,6 +195,11 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_group_set_active);
WM_operatortype_append(OBJECT_OT_vertex_group_sort);
WM_operatortype_append(OBJECT_OT_vertex_group_move);
WM_operatortype_append(OBJECT_OT_vertex_weight_paste);
WM_operatortype_append(OBJECT_OT_vertex_weight_delete);
WM_operatortype_append(OBJECT_OT_vertex_weight_set_active);
WM_operatortype_append(OBJECT_OT_vertex_weight_normalize_active);
WM_operatortype_append(OBJECT_OT_vertex_weight_copy);
WM_operatortype_append(OBJECT_OT_game_property_new);
WM_operatortype_append(OBJECT_OT_game_property_remove);

@ -411,6 +411,239 @@ bool ED_vgroup_copy_array(Object *ob, Object *ob_from)
return true;
}
static MDeformVert *ED_mesh_active_dvert_get_em(Object *ob, BMVert **r_eve)
{
if (ob->mode & OB_MODE_EDIT && ob->type == OB_MESH && ob->defbase.first) {
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
if (cd_dvert_offset != -1) {
BMEditSelection *ese = (BMEditSelection *)em->bm->selected.last;
if (ese && ese->htype == BM_VERT) {
BMVert *eve = (BMVert *)ese->ele;
if (r_eve) *r_eve = eve;
return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
}
}
}
if (r_eve) *r_eve = NULL;
return NULL;
}
/* TODO, cache flip data to speedup calls within a loop. */
static void mesh_defvert_mirror_update_internal(Object *ob,
MDeformVert *dvert_dst, MDeformVert *dvert_src,
const int def_nr)
{
if (def_nr == -1) {
/* all vgroups, add groups where neded */
int flip_map_len;
int *flip_map = defgroup_flip_map(ob, &flip_map_len, true);
defvert_sync_mapped(dvert_dst, dvert_src, flip_map, flip_map_len, true);
MEM_freeN(flip_map);
}
else {
/* single vgroup */
MDeformWeight *dw = defvert_verify_index(dvert_dst, defgroup_flip_index(ob, def_nr, 1));
if (dw) {
dw->weight = defvert_find_weight(dvert_src, def_nr);
}
}
}
static MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index)
{
Mesh *me = ob->data;
int index = BKE_mesh_mselect_active_get(me, ME_VSEL);
if (r_index) *r_index = index;
if (index == -1 || me->dvert == NULL) {
return NULL;
}
else {
return me->dvert + index;
}
}
static void ED_mesh_defvert_mirror_update_em(Object *ob, BMVert *eve, int def_nr, int vidx,
const int cd_dvert_offset)
{
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
BMVert *eve_mirr;
eve_mirr = editbmesh_get_x_mirror_vert(ob, em, eve, eve->co, vidx);
if (eve_mirr && eve_mirr != eve) {
MDeformVert *dvert_src = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
MDeformVert *dvert_dst = BM_ELEM_CD_GET_VOID_P(eve_mirr, cd_dvert_offset);
mesh_defvert_mirror_update_internal(ob, dvert_dst, dvert_src, def_nr);
}
}
static void ED_mesh_defvert_mirror_update_ob(Object *ob, int def_nr, int vidx)
{
int vidx_mirr;
Mesh *me = ob->data;
if (vidx == -1)
return;
vidx_mirr = mesh_get_x_mirror_vert(ob, vidx);
if ((vidx_mirr) >= 0 && (vidx_mirr != vidx)) {
MDeformVert *dvert_src = &me->dvert[vidx];
MDeformVert *dvert_dst = &me->dvert[vidx_mirr];
mesh_defvert_mirror_update_internal(ob, dvert_dst, dvert_src, def_nr);
}
}
static MDeformVert *ED_mesh_active_dvert_get_only(Object *ob)
{
if (ob->type == OB_MESH) {
if (ob->mode & OB_MODE_EDIT) {
return ED_mesh_active_dvert_get_em(ob, NULL);
}
else {
return ED_mesh_active_dvert_get_ob(ob, NULL);
}
}
else {
return NULL;
}
}
/**
* Use when adjusting the active vertex weight and apply to mirror vertices.
*/
void ED_vgroup_vert_active_mirror(Object *ob, int def_nr)
{
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
MDeformVert *dvert_act;
if (me->editflag & ME_EDIT_MIRROR_X) {
if (em) {
BMVert *eve_act;
dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
if (dvert_act) {
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
ED_mesh_defvert_mirror_update_em(ob, eve_act, def_nr, -1, cd_dvert_offset);
}
}
else {
int v_act;
dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
if (dvert_act) {
ED_mesh_defvert_mirror_update_ob(ob, def_nr, v_act);
}
}
}
}
static void vgroup_remove_weight(Object *ob, const int def_nr)
{
MDeformVert *dvert_act;
MDeformWeight *dw;
dvert_act = ED_mesh_active_dvert_get_only(ob);
dw = defvert_find_index(dvert_act, def_nr);
defvert_remove_group(dvert_act, dw);
}
static void vgroup_normalize_active(Object *ob, eVGroupSelect subset_type)
{
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
BMVert *eve_act;
int v_act;
MDeformVert *dvert_act;
int subset_count, vgroup_tot;
const bool *vgroup_validmap;
if (em) {
dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
}
else {
dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
}
if (dvert_act == NULL) {
return;
}
vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
defvert_normalize_subset(dvert_act, vgroup_validmap, vgroup_tot);
MEM_freeN((void *)vgroup_validmap);
if (me->editflag & ME_EDIT_MIRROR_X) {
if (em) {
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
ED_mesh_defvert_mirror_update_em(ob, eve_act, -1, -1, cd_dvert_offset);
}
else {
int v_act = BKE_mesh_mselect_active_get(me, ME_VSEL);
ED_mesh_defvert_mirror_update_ob(ob, -1, v_act);
}
}
}
static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type)
{
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
MDeformVert *dvert_act;
int i, vgroup_tot, subset_count;
const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
if (em) {
BMIter iter;
BMVert *eve, *eve_act;
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
if (dvert_act == NULL) {
return;
}
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && eve != eve_act) {
MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
defvert_copy_subset(dv, dvert_act, vgroup_validmap, vgroup_tot);
if (me->editflag & ME_EDIT_MIRROR_X) {
ED_mesh_defvert_mirror_update_em(ob, eve, -1, i, cd_dvert_offset);
}
}
}
}
else {
MDeformVert *dv;
int v_act;
dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
if (dvert_act == NULL) {
return;
}
dv = me->dvert;
for (i = 0; i < me->totvert; i++, dv++) {
if ((me->mvert[i].flag & SELECT) && dv != dvert_act) {
defvert_copy_subset(dv, dvert_act, vgroup_validmap, vgroup_tot);
if (me->editflag & ME_EDIT_MIRROR_X) {
ED_mesh_defvert_mirror_update_ob(ob, -1, i);
}
}
}
}
MEM_freeN((void *)vgroup_validmap);
}
/***********************Start weight transfer (WT)*********************************/
typedef enum WT_VertexGroupMode {
@ -470,8 +703,8 @@ static EnumPropertyItem WT_vertex_group_select_item[] = {
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem *rna_vertex_group_selection_itemf_helper(
bContext *C, PointerRNA *UNUSED(ptr),
EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(
const bContext *C, PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop), int *free, const unsigned int selection_mask)
{
Object *ob;
@ -505,13 +738,13 @@ static EnumPropertyItem *rna_vertex_group_selection_itemf_helper(
static EnumPropertyItem *rna_vertex_group_with_single_itemf(bContext *C, PointerRNA *ptr,
PropertyRNA *prop, int *free)
{
return rna_vertex_group_selection_itemf_helper(C, ptr, prop, free, WT_VGROUP_MASK_ALL);
return ED_object_vgroup_selection_itemf_helper(C, ptr, prop, free, WT_VGROUP_MASK_ALL);
}
static EnumPropertyItem *rna_vertex_group_select_itemf(bContext *C, PointerRNA *ptr,
PropertyRNA *prop, int *free)
{
return rna_vertex_group_selection_itemf_helper(C, ptr, prop, free, WT_VGROUP_MASK_ALL & ~(1 << WT_VGROUP_ACTIVE));
return ED_object_vgroup_selection_itemf_helper(C, ptr, prop, free, WT_VGROUP_MASK_ALL & ~(1 << WT_VGROUP_ACTIVE));
}
static void vgroup_operator_subset_select_props(wmOperatorType *ot, bool use_active)
@ -976,11 +1209,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 {
@ -1172,11 +1405,6 @@ bool *ED_vgroup_subset_from_select_type(Object *ob, eVGroupSelect subset_type, i
*r_vgroup_tot = BLI_countlist(&ob->defbase);
switch (subset_type) {
case WT_VGROUP_ALL:
vgroup_validmap = MEM_mallocN(*r_vgroup_tot * sizeof(*vgroup_validmap), __func__);
memset(vgroup_validmap, true, *r_vgroup_tot * sizeof(*vgroup_validmap));
*r_subset_count = *r_vgroup_tot;
break;
case WT_VGROUP_ACTIVE:
{
const int def_nr_active = ob->actdef - 1;
@ -1191,20 +1419,44 @@ bool *ED_vgroup_subset_from_select_type(Object *ob, eVGroupSelect subset_type, i
}
break;
}
case WT_VGROUP_BONE_SELECT: {
case WT_VGROUP_BONE_SELECT:
{
vgroup_validmap = BKE_objdef_selected_get(ob, *r_vgroup_tot, r_subset_count);
break;
}
case WT_VGROUP_BONE_DEFORM: {
case WT_VGROUP_BONE_DEFORM:
{
int i;
vgroup_validmap = BKE_objdef_validmap_get(ob, *r_vgroup_tot);
*r_subset_count = 0;
for (i = 0; i < *r_vgroup_tot; i++) {
if (vgroup_validmap[i])
if (vgroup_validmap[i] == true) {
*r_subset_count += 1;
}
}
break;
}
case WT_VGROUP_BONE_DEFORM_OFF:
{
int i;
vgroup_validmap = BKE_objdef_validmap_get(ob, *r_vgroup_tot);
*r_subset_count = 0;
for (i = 0; i < *r_vgroup_tot; i++) {
vgroup_validmap[i] = !vgroup_validmap[i];
if (vgroup_validmap[i] == true) {
*r_subset_count += 1;
}
}
break;
}
case WT_VGROUP_ALL:
default:
{
vgroup_validmap = MEM_mallocN(*r_vgroup_tot * sizeof(*vgroup_validmap), __func__);
memset(vgroup_validmap, true, *r_vgroup_tot * sizeof(*vgroup_validmap));
*r_subset_count = *r_vgroup_tot;
break;
}
}
return vgroup_validmap;
@ -1616,7 +1868,8 @@ static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength,
}
}
static void vgroup_levels_subset(Object *ob, bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count),
static void vgroup_levels_subset(Object *ob, const bool *vgroup_validmap, const int vgroup_tot,
const int UNUSED(subset_count),
const float offset, const float gain)
{
MDeformWeight *dw;
@ -1746,7 +1999,9 @@ static void vgroup_lock_all(Object *ob, int action)
}
}
static void vgroup_invert_subset(Object *ob, bool *vgroup_validmap, const int vgroup_tot, const int UNUSED(subset_count), const bool auto_assign, const bool auto_remove)
static void vgroup_invert_subset(Object *ob,
const bool *vgroup_validmap, const int vgroup_tot,
const int UNUSED(subset_count), const bool auto_assign, const bool auto_remove)
{
MDeformWeight *dw;
MDeformVert *dv, **dvert_array = NULL;
@ -2170,7 +2425,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) {
@ -3001,10 +3256,9 @@ static int vertex_group_levels_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
vgroup_levels_subset(ob, vgroup_validmap, vgroup_tot, subset_count, offset, gain);
MEM_freeN(vgroup_validmap);
MEM_freeN((void *)vgroup_validmap);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@ -3183,10 +3437,9 @@ static int vertex_group_invert_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
vgroup_invert_subset(ob, vgroup_validmap, vgroup_tot, subset_count, auto_assign, auto_remove);
MEM_freeN(vgroup_validmap);
MEM_freeN((void *)vgroup_validmap);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@ -3291,10 +3544,9 @@ static int vertex_group_clean_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
vgroup_clean_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit, keep_single);
MEM_freeN(vgroup_validmap);
MEM_freeN((void *)vgroup_validmap);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@ -3332,10 +3584,9 @@ static int vertex_group_limit_total_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
int remove_tot = vgroup_limit_total_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit);
MEM_freeN(vgroup_validmap);
MEM_freeN((void *)vgroup_validmap);
BKE_reportf(op->reports, remove_tot ? RPT_INFO : RPT_WARNING, "%d vertex weights limited", remove_tot);
@ -3832,3 +4083,226 @@ void OBJECT_OT_vertex_group_move(wmOperatorType *ot)
RNA_def_enum(ot->srna, "direction", vgroup_slot_move, 0, "Direction", "Direction to move, UP or DOWN");
}
static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr)
{
MDeformVert *dvert_act;
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
float weight_act;
int i;
if (em) {
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
BMIter iter;
BMVert *eve, *eve_act;
dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
if (dvert_act == NULL) {
return;
}
weight_act = defvert_find_weight(dvert_act, def_nr);
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && (eve != eve_act)) {
MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
MDeformWeight *dw = defvert_find_index(dv, def_nr);
if (dw) {
dw->weight = weight_act;
if (me->editflag & ME_EDIT_MIRROR_X) {
ED_mesh_defvert_mirror_update_em(ob, eve, -1, i, cd_dvert_offset);
}
}
}
}
if (me->editflag & ME_EDIT_MIRROR_X) {
ED_mesh_defvert_mirror_update_em(ob, eve_act, -1, -1, cd_dvert_offset);
}
}
else {
MDeformVert *dv;
int v_act;
dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
if (dvert_act == NULL) {
return;
}
weight_act = defvert_find_weight(dvert_act, def_nr);
dv = me->dvert;
for (i = 0; i < me->totvert; i++, dv++) {
if ((me->mvert[i].flag & SELECT) && (dv != dvert_act)) {
MDeformWeight *dw = defvert_find_index(dv, def_nr);
if (dw) {
dw->weight = weight_act;
if (me->editflag & ME_EDIT_MIRROR_X) {
ED_mesh_defvert_mirror_update_ob(ob, -1, i);
}
}
}
}
if (me->editflag & ME_EDIT_MIRROR_X) {
ED_mesh_defvert_mirror_update_ob(ob, -1, v_act);
}
}
}
static int vertex_weight_paste(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
const int wg_index = RNA_int_get(op->ptr, "weight_group");
vgroup_copy_active_to_sel_single(ob, wg_index);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
}
void OBJECT_OT_vertex_weight_paste(wmOperatorType *ot)
{
PropertyRNA *prop;
ot->name = "Paste weight to Selected";
ot->idname = "OBJECT_OT_vertex_weight_paste";
ot->description = "Copy this group's weight to other selected verts";
prop = RNA_def_int(ot->srna, "weight_group",
-1, 0, 0, "Weight Index", "Index of source weight in active Weight Group", 0, 0);
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
/* api callbacks */
ot->poll = vertex_group_poll;
ot->exec = vertex_weight_paste;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int vertex_weight_delete(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
const int wg_index = RNA_int_get(op->ptr, "weight_group");
vgroup_remove_weight(ob, wg_index);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
}
void OBJECT_OT_vertex_weight_delete(wmOperatorType *ot)
{
PropertyRNA *prop;
ot->name = "Delete Weight";
ot->idname = "OBJECT_OT_vertex_weight_delete";
ot->description = "Delete this weight from the vertex";
prop = RNA_def_int(ot->srna, "weight_group",
-1, 0, 0, "Weight Index", "Index of source weight in active Weight Group", 0, 0);
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
/* api callbacks */
ot->poll = vertex_group_poll;
ot->exec = vertex_weight_delete;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int vertex_weight_set_active(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
const int wg_index = RNA_int_get(op->ptr, "weight_group");
if (wg_index != -1) {
ob->actdef = wg_index + 1;
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_vertex_weight_set_active(wmOperatorType *ot)
{
PropertyRNA *prop;
ot->name = "Set Active Group";
ot->idname = "OBJECT_OT_vertex_weight_set_active";
ot->description = "Set as active Vertex Group";
prop = RNA_def_int(ot->srna, "weight_group",
-1, 0, 0, "Weight Index", "Index of source weight in active Weight Group", 0, 0);
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
/* api callbacks */
ot->poll = vertex_group_poll;
ot->exec = vertex_weight_set_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int vertex_weight_normalize_active(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
ToolSettings *ts = CTX_data_tool_settings(C);
eVGroupSelect subset_type = ts->vgroupsubset;
vgroup_normalize_active(ob, subset_type);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
}
void OBJECT_OT_vertex_weight_normalize_active(wmOperatorType *ot)
{
ot->name = "Normalize Active";
ot->idname = "OBJECT_OT_vertex_weight_normalize_active";
ot->description = "Normalize Active Vert Weights";
/* api callbacks */
ot->poll = vertex_group_poll;
ot->exec = vertex_weight_normalize_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int vertex_weight_copy(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
ToolSettings *ts = CTX_data_tool_settings(C);
eVGroupSelect subset_type = ts->vgroupsubset;
vgroup_copy_active_to_sel(ob, subset_type);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
}
void OBJECT_OT_vertex_weight_copy(wmOperatorType *ot)
{
ot->name = "Copy Active";
ot->idname = "OBJECT_OT_vertex_weight_copy";
ot->description = "Copy weights from Active to selected";
/* api callbacks */
ot->poll = vertex_group_poll;
ot->exec = vertex_weight_copy;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}

@ -562,10 +562,14 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
RNA_string_get(&itemptr, "name", file_only);
BLI_join_dirfile(seq_load.path, sizeof(seq_load.path), dir_only, file_only);
/* Set seq_load.name, else all video/audio files get the same name! ugly! */
BLI_strncpy(seq_load.name, file_only, sizeof(seq_load.name));
seq = seq_load_func(C, ed->seqbasep, &seq_load);
if (seq) {
if (overlap == FALSE) {
if (BKE_sequence_test_overlap(ed->seqbasep, seq)) BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
if (BKE_sequence_test_overlap(ed->seqbasep, seq))
BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
}
}
}

@ -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 {

@ -116,7 +116,7 @@ typedef struct drawDMVerts_userData {
float th_vertex_size;
/* for skin node drawing */
int has_vskin;
int cd_vskin_offset;
float imat[4][4];
} drawDMVerts_userData;
@ -155,6 +155,11 @@ typedef struct bbsObmodeMeshVerts_userData {
MVert *mvert;
} bbsObmodeMeshVerts_userData;
typedef struct drawDMLayer_userData {
BMEditMesh *em;
int cd_layer_offset;
} drawDMLayer_userData;
static void draw_bounding_volume(Scene *scene, Object *ob, char type);
static void drawcube_size(float size);
@ -1155,8 +1160,8 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
short axis;
/* setup a 45 degree rotation matrix */
vec_rot_to_mat3(mat, imat[2], (float)M_PI / 4.0f);
axis_angle_normalized_to_mat3(mat, imat[2], (float)M_PI / 4.0f);
/* vectors */
mul_v3_v3fl(v1, imat[0], circrad * 1.2f);
mul_v3_v3fl(v2, imat[0], circrad * 2.5f);
@ -2060,7 +2065,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);
}
}
@ -2128,10 +2135,8 @@ static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3],
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) {
/* skin nodes: draw a red circle around the root
* node(s) */
if (data->has_vskin) {
const MVertSkin *vs = CustomData_bmesh_get(&data->em->bm->vdata,
eve->head.data,
CD_MVERT_SKIN);
if (data->cd_vskin_offset != -1) {
const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, data->cd_vskin_offset);
if (vs->flag & MVERT_SKIN_ROOT) {
float radius = (vs->radius[0] + vs->radius[1]) * 0.5f;
bglEnd();
@ -2181,7 +2186,7 @@ static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVer
data.th_vertex_size = UI_GetThemeValuef(TH_VERTEX_SIZE);
/* For skin root drawing */
data.has_vskin = CustomData_has_layer(&em->bm->vdata, CD_MVERT_SKIN);
data.cd_vskin_offset = CustomData_get_offset(&em->bm->vdata, CD_MVERT_SKIN);
/* view-aligned matrix */
mul_m4_m4m4(data.imat, rv3d->viewmat, em->ob->obmat);
invert_m4(data.imat);
@ -2326,9 +2331,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 +2360,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 +2384,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 +2393,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;
@ -2447,58 +2452,61 @@ static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba
static DMDrawOption draw_dm_creases__setDrawOptions(void *userData, int index)
{
BMEditMesh *em = userData;
BMEdge *eed = EDBM_edge_at_index(userData, index);
float *crease = eed ? (float *)CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE) : NULL;
drawDMLayer_userData *data = userData;
BMEditMesh *em = data->em;
BMEdge *eed = EDBM_edge_at_index(em, index);
if (!crease)
return DM_DRAW_OPTION_SKIP;
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && *crease != 0.0f) {
UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_CREASE, *crease);
return DM_DRAW_OPTION_NORMAL;
}
else {
return DM_DRAW_OPTION_SKIP;
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
const float crease = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset);
if (crease != 0.0f) {
UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_CREASE, crease);
return DM_DRAW_OPTION_NORMAL;
}
}
return DM_DRAW_OPTION_SKIP;
}
static void draw_dm_creases(BMEditMesh *em, DerivedMesh *dm)
{
glLineWidth(3.0);
dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, em);
glLineWidth(1.0);
drawDMLayer_userData data;
data.em = em;
data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
if (data.cd_layer_offset != -1) {
glLineWidth(3.0);
dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, &data);
glLineWidth(1.0);
}
}
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);
drawDMLayer_userData *data = userData;
BMEditMesh *em = data->em;
BMEdge *eed = EDBM_edge_at_index(em, index);
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 = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset);
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);
drawDMLayer_userData *data = userData;
BMEditMesh *em = data->em;
BMVert *eve = EDBM_vert_at_index(em, index);
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
const float bweight = BM_ELEM_CD_GET_FLOAT(eve, data->cd_layer_offset);
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 +2514,29 @@ 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();
drawDMLayer_userData data;
data.em = em;
data.cd_layer_offset = CustomData_get_offset(&em->bm->vdata, CD_BWEIGHT);
if (data.cd_layer_offset != -1) {
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2);
bglBegin(GL_POINTS);
dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &data);
bglEnd();
}
}
else {
glLineWidth(3.0);
dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, em);
glLineWidth(1.0);
drawDMLayer_userData data;
data.em = em;
data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
if (data.cd_layer_offset != -1) {
glLineWidth(3.0);
dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, &data);
glLineWidth(1.0);
}
}
}
@ -2958,7 +2980,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;
}
@ -3147,7 +3169,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
}
#endif
if (me->drawflag & ME_DRAWCREASES && CustomData_has_layer(&em->bm->edata, CD_CREASE)) {
if (me->drawflag & ME_DRAWCREASES) {
draw_dm_creases(em, cageDM);
}
if (me->drawflag & ME_DRAWBWEIGHTS) {
@ -7274,7 +7296,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);
}

@ -830,280 +830,19 @@ static MDeformVert *ED_mesh_active_dvert_get_only(Object *ob)
}
}
/* TODO, cache flip data to speedup calls within a loop. */
static void mesh_defvert_mirror_update_internal(Object *ob,
MDeformVert *dvert_dst, MDeformVert *dvert_src,
const int def_nr)
{
if (def_nr == -1) {
/* all vgroups, add groups where neded */
int flip_map_len;
int *flip_map = defgroup_flip_map(ob, &flip_map_len, true);
defvert_sync_mapped(dvert_dst, dvert_src, flip_map, flip_map_len, true);
MEM_freeN(flip_map);
}
else {
/* single vgroup */
MDeformWeight *dw = defvert_verify_index(dvert_dst, defgroup_flip_index(ob, def_nr, 1));
if (dw) {
dw->weight = defvert_find_weight(dvert_src, def_nr);
}
}
}
static void ED_mesh_defvert_mirror_update_em(Object *ob, BMVert *eve, int def_nr, int vidx,
const int cd_dvert_offset)
{
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
BMVert *eve_mirr;
eve_mirr = editbmesh_get_x_mirror_vert(ob, em, eve, eve->co, vidx);
if (eve_mirr && eve_mirr != eve) {
MDeformVert *dvert_src = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
MDeformVert *dvert_dst = BM_ELEM_CD_GET_VOID_P(eve_mirr, cd_dvert_offset);
mesh_defvert_mirror_update_internal(ob, dvert_dst, dvert_src, def_nr);
}
}
static void ED_mesh_defvert_mirror_update_ob(Object *ob, int def_nr, int vidx)
{
int vidx_mirr;
Mesh *me = ob->data;
if (vidx == -1)
return;
vidx_mirr = mesh_get_x_mirror_vert(ob, vidx);
if ((vidx_mirr) >= 0 && (vidx_mirr != vidx)) {
MDeformVert *dvert_src = &me->dvert[vidx];
MDeformVert *dvert_dst = &me->dvert[vidx_mirr];
mesh_defvert_mirror_update_internal(ob, dvert_dst, dvert_src, def_nr);
}
}
static void vgroup_adjust_active(Object *ob, int def_nr)
{
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
MDeformVert *dvert_act;
if (me->editflag & ME_EDIT_MIRROR_X) {
if (em) {
BMVert *eve_act;
dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
if (dvert_act) {
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
ED_mesh_defvert_mirror_update_em(ob, eve_act, def_nr, -1, cd_dvert_offset);
}
}
else {
int v_act;
dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
if (dvert_act) {
ED_mesh_defvert_mirror_update_ob(ob, def_nr, v_act);
}
}
}
}
static void vgroup_remove_weight(Object *ob, const int def_nr)
{
MDeformVert *dvert_act;
MDeformWeight *dw;
dvert_act = ED_mesh_active_dvert_get_only(ob);
dw = defvert_find_index(dvert_act, def_nr);
defvert_remove_group(dvert_act, dw);
}
static void vgroup_copy_active_to_sel(Object *ob)
{
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
MDeformVert *dvert_act;
int i;
if (em) {
BMIter iter;
BMVert *eve, *eve_act;
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
if (dvert_act == NULL) {
return;
}
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && eve != eve_act) {
MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
defvert_copy(dv, dvert_act);
if (me->editflag & ME_EDIT_MIRROR_X) {
ED_mesh_defvert_mirror_update_em(ob, eve, -1, i, cd_dvert_offset);
}
}
}
}
else {
MDeformVert *dv;
int v_act;
dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
if (dvert_act == NULL) {
return;
}
dv = me->dvert;
for (i = 0; i < me->totvert; i++, dv++) {
if ((me->mvert[i].flag & SELECT) && dv != dvert_act) {
defvert_copy(dv, dvert_act);
if (me->editflag & ME_EDIT_MIRROR_X) {
ED_mesh_defvert_mirror_update_ob(ob, -1, i);
}
}
}
}
}
static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr)
{
MDeformVert *dvert_act;
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
float weight_act;
int i;
if (em) {
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
BMIter iter;
BMVert *eve, *eve_act;
dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
if (dvert_act == NULL) {
return;
}
weight_act = defvert_find_weight(dvert_act, def_nr);
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && (eve != eve_act)) {
MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
MDeformWeight *dw = defvert_find_index(dv, def_nr);
if (dw) {
dw->weight = weight_act;
if (me->editflag & ME_EDIT_MIRROR_X) {
ED_mesh_defvert_mirror_update_em(ob, eve, -1, i, cd_dvert_offset);
}
}
}
}
if (me->editflag & ME_EDIT_MIRROR_X) {
ED_mesh_defvert_mirror_update_em(ob, eve_act, -1, -1, cd_dvert_offset);
}
}
else {
MDeformVert *dv;
int v_act;
dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
if (dvert_act == NULL) {
return;
}
weight_act = defvert_find_weight(dvert_act, def_nr);
dv = me->dvert;
for (i = 0; i < me->totvert; i++, dv++) {
if ((me->mvert[i].flag & SELECT) && (dv != dvert_act)) {
MDeformWeight *dw = defvert_find_index(dv, def_nr);
if (dw) {
dw->weight = weight_act;
if (me->editflag & ME_EDIT_MIRROR_X) {
ED_mesh_defvert_mirror_update_ob(ob, -1, i);
}
}
}
}
if (me->editflag & ME_EDIT_MIRROR_X) {
ED_mesh_defvert_mirror_update_ob(ob, -1, v_act);
}
}
}
static void vgroup_normalize_active(Object *ob)
{
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
BMVert *eve_act;
int v_act;
MDeformVert *dvert_act;
if (em) {
dvert_act = ED_mesh_active_dvert_get_em(ob, &eve_act);
}
else {
dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
}
if (dvert_act == NULL) {
return;
}
defvert_normalize(dvert_act);
if (me->editflag & ME_EDIT_MIRROR_X) {
if (em) {
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
ED_mesh_defvert_mirror_update_em(ob, eve_act, -1, -1, cd_dvert_offset);
}
else {
int v_act = BKE_mesh_mselect_active_get(me, ME_VSEL);
ED_mesh_defvert_mirror_update_ob(ob, -1, v_act);
}
}
}
static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
{
Scene *scene = CTX_data_scene(C);
Object *ob = scene->basact->object;
/* XXX TODO Use operators? */
if (event == B_VGRP_PNL_NORMALIZE) {
vgroup_normalize_active(ob);
}
else if (event == B_VGRP_PNL_COPY) {
vgroup_copy_active_to_sel(ob);
}
else if (event >= B_VGRP_PNL_ACTIVE) {
ob->actdef = event - B_VGRP_PNL_ACTIVE + 1;
}
else if (event >= B_VGRP_PNL_COPY_SINGLE) {
vgroup_copy_active_to_sel_single(ob, event - B_VGRP_PNL_COPY_SINGLE);
}
else if (event >= B_VGRP_PNL_DELETE_SINGLE) {
vgroup_remove_weight(ob, event - B_VGRP_PNL_DELETE_SINGLE);
}
else if (event >= B_VGRP_PNL_EDIT_SINGLE) {
vgroup_adjust_active(ob, event - B_VGRP_PNL_EDIT_SINGLE);
if (event < B_VGRP_PNL_EDIT_SINGLE) {
/* not for me */
return;
}
else {
BLI_assert(0);
Scene *scene = CTX_data_scene(C);
Object *ob = scene->basact->object;
ED_vgroup_vert_active_mirror(ob, event - B_VGRP_PNL_EDIT_SINGLE);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
}
#if 0 /* TODO */
if (((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X)
ED_vgroup_mirror(ob, 1, 1, 0);
#endif
/* default for now */
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
}
static int view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt))
@ -1132,22 +871,39 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
dv = ED_mesh_active_dvert_get_only(ob);
if (dv && dv->totweight) {
uiLayout *col;
ToolSettings *ts = scene->toolsettings;
wmOperatorType *ot_weight_set_active = WM_operatortype_find("OBJECT_OT_vertex_weight_set_active", true);
wmOperatorType *ot_weight_paste = WM_operatortype_find("OBJECT_OT_vertex_weight_paste", true);
wmOperatorType *ot_weight_delete = WM_operatortype_find("OBJECT_OT_vertex_weight_delete", true);
wmOperatorType *ot;
PointerRNA op_ptr, tools_ptr;
PointerRNA *but_ptr;
uiLayout *col, *bcol;
uiLayout *row;
uiLayout *box;
uiBut *but;
bDeformGroup *dg;
unsigned int i;
int subset_count, vgroup_tot;
bool *vgroup_validmap;
eVGroupSelect subset_type = WT_VGROUP_ALL;
const bool *vgroup_validmap;
eVGroupSelect subset_type = ts->vgroupsubset;
int yco = 0;
uiBlockSetHandleFunc(block, do_view3d_vgroup_buttons, NULL);
box = uiLayoutBox(pa->layout);
bcol = uiLayoutColumn(pa->layout, true);
row = uiLayoutRow(bcol, true); /* The filter button row */
RNA_pointer_create(NULL, &RNA_ToolSettings, ts, &tools_ptr);
uiItemR(row, &tools_ptr, "vertex_group_subset", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
col = uiLayoutColumn(bcol, true);
box = uiLayoutBox(col); /* The list box */
col = uiLayoutColumn(box, true);
vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
for (i = 0, dg = ob->defbase.first; dg; i++, dg = dg->next) {
if (vgroup_validmap[i]) {
@ -1155,56 +911,68 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
if (dw) {
int x, xco = 0;
row = uiLayoutRow(col, true);
(void)row;
uiBlockSetEmboss(block, UI_EMBOSSN);
but = uiDefBut(block, BUT, B_VGRP_PNL_ACTIVE + i, dg->name,
xco, yco, (x = UI_UNIT_X * 5), UI_UNIT_Y,
NULL, 0.0, 1.0, 1, 3, "");
uiButSetFlag(but, UI_TEXT_LEFT);
/* The Weight Group Name */
ot = ot_weight_set_active;
but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, dg->name,
xco, yco, (x = UI_UNIT_X * 5), UI_UNIT_Y, "");
but_ptr = uiButGetOperatorPtrRNA(but);
RNA_int_set(but_ptr, "weight_group", i);
uiButSetFlag(but, UI_TEXT_LEFT);
if (ob->actdef != i + 1) {
uiButSetFlag(but, UI_BUT_INACTIVE);
}
xco += x;
//uiBlockSetEmboss(block, UI_EMBOSS);
/* The weight group value */
/* To be reworked still */
but = uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + i, "",
xco, yco, (x = UI_UNIT_X * 4), UI_UNIT_Y,
&dw->weight, 0.0, 1.0, 1, 3, "");
uiButSetFlag(but, UI_TEXT_LEFT);
xco += x;
uiDefIconBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + i, ICON_PASTEDOWN,
xco, yco, (x = UI_UNIT_X), UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Copy this group's weight to other selected verts"));
xco += x;
/* The weight group paste function */
uiDefIconBut(block, BUT, B_VGRP_PNL_DELETE_SINGLE + i, ICON_X,
xco, yco, (x = UI_UNIT_X), UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Delete this weight from the vertex"));
xco += x;
ot = ot_weight_paste;
WM_operator_properties_create_ptr(&op_ptr, ot);
RNA_int_set(&op_ptr, "weight_group", i);
uiItemFullO_ptr(row, ot, "", ICON_PASTEDOWN, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0);
/* The weight entry delete function */
ot = ot_weight_delete;
WM_operator_properties_create_ptr(&op_ptr, ot);
RNA_int_set(&op_ptr, "weight_group", i);
uiItemFullO_ptr(row, ot, "", ICON_X, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0);
yco -= UI_UNIT_Y;
(void)xco;
}
}
}
MEM_freeN(vgroup_validmap);
MEM_freeN((void *)vgroup_validmap);
uiBlockSetEmboss(block, UI_EMBOSS);
yco -= 2;
uiBlockSetEmboss(block, UI_EMBOSS);
col = uiLayoutColumn(pa->layout, true);
row = uiLayoutRow(col, true);
uiDefBut(block, BUT, B_VGRP_PNL_NORMALIZE, IFACE_("Normalize"),
0, yco, UI_UNIT_X * 5, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Normalize active vertex weights"));
uiDefBut(block, BUT, B_VGRP_PNL_COPY, IFACE_("Copy"),
UI_UNIT_X * 5, yco, UI_UNIT_X * 5, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Copy active vertex to other selected verts"));
ot = WM_operatortype_find("OBJECT_OT_vertex_weight_normalize_active", 1);
but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, "Normalize",
0, yco,UI_UNIT_X * 5, UI_UNIT_Y,
TIP_("Normalize active vertex weights"));
ot = WM_operatortype_find("OBJECT_OT_vertex_weight_copy", 1);
but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, "Copy",
UI_UNIT_X * 5, yco,UI_UNIT_X * 5, UI_UNIT_Y,
TIP_("Copy active vertex to other selected verts"));
}
}

@ -1736,12 +1736,15 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
/* convert flag to enum */
switch (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
switch (t->flag & T_PROP_EDIT_ALL) {
case T_PROP_EDIT:
proportional = PROP_EDIT_ON;
break;
case (T_PROP_EDIT | T_PROP_CONNECTED):
proportional = PROP_EDIT_CONNECTED;
break;
case T_PROP_EDIT:
proportional = PROP_EDIT_ON;
case (T_PROP_EDIT | T_PROP_PROJECTED):
proportional = PROP_EDIT_PROJECTED;
break;
default:
proportional = PROP_EDIT_OFF;
@ -2181,17 +2184,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);
}
@ -2956,7 +2948,7 @@ static void headerResize(TransInfo *t, float vec[3], char *str)
}
}
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
if (t->flag & T_PROP_EDIT_ALL) {
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
}
@ -3154,7 +3146,7 @@ int Resize(TransInfo *t, const int mval[2])
/* vertices in the radius of the brush end */
/* outside the clipping area */
/* XXX HACK - dg */
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
if (t->flag & T_PROP_EDIT_ALL) {
clipUVData(t);
}
}
@ -3614,7 +3606,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
float mat[3][3];
int i;
vec_rot_to_mat3(mat, axis, angle);
axis_angle_normalized_to_mat3(mat, axis, angle);
for (i = 0; i < t->total; i++, td++) {
@ -3626,10 +3618,10 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
if (t->con.applyRot) {
t->con.applyRot(t, td, axis, NULL);
vec_rot_to_mat3(mat, axis, angle * td->factor);
axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
}
else if (t->flag & T_PROP_EDIT) {
vec_rot_to_mat3(mat, axis, angle * td->factor);
axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
}
ElementRotation(t, td, mat, t->around);
@ -3674,7 +3666,7 @@ int Rotation(TransInfo *t, const int UNUSED(mval[2]))
RAD2DEGF(final), t->con.text, t->proptext);
}
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
if (t->flag & T_PROP_EDIT_ALL) {
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
@ -3710,14 +3702,14 @@ void initTrackball(TransInfo *t)
t->flag |= T_NO_CONSTRAINT;
}
static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float angles[2])
static void applyTrackball(TransInfo *t, const float axis1[3], const float axis2[3], float angles[2])
{
TransData *td = t->data;
float mat[3][3], smat[3][3], totmat[3][3];
int i;
vec_rot_to_mat3(smat, axis1, angles[0]);
vec_rot_to_mat3(totmat, axis2, angles[1]);
axis_angle_normalized_to_mat3(smat, axis1, angles[0]);
axis_angle_normalized_to_mat3(totmat, axis2, angles[1]);
mul_m3_m3m3(mat, smat, totmat);
@ -3729,8 +3721,8 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a
continue;
if (t->flag & T_PROP_EDIT) {
vec_rot_to_mat3(smat, axis1, td->factor * angles[0]);
vec_rot_to_mat3(totmat, axis2, td->factor * angles[1]);
axis_angle_normalized_to_mat3(smat, axis1, td->factor * angles[0]);
axis_angle_normalized_to_mat3(totmat, axis2, td->factor * angles[1]);
mul_m3_m3m3(mat, smat, totmat);
}
@ -3775,12 +3767,12 @@ int Trackball(TransInfo *t, const int UNUSED(mval[2]))
RAD2DEGF(phi[0]), RAD2DEGF(phi[1]), t->proptext);
}
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
if (t->flag & T_PROP_EDIT_ALL) {
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
vec_rot_to_mat3(smat, axis1, phi[0]);
vec_rot_to_mat3(totmat, axis2, phi[1]);
axis_angle_normalized_to_mat3(smat, axis1, phi[0]);
axis_angle_normalized_to_mat3(totmat, axis2, phi[1]);
mul_m3_m3m3(mat, smat, totmat);
@ -3923,7 +3915,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str)
}
}
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
if (t->flag & T_PROP_EDIT_ALL) {
ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
}
@ -4030,7 +4022,7 @@ int Translation(TransInfo *t, const int UNUSED(mval[2]))
/* vertices in the radius of the brush end */
/* outside the clipping area */
/* XXX HACK - dg */
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
if (t->flag & T_PROP_EDIT_ALL) {
clipUVData(t);
}
}

@ -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 */
@ -395,6 +394,8 @@ typedef struct TransInfo {
#define T_PROP_EDIT (1 << 11)
#define T_PROP_CONNECTED (1 << 12)
#define T_PROP_PROJECTED (1 << 25)
#define T_PROP_EDIT_ALL (T_PROP_EDIT | T_PROP_CONNECTED | T_PROP_PROJECTED)
#define T_V3D_ALIGN (1 << 14)
/* for 2d views like uv or ipo */

@ -201,6 +201,17 @@ static void set_prop_dist(TransInfo *t, const bool with_dist)
TransData *tob;
int a;
float _proj_vec[3];
const float *proj_vec = NULL;
if (t->flag & T_PROP_PROJECTED) {
if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = t->ar->regiondata;
normalize_v3_v3(_proj_vec, rv3d->viewinv[2]);
proj_vec = _proj_vec;
}
}
for (a = 0, tob = t->data; a < t->total; a++, tob++) {
tob->rdist = 0.0f; // init, it was mallocced
@ -216,6 +227,13 @@ static void set_prop_dist(TransInfo *t, const bool with_dist)
if (td->flag & TD_SELECTED) {
sub_v3_v3v3(vec, tob->center, td->center);
mul_m3_v3(tob->mtx, vec);
if (proj_vec) {
float vec_p[3];
project_v3_v3v3(vec_p, vec, proj_vec);
sub_v3_v3(vec, vec_p);
}
dist = len_squared_v3(vec);
if ((tob->rdist == -1.0f) || (dist < (tob->rdist * tob->rdist))) {
tob->rdist = sqrtf(dist);
@ -989,7 +1007,7 @@ static void createTransPose(TransInfo *t, Object *ob)
t->poseobj = ob; /* we also allow non-active objects to be transformed, in weightpaint */
/* disable PET, its not usable in pose mode yet [#32444] */
t->flag &= ~(T_PROP_EDIT | T_PROP_CONNECTED);
t->flag &= ~T_PROP_EDIT_ALL;
/* init trans data */
td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransPoseBone");
@ -2013,14 +2031,14 @@ static void createTransEditVerts(TransInfo *t)
float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
float *dists = NULL;
int count = 0, countsel = 0, a, totleft;
int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) : 0;
int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0;
int mirror = 0;
char *selstate = NULL;
short selectmode = ts->selectmode;
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, (t->flag & T_PROP_EDIT) == 0);
mirror = 1;
}
@ -5827,7 +5845,7 @@ static void createTransNodeData(bContext *UNUSED(C), TransInfo *t)
}
/* nodes dont support PET and probably never will */
t->flag &= ~(T_PROP_EDIT | T_PROP_CONNECTED);
t->flag &= ~T_PROP_EDIT_ALL;
/* set transform flags on nodes */
for (node = snode->edittree->nodes.first; node; node = node->next) {

@ -1023,6 +1023,20 @@ void resetTransRestrictions(TransInfo *t)
t->flag &= ~T_ALL_RESTRICTIONS;
}
static int initTransInfo_edit_pet_to_flag(const int proportional)
{
switch (proportional) {
case PROP_EDIT_ON:
return T_PROP_EDIT;
case PROP_EDIT_CONNECTED:
return T_PROP_EDIT | T_PROP_CONNECTED;
case PROP_EDIT_PROJECTED:
return T_PROP_EDIT | T_PROP_PROJECTED;
default:
return 0;
}
}
/* the *op can be NULL */
int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event)
{
@ -1245,24 +1259,14 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *even
/* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */
if (op && (prop = RNA_struct_find_property(op->ptr, "proportional"))) {
if (RNA_property_is_set(op->ptr, prop)) {
switch (RNA_property_enum_get(op->ptr, prop)) {
case PROP_EDIT_CONNECTED:
t->flag |= T_PROP_CONNECTED;
case PROP_EDIT_ON:
t->flag |= T_PROP_EDIT;
break;
}
t->flag |= initTransInfo_edit_pet_to_flag(RNA_property_enum_get(op->ptr, prop));
}
else {
/* use settings from scene only if modal */
if (t->flag & T_MODAL) {
if ((t->options & CTX_NO_PET) == 0) {
if (t->obedit && ts->proportional != PROP_EDIT_OFF) {
t->flag |= T_PROP_EDIT;
if (ts->proportional == PROP_EDIT_CONNECTED) {
t->flag |= T_PROP_CONNECTED;
}
if (t->obedit) {
t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional);
}
else if (t->options & CTX_MASK) {
if (ts->proportional_mask) {
@ -1310,9 +1314,11 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *even
}
// Mirror is not supported with PET, turn it off.
#if 0
if (t->flag & T_PROP_EDIT) {
t->flag &= ~T_MIRROR;
}
#endif
setTransformViewMatrices(t);
initNumInput(&t->num);

@ -1446,7 +1446,9 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes
else {
eve = EDBM_vert_at_index(em, index);
if (eve && (BM_elem_flag_test(eve, BM_ELEM_HIDDEN) || BM_elem_flag_test(eve, BM_ELEM_SELECT))) {
if ((BM_elem_flag_test(eve, BM_ELEM_HIDDEN) ||
BM_elem_flag_test(eve, BM_ELEM_SELECT)))
{
test = 0;
}
}
@ -1475,7 +1477,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 +1493,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;
}

@ -84,8 +84,8 @@
#include "uvedit_intern.h"
static void uv_select_all_perform(Scene *scene, Image *ima, BMEditMesh *em, int action);
static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object *obedit, bool select);
static void uv_select_flush_from_tag_loop(SpaceImage *sima, Scene *scene, Object *obedit, bool select);
static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object *obedit, const bool select);
static void uv_select_flush_from_tag_loop(SpaceImage *sima, Scene *scene, Object *obedit, const bool select);
/************************* state testing ************************/
@ -2694,7 +2694,7 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object
*
* \note! This function is very similar to #uv_select_flush_from_tag_loop, be sure to update both upon changing.
*/
static void uv_select_flush_from_tag_loop(SpaceImage *sima, Scene *scene, Object *obedit, bool select)
static void uv_select_flush_from_tag_loop(SpaceImage *sima, Scene *scene, Object *obedit, const bool select)
{
/* Selecting UV Loops with some modes requires us to change
* the selection in other faces (depending on the sticky mode).

@ -1147,7 +1147,7 @@ void GPU_free_unused_buffers(void)
ima = node->link;
/* check in case it was freed in the meantime */
if (BLI_findindex(&G.main->image, ima) != -1)
if (G.main && BLI_findindex(&G.main->image, ima) != -1)
GPU_free_image(ima);
}

@ -248,24 +248,24 @@ typedef struct ImBuf {
/* dds */
#ifdef WITH_DDS
#ifndef MAKEFOURCC
#define MAKEFOURCC(ch0, ch1, ch2, ch3)\
#ifndef DDS_MAKEFOURCC
#define DDS_MAKEFOURCC(ch0, ch1, ch2, ch3)\
((unsigned long)(unsigned char)(ch0) | \
((unsigned long)(unsigned char)(ch1) << 8) | \
((unsigned long)(unsigned char)(ch2) << 16) | \
((unsigned long)(unsigned char)(ch3) << 24))
#endif /* MAKEFOURCC */
#endif /* DDS_MAKEFOURCC */
/*
* FOURCC codes for DX compressed-texture pixel formats
*/
#define FOURCC_DDS (MAKEFOURCC('D','D','S',' '))
#define FOURCC_DXT1 (MAKEFOURCC('D','X','T','1'))
#define FOURCC_DXT2 (MAKEFOURCC('D','X','T','2'))
#define FOURCC_DXT3 (MAKEFOURCC('D','X','T','3'))
#define FOURCC_DXT4 (MAKEFOURCC('D','X','T','4'))
#define FOURCC_DXT5 (MAKEFOURCC('D','X','T','5'))
#define FOURCC_DDS (DDS_MAKEFOURCC('D','D','S',' '))
#define FOURCC_DXT1 (DDS_MAKEFOURCC('D','X','T','1'))
#define FOURCC_DXT2 (DDS_MAKEFOURCC('D','X','T','2'))
#define FOURCC_DXT3 (DDS_MAKEFOURCC('D','X','T','3'))
#define FOURCC_DXT4 (DDS_MAKEFOURCC('D','X','T','4'))
#define FOURCC_DXT5 (DDS_MAKEFOURCC('D','X','T','5'))
#endif /* DDS */
extern const char *imb_ext_image[];

@ -65,28 +65,28 @@
/*** declarations ***/
#if !defined(MAKEFOURCC)
# define MAKEFOURCC(ch0, ch1, ch2, ch3) \
#if !defined(DDS_MAKEFOURCC)
# define DDS_MAKEFOURCC(ch0, ch1, ch2, ch3) \
(uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | \
(uint(uint8(ch2)) << 16) | (uint(uint8(ch3)) << 24 ))
#endif
static const uint FOURCC_NVTT = MAKEFOURCC('N', 'V', 'T', 'T');
static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' ');
static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1');
static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2');
static const uint FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3');
static const uint FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4');
static const uint FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5');
static const uint FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B');
static const uint FOURCC_ATI1 = MAKEFOURCC('A', 'T', 'I', '1');
static const uint FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2');
static const uint FOURCC_NVTT = DDS_MAKEFOURCC('N', 'V', 'T', 'T');
static const uint FOURCC_DDS = DDS_MAKEFOURCC('D', 'D', 'S', ' ');
static const uint FOURCC_DXT1 = DDS_MAKEFOURCC('D', 'X', 'T', '1');
static const uint FOURCC_DXT2 = DDS_MAKEFOURCC('D', 'X', 'T', '2');
static const uint FOURCC_DXT3 = DDS_MAKEFOURCC('D', 'X', 'T', '3');
static const uint FOURCC_DXT4 = DDS_MAKEFOURCC('D', 'X', 'T', '4');
static const uint FOURCC_DXT5 = DDS_MAKEFOURCC('D', 'X', 'T', '5');
static const uint FOURCC_RXGB = DDS_MAKEFOURCC('R', 'X', 'G', 'B');
static const uint FOURCC_ATI1 = DDS_MAKEFOURCC('A', 'T', 'I', '1');
static const uint FOURCC_ATI2 = DDS_MAKEFOURCC('A', 'T', 'I', '2');
static const uint FOURCC_A2XY = MAKEFOURCC('A', '2', 'X', 'Y');
static const uint FOURCC_A2XY = DDS_MAKEFOURCC('A', '2', 'X', 'Y');
static const uint FOURCC_DX10 = MAKEFOURCC('D', 'X', '1', '0');
static const uint FOURCC_DX10 = DDS_MAKEFOURCC('D', 'X', '1', '0');
static const uint FOURCC_UVER = MAKEFOURCC('U', 'V', 'E', 'R');
static const uint FOURCC_UVER = DDS_MAKEFOURCC('U', 'V', 'E', 'R');
// 32 bit RGB formats.
static const uint D3DFMT_R8G8B8 = 20;
@ -672,7 +672,7 @@ void DDSHeader::setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3)
{
// set fourcc pixel format.
this->pf.flags = DDPF_FOURCC;
this->pf.fourcc = MAKEFOURCC(c0, c1, c2, c3);
this->pf.fourcc = DDS_MAKEFOURCC(c0, c1, c2, c3);
this->pf.bitcount = 0;
this->pf.rmask = 0;
@ -696,7 +696,7 @@ void DDSHeader::setFormatCode(uint32 code)
void DDSHeader::setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3)
{
this->pf.bitcount = MAKEFOURCC(c0, c1, c2, c3);
this->pf.bitcount = DDS_MAKEFOURCC(c0, c1, c2, c3);
}

@ -640,7 +640,7 @@ void IMB_exrtile_begin_write(void *handle, const char *filename, int mipmap, int
data->ofile_stream = new OFileStream(filename);
data->tofile = new TiledOutputFile(*(data->ofile_stream), header);
}
catch (const std::exception &exc) {
catch (const std::exception &) {
delete data->tofile;
delete data->ofile_stream;
@ -660,7 +660,7 @@ int IMB_exr_begin_read(void *handle, const char *filename, int *width, int *heig
data->ifile_stream = new IFileStream(filename);
data->ifile = new InputFile(*(data->ifile_stream));
}
catch (const std::exception &exc) {
catch (const std::exception &) {
delete data->ifile;
delete data->ifile_stream;

@ -1076,11 +1076,11 @@ typedef struct ToolSettings {
short proportional, prop_mode;
char proportional_objects; /* proportional edit, object mode */
char proportional_mask; /* proportional edit, object mode */
char pad4[1];
char auto_normalize; /*auto normalizing mode in wpaint*/
char multipaint; /* paint multiple bones in wpaint */
char weightuser;
char vgroupsubset; /* subset selection filter in wpaint */
/* UV painting */
int use_uv_sculpt;
@ -1501,7 +1501,8 @@ typedef struct Scene {
/* toolsettings->proportional */
#define PROP_EDIT_OFF 0
#define PROP_EDIT_ON 1
#define PROP_EDIT_CONNECTED 2
#define PROP_EDIT_CONNECTED 2
#define PROP_EDIT_PROJECTED 3
/* toolsettings->weightuser */
enum {
@ -1510,6 +1511,24 @@ enum {
OB_DRAW_GROUPUSER_ALL = 2
};
/* toolsettings->vgroupsubset */
/* object_vgroup.c */
typedef enum eVGroupSelect {
WT_VGROUP_ALL = 0,
WT_VGROUP_ACTIVE = 1,
WT_VGROUP_BONE_SELECT = 2,
WT_VGROUP_BONE_DEFORM = 3,
WT_VGROUP_BONE_DEFORM_OFF = 4
} eVGroupSelect;
#define WT_VGROUP_MASK_ALL \
((1 << WT_VGROUP_ACTIVE) | \
(1 << WT_VGROUP_BONE_SELECT) | \
(1 << WT_VGROUP_BONE_DEFORM) | \
(1 << WT_VGROUP_BONE_DEFORM_OFF) | \
(1 << WT_VGROUP_ALL))
/* sce->flag */
#define SCE_DS_SELECTED (1<<0)
#define SCE_DS_COLLAPSED (1<<1)

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