-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathknot_vector.cxx
110 lines (95 loc) · 2.83 KB
/
knot_vector.cxx
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
#include "knot_vector.h"
#include <cgv/utils/scan.h>
#include <cgv_gl/gl/gl.h>
template <typename T>
void knot_vector<T>::append_point(const pnt_type& p)
{
pnt_idx = int(points.size());
points.push_back(p);
if (find_control(pnt_idx))
find_control(pnt_idx)->set("max", pnt_idx);
append_callback(pnt_idx);
on_set(&pnt_idx);
}
/// construct with empty skeleton
template <typename T>
knot_vector<T>::knot_vector() : p(0, 0, 0)
{
pnt_idx = 0;
}
/// reflect members to expose them to serialization
template <typename T>
bool knot_vector<T>::self_reflect(cgv::reflect::reflection_handler& rh)
{
size_t n = points.size();
// reflect statically allocated members
bool do_continue =
rh.reflect_member("n", n) &&
implicit_primitive<T>::self_reflect(rh);
// ensure dynamic allocation of points
if (rh.is_creative()) {
while (points.size() < n)
append_point(pnt_type(0, 0, 0));
while (points.size() > n)
points.pop_back();
}
// check whether to termine self reflection
if (!do_continue)
return false;
// reflect all point positions
for (size_t i = 0; i < points.size(); ++i) {
if (!rh.reflect_member(std::string("x") + cgv::utils::to_string(i), points[i].x()))
return false;
if (!rh.reflect_member(std::string("y") + cgv::utils::to_string(i), points[i].y()))
return false;
if (!rh.reflect_member(std::string("z") + cgv::utils::to_string(i), points[i].z()))
return false;
}
return true;
}
/// implementation of updates needed after members changed
template <typename T>
void knot_vector<T>::on_set(void* member_ptr)
{
if (member_ptr == &pnt_idx) {
p = points[pnt_idx];
update_member(&p(0));
update_member(&p(1));
update_member(&p(2));
point_index_selection_callback();
}
for (unsigned c = 0; c < 3; ++c) {
if (member_ptr == &p(c)) {
points[pnt_idx](c) = p(c);
position_changed_callback(pnt_idx);
}
for (size_t i = 0; i < points.size(); ++i) {
if (member_ptr == &points[i](c)) {
if (i == pnt_idx) {
p(c) = points[i](c);
update_member(&p(c));
position_changed_callback(i);
}
}
}
}
base::update_member(member_ptr);
base::update_scene();
}
template <typename T>
void knot_vector<T>::create_gui()
{
if (points.empty()) {
append_point(pnt_type(0, 0, 0));
append_point(pnt_type(1, 0, 0));
}
add_member_control(this, "pnt_idx", pnt_idx, "value_slider", "min=0;max=1;ticks=true");
find_control(pnt_idx)->set("max", (int)points.size() - 1);
connect_copy(base::add_button("append")->click,
cgv::signal::rebind(this, &knot_vector<T>::append_point, cgv::signal::_r(p)));
add_member_control(this, "x", p(0), "value_slider", "min=-5;max=5;ticks=true");
add_member_control(this, "y", p(1), "value_slider", "min=-5;max=5;ticks=true");
add_member_control(this, "z", p(2), "value_slider", "min=-5;max=5;ticks=true");
}
template class knot_vector<float>;
template class knot_vector<double>;