Merge branch 'master' into blender2.8

Notes:

- Changes in paint_vertex.c were simple to merge, mainly related on passing
  evaluation context.

- Conflicts in EditDM and drawmesh.c are solved using code from blender2.8
  branch. Those areas are deprecated and not to be used in final release.

  However, it's possible that some reference code from master is lost, so
  keep attention when adding alpha support for vertex painting.
This commit is contained in:
2017-10-03 12:59:06 +05:00
30 changed files with 1032 additions and 446 deletions

View File

@@ -245,8 +245,7 @@ def git_submodules_update():
def lib_svn_step(dir):
name = "lib svn"
return SVN(name=name,
return SVN(name='lib svn',
baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + dir,
codebase='lib svn',
mode='update',
@@ -307,7 +306,7 @@ def generic_builder(id, libdir='', branch='', rsync=False):
# Builders
add_builder(c, 'mac_x86_64_10_6_cmake', 'darwin', generic_builder, hour=1)
add_builder(c, 'mac_x86_64_10_9_cmake', 'darwin', generic_builder, hour=1)
add_builder(c, 'linux_glibc219_i686_cmake', '', generic_builder, hour=2)
add_builder(c, 'linux_glibc219_x86_64_cmake', '', generic_builder, hour=1)
add_builder(c, 'win32_cmake_vc2013', 'windows_vc12', generic_builder, hour=1)

View File

@@ -70,14 +70,12 @@ if 'cmake' in builder:
if builder.startswith('mac'):
# Set up OSX architecture
if builder.endswith('x86_64_10_6_cmake'):
if builder.endswith('x86_64_10_9_cmake'):
cmake_extra_options.append('-DCMAKE_OSX_ARCHITECTURES:STRING=x86_64')
cmake_extra_options.append('-DCMAKE_OSX_DEPLOYMENT_TARGET=10.6')
cmake_extra_options.append('-DCMAKE_OSX_DEPLOYMENT_TARGET=10.9')
cmake_extra_options.append('-DCUDA_HOST_COMPILER=/usr/local/cuda-hack/clang')
cmake_extra_options.append('-DCUDA_NVCC_EXECUTABLE=/usr/local/cuda-hack/nvcc')
elif builder.startswith('win'):
if builder.endswith('_vc2015'):
if builder.startswith('win64'):

View File

@@ -101,13 +101,9 @@ if builder.find('cmake') != -1:
platform = builder.split('_')[0]
if platform == 'mac':
# Special exception for OSX
platform = 'OSX-10.6-'
if builder.endswith('x86_64_10_6_cmake'):
platform = 'OSX-10.9-'
if builder.endswith('x86_64_10_9_cmake'):
platform += 'x86_64'
elif builder.endswith('i386_10_6_cmake'):
platform += 'i386'
elif builder.endswith('ppc_10_6_cmake'):
platform += 'ppc'
if builder.endswith('vc2015'):
platform += "-vc14"
builderified_name = 'blender-{}-{}-{}'.format(blender_full_version, git_hash, platform)

View File

@@ -321,7 +321,7 @@ if(WITH_CYCLES_CUDA_BINARIES)
set(CUDA_VERSION "${CUDA_VERSION_MAJOR}${CUDA_VERSION_MINOR}")
# warn for other versions
if(CUDA_VERSION MATCHES "80")
if(CUDA_VERSION MATCHES "80" OR CUDA_VERSION MATCHES "90")
else()
message(WARNING
"CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, "
@@ -399,13 +399,17 @@ if(WITH_CYCLES_CUDA_BINARIES)
endmacro()
foreach(arch ${CYCLES_CUDA_BINARIES_ARCH})
# Compile regular kernel
CYCLES_CUDA_KERNEL_ADD(${arch} kernel "" "${cuda_sources}" FALSE)
CYCLES_CUDA_KERNEL_ADD(${arch} filter "" "${cuda_filter_sources}" FALSE)
if(CUDA_VERSION MATCHES "90" AND ${arch} MATCHES "sm_2.")
message(STATUS "CUDA binaries for ${arch} disabled, not supported by CUDA 9.")
else()
# Compile regular kernel
CYCLES_CUDA_KERNEL_ADD(${arch} kernel "" "${cuda_sources}" FALSE)
CYCLES_CUDA_KERNEL_ADD(${arch} filter "" "${cuda_filter_sources}" FALSE)
if(WITH_CYCLES_CUDA_SPLIT_KERNEL_BINARIES)
# Compile split kernel
CYCLES_CUDA_KERNEL_ADD(${arch} kernel_split "-D__SPLIT__" ${cuda_sources} FALSE)
if(WITH_CYCLES_CUDA_SPLIT_KERNEL_BINARIES)
# Compile split kernel
CYCLES_CUDA_KERNEL_ADD(${arch} kernel_split "-D__SPLIT__" ${cuda_sources} FALSE)
endif()
endif()
endforeach()

View File

@@ -1761,9 +1761,16 @@ class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
wpaint = tool_settings.weight_paint
col = layout.column()
col.label("Falloff:")
row = col.row()
row.prop(wpaint, "use_normal")
row.prop(wpaint, "falloff_shape", expand=True)
row = col.row()
row.prop(wpaint, "use_backface_culling")
row = col.row()
row.prop(wpaint, "use_normal_falloff")
sub = row.row()
sub.active = (wpaint.use_normal_falloff)
sub.prop(wpaint, "normal_angle", text="")
col = layout.column()
row = col.row()
row.prop(wpaint, "use_spray")
@@ -1798,19 +1805,21 @@ class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel):
vpaint = toolsettings.vertex_paint
col = layout.column()
col.label("Falloff:")
row = col.row()
# col.prop(vpaint, "mode", text="")
row.prop(vpaint, "use_normal")
row.prop(vpaint, "falloff_shape", expand=True)
row = col.row()
row.prop(vpaint, "use_backface_culling")
row = col.row()
row.prop(vpaint, "use_normal_falloff")
sub = row.row()
sub.active = (vpaint.use_normal_falloff)
sub.prop(vpaint, "normal_angle", text="")
col.prop(vpaint, "use_spray")
self.unified_paint_settings(col, context)
# Commented out because the Apply button isn't an operator yet, making these settings useless
#~ col.label(text="Gamma:")
#~ col.prop(vpaint, "gamma", text="")
#~ col.label(text="Multiply:")
#~ col.prop(vpaint, "mul", text="")
class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel):
bl_category = "Tools"

View File

@@ -70,7 +70,7 @@ void BKE_brush_randomize_texture_coords(struct UnifiedPaintSettings *ups, bool m
/* brush curve */
void BKE_brush_curve_preset(struct Brush *b, int preset);
float BKE_brush_curve_strength_clamped(struct Brush *br, float p, const float len);
float BKE_brush_curve_strength(struct Brush *br, float p, const float len);
float BKE_brush_curve_strength(const struct Brush *br, float p, const float len);
/* sampling */
float BKE_brush_sample_tex_3D(

View File

@@ -230,9 +230,12 @@ typedef struct SculptSession {
/* Vertex aligned arrays of weights. */
float *previous_accum;
float *previous_weight;
/* Keep track of how much each vertex has been painted (non-airbrush only). */
float *alpha_weight;
/* Needed to continuously re-apply over the same weights (VP_FLAG_SPRAY disabled).
* Lazy initialize as needed (flag is set to 1 to tag it as uninitialized). */
struct MDeformVert *dvert_prev;
} wpaint;
//struct {

View File

@@ -966,7 +966,7 @@ void BKE_brush_randomize_texture_coords(UnifiedPaintSettings *ups, bool mask)
}
/* Uses the brush curve control to find a strength value */
float BKE_brush_curve_strength(Brush *br, float p, const float len)
float BKE_brush_curve_strength(const Brush *br, float p, const float len)
{
float strength;

View File

@@ -641,18 +641,8 @@ static void cdDM_drawMappedFaces(
/* avoid buffer problems in following code */
}
else if (setDrawOptions == NULL) {
const bool show_alpha = true;
if (show_alpha) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
/* just draw the entire face array */
GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, 0, tot_tri_elem);
if (show_alpha) {
glDisable(GL_BLEND);
}
}
else {
for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) {

View File

@@ -49,6 +49,7 @@
#include "BKE_brush.h"
#include "BKE_colortools.h"
#include "BKE_deform.h"
#include "BKE_main.h"
#include "BKE_context.h"
#include "BKE_crazyspace.h"
@@ -689,8 +690,12 @@ void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss)
gmap = &ss->mode.wpaint.gmap;
MEM_SAFE_FREE(ss->mode.wpaint.alpha_weight);
MEM_SAFE_FREE(ss->mode.wpaint.previous_weight);
MEM_SAFE_FREE(ss->mode.wpaint.previous_accum);
if (ss->mode.wpaint.dvert_prev) {
BKE_defvert_array_free_elems(ss->mode.wpaint.dvert_prev, ss->totvert);
MEM_freeN(ss->mode.wpaint.dvert_prev);
ss->mode.wpaint.dvert_prev = NULL;
}
}
else {
return;

View File

@@ -2199,12 +2199,12 @@ static void ccgDM_buffer_copy_color(
for (S = 0; S < numVerts; S++) {
for (y = 0; y < gridFaces; y++) {
for (x = 0; x < gridFaces; x++) {
copy_v3_v3_uchar(&varray[start + 0], &mloopcol[iface * 16 + 0]);
copy_v3_v3_uchar(&varray[start + 3], &mloopcol[iface * 16 + 12]);
copy_v3_v3_uchar(&varray[start + 6], &mloopcol[iface * 16 + 8]);
copy_v3_v3_uchar(&varray[start + 9], &mloopcol[iface * 16 + 4]);
copy_v4_v4_uchar(&varray[start + 0], &mloopcol[iface * 16 + 0]);
copy_v4_v4_uchar(&varray[start + 4], &mloopcol[iface * 16 + 12]);
copy_v4_v4_uchar(&varray[start + 8], &mloopcol[iface * 16 + 8]);
copy_v4_v4_uchar(&varray[start + 12], &mloopcol[iface * 16 + 4]);
start += 12;
start += 16;
iface++;
}
}
@@ -3544,16 +3544,16 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
if (cp) glColor3ubv(&cp[4]);
if (cp) glColor4ubv(&cp[4]);
glNormal3fv(ln[1]);
glVertex3fv(d);
if (cp) glColor3ubv(&cp[8]);
if (cp) glColor4ubv(&cp[8]);
glNormal3fv(ln[2]);
glVertex3fv(c);
if (cp) glColor3ubv(&cp[12]);
if (cp) glColor4ubv(&cp[12]);
glNormal3fv(ln[3]);
glVertex3fv(b);
if (cp) glColor3ubv(&cp[0]);
if (cp) glColor4ubv(&cp[0]);
glNormal3fv(ln[0]);
glVertex3fv(a);
@@ -3571,10 +3571,10 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
a = CCG_grid_elem(&key, faceGridData, x, y + 0);
b = CCG_grid_elem(&key, faceGridData, x, y + 1);
if (cp) glColor3ubv(&cp[0]);
if (cp) glColor4ubv(&cp[0]);
glNormal3fv(CCG_elem_no(&key, a));
glVertex3fv(CCG_elem_co(&key, a));
if (cp) glColor3ubv(&cp[4]);
if (cp) glColor4ubv(&cp[4]);
glNormal3fv(CCG_elem_no(&key, b));
glVertex3fv(CCG_elem_co(&key, b));
@@ -3586,10 +3586,10 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
a = CCG_grid_elem(&key, faceGridData, x, y + 0);
b = CCG_grid_elem(&key, faceGridData, x, y + 1);
if (cp) glColor3ubv(&cp[12]);
if (cp) glColor4ubv(&cp[12]);
glNormal3fv(CCG_elem_no(&key, a));
glVertex3fv(CCG_elem_co(&key, a));
if (cp) glColor3ubv(&cp[8]);
if (cp) glColor4ubv(&cp[8]);
glNormal3fv(CCG_elem_no(&key, b));
glVertex3fv(CCG_elem_co(&key, b));
@@ -3609,13 +3609,13 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
ccgDM_glNormalFast(a, b, c, d);
if (cp) glColor3ubv(&cp[4]);
if (cp) glColor4ubv(&cp[4]);
glVertex3fv(d);
if (cp) glColor3ubv(&cp[8]);
if (cp) glColor4ubv(&cp[8]);
glVertex3fv(c);
if (cp) glColor3ubv(&cp[12]);
if (cp) glColor4ubv(&cp[12]);
glVertex3fv(b);
if (cp) glColor3ubv(&cp[0]);
if (cp) glColor4ubv(&cp[0]);
glVertex3fv(a);
if (cp) cp += 16;

View File

@@ -119,6 +119,26 @@ float dist_squared_ray_to_seg_v3(
const float ray_origin[3], const float ray_direction[3],
const float v0[3], const float v1[3],
float r_point[3], float *r_depth);
struct DistRayAABB_Precalc {
float ray_origin[3];
float ray_direction[3];
float ray_inv_dir[3];
bool sign[3];
};
void dist_squared_ray_to_aabb_precalc(
struct DistRayAABB_Precalc *neasrest_precalc,
const float ray_origin[3], const float ray_direction[3]);
float dist_squared_ray_to_aabb(
const struct DistRayAABB_Precalc *data,
const float bb_min[3], const float bb_max[3],
float r_point[3], float *r_depth);
/* when there is no advantage to precalc. */
float dist_squared_to_ray_to_aabb_simple(
const float ray_origin[3], const float ray_direction[3],
const float bb_min[3], const float bb_max[3],
float r_point[3], float *r_depth);
float closest_to_line_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2]);
float closest_to_line_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3]);
void closest_to_line_segment_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2]);

