Merge branch 'master' into blender2.8

This commit is contained in:
Campbell Barton 2017-10-16 14:31:19 +11:00
commit 14af3e485f
13 changed files with 246 additions and 379 deletions

View File

@ -108,6 +108,73 @@ void BVH::refit(Progress& progress)
refit_nodes();
}
void BVH::refit_primitives(int start, int end, BoundBox& bbox, uint& visibility)
{
/* Refit range of primitives. */
for(int prim = start; prim < end; prim++) {
int pidx = pack.prim_index[prim];
int tob = pack.prim_object[prim];
Object *ob = objects[tob];
if(pidx == -1) {
/* Object instance. */
bbox.grow(ob->bounds);
}
else {
/* Primitives. */
const Mesh *mesh = ob->mesh;
if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
/* Curves. */
int str_offset = (params.top_level)? mesh->curve_offset: 0;
Mesh::Curve curve = mesh->get_curve(pidx - str_offset);
int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox);
visibility |= PATH_RAY_CURVE;
/* Motion curves. */
if(mesh->use_motion_blur) {
Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if(attr) {
size_t mesh_size = mesh->curve_keys.size();
size_t steps = mesh->motion_steps - 1;
float3 *key_steps = attr->data_float3();
for(size_t i = 0; i < steps; i++)
curve.bounds_grow(k, key_steps + i*mesh_size, &mesh->curve_radius[0], bbox);
}
}
}
else {
/* Triangles. */
int tri_offset = (params.top_level)? mesh->tri_offset: 0;
Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
const float3 *vpos = &mesh->verts[0];
triangle.bounds_grow(vpos, bbox);
/* Motion triangles. */
if(mesh->use_motion_blur) {
Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if(attr) {
size_t mesh_size = mesh->verts.size();
size_t steps = mesh->motion_steps - 1;
float3 *vert_steps = attr->data_float3();
for(size_t i = 0; i < steps; i++)
triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
}
}
}
}
visibility |= ob->visibility_for_tracing();
}
}
/* Triangles */
void BVH::pack_triangle(int idx, float4 tri_verts[3])

View File

@ -91,6 +91,9 @@ public:
protected:
BVH(const BVHParams& params, const vector<Object*>& objects);
/* Refit range of primitives. */
void refit_primitives(int start, int end, BoundBox& bbox, uint& visibility);
/* triangles and strands */
void pack_primitives();
void pack_triangle(int idx, float4 storage[3]);

View File

@ -247,73 +247,14 @@ void BVH2::refit_nodes()
void BVH2::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
{
if(leaf) {
/* refit leaf node */
assert(idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size());
const int4 *data = &pack.leaf_nodes[idx];
const int c0 = data[0].x;
const int c1 = data[0].y;
/* refit leaf node */
for(int prim = c0; prim < c1; prim++) {
int pidx = pack.prim_index[prim];
int tob = pack.prim_object[prim];
Object *ob = objects[tob];
if(pidx == -1) {
/* object instance */
bbox.grow(ob->bounds);
}
else {
/* primitives */
const Mesh *mesh = ob->mesh;
BVH::refit_primitives(c0, c1, bbox, visibility);
if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
/* curves */
int str_offset = (params.top_level)? mesh->curve_offset: 0;
Mesh::Curve curve = mesh->get_curve(pidx - str_offset);
int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox);
visibility |= PATH_RAY_CURVE;
/* motion curves */
if(mesh->use_motion_blur) {
Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if(attr) {
size_t mesh_size = mesh->curve_keys.size();
size_t steps = mesh->motion_steps - 1;
float3 *key_steps = attr->data_float3();
for(size_t i = 0; i < steps; i++)
curve.bounds_grow(k, key_steps + i*mesh_size, &mesh->curve_radius[0], bbox);
}
}
}
else {
/* triangles */
int tri_offset = (params.top_level)? mesh->tri_offset: 0;
Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
const float3 *vpos = &mesh->verts[0];
triangle.bounds_grow(vpos, bbox);
/* motion triangles */
if(mesh->use_motion_blur) {
Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if(attr) {
size_t mesh_size = mesh->verts.size();
size_t steps = mesh->motion_steps - 1;
float3 *vert_steps = attr->data_float3();
for(size_t i = 0; i < steps; i++)
triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
}
}
}
}
visibility |= ob->visibility_for_tracing();
}
/* TODO(sergey): De-duplicate with pack_leaf(). */
float4 leaf_data[BVH_NODE_LEAF_SIZE];
leaf_data[0].x = __int_as_float(c0);

