1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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);
}
|