View File

@@ -619,6 +619,152 @@ float dist_squared_ray_to_seg_v3(
return len_squared_v3(t) - SQUARE(*r_depth);
}
/* -------------------------------------------------------------------- */
/** \name dist_squared_to_ray_to_aabb and helpers
* \{ */
void dist_squared_ray_to_aabb_precalc(
struct DistRayAABB_Precalc *neasrest_precalc,
const float ray_origin[3], const float ray_direction[3])
{
copy_v3_v3(neasrest_precalc->ray_origin, ray_origin);
copy_v3_v3(neasrest_precalc->ray_direction, ray_direction);
for (int i = 0; i < 3; i++) {
neasrest_precalc->ray_inv_dir[i] =
(neasrest_precalc->ray_direction[i] != 0.0f) ?
(1.0f / neasrest_precalc->ray_direction[i]) : FLT_MAX;
neasrest_precalc->sign[i] = (neasrest_precalc->ray_inv_dir[i] < 0.0f);
}
}
/**
* Returns the distance from a ray to a bound-box (projected on ray)
*/
float dist_squared_ray_to_aabb(
const struct DistRayAABB_Precalc *data,
const float bb_min[3], const float bb_max[3],
float r_point[3], float *r_depth)
{
// bool r_axis_closest[3];
float local_bvmin[3], local_bvmax[3];
if (data->sign[0]) {
local_bvmin[0] = bb_max[0];
local_bvmax[0] = bb_min[0];
}
else {
local_bvmin[0] = bb_min[0];
local_bvmax[0] = bb_max[0];
}
if (data->sign[1]) {
local_bvmin[1] = bb_max[1];
local_bvmax[1] = bb_min[1];
}
else {
local_bvmin[1] = bb_min[1];
local_bvmax[1] = bb_max[1];
}
if (data->sign[2]) {
local_bvmin[2] = bb_max[2];
local_bvmax[2] = bb_min[2];
}
else {
local_bvmin[2] = bb_min[2];
local_bvmax[2] = bb_max[2];
}
const float tmin[3] = {
(local_bvmin[0] - data->ray_origin[0]) * data->ray_inv_dir[0],
(local_bvmin[1] - data->ray_origin[1]) * data->ray_inv_dir[1],
(local_bvmin[2] - data->ray_origin[2]) * data->ray_inv_dir[2],
};
const float tmax[3] = {
(local_bvmax[0] - data->ray_origin[0]) * data->ray_inv_dir[0],
(local_bvmax[1] - data->ray_origin[1]) * data->ray_inv_dir[1],
(local_bvmax[2] - data->ray_origin[2]) * data->ray_inv_dir[2],
};
/* `va` and `vb` are the coordinates of the AABB edge closest to the ray */
float va[3], vb[3];
/* `rtmin` and `rtmax` are the minimum and maximum distances of the ray hits on the AABB */
float rtmin, rtmax;
int main_axis;
if ((tmax[0] <= tmax[1]) && (tmax[0] <= tmax[2])) {
rtmax = tmax[0];
va[0] = vb[0] = local_bvmax[0];
main_axis = 3;
// r_axis_closest[0] = data->sign[0];
}
else if ((tmax[1] <= tmax[0]) && (tmax[1] <= tmax[2])) {
rtmax = tmax[1];
va[1] = vb[1] = local_bvmax[1];
main_axis = 2;
// r_axis_closest[1] = data->sign[1];
}
else {
rtmax = tmax[2];
va[2] = vb[2] = local_bvmax[2];
main_axis = 1;
// r_axis_closest[2] = data->sign[2];
}
if ((tmin[0] >= tmin[1]) && (tmin[0] >= tmin[2])) {
rtmin = tmin[0];
va[0] = vb[0] = local_bvmin[0];
main_axis -= 3;
// r_axis_closest[0] = !data->sign[0];
}
else if ((tmin[1] >= tmin[0]) && (tmin[1] >= tmin[2])) {
rtmin = tmin[1];
va[1] = vb[1] = local_bvmin[1];
main_axis -= 1;
// r_axis_closest[1] = !data->sign[1];
}
else {
rtmin = tmin[2];
va[2] = vb[2] = local_bvmin[2];
main_axis -= 2;
// r_axis_closest[2] = !data->sign[2];
}
if (main_axis < 0) {
main_axis += 3;
}
/* if rtmin <= rtmax, ray intersect `AABB` */
if (rtmin <= rtmax) {
float dvec[3];
copy_v3_v3(r_point, local_bvmax);
sub_v3_v3v3(dvec, local_bvmax, data->ray_origin);
*r_depth = dot_v3v3(dvec, data->ray_direction);
return 0.0f;
}
if (data->sign[main_axis]) {
va[main_axis] = local_bvmax[main_axis];
vb[main_axis] = local_bvmin[main_axis];
}
else {
va[main_axis] = local_bvmin[main_axis];
vb[main_axis] = local_bvmax[main_axis];
}
return dist_squared_ray_to_seg_v3(
data->ray_origin, data->ray_direction, va, vb,
r_point, r_depth);
}
float dist_squared_to_ray_to_aabb_simple(
const float ray_origin[3], const float ray_direction[3],
const float bbmin[3], const float bbmax[3],
float r_point[3], float *r_depth)
{
struct DistRayAABB_Precalc data;
dist_squared_ray_to_aabb_precalc(&data, ray_origin, ray_direction);
return dist_squared_ray_to_aabb(&data, bbmin, bbmax, r_point, r_depth);
}
/** \} */
/* Adapted from "Real-Time Collision Detection" by Christer Ericson,
* published by Morgan Kaufmann Publishers, copyright 2005 Elsevier Inc.
*

View File

@@ -1653,23 +1653,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
{
Brush *br;
br = (Brush *)BKE_libblock_find_name_ex(main, ID_BR, "Average");
if (!br) {
br = BKE_brush_add(main, "Average", OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT);
br->vertexpaint_tool = PAINT_BLEND_AVERAGE;
br->ob_mode = OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT;
}
br = (Brush *)BKE_libblock_find_name_ex(main, ID_BR, "Smear");
if (!br) {
br = BKE_brush_add(main, "Smear", OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT);
br->vertexpaint_tool = PAINT_BLEND_SMEAR;
br->ob_mode = OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT;
}
}
FOREACH_NODETREE(main, ntree, id) {
if (ntree->type == NTREE_COMPOSIT) {
do_versions_compositor_render_passes(ntree);
@@ -1720,6 +1703,20 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
}
if (!DNA_struct_elem_find(fd->filesdna, "VPaint", "char", "falloff_shape")) {
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
ToolSettings *ts = scene->toolsettings;
for (int i = 0; i < 2; i++) {
VPaint *vp = i ? ts->vpaint : ts->wpaint;
if (vp != NULL) {
/* remove all other flags */
vp->flag &= (VP_FLAG_SPRAY | VP_FLAG_VGROUP_RESTRICT);
vp->normal_angle = 80;
}
}
}
}
}
}