View File

@ -375,71 +375,12 @@ void BVH4::refit_nodes()
void BVH4::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
{
if(leaf) {
/* Refit leaf node. */
int4 *data = &pack.leaf_nodes[idx];
int4 c = data[0];
/* Refit leaf node. */
for(int prim = c.x; prim < c.y; prim++) {
int pidx = pack.prim_index[prim];
int tob = pack.prim_object[prim];
Object *ob = objects[tob];
if(pidx == -1) {
/* Object instance. */
bbox.grow(ob->bounds);
}
else {
/* Primitives. */
const Mesh *mesh = ob->mesh;
BVH::refit_primitives(c.x, c.y, bbox, visibility);
if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
/* Curves. */
int str_offset = (params.top_level)? mesh->curve_offset: 0;
Mesh::Curve curve = mesh->get_curve(pidx - str_offset);
int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox);
visibility |= PATH_RAY_CURVE;
/* Motion curves. */
if(mesh->use_motion_blur) {
Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if(attr) {
size_t mesh_size = mesh->curve_keys.size();
size_t steps = mesh->motion_steps - 1;
float3 *key_steps = attr->data_float3();
for(size_t i = 0; i < steps; i++)
curve.bounds_grow(k, key_steps + i*mesh_size, &mesh->curve_radius[0], bbox);
}
}
}
else {
/* Triangles. */
int tri_offset = (params.top_level)? mesh->tri_offset: 0;
Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
const float3 *vpos = &mesh->verts[0];
triangle.bounds_grow(vpos, bbox);
/* Motion triangles. */
if(mesh->use_motion_blur) {
Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if(attr) {
size_t mesh_size = mesh->verts.size();
size_t steps = mesh->motion_steps - 1;
float3 *vert_steps = attr->data_float3();
for(size_t i = 0; i < steps; i++)
triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
}
}
}
}
visibility |= ob->visibility_for_tracing();
}
/* TODO(sergey): This is actually a copy of pack_leaf(),
* but this chunk of code only knows actual data and has
* no idea about BVHNode.

View File

@ -87,7 +87,7 @@ ccl_device T kernel_tex_image_interp_bicubic(const TextureInfo& info, CUtexObjec
g1x * tex2D<T>(tex, x1, y1));
}
/* Fast tricubic texture lookup using 8 bilinear lookups. */
/* Fast tricubic texture lookup using 8 trilinear lookups. */
template<typename T>
ccl_device T kernel_tex_image_interp_bicubic_3d(const TextureInfo& info, CUtexObject tex, float x, float y, float z)
{

View File

@ -27,9 +27,21 @@ ccl_device_inline ccl_global TextureInfo* kernel_tex_info(KernelGlobals *kg, uin
#define tex_fetch(type, info, index) ((ccl_global type*)(kg->buffers[info->cl_buffer] + info->data))[(index)]
ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg, int id, int offset)
ccl_device_inline int svm_image_texture_wrap_periodic(int x, int width)
{
x %= width;
if(x < 0)
x += width;
return x;
}
ccl_device_inline int svm_image_texture_wrap_clamp(int x, int width)
{
return clamp(x, 0, width-1);
}
ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg, const ccl_global TextureInfo *info, int id, int offset)
{
const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
const int texture_type = kernel_tex_type(id);
/* Float4 */
@ -55,19 +67,45 @@ ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg, int id, int o
}
}
ccl_device_inline int svm_image_texture_wrap_periodic(int x, int width)
ccl_device_inline float4 svm_image_texture_read_2d(KernelGlobals *kg, int id, int x, int y)
{
x %= width;
if(x < 0)
x += width;
return x;
const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
/* Wrap */
if(info->extension == EXTENSION_REPEAT) {
x = svm_image_texture_wrap_periodic(x, info->width);
y = svm_image_texture_wrap_periodic(y, info->height);
}
else {
x = svm_image_texture_wrap_clamp(x, info->width);
y = svm_image_texture_wrap_clamp(y, info->height);
}
int offset = x + info->width * y;
return svm_image_texture_read(kg, info, id, offset);
}
ccl_device_inline int svm_image_texture_wrap_clamp(int x, int width)
ccl_device_inline float4 svm_image_texture_read_3d(KernelGlobals *kg, int id, int x, int y, int z)
{
return clamp(x, 0, width-1);
const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
/* Wrap */
if(info->extension == EXTENSION_REPEAT) {
x = svm_image_texture_wrap_periodic(x, info->width);
y = svm_image_texture_wrap_periodic(y, info->height);
z = svm_image_texture_wrap_periodic(z, info->depth);
}
else {
x = svm_image_texture_wrap_clamp(x, info->width);
y = svm_image_texture_wrap_clamp(y, info->height);
z = svm_image_texture_wrap_clamp(z, info->depth);
}
int offset = x + info->width * y + info->width * info->height * z;
return svm_image_texture_read(kg, info, id, offset);
}
ccl_device_inline float svm_image_texture_frac(float x, int *ix)
{
int i = float_to_int(x) - ((x < 0.0f)? 1: 0);
@ -87,107 +125,52 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl
{
const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
uint width = info->width;
uint height = info->height;
uint interpolation = info->interpolation;
uint extension = info->extension;
if(info->extension == EXTENSION_CLIP) {
if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
}
/* Actual sampling. */
if(interpolation == INTERPOLATION_CLOSEST) {
if(info->interpolation == INTERPOLATION_CLOSEST) {
/* Closest interpolation. */
int ix, iy;
svm_image_texture_frac(x*width, &ix);
svm_image_texture_frac(y*height, &iy);
svm_image_texture_frac(x*info->width, &ix);
svm_image_texture_frac(y*info->height, &iy);
if(extension == EXTENSION_REPEAT) {
ix = svm_image_texture_wrap_periodic(ix, width);
iy = svm_image_texture_wrap_periodic(iy, height);
}
else {
if(extension == EXTENSION_CLIP) {
if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
}
/* Fall through. */
/* EXTENSION_EXTEND */
ix = svm_image_texture_wrap_clamp(ix, width);
iy = svm_image_texture_wrap_clamp(iy, height);
}
return svm_image_texture_read_2d(kg, id, ix, iy);
}
else if(info->interpolation == INTERPOLATION_LINEAR) {
/* Bilinear interpolation. */
int ix, iy;
float tx = svm_image_texture_frac(x*info->width - 0.5f, &ix);
float ty = svm_image_texture_frac(y*info->height - 0.5f, &iy);
return svm_image_texture_read(kg, id, ix + iy*width);
float4 r;
r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read_2d(kg, id, ix, iy);
r += (1.0f - ty)*tx*svm_image_texture_read_2d(kg, id, ix+1, iy);
r += ty*(1.0f - tx)*svm_image_texture_read_2d(kg, id, ix, iy+1);
r += ty*tx*svm_image_texture_read_2d(kg, id, ix+1, iy+1);
return r;
}
else {
/* Bilinear or bicubic interpolation. */
int ix, iy, nix, niy;
float tx = svm_image_texture_frac(x*width - 0.5f, &ix);
float ty = svm_image_texture_frac(y*height - 0.5f, &iy);
if(extension == EXTENSION_REPEAT) {
ix = svm_image_texture_wrap_periodic(ix, width);
iy = svm_image_texture_wrap_periodic(iy, height);
nix = svm_image_texture_wrap_periodic(ix+1, width);
niy = svm_image_texture_wrap_periodic(iy+1, height);
}
else {
if(extension == EXTENSION_CLIP) {
if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) {
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
}
ix = svm_image_texture_wrap_clamp(ix, width);
iy = svm_image_texture_wrap_clamp(iy, height);
nix = svm_image_texture_wrap_clamp(ix+1, width);
niy = svm_image_texture_wrap_clamp(iy+1, height);
}
if(interpolation == INTERPOLATION_LINEAR) {
/* Bilinear interpolation. */
float4 r;
r = (1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, ix + iy*width);
r += (1.0f - ty)*tx*svm_image_texture_read(kg, id, nix + iy*width);
r += ty*(1.0f - tx)*svm_image_texture_read(kg, id, ix + niy*width);
r += ty*tx*svm_image_texture_read(kg, id, nix + niy*width);
return r;
}
/* Bicubic interpolation. */
int pix, piy, nnix, nniy;
if(extension == EXTENSION_REPEAT) {
pix = svm_image_texture_wrap_periodic(ix-1, width);
piy = svm_image_texture_wrap_periodic(iy-1, height);
nnix = svm_image_texture_wrap_periodic(ix+2, width);
nniy = svm_image_texture_wrap_periodic(iy+2, height);
}
else {
pix = svm_image_texture_wrap_clamp(ix-1, width);
piy = svm_image_texture_wrap_clamp(iy-1, height);
nnix = svm_image_texture_wrap_clamp(ix+2, width);
nniy = svm_image_texture_wrap_clamp(iy+2, height);
}
int ix, iy;
float tx = svm_image_texture_frac(x*info->width - 0.5f, &ix);
float ty = svm_image_texture_frac(y*info->height - 0.5f, &iy);
const int xc[4] = {pix, ix, nix, nnix};
const int yc[4] = {width * piy,
width * iy,
width * niy,
width * nniy};
float u[4], v[4];
/* Some helper macro to keep code reasonable size,
* let compiler to inline all the matrix multiplications.
*/
#define DATA(x, y) (svm_image_texture_read(kg, id, xc[x] + yc[y]))
#define TERM(col) \
(v[col] * (u[0] * DATA(0, col) + \
u[1] * DATA(1, col) + \
u[2] * DATA(2, col) + \
u[3] * DATA(3, col)))
SET_CUBIC_SPLINE_WEIGHTS(u, tx);
SET_CUBIC_SPLINE_WEIGHTS(v, ty);
/* Actual interpolation. */
return TERM(0) + TERM(1) + TERM(2) + TERM(3);
#undef TERM
#undef DATA
float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
for(int y = 0; y < 4; y++) {
for(int x = 0; x < 4; x++) {
float weight = u[x]*v[y];
r += weight*svm_image_texture_read_2d(kg, id, ix+x-1, iy+y-1);
}
}
return r;
}
}
@ -196,145 +179,67 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x,
{
const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
uint width = info->width;
uint height = info->height;
uint depth = info->depth;
if(info->extension == EXTENSION_CLIP) {
if(x < 0.0f || y < 0.0f || z < 0.0f ||
x > 1.0f || y > 1.0f || z > 1.0f)
{
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
}
uint interpolation = (interp == INTERPOLATION_NONE)? info->interpolation: interp;
uint extension = info->extension;
/* Actual sampling. */
if(interpolation == INTERPOLATION_CLOSEST) {
/* Closest interpolation. */
int ix, iy, iz;
svm_image_texture_frac(x*width, &ix);
svm_image_texture_frac(y*height, &iy);
svm_image_texture_frac(z*depth, &iz);
svm_image_texture_frac(x*info->width, &ix);
svm_image_texture_frac(y*info->height, &iy);
svm_image_texture_frac(z*info->depth, &iz);
if(extension == EXTENSION_REPEAT) {
ix = svm_image_texture_wrap_periodic(ix, width);
iy = svm_image_texture_wrap_periodic(iy, height);
iz = svm_image_texture_wrap_periodic(iz, depth);
}
else {
if(extension == EXTENSION_CLIP) {
if(x < 0.0f || y < 0.0f || z < 0.0f ||
x > 1.0f || y > 1.0f || z > 1.0f)
{
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
}
/* Fall through. */
/* EXTENSION_EXTEND */
ix = svm_image_texture_wrap_clamp(ix, width);
iy = svm_image_texture_wrap_clamp(iy, height);
iz = svm_image_texture_wrap_clamp(iz, depth);
}
return svm_image_texture_read(kg, id, ix + iy*width + iz*width*height);
return svm_image_texture_read_3d(kg, id, ix, iy, iz);
}
else if(interpolation == INTERPOLATION_LINEAR) {
/* Bilinear interpolation. */
int ix, iy, iz;
float tx = svm_image_texture_frac(x*info->width - 0.5f, &ix);
float ty = svm_image_texture_frac(y*info->height - 0.5f, &iy);
float tz = svm_image_texture_frac(z*info->depth - 0.5f, &iz);
float4 r;
r = (1.0f - tz)*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read_3d(kg, id, ix, iy, iz);
r += (1.0f - tz)*(1.0f - ty)*tx*svm_image_texture_read_3d(kg, id, ix+1, iy, iz);
r += (1.0f - tz)*ty*(1.0f - tx)*svm_image_texture_read_3d(kg, id, ix, iy+1, iz);
r += (1.0f - tz)*ty*tx*svm_image_texture_read_3d(kg, id, ix+1, iy+1, iz);
r += tz*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read_3d(kg, id, ix, iy, iz+1);
r += tz*(1.0f - ty)*tx*svm_image_texture_read_3d(kg, id, ix+1, iy, iz+1);
r += tz*ty*(1.0f - tx)*svm_image_texture_read_3d(kg, id, ix, iy+1, iz+1);
r += tz*ty*tx*svm_image_texture_read_3d(kg, id, ix+1, iy+1, iz+1);
return r;
}
else {
/* Bilinear or bicubic interpolation. */
int ix, iy, iz, nix, niy, niz;
float tx = svm_image_texture_frac(x*(float)width - 0.5f, &ix);
float ty = svm_image_texture_frac(y*(float)height - 0.5f, &iy);
float tz = svm_image_texture_frac(z*(float)depth - 0.5f, &iz);
if(extension == EXTENSION_REPEAT) {
ix = svm_image_texture_wrap_periodic(ix, width);
iy = svm_image_texture_wrap_periodic(iy, height);
iz = svm_image_texture_wrap_periodic(iz, depth);
nix = svm_image_texture_wrap_periodic(ix+1, width);
niy = svm_image_texture_wrap_periodic(iy+1, height);
niz = svm_image_texture_wrap_periodic(iz+1, depth);
}
else {
if(extension == EXTENSION_CLIP) {
if(x < 0.0f || y < 0.0f || z < 0.0f ||
x > 1.0f || y > 1.0f || z > 1.0f)
{
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
}
}
/* Fall through. */
/* EXTENSION_EXTEND */
nix = svm_image_texture_wrap_clamp(ix+1, width);
niy = svm_image_texture_wrap_clamp(iy+1, height);
niz = svm_image_texture_wrap_clamp(iz+1, depth);
ix = svm_image_texture_wrap_clamp(ix, width);
iy = svm_image_texture_wrap_clamp(iy, height);
iz = svm_image_texture_wrap_clamp(iz, depth);
}
if(interpolation == INTERPOLATION_LINEAR) {
/* Bilinear interpolation. */
float4 r;
r = (1.0f - tz)*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, ix + iy*width + iz*width*height);
r += (1.0f - tz)*(1.0f - ty)*tx*svm_image_texture_read(kg, id, nix + iy*width + iz*width*height);
r += (1.0f - tz)*ty*(1.0f - tx)*svm_image_texture_read(kg, id, ix + niy*width + iz*width*height);
r += (1.0f - tz)*ty*tx*svm_image_texture_read(kg, id, nix + niy*width + iz*width*height);
r += tz*(1.0f - ty)*(1.0f - tx)*svm_image_texture_read(kg, id, ix + iy*width + niz*width*height);
r += tz*(1.0f - ty)*tx*svm_image_texture_read(kg, id, nix + iy*width + niz*width*height);
r += tz*ty*(1.0f - tx)*svm_image_texture_read(kg, id, ix + niy*width + niz*width*height);
r += tz*ty*tx*svm_image_texture_read(kg, id, nix + niy*width + niz*width*height);
return r;
}
/* Bicubic interpolation. */
int pix, piy, piz, nnix, nniy, nniz;
if(extension == EXTENSION_REPEAT) {
pix = svm_image_texture_wrap_periodic(ix-1, width);
piy = svm_image_texture_wrap_periodic(iy-1, height);
piz = svm_image_texture_wrap_periodic(iz-1, depth);
nnix = svm_image_texture_wrap_periodic(ix+2, width);
nniy = svm_image_texture_wrap_periodic(iy+2, height);
nniz = svm_image_texture_wrap_periodic(iz+2, depth);
}
else {
pix = svm_image_texture_wrap_clamp(ix-1, width);
piy = svm_image_texture_wrap_clamp(iy-1, height);
piz = svm_image_texture_wrap_clamp(iz-1, depth);
nnix = svm_image_texture_wrap_clamp(ix+2, width);
nniy = svm_image_texture_wrap_clamp(iy+2, height);
nniz = svm_image_texture_wrap_clamp(iz+2, depth);
}
int ix, iy, iz;
float tx = svm_image_texture_frac(x*info->width - 0.5f, &ix);
float ty = svm_image_texture_frac(y*info->height - 0.5f, &iy);
float tz = svm_image_texture_frac(z*info->depth - 0.5f, &iz);
const int xc[4] = {pix, ix, nix, nnix};
const int yc[4] = {width * piy,
width * iy,
width * niy,
width * nniy};
const int zc[4] = {width * height * piz,
width * height * iz,
width * height * niz,
width * height * nniz};
float u[4], v[4], w[4];
/* Some helper macro to keep code reasonable size,
* let compiler to inline all the matrix multiplications.
*/
#define DATA(x, y, z) (svm_image_texture_read(kg, id, xc[x] + yc[y] + zc[z]))
#define COL_TERM(col, row) \
(v[col] * (u[0] * DATA(0, col, row) + \
u[1] * DATA(1, col, row) + \
u[2] * DATA(2, col, row) + \
u[3] * DATA(3, col, row)))
#define ROW_TERM(row) \
(w[row] * (COL_TERM(0, row) + \
COL_TERM(1, row) + \
COL_TERM(2, row) + \
COL_TERM(3, row)))
SET_CUBIC_SPLINE_WEIGHTS(u, tx);
SET_CUBIC_SPLINE_WEIGHTS(v, ty);
SET_CUBIC_SPLINE_WEIGHTS(w, tz);
/* Actual interpolation. */
return ROW_TERM(0) + ROW_TERM(1) + ROW_TERM(2) + ROW_TERM(3);
float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
#undef COL_TERM
#undef ROW_TERM
#undef DATA
for(int z = 0; z < 4; z++) {
for(int y = 0; y < 4; y++) {
for(int x = 0; x < 4; x++) {
float weight = u[x]*v[y]*w[z];
r += weight*svm_image_texture_read_3d(kg, id, ix+x-1, iy+y-1, iz+z-1);
}
}
}
return r;
}
}

View File

@ -827,7 +827,7 @@ static int paint_weight_gradient_invoke(bContext *C, wmOperator *op, const wmEve
/* TODO, hardcoded, extend WM_gesture_straightline_ */
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
wmGesture *gesture = op->customdata;
gesture->mode = 1;
gesture->is_active = true;
}
}
}

View File

@ -73,9 +73,6 @@ static EnumPropertyItem property_flag_items[] = {
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE', 'PROPORTIONAL'," \
"'TEXTEDIT_UPDATE'].\n" \
" :type options: set\n" \
" :arg poll: function to be called to determine whether an item is valid for this property.\n" \
" The function must take 2 values (self,object) and return Bool.\n" \
" :type poll: function\n" \
static EnumPropertyItem property_flag_enum_items[] = {
{PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
@ -1941,6 +1938,11 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *ge
" *Warning* there are no safety checks to avoid infinite recursion.\n" \
" :type update: function\n" \
#define BPY_PROPDEF_POLL_DOC \
" :arg poll: function to be called to determine whether an item is valid for this property.\n" \
" The function must take 2 values (self, object) and return Bool.\n" \
" :type poll: function\n" \
#define BPY_PROPDEF_GET_DOC \
" :arg get: Function to be called when this value is 'read',\n" \
" This function must take 1 value (self) and return the value of the property.\n" \
@ -2884,6 +2886,7 @@ BPY_PROPDEF_TYPE_DOC
BPY_PROPDEF_NAME_DOC
BPY_PROPDEF_DESC_DOC
BPY_PROPDEF_OPTIONS_DOC
BPY_PROPDEF_POLL_DOC
BPY_PROPDEF_UPDATE_DOC
);
PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)

View File

@ -414,11 +414,14 @@ typedef struct wmNotifier {
typedef struct wmGesture {
struct wmGesture *next, *prev;
int event_type; /* event->type */
int mode; /* for modal callback */
int type; /* gesture type define */
int swinid; /* initial subwindow id where it started */
int points; /* optional, amount of points stored */
int size; /* optional, maximum amount of points stored */
int points_alloc; /* optional, maximum amount of points stored */
/* For modal operators which may be running idle, waiting for an event to activate the gesture.
* Typically this is set when the user is click-dragging the gesture (border and circle select for eg). */
uint is_active : 1;
void *customdata;
/* customdata for border is a recti */

View File

@ -84,6 +84,9 @@
#include "RNA_enum_types.h"
/* Motion in pixels allowed before we don't consider single/double click. */
#define WM_EVENT_CLICK_WIGGLE_ROOM 2
static void wm_notifier_clear(wmNotifier *note);
static void update_tablet_data(wmWindow *win, wmEvent *event);
@ -2397,7 +2400,9 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
if ((event->val == KM_RELEASE) &&
(win->eventstate->prevval == KM_PRESS) &&
(win->eventstate->check_click == true))
(win->eventstate->check_click == true) &&
((abs(event->x - win->eventstate->prevclickx)) <= WM_EVENT_CLICK_WIGGLE_ROOM &&
(abs(event->y - win->eventstate->prevclicky)) <= WM_EVENT_CLICK_WIGGLE_ROOM))
{
event->val = KM_CLICK;
@ -3394,8 +3399,9 @@ static bool wm_event_is_double_click(wmEvent *event, const wmEvent *event_state)
(event_state->prevval == KM_RELEASE) &&
(event->val == KM_PRESS))
{
if ((ISMOUSE(event->type) == false) || ((ABS(event->x - event_state->prevclickx)) <= 2 &&
(ABS(event->y - event_state->prevclicky)) <= 2))
if ((ISMOUSE(event->type) == false) ||
((abs(event->x - event_state->prevclickx)) <= WM_EVENT_CLICK_WIGGLE_ROOM &&
(abs(event->y - event_state->prevclicky)) <= WM_EVENT_CLICK_WIGGLE_ROOM))
{
if ((PIL_check_seconds_timer() - event_state->prevclicktime) * 1000 < U.dbl_click_time) {
return true;

View File

@ -97,11 +97,11 @@ wmGesture *WM_gesture_new(bContext *C, const wmEvent *event, int type)
}
else if (ELEM(type, WM_GESTURE_LINES, WM_GESTURE_LASSO)) {
short *lasso;
gesture->customdata = lasso = MEM_callocN(2 * sizeof(short) * WM_LASSO_MIN_POINTS, "lasso points");
gesture->points_alloc = 1024;
gesture->customdata = lasso = MEM_mallocN(sizeof(short[2]) * gesture->points_alloc, "lasso points");
lasso[0] = event->x - sx;
lasso[1] = event->y - sy;
gesture->points = 1;
gesture->size = WM_LASSO_MIN_POINTS;
}
return gesture;
@ -437,10 +437,12 @@ void wm_gesture_draw(wmWindow *win)
else if (gt->type == WM_GESTURE_CIRCLE)
wm_gesture_draw_circle(gt);
else if (gt->type == WM_GESTURE_CROSS_RECT) {
if (gt->mode == 1)
if (gt->is_active) {
wm_gesture_draw_rect(gt);
else
}
else {
wm_gesture_draw_cross(win, gt);
}
}
else if (gt->type == WM_GESTURE_LINES)
wm_gesture_draw_lasso(win, gt, false);

View File

@ -2389,7 +2389,7 @@ int WM_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->type == MOUSEMOVE) {
wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->mode == 0) {
if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->is_active == false) {
rect->xmin = rect->xmax = event->x - sx;
rect->ymin = rect->ymax = event->y - sy;
}
@ -2404,8 +2404,8 @@ int WM_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
else if (event->type == EVT_MODAL_MAP) {
switch (event->val) {
case GESTURE_MODAL_BEGIN:
if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->mode == 0) {
gesture->mode = 1;
if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->is_active == false) {
gesture->is_active = true;
wm_gesture_tag_redraw(C);
}
break;
@ -2500,8 +2500,9 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
wm_gesture_tag_redraw(C);
if (gesture->mode)
if (gesture->is_active) {
gesture_circle_apply(C, op);
}
}
else if (event->type == EVT_MODAL_MAP) {
float fac;
@ -2534,7 +2535,7 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->val != GESTURE_MODAL_NOP) {
/* apply first click */
gesture_circle_apply(C, op);
gesture->mode = 1;
gesture->is_active = true;
wm_gesture_tag_redraw(C);
}
break;
@ -2744,28 +2745,24 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
switch (event->type) {
case MOUSEMOVE:
case INBETWEEN_MOUSEMOVE:
wm_gesture_tag_redraw(C);
wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
if (gesture->points == gesture->size) {
short *old_lasso = gesture->customdata;
gesture->customdata = MEM_callocN(2 * sizeof(short) * (gesture->size + WM_LASSO_MIN_POINTS), "lasso points");
memcpy(gesture->customdata, old_lasso, 2 * sizeof(short) * gesture->size);
gesture->size = gesture->size + WM_LASSO_MIN_POINTS;
MEM_freeN(old_lasso);
// printf("realloc\n");
if (gesture->points == gesture->points_alloc) {
gesture->points_alloc *= 2;
gesture->customdata = MEM_reallocN(gesture->customdata, sizeof(short[2]) * gesture->points_alloc);
}
{
int x, y;
short *lasso = gesture->customdata;
lasso += (2 * gesture->points - 2);
x = (event->x - sx - lasso[0]);
y = (event->y - sy - lasso[1]);
/* make a simple distance check to get a smoother lasso
* add only when at least 2 pixels between this and previous location */
if ((x * x + y * y) > 4) {
@ -2776,7 +2773,7 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
break;
case LEFTMOUSE:
case MIDDLEMOUSE:
case RIGHTMOUSE:
@ -2934,7 +2931,7 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *ev
if (event->type == MOUSEMOVE) {
wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
if (gesture->mode == 0) {
if (gesture->is_active == false) {
rect->xmin = rect->xmax = event->x - sx;
rect->ymin = rect->ymax = event->y - sy;
}
@ -2949,8 +2946,8 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *ev
else if (event->type == EVT_MODAL_MAP) {
switch (event->val) {
case GESTURE_MODAL_BEGIN:
if (gesture->mode == 0) {
gesture->mode = 1;
if (gesture->is_active == false) {
gesture->is_active = true;
wm_gesture_tag_redraw(C);
}
break;

View File

@ -62,7 +62,6 @@ void wm_window_keymap(wmKeyConfig *keyconf);
void wm_tweakevent_test(bContext *C, const wmEvent *event, int action);
/* wm_gesture.c */
#define WM_LASSO_MIN_POINTS 1024
void wm_gesture_draw(struct wmWindow *win);
int wm_gesture_evaluate(wmGesture *gesture);
void wm_gesture_tag_redraw(bContext *C);