Merge branch 'master' into blender2.8
This commit is contained in:
@@ -60,8 +60,6 @@ ccl_device_inline void path_state_init(KernelGlobals *kg,
|
||||
if(kernel_data.integrator.use_volumes) {
|
||||
/* Initialize volume stack with volume we are inside of. */
|
||||
kernel_volume_stack_init(kg, stack_sd, state, ray, state->volume_stack);
|
||||
/* Seed RNG for cases where we can't use stratified samples .*/
|
||||
state->rng_congruential = lcg_init(rng_hash + sample*0x51633e2d);
|
||||
}
|
||||
else {
|
||||
state->volume_stack[0].shader = SHADER_NONE;
|
||||
|
||||
@@ -199,6 +199,19 @@ ccl_device_inline void path_state_rng_2D(KernelGlobals *kg,
|
||||
fx, fy);
|
||||
}
|
||||
|
||||
ccl_device_inline float path_state_rng_1D_hash(KernelGlobals *kg,
|
||||
const ccl_addr_space PathState *state,
|
||||
uint hash)
|
||||
{
|
||||
/* Use a hash instead of dimension, this is not great but avoids adding
|
||||
* more dimensions to each bounce which reduces quality of dimensions we
|
||||
* are already using. */
|
||||
return path_rng_1D(kg,
|
||||
cmj_hash_simple(state->rng_hash, hash),
|
||||
state->sample, state->num_samples,
|
||||
state->rng_offset);
|
||||
}
|
||||
|
||||
ccl_device_inline float path_branched_rng_1D(
|
||||
KernelGlobals *kg,
|
||||
uint rng_hash,
|
||||
|
||||
@@ -1107,7 +1107,6 @@ typedef struct PathState {
|
||||
#ifdef __VOLUME__
|
||||
int volume_bounce;
|
||||
int volume_bounds_bounce;
|
||||
uint rng_congruential;
|
||||
VolumeStack volume_stack[VOLUME_STACK_SIZE];
|
||||
#endif
|
||||
} PathState;
|
||||
|
||||
@@ -156,6 +156,24 @@ ccl_device int volume_stack_sampling_method(KernelGlobals *kg, VolumeStack *stac
|
||||
return method;
|
||||
}
|
||||
|
||||
ccl_device_inline void kernel_volume_step_init(KernelGlobals *kg,
|
||||
ccl_addr_space PathState *state,
|
||||
float t,
|
||||
float *step_size,
|
||||
float *step_offset)
|
||||
{
|
||||
const int max_steps = kernel_data.integrator.volume_max_steps;
|
||||
float step = min(kernel_data.integrator.volume_step_size, t);
|
||||
|
||||
/* compute exact steps in advance for malloc */
|
||||
if(t > max_steps * step) {
|
||||
step = t / (float)max_steps;
|
||||
}
|
||||
|
||||
*step_size = step;
|
||||
*step_offset = path_state_rng_1D_hash(kg, state, 0x1e31d8a4) * step;
|
||||
}
|
||||
|
||||
/* Volume Shadows
|
||||
*
|
||||
* These functions are used to attenuate shadow rays to lights. Both absorption
|
||||
@@ -188,8 +206,8 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg,
|
||||
|
||||
/* prepare for stepping */
|
||||
int max_steps = kernel_data.integrator.volume_max_steps;
|
||||
float step = kernel_data.integrator.volume_step_size;
|
||||
float random_jitter_offset = lcg_step_float_addrspace(&state->rng_congruential) * step;
|
||||
float step_offset, step_size;
|
||||
kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
|
||||
|
||||
/* compute extinction at the start */
|
||||
float t = 0.0f;
|
||||
@@ -198,14 +216,15 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg,
|
||||
|
||||
for(int i = 0; i < max_steps; i++) {
|
||||
/* advance to new position */
|
||||
float new_t = min(ray->t, (i+1) * step);
|
||||
float dt = new_t - t;
|
||||
float new_t = min(ray->t, (i+1) * step_size);
|
||||
|
||||
/* use random position inside this segment to sample shader */
|
||||
if(new_t == ray->t)
|
||||
random_jitter_offset = lcg_step_float_addrspace(&state->rng_congruential) * dt;
|
||||
/* use random position inside this segment to sample shader, adjust
|
||||
* for last step that is shorter than other steps. */
|
||||
if(new_t == ray->t) {
|
||||
step_offset *= (new_t - t) / step_size;
|
||||
}
|
||||
|
||||
float3 new_P = ray->P + ray->D * (t + random_jitter_offset);
|
||||
float3 new_P = ray->P + ray->D * (t + step_offset);
|
||||
float3 sigma_t;
|
||||
|
||||
/* compute attenuation over segment */
|
||||
@@ -504,8 +523,8 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
|
||||
|
||||
/* prepare for stepping */
|
||||
int max_steps = kernel_data.integrator.volume_max_steps;
|
||||
float step_size = kernel_data.integrator.volume_step_size;
|
||||
float random_jitter_offset = lcg_step_float_addrspace(&state->rng_congruential) * step_size;
|
||||
float step_offset, step_size;
|
||||
kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
|
||||
|
||||
/* compute coefficients at the start */
|
||||
float t = 0.0f;
|
||||
@@ -522,11 +541,13 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
|
||||
float new_t = min(ray->t, (i+1) * step_size);
|
||||
float dt = new_t - t;
|
||||
|
||||
/* use random position inside this segment to sample shader */
|
||||
if(new_t == ray->t)
|
||||
random_jitter_offset = lcg_step_float_addrspace(&state->rng_congruential) * dt;
|
||||
/* use random position inside this segment to sample shader,
|
||||
* for last shorter step we remap it to fit within the segment. */
|
||||
if(new_t == ray->t) {
|
||||
step_offset *= (new_t - t) / step_size;
|
||||
}
|
||||
|
||||
float3 new_P = ray->P + ray->D * (t + random_jitter_offset);
|
||||
float3 new_P = ray->P + ray->D * (t + step_offset);
|
||||
VolumeShaderCoefficients coeff;
|
||||
|
||||
/* compute segment */
|
||||
@@ -694,19 +715,12 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
|
||||
|
||||
/* prepare for volume stepping */
|
||||
int max_steps;
|
||||
float step_size, random_jitter_offset;
|
||||
float step_size, step_offset;
|
||||
|
||||
if(heterogeneous) {
|
||||
const int global_max_steps = kernel_data.integrator.volume_max_steps;
|
||||
step_size = kernel_data.integrator.volume_step_size;
|
||||
/* compute exact steps in advance for malloc */
|
||||
if(ray->t > global_max_steps*step_size) {
|
||||
max_steps = global_max_steps;
|
||||
step_size = ray->t / (float)max_steps;
|
||||
}
|
||||
else {
|
||||
max_steps = max((int)ceilf(ray->t/step_size), 1);
|
||||
}
|
||||
max_steps = kernel_data.integrator.volume_max_steps;
|
||||
kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
|
||||
|
||||
#ifdef __KERNEL_CPU__
|
||||
/* NOTE: For the branched path tracing it's possible to have direct
|
||||
* and indirect light integration both having volume segments allocated.
|
||||
@@ -723,19 +737,18 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
|
||||
sizeof(*kg->decoupled_volume_steps));
|
||||
if(kg->decoupled_volume_steps[index] == NULL) {
|
||||
kg->decoupled_volume_steps[index] =
|
||||
(VolumeStep*)malloc(sizeof(VolumeStep)*global_max_steps);
|
||||
(VolumeStep*)malloc(sizeof(VolumeStep)*max_steps);
|
||||
}
|
||||
segment->steps = kg->decoupled_volume_steps[index];
|
||||
++kg->decoupled_volume_steps_index;
|
||||
#else
|
||||
segment->steps = (VolumeStep*)malloc(sizeof(VolumeStep)*max_steps);
|
||||
#endif
|
||||
random_jitter_offset = lcg_step_float(&state->rng_congruential) * step_size;
|
||||
}
|
||||
else {
|
||||
max_steps = 1;
|
||||
step_size = ray->t;
|
||||
random_jitter_offset = 0.0f;
|
||||
step_offset = 0.0f;
|
||||
segment->steps = &segment->stack_step;
|
||||
}
|
||||
|
||||
@@ -757,11 +770,13 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
|
||||
float new_t = min(ray->t, (i+1) * step_size);
|
||||
float dt = new_t - t;
|
||||
|
||||
/* use random position inside this segment to sample shader */
|
||||
if(heterogeneous && new_t == ray->t)
|
||||
random_jitter_offset = lcg_step_float(&state->rng_congruential) * dt;
|
||||
/* use random position inside this segment to sample shader,
|
||||
* for last shorter step we remap it to fit within the segment. */
|
||||
if(new_t == ray->t) {
|
||||
step_offset *= (new_t - t) / step_size;
|
||||
}
|
||||
|
||||
float3 new_P = ray->P + ray->D * (t + random_jitter_offset);
|
||||
float3 new_P = ray->P + ray->D * (t + step_offset);
|
||||
VolumeShaderCoefficients coeff;
|
||||
|
||||
/* compute segment */
|
||||
@@ -818,7 +833,7 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
|
||||
step->accum_transmittance = accum_transmittance;
|
||||
step->cdf_distance = cdf_distance;
|
||||
step->t = new_t;
|
||||
step->shade_t = t + random_jitter_offset;
|
||||
step->shade_t = t + step_offset;
|
||||
|
||||
/* stop if at the end of the volume */
|
||||
t = new_t;
|
||||
|
||||
@@ -43,6 +43,7 @@ set(INC_SYS
|
||||
set(SRC
|
||||
paint_cursor.c
|
||||
paint_curve.c
|
||||
paint_curve_undo.c
|
||||
paint_hide.c
|
||||
paint_image.c
|
||||
paint_image_2d.c
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "DNA_workspace_types.h"
|
||||
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_main.h"
|
||||
@@ -43,7 +42,6 @@
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
||||
#include "ED_paint.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
@@ -59,7 +57,6 @@
|
||||
#define PAINT_CURVE_SELECT_THRESHOLD 40.0f
|
||||
#define PAINT_CURVE_POINT_SELECT(pcp, i) (*(&pcp->bez.f1 + i) = SELECT)
|
||||
|
||||
|
||||
int paint_curve_poll(bContext *C)
|
||||
{
|
||||
const WorkSpace *workspace = CTX_wm_workspace(C);
|
||||
@@ -85,91 +82,6 @@ int paint_curve_poll(bContext *C)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Paint Curve Undo*/
|
||||
|
||||
typedef struct UndoCurve {
|
||||
struct UndoImageTile *next, *prev;
|
||||
|
||||
PaintCurvePoint *points; /* points of curve */
|
||||
int tot_points;
|
||||
int active_point;
|
||||
|
||||
char idname[MAX_ID_NAME]; /* name instead of pointer*/
|
||||
} UndoCurve;
|
||||
|
||||
static void paintcurve_undo_restore(bContext *C, ListBase *lb)
|
||||
{
|
||||
Paint *p = BKE_paint_get_active_from_context(C);
|
||||
UndoCurve *uc;
|
||||
PaintCurve *pc = NULL;
|
||||
|
||||
if (p->brush) {
|
||||
pc = p->brush->paint_curve;
|
||||
}
|
||||
|
||||
if (!pc)
|
||||
return;
|
||||
|
||||
uc = (UndoCurve *)lb->first;
|
||||
|
||||
if (STREQLEN(uc->idname, pc->id.name, BLI_strnlen(uc->idname, sizeof(uc->idname)))) {
|
||||
SWAP(PaintCurvePoint *, pc->points, uc->points);
|
||||
SWAP(int, pc->tot_points, uc->tot_points);
|
||||
SWAP(int, pc->add_index, uc->active_point);
|
||||
}
|
||||
}
|
||||
|
||||
static void paintcurve_undo_delete(ListBase *lb)
|
||||
{
|
||||
UndoCurve *uc;
|
||||
uc = (UndoCurve *)lb->first;
|
||||
|
||||
if (uc->points)
|
||||
MEM_freeN(uc->points);
|
||||
uc->points = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void paintcurve_undo_begin(bContext *C, wmOperator *op, PaintCurve *pc)
|
||||
{
|
||||
ePaintMode mode = BKE_paintmode_get_active_from_context(C);
|
||||
ListBase *lb = NULL;
|
||||
int undo_stack_id;
|
||||
UndoCurve *uc;
|
||||
|
||||
switch (mode) {
|
||||
case ePaintTexture2D:
|
||||
case ePaintTextureProjective:
|
||||
undo_stack_id = UNDO_PAINT_IMAGE;
|
||||
break;
|
||||
|
||||
case ePaintSculpt:
|
||||
undo_stack_id = UNDO_PAINT_MESH;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* do nothing, undo is handled by global */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ED_undo_paint_push_begin(undo_stack_id, op->type->name,
|
||||
paintcurve_undo_restore, paintcurve_undo_delete, NULL);
|
||||
lb = undo_paint_push_get_list(undo_stack_id);
|
||||
|
||||
uc = MEM_callocN(sizeof(*uc), "Undo_curve");
|
||||
|
||||
lb->first = uc;
|
||||
|
||||
BLI_strncpy(uc->idname, pc->id.name, sizeof(uc->idname));
|
||||
uc->tot_points = pc->tot_points;
|
||||
uc->active_point = pc->add_index;
|
||||
uc->points = MEM_dupallocN(pc->points);
|
||||
|
||||
undo_paint_push_count_alloc(undo_stack_id, sizeof(*uc) + sizeof(*pc->points) * pc->tot_points);
|
||||
|
||||
ED_undo_paint_push_end(undo_stack_id);
|
||||
}
|
||||
#define SEL_F1 (1 << 0)
|
||||
#define SEL_F2 (1 << 1)
|
||||
#define SEL_F3 (1 << 2)
|
||||
@@ -295,7 +207,7 @@ static void paintcurve_point_add(bContext *C, wmOperator *op, const int loc[2])
|
||||
br->paint_curve = pc = BKE_paint_curve_add(bmain, "PaintCurve");
|
||||
}
|
||||
|
||||
paintcurve_undo_begin(C, op, pc);
|
||||
ED_paintcurve_undo_push(C, op, pc);
|
||||
|
||||
pcp = MEM_mallocN((pc->tot_points + 1) * sizeof(PaintCurvePoint), "PaintCurvePoint");
|
||||
add_index = pc->add_index;
|
||||
@@ -394,7 +306,7 @@ static int paintcurve_delete_point_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
paintcurve_undo_begin(C, op, pc);
|
||||
ED_paintcurve_undo_push(C, op, pc);
|
||||
|
||||
#define DELETE_TAG 2
|
||||
|
||||
@@ -471,7 +383,7 @@ static bool paintcurve_point_select(bContext *C, wmOperator *op, const int loc[2
|
||||
if (!pc)
|
||||
return false;
|
||||
|
||||
paintcurve_undo_begin(C, op, pc);
|
||||
ED_paintcurve_undo_push(C, op, pc);
|
||||
|
||||
if (toggle) {
|
||||
PaintCurvePoint *pcp;
|
||||
@@ -655,7 +567,7 @@ static int paintcurve_slide_invoke(bContext *C, wmOperator *op, const wmEvent *e
|
||||
op->customdata = psd;
|
||||
|
||||
if (do_select)
|
||||
paintcurve_undo_begin(C, op, pc);
|
||||
ED_paintcurve_undo_push(C, op, pc);
|
||||
|
||||
/* first, clear all selection from points */
|
||||
for (i = 0; i < pc->tot_points; i++)
|
||||
|
||||
129
source/blender/editors/sculpt_paint/paint_curve_undo.c
Normal file
129
source/blender/editors/sculpt_paint/paint_curve_undo.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/editors/sculpt_paint/paint_curve_undo.c
|
||||
* \ingroup edsculpt
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_paint.h"
|
||||
|
||||
#include "ED_paint.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "paint_intern.h"
|
||||
|
||||
typedef struct UndoCurve {
|
||||
struct UndoImageTile *next, *prev;
|
||||
|
||||
PaintCurvePoint *points; /* points of curve */
|
||||
int tot_points;
|
||||
int active_point;
|
||||
|
||||
char idname[MAX_ID_NAME]; /* name instead of pointer*/
|
||||
} UndoCurve;
|
||||
|
||||
static void paintcurve_undo_restore(bContext *C, ListBase *lb)
|
||||
{
|
||||
Paint *p = BKE_paint_get_active_from_context(C);
|
||||
UndoCurve *uc;
|
||||
PaintCurve *pc = NULL;
|
||||
|
||||
if (p->brush) {
|
||||
pc = p->brush->paint_curve;
|
||||
}
|
||||
|
||||
if (!pc) {
|
||||
return;
|
||||
}
|
||||
|
||||
uc = (UndoCurve *)lb->first;
|
||||
|
||||
if (STREQLEN(uc->idname, pc->id.name, BLI_strnlen(uc->idname, sizeof(uc->idname)))) {
|
||||
SWAP(PaintCurvePoint *, pc->points, uc->points);
|
||||
SWAP(int, pc->tot_points, uc->tot_points);
|
||||
SWAP(int, pc->add_index, uc->active_point);
|
||||
}
|
||||
}
|
||||
|
||||
static void paintcurve_undo_delete(ListBase *lb)
|
||||
{
|
||||
UndoCurve *uc;
|
||||
uc = (UndoCurve *)lb->first;
|
||||
|
||||
if (uc->points)
|
||||
MEM_freeN(uc->points);
|
||||
uc->points = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \note This is called before executing steps (not after).
|
||||
*/
|
||||
void ED_paintcurve_undo_push(bContext *C, wmOperator *op, PaintCurve *pc)
|
||||
{
|
||||
ePaintMode mode = BKE_paintmode_get_active_from_context(C);
|
||||
ListBase *lb = NULL;
|
||||
int undo_stack_id;
|
||||
UndoCurve *uc;
|
||||
|
||||
switch (mode) {
|
||||
case ePaintTexture2D:
|
||||
case ePaintTextureProjective:
|
||||
undo_stack_id = UNDO_PAINT_IMAGE;
|
||||
break;
|
||||
|
||||
case ePaintSculpt:
|
||||
undo_stack_id = UNDO_PAINT_MESH;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* do nothing, undo is handled by global */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ED_undo_paint_push_begin(undo_stack_id, op->type->name,
|
||||
paintcurve_undo_restore, paintcurve_undo_delete, NULL);
|
||||
lb = undo_paint_push_get_list(undo_stack_id);
|
||||
|
||||
uc = MEM_callocN(sizeof(*uc), "Undo_curve");
|
||||
|
||||
lb->first = uc;
|
||||
|
||||
BLI_strncpy(uc->idname, pc->id.name, sizeof(uc->idname));
|
||||
uc->tot_points = pc->tot_points;
|
||||
uc->active_point = pc->add_index;
|
||||
uc->points = MEM_dupallocN(pc->points);
|
||||
|
||||
undo_paint_push_count_alloc(undo_stack_id, sizeof(*uc) + sizeof(*pc->points) * pc->tot_points);
|
||||
|
||||
ED_undo_paint_push_end(undo_stack_id);
|
||||
}
|
||||
@@ -43,6 +43,7 @@ struct MTex;
|
||||
struct Object;
|
||||
struct PaintStroke;
|
||||
struct Paint;
|
||||
struct PaintCurve;
|
||||
struct PointerRNA;
|
||||
struct rcti;
|
||||
struct Scene;
|
||||
@@ -342,6 +343,9 @@ void PAINTCURVE_OT_slide(struct wmOperatorType *ot);
|
||||
void PAINTCURVE_OT_draw(struct wmOperatorType *ot);
|
||||
void PAINTCURVE_OT_cursor(struct wmOperatorType *ot);
|
||||
|
||||
/* paint_curve_undo.c */
|
||||
void ED_paintcurve_undo_push(struct bContext *C, struct wmOperator *op, struct PaintCurve *pc);
|
||||
|
||||
/* image painting blur kernel */
|
||||
typedef struct {
|
||||
float *wdata; /* actual kernel */
|
||||
|
||||
Reference in New Issue
Block a user