View File

@@ -28,9 +28,11 @@
#include <vector>
extern "C" {
#include "BLI_sys_types.h"
#include "BLI_fileops.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "DNA_node_types.h"
#include "BKE_appdir.h"
#include "BKE_node.h"
@@ -174,7 +176,7 @@ int DebugInfo::graphviz_operation(const ExecutionSystem *system, const NodeOpera
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, "%s\\n(%s)", m_op_names[operation].c_str(), typeid(*operation).name());
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, " (%d,%d)", operation->getWidth(), operation->getHeight());
len += snprintf(str + len, maxlen > len ? maxlen - len : 0, " (%u,%u)", operation->getWidth(), operation->getHeight());
int totoutputs = operation->getNumberOfOutputSockets();
if (totoutputs != 0) {

View File

@@ -52,6 +52,9 @@ void ScaleNode::convertToOperations(NodeConverter &converter, const CompositorCo
converter.mapInputSocket(inputXSocket, operation->getInputSocket(1));
converter.mapInputSocket(inputYSocket, operation->getInputSocket(2));
converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
operation->setVariableSize(inputXSocket->isLinked() ||
inputYSocket->isLinked());
break;
}
case CMP_SCALE_SCENEPERCENT:
@@ -67,6 +70,10 @@ void ScaleNode::convertToOperations(NodeConverter &converter, const CompositorCo
converter.addLink(scaleFactorOperation->getOutputSocket(), operation->getInputSocket(1));
converter.addLink(scaleFactorOperation->getOutputSocket(), operation->getInputSocket(2));
converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
operation->setVariableSize(inputXSocket->isLinked() ||
inputYSocket->isLinked());
break;
}
case CMP_SCALE_RENDERPERCENT:
@@ -81,9 +88,13 @@ void ScaleNode::convertToOperations(NodeConverter &converter, const CompositorCo
operation->setNewHeight(rd->ysch * rd->size / 100.0f);
operation->getInputSocket(0)->setResizeMode(COM_SC_NO_RESIZE);
converter.addOperation(operation);
converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
operation->setVariableSize(inputXSocket->isLinked() ||
inputYSocket->isLinked());
break;
}
case CMP_SCALE_ABSOLUTE:
@@ -91,11 +102,15 @@ void ScaleNode::convertToOperations(NodeConverter &converter, const CompositorCo
/* TODO: what is the use of this one.... perhaps some issues when the ui was updated... */
ScaleAbsoluteOperation *operation = new ScaleAbsoluteOperation();
converter.addOperation(operation);
converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
converter.mapInputSocket(inputXSocket, operation->getInputSocket(1));
converter.mapInputSocket(inputYSocket, operation->getInputSocket(2));
converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
operation->setVariableSize(inputXSocket->isLinked() ||
inputYSocket->isLinked());
break;
}
}

