-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsuper_quadric.cxx
73 lines (68 loc) · 2.15 KB
/
super_quadric.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
#include "implicit_primitive.h"
template <typename T>
struct super_quadric : public implicit_primitive<T>
{
/// main templated superclass which we want to inherit stuff from
typedef implicit_primitive<T> base;
using typename base::vec_type;
using typename base::pnt_type;
using base::gui_color;
using base::evaluate_gradient;
using base::add_member_control;
/// the two parameters of the super quadric defining the norm
T p1, p2;
/// reciprocals of parameters
T inv_p1, inv_p2;
/// construct with default values for the p_i
super_quadric() {
p1 = p2 = 2;
inv_p1 = inv_p2 = T(0.5);
gui_color = 0xFF8888;
}
/// reflect members to expose them to serialization
bool self_reflect(cgv::reflect::reflection_handler& rh)
{
return
rh.reflect_member("p1", p1) &&
rh.reflect_member("p2", p2) &&
base::self_reflect(rh);
}
/// ensure that reciprocals are computed and that scene is updated if parameters change
void on_set(void* member_ptr)
{
if (member_ptr == &p1)
inv_p1 = (p1 < 1e-12) ? 1e12 : 1 / p1;
if (member_ptr == &p2)
inv_p2 = (p2 < 1e-12) ? 1e12 : 1 / p2;
base::on_set(member_ptr);
}
/// helper function
static T signum(const T& v)
{
if (abs(v) < 1e-12)
return 0;
return v > 0 ? 1 : -1;
}
/// overload to return the type name of this object
std::string get_type_name() const
{
return "super_quadric";
}
/// evaluate the implicit function itself, this must be overloaded
T evaluate(const pnt_type& p) const {
T xy = pow(abs(p(0)),p1) + pow(abs(p(1)),p1);
return pow(pow(xy, inv_p1*p2) + pow(abs(p(2)),p2), inv_p2) - 1;
}
vec_type evaluate_gradient(const pnt_type& p) const {
T xy = pow(abs(p(0)),p1) + pow(abs(p(1)),p1);
return vec_type(p2*pow(abs(p(0)),p1-1)*signum(p(0))*pow(xy, inv_p1*p2-1),
p2*pow(abs(p(1)),p1-1)*signum(p(1))*pow(xy, inv_p1*p2-1),
p2*pow(abs(p(2)),p1-1)*signum(p(2)));
}
void create_gui()
{
add_member_control(this, "p1", p1, "value_slider", "min=0;max=50;ticks=true;log=true");
add_member_control(this, "p2", p2, "value_slider", "min=0;max=50;ticks=true;log=true");
}
};
scene_factory_registration<super_quadric<double> >sfr_super_quadric("super_quadric;U");