-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdefine_a_wt_with_custom_lifting_steps.cpp
195 lines (167 loc) · 7.89 KB
/
define_a_wt_with_custom_lifting_steps.cpp
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#include <wtlib/ptq_impl/vertex_classification.hpp>
#include <map>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
// Some handy type definitions.
using Mesh = CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>>;
using Vertex_handle = Mesh::Vertex_handle;
using Vertex_const_handle = Mesh::Vertex_const_handle;
using Vertices = std::vector<Vertex_handle>;
using Bands = std::vector<Vertex_handle*>;
struct Vertex_info {
int level;
int type;
int id;
bool border;
};
/**
* Defining a lifted wavelet transform can be decomposed into the steps as
* follows. First, instantiate the Wavelet_mesh_operations class that defines
* access to vertex properties. Then, instantiate Wavelet_analysis_ops and
* Wavelet_synthesis_ops classes that abstract operations in the FWT and IWT,
* respectively. Next, use the instantiated Wavelet_mesh_operations and
* Wavelet_analysis_ops (Wavelet_synthesis_ops) to instantiate Wavelet_analyze
* (Wavelet_synthesize) for computing FWT (IWT). The code below illustrates the
* class instantiations step by step.
*/
int main() {
/** Wavelet_mesh_operations instantiation */
// Construct a vertex property map that stores vertex properties.
std::map<Vertex_const_handle, Vertex_info> props;
// Construct lambda functions that define access to vertex properties.
auto get_level = [&props](Vertex_const_handle v) -> int {
return props.at(v).level;
};
auto set_level = [&props](Vertex_handle v, int level) -> void {
props[v].level = level;
};
auto get_type = [&props](Vertex_const_handle v) -> int {
return props.at(v).type;
};
auto set_type = [&props](Vertex_handle v, int type) -> void {
props[v].type = type;
};
auto get_id = [&props](Vertex_const_handle v) -> int {
return props.at(v).id;
};
auto set_id = [&props](Vertex_handle v, int id) -> void {
props[v].id = id;
};
auto get_border = [&props](Vertex_const_handle v) -> bool {
return props.at(v).border;
};
auto set_border = [&props](Vertex_handle v, bool border) -> void {
props[v].border = border;
};
// Use the lambda functions to instantiate Wavelet_mesh_operations.
using Mesh_ops = wtlib::Wavelet_mesh_operations<Mesh,
decltype(get_id),
decltype(set_id),
decltype(get_level),
decltype(set_level),
decltype(get_type),
decltype(set_type),
decltype(get_border),
decltype(set_border)>;
// Construct a mesh_ops object, which will be used in computing FWT and IWT.
Mesh_ops mesh_ops(get_id, set_id,
get_level, set_level,
get_type, set_type,
get_border, set_border);
/** Wavelet_analysis_ops instantiation */
// Construct lambda functions that define the operations in the FWT.
auto get_num_types = [](Mesh& mesh, const Mesh_ops& mesh_ops) -> int {
// This function should return the number of types of the vertices. Here we
// use 2 as an example.
return 2;
};
auto classify = [](Mesh& mesh, const Mesh_ops& mesh_ops,
int levels, Vertices& vertices, Bands& bands) -> bool {
// Since vertex classification is a non-trivial task, in order to minimize
// the page, the implementation in WTT is used here.
return wtlib::ptq_impl::PTQ_classify_vertices<Mesh, Mesh_ops>::
classify(mesh, mesh_ops, levels, vertices, bands, true);
};
auto fwt_initialize = [](Mesh& mesh, const Mesh_ops& mesh_ops, int levels) -> void {
// Do any necessary initialization before lifting.
};
auto fwt_cleanup = [](Mesh& mesh, const Mesh_ops& mesh_ops) -> void {
// Cleanup acquired resources in initialization.
};
auto fwt_lift = [](Mesh& mesh, const Mesh_ops& mesh_ops,
Vertex_handle** first,
Vertex_handle** last) -> void {
// Do lifting calculation. Vertices [*first, *(first+1)) are the old
// vertices, and [*(first+1), *last) are the new vertices. Incrementing
// *(first+1) obtains the vertices of the next type.
};
auto coarsen = [](Mesh& mesh,
const Mesh_ops& mesh_ops,
int level) -> void {
// If PTQ is used, the implementation in WTT can be used.
wtlib::ptq_impl::PTQ_subdivision_modifier<Mesh, Mesh_ops>::
coarsen(mesh, mesh_ops, level);
};
// Use the lambda functions to instantiate Wavlet_analysis_ops.
using FWT_ops = wtlib::Wavelet_analysis_ops<Mesh, Mesh_ops,
decltype(get_num_types),
decltype(classify),
decltype(fwt_initialize),
decltype(fwt_cleanup),
decltype(fwt_lift),
decltype(coarsen)>;
// Construct an object which will be used in computing the FWT.
FWT_ops fwt_ops(get_num_types, classify, fwt_initialize, fwt_cleanup, fwt_lift, coarsen);
/** Wavelet_synthesis_ops instantiation */
// Construct lambda functions that define operations in the IWT.
auto get_mesh_size = [](Mesh& mesh,
const Mesh_ops& mesh_ops,
int levels) -> int {
// Predicate the final number of vertices after computing the given levels of the IWT.
return wtlib::ptq_impl::
PTQ_subdivision_modifier<Mesh, Mesh_ops>::
get_mesh_size(mesh, mesh_ops, levels);
};
auto iwt_initialize = [](Mesh& mesh, const Mesh_ops& mesh_ops, int levels) -> void {
// Do any necessary initialization before lifting.
};
auto iwt_cleanup = [](Mesh& mesh, const Mesh_ops& mesh_ops) -> void {
// Cleanup resources acquired in initialization after the IWT is done.
};
auto refine = [](Mesh& mesh, const Mesh_ops& mesh_ops,
int level, Vertices& vertices, Bands& bands) -> void {
// If PTQ is used, the implementation in WTT can be used.
wtlib::ptq_impl::PTQ_subdivision_modifier<Mesh, Mesh_ops>::
refine(mesh, mesh_ops, level, vertices, bands);
};
auto iwt_lift = [](Mesh& mesh, const Mesh_ops& mesh_ops,
Vertex_handle** first,
Vertex_handle** last) -> void {
// Do lifting calculation. Vertices [*first, *(first+1)) are the old
// vertices, and [*(first+1), *last) are the new vertices. Incrementing
// *(first+1) obtains the vertices of the next type.
};
// Use the lambda functions to instantiate Wavelet_synthesis_ops.
using IWT_ops = wtlib::Wavelet_synthesis_ops<
Mesh, Mesh_ops,
decltype(get_num_types), decltype(get_mesh_size),
decltype(iwt_initialize), decltype(iwt_cleanup),
decltype(refine), decltype(iwt_lift)>;
// Construct an object which will be used in computing the IWT.
IWT_ops iwt_ops(get_num_types, get_mesh_size,
iwt_initialize, iwt_cleanup,
refine, iwt_lift);
// Instantiate Wavelet_analyze
using FWT = wtlib::Wavelet_analyze<Mesh_ops, FWT_ops>;
// Instantiate Wavelet_synthesize
using IWT = wtlib::Wavelet_synthesize<Mesh_ops, IWT_ops>;
// The constructed objects can be used as function calls to compute the FWT and IWT.
FWT fwt(mesh_ops, fwt_ops);
IWT iwt(mesh_ops, iwt_ops);
Mesh mesh;
std::cin >> mesh;
std::vector<std::vector<Vector3>> coefs;
int num_levels = 4;
fwt(mesh, coefs, num_levels); // Compute the FWT.
iwt(mesh, coefs, num_levels); // Compute the IWT.
}