View File

@@ -36,6 +36,7 @@ BaseScaleOperation::BaseScaleOperation()
#else
m_sampler = -1;
#endif
m_variable_size = false;
}
ScaleOperation::ScaleOperation() : BaseScaleOperation()
@@ -87,20 +88,27 @@ void ScaleOperation::executePixelSampled(float output[4], float x, float y, Pixe
bool ScaleOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
rcti newInput;
float scaleX[4];
float scaleY[4];
if (!m_variable_size) {
float scaleX[4];
float scaleY[4];
this->m_inputXOperation->readSampled(scaleX, 0, 0, COM_PS_NEAREST);
this->m_inputYOperation->readSampled(scaleY, 0, 0, COM_PS_NEAREST);
this->m_inputXOperation->readSampled(scaleX, 0, 0, COM_PS_NEAREST);
this->m_inputYOperation->readSampled(scaleY, 0, 0, COM_PS_NEAREST);
const float scx = scaleX[0];
const float scy = scaleY[0];
newInput.xmax = this->m_centerX + (input->xmax - this->m_centerX) / scx;
newInput.xmin = this->m_centerX + (input->xmin - this->m_centerX) / scx;
newInput.ymax = this->m_centerY + (input->ymax - this->m_centerY) / scy;
newInput.ymin = this->m_centerY + (input->ymin - this->m_centerY) / scy;
const float scx = scaleX[0];
const float scy = scaleY[0];
newInput.xmax = this->m_centerX + (input->xmax - this->m_centerX) / scx;
newInput.xmin = this->m_centerX + (input->xmin - this->m_centerX) / scx;
newInput.ymax = this->m_centerY + (input->ymax - this->m_centerY) / scy;
newInput.ymin = this->m_centerY + (input->ymin - this->m_centerY) / scy;
}
else {
newInput.xmax = this->getWidth();
newInput.xmin = 0;
newInput.ymax = this->getHeight();
newInput.ymin = 0;
}
return BaseScaleOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
@@ -162,24 +170,32 @@ void ScaleAbsoluteOperation::executePixelSampled(float output[4], float x, float
bool ScaleAbsoluteOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
rcti newInput;
float scaleX[4];
float scaleY[4];
if (!m_variable_size) {
float scaleX[4];
float scaleY[4];
this->m_inputXOperation->readSampled(scaleX, 0, 0, COM_PS_NEAREST);
this->m_inputYOperation->readSampled(scaleY, 0, 0, COM_PS_NEAREST);
this->m_inputXOperation->readSampled(scaleX, 0, 0, COM_PS_NEAREST);
this->m_inputYOperation->readSampled(scaleY, 0, 0, COM_PS_NEAREST);
const float scx = scaleX[0];
const float scy = scaleY[0];
const float width = this->getWidth();
const float height = this->getHeight();
//div
float relateveXScale = scx / width;
float relateveYScale = scy / height;
const float scx = scaleX[0];
const float scy = scaleY[0];
const float width = this->getWidth();
const float height = this->getHeight();
//div
float relateveXScale = scx / width;
float relateveYScale = scy / height;
newInput.xmax = this->m_centerX + (input->xmax - this->m_centerX) / relateveXScale;
newInput.xmin = this->m_centerX + (input->xmin - this->m_centerX) / relateveXScale;
newInput.ymax = this->m_centerY + (input->ymax - this->m_centerY) / relateveYScale;
newInput.ymin = this->m_centerY + (input->ymin - this->m_centerY) / relateveYScale;
newInput.xmax = this->m_centerX + (input->xmax - this->m_centerX) / relateveXScale;
newInput.xmin = this->m_centerX + (input->xmin - this->m_centerX) / relateveXScale;
newInput.ymax = this->m_centerY + (input->ymax - this->m_centerY) / relateveYScale;
newInput.ymin = this->m_centerY + (input->ymin - this->m_centerY) / relateveYScale;
}
else {
newInput.xmax = this->getWidth();
newInput.xmin = 0;
newInput.ymax = this->getHeight();
newInput.ymin = 0;
}
return BaseScaleOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}

View File

@@ -28,6 +28,7 @@
class BaseScaleOperation : public NodeOperation {
public:
void setSampler(PixelSampler sampler) { this->m_sampler = (int) sampler; }
void setVariableSize(bool variable_size) { m_variable_size = variable_size; };
protected:
BaseScaleOperation();
@@ -35,6 +36,7 @@ protected:
PixelSampler getEffectiveSampler(PixelSampler sampler) { return (m_sampler == -1) ? sampler : (PixelSampler) m_sampler; }
int m_sampler;
bool m_variable_size;
};
class ScaleOperation : public BaseScaleOperation {

View File

@@ -454,15 +454,6 @@ int join_mesh_exec(bContext *C, wmOperator *op)
/* adjust settings to fit (allocate a new data-array) */
kbn->data = MEM_callocN(sizeof(float) * 3 * totvert, "joined_shapekey");
kbn->totelem = totvert;
/* XXX 2.5 Animato */
#if 0
/* also, copy corresponding ipo-curve to ipo-block if applicable */
if (me->key->ipo && key->ipo) {
/* FIXME... this is a luxury item! */
puts("FIXME: ignoring IPO's when joining shapekeys on Meshes for now...");
}
#endif
}
kb_map[i] = kbn;

File diff suppressed because it is too large Load Diff

View File

@@ -281,7 +281,7 @@ BLI_INLINE uint mcol_darken(uint col1, uint col2, int fac)
BLI_INLINE uint mcol_colordodge(uint col1, uint col2, int fac)
{
uchar *cp1, *cp2, *cp;
int mfac,temp;
int mfac, temp;
uint col = 0;
if (fac == 0) {

View File

@@ -676,15 +676,14 @@ static void gradientVertInit__mapFunc(
static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
int ret = WM_gesture_straightline_modal(C, op, event);
wmGesture *gesture = op->customdata;
DMGradient_vertStoreBase *vert_cache = gesture->userdata;
bool do_gesture_free = false;
int ret = WM_gesture_straightline_modal(C, op, event);
if (ret & OPERATOR_RUNNING_MODAL) {
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) { /* XXX, hardcoded */
/* generally crap! redo! */
do_gesture_free = true;
WM_gesture_straightline_cancel(C, op);
ret &= ~OPERATOR_RUNNING_MODAL;
ret |= OPERATOR_FINISHED;
}
@@ -698,16 +697,14 @@ static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEven
BKE_defvert_array_copy(me->dvert, vert_cache->wpp.wpaint_prev, me->totvert);
wpaint_prev_destroy(&vert_cache->wpp);
}
MEM_freeN(vert_cache);
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
else if (ret & OPERATOR_FINISHED) {
wpaint_prev_destroy(&vert_cache->wpp);
}
if (do_gesture_free) {
WM_gesture_straightline_cancel(C, op);
MEM_freeN(vert_cache);
}
return ret;
@@ -743,6 +740,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
sizeof(DMGradient_vertStoreBase) +
(sizeof(DMGradient_vertStore) * me->totvert),
__func__);
gesture->userdata_free = false;
data.is_init = true;
wpaint_prev_create(&((DMGradient_vertStoreBase *)gesture->userdata)->wpp, me->dvert, me->totvert);

View File

@@ -185,6 +185,93 @@ BLI_INLINE float wval_darken(const float weight, const float paintval, const flo
return (weight > paintval) ? wval_blend(weight, paintval, alpha) : weight;
}
/* mainly for color */
BLI_INLINE float wval_colordodge(float weight, float paintval, float fac)
{
float mfac, temp;
if (fac == 0.0f) {
return weight;
}
mfac = 1.0f - fac;
temp = (paintval == 1.0f) ? 1.0f : min_ff((weight * (225.0f / 255.0f)) / (1.0f - paintval), 1.0f);
return mfac * weight + temp * fac;
}
BLI_INLINE float wval_difference(float weight, float paintval, float fac)
{
float mfac, temp;
if (fac == 0.0f) {
return weight;
}
mfac = 1.0f - fac;
temp = fabsf(weight - paintval);
return mfac * weight + temp * fac;
}
BLI_INLINE float wval_screen(float weight, float paintval, float fac)
{
float mfac, temp;
if (fac == 0.0f) {
return weight;
}
mfac = 1.0f - fac;
temp = max_ff(1.0f - (((1.0f - weight) * (1.0f - paintval))), 0);
return mfac * weight + temp * fac;
}
BLI_INLINE float wval_hardlight(float weight, float paintval, float fac)
{
float mfac, temp;
if (fac == 0.0f) {
return weight;
}
mfac = 1.0f - fac;
if (paintval > 0.5f) {
temp = 1.0f - ((1.0f - 2.0f * (paintval - 0.5f)) * (1.0f - weight));
}
else {
temp = (2.0f * paintval * weight);
}
return mfac * weight + temp * fac;
}
BLI_INLINE float wval_overlay(float weight, float paintval, float fac)
{
float mfac, temp;
if (fac == 0.0f) {
return weight;
}
mfac = 1.0f - fac;
if (weight > 0.5f) {
temp = 1.0f - ((1.0f - 2.0f * (weight - 0.5f)) * (1.0f - paintval));
}
else {
temp = (2.0f * paintval * weight);
}
return mfac * weight + temp * fac;
}
BLI_INLINE float wval_softlight(float weight, float paintval, float fac)
{
float mfac, temp;
if (fac == 0.0f) {
return weight;
}
mfac = 1.0f - fac;
if (weight < 0.5f) {
temp = ((2.0f * ((paintval / 2.0f) + 0.25f)) * weight);
}
else {
temp = 1.0f - (2.0f * (1.0f - ((paintval / 2.0f) + 0.25f)) * (1.0f - weight));
}
return temp * fac + weight * mfac;
}
BLI_INLINE float wval_exclusion(float weight, float paintval, float fac)
{
float mfac, temp;
if (fac == 0.0f) {
return weight;
}
mfac = 1.0f - fac;
temp = 0.5f - ((2.0f * (weight - 0.5f) * (paintval - 0.5f)));
return temp * fac + weight * mfac;
}
/* vpaint has 'vpaint_blend_tool' */
/* result is not clamped from [0-1] */
float ED_wpaint_blend_tool(
@@ -197,15 +284,27 @@ float ED_wpaint_blend_tool(
case PAINT_BLEND_MIX:
case PAINT_BLEND_AVERAGE:
case PAINT_BLEND_SMEAR:
case PAINT_BLEND_BLUR: return wval_blend(weight, paintval, alpha);
case PAINT_BLEND_ADD: return wval_add(weight, paintval, alpha);
case PAINT_BLEND_SUB: return wval_sub(weight, paintval, alpha);
case PAINT_BLEND_MUL: return wval_mul(weight, paintval, alpha);
case PAINT_BLEND_LIGHTEN: return wval_lighten(weight, paintval, alpha);
case PAINT_BLEND_DARKEN: return wval_darken(weight, paintval, alpha);
default:
BLI_assert(0);
return 0.0f;
case PAINT_BLEND_BLUR: return wval_blend(weight, paintval, alpha);
case PAINT_BLEND_ADD: return wval_add(weight, paintval, alpha);
case PAINT_BLEND_SUB: return wval_sub(weight, paintval, alpha);
case PAINT_BLEND_MUL: return wval_mul(weight, paintval, alpha);
case PAINT_BLEND_LIGHTEN: return wval_lighten(weight, paintval, alpha);
case PAINT_BLEND_DARKEN: return wval_darken(weight, paintval, alpha);
/* Mostly make sense for color: support anyway. */
case PAINT_BLEND_COLORDODGE: return wval_colordodge(weight, paintval, alpha);
case PAINT_BLEND_DIFFERENCE: return wval_difference(weight, paintval, alpha);
case PAINT_BLEND_SCREEN: return wval_screen(weight, paintval, alpha);
case PAINT_BLEND_HARDLIGHT: return wval_hardlight(weight, paintval, alpha);
case PAINT_BLEND_OVERLAY: return wval_overlay(weight, paintval, alpha);
case PAINT_BLEND_SOFTLIGHT: return wval_softlight(weight, paintval, alpha);
case PAINT_BLEND_EXCLUSION: return wval_exclusion(weight, paintval, alpha);
/* Only for color: just use blend. */
case PAINT_BLEND_LUMINOCITY:
case PAINT_BLEND_SATURATION:
case PAINT_BLEND_HUE:
case PAINT_BLEND_ALPHA_SUB:
case PAINT_BLEND_ALPHA_ADD:
default: return wval_blend(weight, paintval, alpha);
}
}

View File

@@ -523,6 +523,9 @@ void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test)
copy_v3_v3(test->location, ss->cache->location);
test->dist = 0.0f; /* just for initialize */
/* Only for 2D projection. */
zero_v4(test->plane);
test->mirror_symmetry_pass = ss->cache->mirror_symmetry_pass;
if (rv3d->rflag & RV3D_CLIPPING) {
@@ -544,7 +547,7 @@ BLI_INLINE bool sculpt_brush_test_clipping(const SculptBrushTest *test, const fl
return ED_view3d_clipping_test(rv3d, symm_co, true);
}
bool sculpt_brush_test(SculptBrushTest *test, const float co[3])
bool sculpt_brush_test_sphere(SculptBrushTest *test, const float co[3])
{
float distsq = len_squared_v3v3(co, test->location);
@@ -560,7 +563,7 @@ bool sculpt_brush_test(SculptBrushTest *test, const float co[3])
}
}
bool sculpt_brush_test_sq(SculptBrushTest *test, const float co[3])
bool sculpt_brush_test_sphere_sq(SculptBrushTest *test, const float co[3])
{
float distsq = len_squared_v3v3(co, test->location);
@@ -576,7 +579,7 @@ bool sculpt_brush_test_sq(SculptBrushTest *test, const float co[3])
}
}
bool sculpt_brush_test_fast(const SculptBrushTest *test, const float co[3])
bool sculpt_brush_test_sphere_fast(const SculptBrushTest *test, const float co[3])
{
if (sculpt_brush_test_clipping(test, co)) {
return 0;
@@ -584,6 +587,24 @@ bool sculpt_brush_test_fast(const SculptBrushTest *test, const float co[3])
return len_squared_v3v3(co, test->location) <= test->radius_squared;
}
bool sculpt_brush_test_circle_sq(SculptBrushTest *test, const float co[3])
{
float co_proj[3];
closest_to_plane_normalized_v3(co_proj, test->plane, co);
float distsq = len_squared_v3v3(co_proj, test->location);
if (distsq <= test->radius_squared) {
if (sculpt_brush_test_clipping(test, co)) {
return 0;
}
test->dist = distsq;
return 1;
}
else {
return 0;
}
}
bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float local[4][4])
{
float side = M_SQRT1_2;
@@ -639,7 +660,7 @@ static float frontface(Brush *br, const float sculpt_normal[3],
static bool sculpt_brush_test_cyl(SculptBrushTest *test, float co[3], float location[3], const float area_no[3])
{
if (sculpt_brush_test_fast(test, co)) {
if (sculpt_brush_test_sphere_fast(test, co)) {
float t1[3], t2[3], t3[3], dist;
sub_v3_v3v3(t1, location, co);
@@ -786,7 +807,7 @@ static void calc_area_normal_and_center_task_cb(void *userdata, const int n)
closest_on_tri_to_point_v3(co, test.location, UNPACK3(co_tri));
if (sculpt_brush_test_fast(&test, co)) {
if (sculpt_brush_test_sphere_fast(&test, co)) {
float no[3];
int flip_index;
@@ -820,7 +841,7 @@ static void calc_area_normal_and_center_task_cb(void *userdata, const int n)
co = vd.co;
}
if (sculpt_brush_test_fast(&test, co)) {
if (sculpt_brush_test_sphere_fast(&test, co)) {
float no_buf[3];
const float *no;
int flip_index;
@@ -1213,6 +1234,24 @@ bool sculpt_search_sphere_cb(PBVHNode *node, void *data_v)
return len_squared_v3(t) < data->radius_squared;
}
/* 2D projection (distance to line). */
bool sculpt_search_circle_cb(PBVHNode *node, void *data_v)
{
SculptSearchCircleData *data = data_v;
float bb_min[3], bb_max[3];
if (data->original)
BKE_pbvh_node_get_original_BB(node, bb_min, bb_max);
else
BKE_pbvh_node_get_BB(node, bb_min, bb_min);
float dummy_co[3], dummy_depth;
const float dist_sq = dist_squared_ray_to_aabb(
data->dist_ray_to_aabb_precalc, bb_min, bb_max, dummy_co, &dummy_depth);
return dist_sq < data->radius_squared;
}
/* Handles clipping against a mirror modifier and SCULPT_LOCK axis flags */
static void sculpt_clip(Sculpt *sd, SculptSession *ss, float co[3], const float val[3])
{
@@ -1530,7 +1569,7 @@ static void do_smooth_brush_mesh_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
if (sculpt_brush_test_sphere(&test, vd.co)) {
const float fade = bstrength * tex_strength(
ss, brush, vd.co, test.dist, vd.no, vd.fno,
smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f),
@@ -1578,7 +1617,7 @@ static void do_smooth_brush_bmesh_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
if (sculpt_brush_test_sphere(&test, vd.co)) {
const float fade = bstrength * tex_strength(
ss, brush, vd.co, test.dist, vd.no, vd.fno, smooth_mask ? 0.0f : *vd.mask,
thread_id);
@@ -1717,7 +1756,7 @@ static void do_smooth_brush_multires_task_cb_ex(
fno = CCG_elem_offset_no(&key, gddata, index);
mask = CCG_elem_offset_mask(&key, gddata, index);
if (sculpt_brush_test(&test, co)) {
if (sculpt_brush_test_sphere(&test, co)) {
const float strength_mask = (smooth_mask ? 0.0f : *mask);
const float fade = bstrength * tex_strength(
ss, brush, co, test.dist, NULL, fno, strength_mask, thread_id);
@@ -1837,7 +1876,7 @@ static void do_mask_brush_draw_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
if (sculpt_brush_test_sphere(&test, vd.co)) {
const float fade = tex_strength(ss, brush, vd.co, test.dist, vd.no, vd.fno, 0.0f, thread_id);
(*vd.mask) += fade * bstrength;
@@ -1897,7 +1936,7 @@ static void do_draw_brush_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
if (sculpt_brush_test_sphere(&test, vd.co)) {
/* offset vertex */
const float fade = tex_strength(
ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id);
@@ -1958,7 +1997,7 @@ static void do_crease_brush_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
if (sculpt_brush_test_sphere(&test, vd.co)) {
/* offset vertex */
const float fade = tex_strength(
ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id);
@@ -2044,7 +2083,7 @@ static void do_pinch_brush_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
if (sculpt_brush_test_sphere(&test, vd.co)) {
const float fade = bstrength * tex_strength(
ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id);
float val[3];
@@ -2096,7 +2135,7 @@ static void do_grab_brush_task_cb_ex(
{
sculpt_orig_vert_data_update(&orig_data, &vd);
if (sculpt_brush_test(&test, orig_data.co)) {
if (sculpt_brush_test_sphere(&test, orig_data.co)) {
const float fade = bstrength * tex_strength(
ss, brush, orig_data.co, test.dist, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f,
thread_id);
@@ -2151,7 +2190,7 @@ static void do_nudge_brush_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
if (sculpt_brush_test_sphere(&test, vd.co)) {
const float fade = bstrength * tex_strength(
ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id);
@@ -2210,7 +2249,7 @@ static void do_snake_hook_brush_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
if (sculpt_brush_test_sphere(&test, vd.co)) {
const float fade = bstrength * tex_strength(
ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id);
@@ -2311,7 +2350,7 @@ static void do_thumb_brush_task_cb_ex(
{
sculpt_orig_vert_data_update(&orig_data, &vd);
if (sculpt_brush_test(&test, orig_data.co)) {
if (sculpt_brush_test_sphere(&test, orig_data.co)) {
const float fade = bstrength * tex_strength(
ss, brush, orig_data.co, test.dist, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f,
thread_id);
@@ -2371,7 +2410,7 @@ static void do_rotate_brush_task_cb_ex(
{
sculpt_orig_vert_data_update(&orig_data, &vd);
if (sculpt_brush_test(&test, orig_data.co)) {
if (sculpt_brush_test_sphere(&test, orig_data.co)) {
float vec[3], rot[3][3];
const float fade = bstrength * tex_strength(
ss, brush, orig_data.co, test.dist, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f,
@@ -2439,7 +2478,7 @@ static void do_layer_brush_task_cb_ex(
{
sculpt_orig_vert_data_update(&orig_data, &vd);
if (sculpt_brush_test(&test, orig_data.co)) {
if (sculpt_brush_test_sphere(&test, orig_data.co)) {
const float fade = bstrength * tex_strength(
ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id);
float *disp = &layer_disp[vd.i];
@@ -2511,7 +2550,7 @@ static void do_inflate_brush_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test(&test, vd.co)) {
if (sculpt_brush_test_sphere(&test, vd.co)) {
const float fade = bstrength * tex_strength(
ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id);
float val[3];
@@ -2617,16 +2656,6 @@ static void calc_sculpt_plane(
}
}
/* Projects a point onto a plane along the plane's normal */
static void point_plane_project(
float intr[3],
const float co[3], const float plane_normal[3], const float plane_center[3])
{
sub_v3_v3v3(intr, co, plane_center);
mul_v3_v3fl(intr, plane_normal, dot_v3v3(plane_normal, intr));
sub_v3_v3v3(intr, co, intr);
}
static int plane_trim(const StrokeCache *cache, const Brush *brush, const float val[3])
{
return (!(brush->flag & BRUSH_PLANE_TRIM) ||
@@ -2634,26 +2663,18 @@ static int plane_trim(const StrokeCache *cache, const Brush *brush, const float
}
static bool plane_point_side_flip(
const float co[3], const float plane_normal[3], const float plane_center[3],
const float co[3], const float plane[4],
const bool flip)
{
float delta[3];
float d;
sub_v3_v3v3(delta, co, plane_center);
d = dot_v3v3(plane_normal, delta);
float d = plane_point_side_v3(plane, co);
if (flip) d = -d;
return d <= 0.0f;
}
static int plane_point_side(const float co[3], const float plane_normal[3], const float plane_center[3])
static int plane_point_side(const float co[3], const float plane[4])
{
float delta[3];
sub_v3_v3v3(delta, co, plane_center);
return dot_v3v3(plane_normal, delta) <= 0.0f;
float d = plane_point_side_v3(plane, co);
return d <= 0.0f;
}
static float get_offset(Sculpt *sd, SculptSession *ss)
@@ -2686,14 +2707,15 @@ static void do_flatten_brush_task_cb_ex(
proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
sculpt_brush_test_init(ss, &test);
plane_from_point_normal_v3(test.plane, area_co, area_no);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq(&test, vd.co)) {
if (sculpt_brush_test_sphere_sq(&test, vd.co)) {
float intr[3];
float val[3];
point_plane_project(intr, vd.co, area_no, area_co);
closest_to_plane_normalized_v3(intr, test.plane, vd.co);
sub_v3_v3v3(val, intr, vd.co);
@@ -2762,15 +2784,16 @@ static void do_clay_brush_task_cb_ex(
proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
sculpt_brush_test_init(ss, &test);
plane_from_point_normal_v3(test.plane, area_co, area_no);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq(&test, vd.co)) {
if (plane_point_side_flip(vd.co, area_no, area_co, flip)) {
if (sculpt_brush_test_sphere_sq(&test, vd.co)) {
if (plane_point_side_flip(vd.co, test.plane, flip)) {
float intr[3];
float val[3];
point_plane_project(intr, vd.co, area_no, area_co);
closest_to_plane_normalized_v3(intr, test.plane, vd.co);
sub_v3_v3v3(val, intr, vd.co);
@@ -2846,15 +2869,16 @@ static void do_clay_strips_brush_task_cb_ex(
proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
sculpt_brush_test_init(ss, &test);
plane_from_point_normal_v3(test.plane, area_co, area_no_sp);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_cube(&test, vd.co, mat)) {
if (plane_point_side_flip(vd.co, area_no_sp, area_co, flip)) {
if (plane_point_side_flip(vd.co, test.plane, flip)) {
float intr[3];
float val[3];
point_plane_project(intr, vd.co, area_no_sp, area_co);
closest_to_plane_normalized_v3(intr, test.plane, vd.co);
sub_v3_v3v3(val, intr, vd.co);
@@ -2953,15 +2977,16 @@ static void do_fill_brush_task_cb_ex(
proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
sculpt_brush_test_init(ss, &test);
plane_from_point_normal_v3(test.plane, area_co, area_no);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq(&test, vd.co)) {
if (plane_point_side(vd.co, area_no, area_co)) {
if (sculpt_brush_test_sphere_sq(&test, vd.co)) {
if (plane_point_side(vd.co, test.plane)) {
float intr[3];
float val[3];
point_plane_project(intr, vd.co, area_no, area_co);
closest_to_plane_normalized_v3(intr, test.plane, vd.co);
sub_v3_v3v3(val, intr, vd.co);
@@ -3031,15 +3056,16 @@ static void do_scrape_brush_task_cb_ex(
proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
sculpt_brush_test_init(ss, &test);
plane_from_point_normal_v3(test.plane, area_co, area_no);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq(&test, vd.co)) {
if (!plane_point_side(vd.co, area_no, area_co)) {
if (sculpt_brush_test_sphere_sq(&test, vd.co)) {
if (!plane_point_side(vd.co, test.plane)) {
float intr[3];
float val[3];
point_plane_project(intr, vd.co, area_no, area_co);
closest_to_plane_normalized_v3(intr, test.plane, vd.co);
sub_v3_v3v3(val, intr, vd.co);
@@ -3109,7 +3135,7 @@ static void do_gravity_task_cb_ex(
sculpt_brush_test_init(ss, &test);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
if (sculpt_brush_test_sq(&test, vd.co)) {
if (sculpt_brush_test_sphere_sq(&test, vd.co)) {
const float fade = tex_strength(
ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f,
thread_id);

View File

@@ -181,10 +181,15 @@ typedef struct SculptBrushTest {
float dist;
int mirror_symmetry_pass;
/* For circle (not sphere) projection. */
float plane[4];
/* View3d clipping - only set rv3d for clipping */
struct RegionView3D *clip_rv3d;
} SculptBrushTest;
typedef bool (*SculptBrushTestFn)(SculptBrushTest *test, const float co[3]);
typedef struct {
struct Sculpt *sd;
struct SculptSession *ss;
@@ -192,12 +197,22 @@ typedef struct {
bool original;
} SculptSearchSphereData;
typedef struct {
struct Sculpt *sd;
struct SculptSession *ss;
float radius_squared;
bool original;
struct DistRayAABB_Precalc *dist_ray_to_aabb_precalc;
} SculptSearchCircleData;
void sculpt_brush_test_init(struct SculptSession *ss, SculptBrushTest *test);
bool sculpt_brush_test(SculptBrushTest *test, const float co[3]);
bool sculpt_brush_test_sq(SculptBrushTest *test, const float co[3]);
bool sculpt_brush_test_fast(const SculptBrushTest *test, const float co[3]);
bool sculpt_brush_test_sphere(SculptBrushTest *test, const float co[3]);
bool sculpt_brush_test_sphere_sq(SculptBrushTest *test, const float co[3]);
bool sculpt_brush_test_sphere_fast(const SculptBrushTest *test, const float co[3]);
bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float local[4][4]);
bool sculpt_brush_test_circle_sq(SculptBrushTest *test, const float co[3]);
bool sculpt_search_sphere_cb(PBVHNode *node, void *data_v);
bool sculpt_search_circle_cb(PBVHNode *node, void *data_v);
float tex_strength(
struct SculptSession *ss, struct Brush *br,
const float point[3],

View File

@@ -813,26 +813,51 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
}
/* copy pixel data. While copying, we flip the image vertically. */
const int channels_in_float = ibuf->channels ? ibuf->channels : 4;
for (x = 0; x < ibuf->x; x++) {
for (y = 0; y < ibuf->y; y++) {
from_i = 4 * (y * ibuf->x + x);
from_i = ((size_t)channels_in_float) * (y * ibuf->x + x);
to_i = samplesperpixel * ((ibuf->y - y - 1) * ibuf->x + x);
if (pixels16) {
/* convert from float source */
float rgb[4];
if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
/* float buffer was managed already, no need in color space conversion */
copy_v3_v3(rgb, &fromf[from_i]);
if (channels_in_float == 3 || channels_in_float == 4) {
if (ibuf->float_colorspace ||
(ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA))
{
/* Float buffer was managed already, no need in color
* space conversion.
*/
copy_v3_v3(rgb, &fromf[from_i]);
}
else {
/* Standard linear-to-srgb conversion if float buffer
* wasn't managed.
*/
linearrgb_to_srgb_v3_v3(rgb, &fromf[from_i]);
}
if (channels_in_float == 4) {
rgb[3] = fromf[from_i + 3];
}
else {
rgb[3] = 1.0f;
}
}
else {
/* standard linear-to-srgb conversion if float buffer wasn't managed */
linearrgb_to_srgb_v3_v3(rgb, &fromf[from_i]);
if (ibuf->float_colorspace ||
(ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA))
{
rgb[0] = fromf[from_i];
}
else {
rgb[0] = linearrgb_to_srgb(fromf[from_i]);
}
rgb[1] = rgb[2] = rgb[0];
rgb[3] = 1.0f;
}
rgb[3] = fromf[from_i + 3];
for (i = 0; i < samplesperpixel; i++, to_i++)
to16[to_i] = FTOUSHORT(rgb[i]);
}

View File

@@ -1121,18 +1121,26 @@ typedef struct UvSculpt {
/* Vertex Paint */
typedef struct VPaint {
Paint paint;
short flag, pad;
short flag;
char falloff_shape, normal_angle;
int radial_symm[3]; /* For mirrored painting */
} VPaint;
/* VPaint.flag */
enum {
// VP_COLINDEX = (1 << 0), /* only paint onto active material*/ /* deprecated since before 2.49 */
// VP_AREA = (1 << 1), /* deprecated since 2.70 */
VP_NORMALS = (1 << 3),
VP_SPRAY = (1 << 4),
// VP_MIRROR_X = (1 << 5), /* deprecated in 2.5x use (me->editflag & ME_EDIT_MIRROR_X) */
VP_ONLYVGROUP = (1 << 7) /* weight paint only */
VP_FLAG_PROJECT_BACKFACE = (1 << 0),
/* TODO */
// VP_FLAG_PROJECT_XRAY = (1 << 1),
VP_FLAG_PROJECT_FLAT = (1 << 3),
VP_FLAG_SPRAY = (1 << 4),
/* weight paint only */
VP_FLAG_VGROUP_RESTRICT = (1 << 7)
};
/* VPaint.falloff_shape */
enum {
VP_FALLOFF_SHAPE_SPHERE = 0,
VP_FALLOFF_SHAPE_TUBE = 1,
};
/* ------------------------------------------- */

View File

@@ -690,23 +690,44 @@ static void rna_def_vertex_paint(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_VertexPaint_path");
RNA_def_struct_ui_text(srna, "Vertex Paint", "Properties of vertex and weight paint mode");
/* vertex paint only */
prop = RNA_def_property(srna, "use_normal", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_NORMALS);
RNA_def_property_ui_text(prop, "Normals", "Apply the vertex normal before painting");
static EnumPropertyItem prop_falloff_items[] = {
{VP_FALLOFF_SHAPE_SPHERE, "SPHERE", 0, "Sphere", "Spherical falloff from the brush"},
{VP_FALLOFF_SHAPE_TUBE, "TUBE", 0, "Circle", "Circular falloff from the brush along the view"},
{0, NULL, 0, NULL, NULL}
};
prop = RNA_def_property(srna, "falloff_shape", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "falloff_shape");
RNA_def_property_enum_items(prop, prop_falloff_items);
RNA_def_property_ui_text(prop, "Falloff", "");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "use_backface_culling", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", VP_FLAG_PROJECT_BACKFACE);
RNA_def_property_ui_text(prop, "Cull", "Ignore vertices pointing away from the view (faster)");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "use_normal_falloff", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", VP_FLAG_PROJECT_FLAT);
RNA_def_property_ui_text(prop, "Normals", "Paint most on faces pointing towards the view");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "use_spray", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_SPRAY);
RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_FLAG_SPRAY);
RNA_def_property_ui_text(prop, "Spray", "Keep applying paint effect while holding mouse");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
/* weight paint only */
prop = RNA_def_property(srna, "use_group_restrict", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_ONLYVGROUP);
RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_FLAG_VGROUP_RESTRICT);
RNA_def_property_ui_text(prop, "Restrict", "Restrict painting to vertices in the group");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "normal_angle", PROP_INT, PROP_UNSIGNED);
RNA_def_property_range(prop, 0, 90);
RNA_def_property_ui_text(prop, "Angle", "Paint most on faces pointing towards the view according to this angle");
/* Mirroring */
prop = RNA_def_property(srna, "radial_symmetry", PROP_INT, PROP_XYZ);
RNA_def_property_int_sdna(prop, NULL, "radial_symm");

View File

@@ -428,6 +428,7 @@ typedef struct wmGesture {
/* free pointer to use for operator allocs (if set, its freed on exit)*/
void *userdata;
bool userdata_free;
} wmGesture;
/* ************** wmEvent ************************ */

View File

@@ -71,6 +71,7 @@ wmGesture *WM_gesture_new(bContext *C, const wmEvent *event, int type)
gesture->type = type;
gesture->event_type = event->type;
gesture->swinid = ar->swinid; /* means only in area-region context! */
gesture->userdata_free = true; /* Free if userdata is set. */
wm_subwindow_origin_get(window, gesture->swinid, &sx, &sy);
@@ -114,7 +115,7 @@ void WM_gesture_end(bContext *C, wmGesture *gesture)
win->tweak = NULL;
BLI_remlink(&win->gesture, gesture);
MEM_freeN(gesture->customdata);
if (gesture->userdata) {
if (gesture->userdata && gesture->userdata_free) {
MEM_freeN(gesture->userdata);
}
MEM_freeN(gesture);