Skip to content

Commit 81c6fc2

Browse files
committed
Added optional showing of mesh edges.
1 parent 0de7b93 commit 81c6fc2

File tree

7 files changed

+122
-41
lines changed

7 files changed

+122
-41
lines changed

src/fragment-edge.glsl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#version 410
2+
3+
smooth in vec4 vertexColor;
4+
smooth in vec3 vBC;
5+
out vec4 outputColor;
6+
7+
float edgeFactor(){
8+
vec3 d = fwidth(vBC);
9+
vec3 a3 = smoothstep(vec3(0.0), d*1.0, vBC);
10+
return min(min(a3.x, a3.y), a3.z);
11+
}
12+
13+
void main()
14+
{
15+
gl_FragColor = vec4(mix(vec3(0.0,0.5,0.0),
16+
vertexColor.xyz,
17+
edgeFactor()), 1.0);
18+
}

src/mesh-viewer.cc

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -134,47 +134,64 @@ void MeshViewer::init_shaders ()
134134
/* load the vertex shader */
135135
Glib::RefPtr<const Glib::Bytes> vertex_source = Gio::Resource::lookup_data_global("/shaders/vertex.glsl");
136136
Glib::RefPtr<const Glib::Bytes> fragment_source = Gio::Resource::lookup_data_global("/shaders/fragment.glsl");
137+
Glib::RefPtr<const Glib::Bytes> fragment_edge_source = Gio::Resource::lookup_data_global("/shaders/fragment-edge.glsl");
137138

138139
guint vertex = create_shader(GL_VERTEX_SHADER, vertex_source);
140+
guint vertex_edge = create_shader(GL_VERTEX_SHADER, vertex_source);
139141
guint fragment = create_shader(GL_FRAGMENT_SHADER, fragment_source);
142+
guint fragment_edge = create_shader(GL_FRAGMENT_SHADER, fragment_edge_source);
140143
m_program = glCreateProgram ();
141144
glAttachShader (m_program, vertex);
142145
glAttachShader (m_program, fragment);
143146
glLinkProgram (m_program);
144147

148+
// A different program for showing edges
149+
m_program_edge = glCreateProgram();
150+
glAttachShader (m_program_edge, vertex_edge);
151+
glAttachShader (m_program_edge, fragment_edge);
152+
glLinkProgram (m_program_edge);
153+
145154
m_position_index = 0;
146155
m_color_index = 1;
147156
m_normal_index = 2;
148157
m_bary_index = 3;
149158

150-
glBindAttribLocation(m_program, m_position_index, "position");
151-
glBindAttribLocation(m_program, m_color_index, "color");
152-
glBindAttribLocation(m_program, m_normal_index, "normal");
153-
glBindAttribLocation(m_program, m_bary_index, "bary");
154-
155-
int status = 0;
156-
glGetProgramiv (m_program, GL_LINK_STATUS, &status);
157-
if (status == GL_FALSE)
159+
for (auto p : {m_program, m_program_edge})
158160
{
159-
int log_len = 0;
160-
glGetProgramiv (m_program, GL_INFO_LOG_LENGTH, &log_len);
161-
162-
string error_string;
163-
error_string.resize(log_len+1);
164-
glGetProgramInfoLog (m_program, log_len, NULL, &error_string[0]);
165-
166-
glDeleteProgram (m_program);
167-
throw runtime_error(
168-
format(
169-
"Linking failure in program: {}",
170-
error_string));
161+
glBindAttribLocation(p, m_position_index, "position");
162+
glBindAttribLocation(p, m_color_index, "color");
163+
glBindAttribLocation(p, m_normal_index, "normal");
164+
glBindAttribLocation(p, m_bary_index, "bary");
165+
166+
int status = 0;
167+
glGetProgramiv (p, GL_LINK_STATUS, &status);
168+
if (status == GL_FALSE)
169+
{
170+
int log_len = 0;
171+
glGetProgramiv (p, GL_INFO_LOG_LENGTH, &log_len);
172+
173+
string error_string;
174+
error_string.resize(log_len+1);
175+
glGetProgramInfoLog (p, log_len, NULL, &error_string[0]);
176+
177+
glDeleteProgram (p);
178+
throw runtime_error(
179+
format(
180+
"Linking failure in program: {}",
181+
error_string));
182+
}
171183
}
172184

173185
/* the individual shaders can be detached and destroyed */
174186
glDetachShader (m_program, vertex);
175187
glDetachShader (m_program, fragment);
188+
glDetachShader (m_program_edge, vertex_edge);
189+
glDetachShader (m_program_edge, fragment_edge);
190+
176191
glDeleteShader (vertex);
192+
glDeleteShader (vertex_edge);
177193
glDeleteShader (fragment);
194+
glDeleteShader (fragment_edge);
178195
}
179196

180197
void MeshViewer::init_buffers (guint *vao_out)
@@ -341,19 +358,24 @@ void MeshViewer::build_projection_matrix()
341358
// Draw the mesh (or meshes)
342359
void MeshViewer::draw_mesh()
343360
{
361+
guint program;
362+
if (m_show_edge)
363+
program = m_program_edge;
364+
else
365+
program = m_program;
366+
glUseProgram(program);
367+
344368
setup_world(m_size_scale*m_view_scale,
345369
m_view_quat, m_pivot);
346370

347-
glUseProgram(m_program);
348-
349371
// get the uniform locations
350-
m_proj_loc = glGetUniformLocation (m_program, "projMatrix");
351-
m_mv_loc = glGetUniformLocation (m_program, "mvMatrix");
352-
m_normal_matrix_loc = glGetUniformLocation (m_program, "normalMatrix");
353-
guint shininess_loc=glGetUniformLocation (m_program, "shininess");
354-
guint specular_loc=glGetUniformLocation (m_program, "specular");
355-
guint diffuse_loc=glGetUniformLocation (m_program, "diffuse");
356-
guint ambient_loc=glGetUniformLocation (m_program, "ambient");
372+
m_proj_loc = glGetUniformLocation (program, "projMatrix");
373+
m_mv_loc = glGetUniformLocation (program, "mvMatrix");
374+
m_normal_matrix_loc = glGetUniformLocation (program, "normalMatrix");
375+
guint shininess_loc=glGetUniformLocation (program, "shininess");
376+
guint specular_loc=glGetUniformLocation (program, "specular");
377+
guint diffuse_loc=glGetUniformLocation (program, "diffuse");
378+
guint ambient_loc=glGetUniformLocation (program, "ambient");
357379

358380
// Fixed light properties - Should be configurable
359381
glUniform1f(shininess_loc, 10.0);
@@ -642,3 +664,9 @@ void MeshViewer::view_port_to_world(glm::vec3 view_port_coord,
642664

643665
world_coord = glm::vec3(v.x/v.w,v.y/v.w,v.z/v.w);
644666
}
667+
668+
void MeshViewer::set_show_edge(bool show_edge)
669+
{
670+
m_show_edge = show_edge;
671+
queue_render();
672+
}

src/mesh-viewer.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ class MeshViewer : public Gtk::GLArea
3434
// Reset the view to the original view
3535
void reset_view();
3636

37+
// Whether to use the edge shader or the non-edge shader
38+
void set_show_edge(bool show_edge);
39+
3740
private:
3841

3942
// signals
@@ -75,6 +78,7 @@ class MeshViewer : public Gtk::GLArea
7578
guint m_vao {0};
7679
guint m_buffer {0};
7780
guint m_program {0};
81+
guint m_program_edge {0};
7882

7983
// Describe the vertex attribute layout
8084
guint m_position_index {0};
@@ -95,6 +99,9 @@ class MeshViewer : public Gtk::GLArea
9599
guint m_diffuse;
96100
guint m_ambient;
97101

102+
// which shader to use
103+
bool m_show_edge = false;
104+
98105
// world description
99106
glm::mat4 m_proj_matrix;
100107
glm::mat4 m_world;

src/pomelo.cc

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ Pomelo::Pomelo(shared_ptr<PomeloSettings> pomelo_settings)
6666
m_refActionGroup->add_action("view_skeleton",
6767
sigc::mem_fun(*this, &Pomelo::on_action_view_skeleton) );
6868

69+
bool init_show_edge = m_pomelo_settings->get_int_default("show_edge",0);
70+
m_mesh_viewer.set_show_edge(init_show_edge);
71+
m_ref_show_edge_toggle = m_refActionGroup->add_action_bool("show_edge",
72+
sigc::mem_fun(*this, &Pomelo::on_action_show_edge), init_show_edge );
73+
6974
m_refActionGroup->add_action("settings",
7075
sigc::mem_fun(*this, &Pomelo::on_action_view_settings) );
7176

@@ -76,47 +81,51 @@ Pomelo::Pomelo(shared_ptr<PomeloSettings> pomelo_settings)
7681
"<interface>"
7782
" <menu id='menubar'>"
7883
" <submenu>"
79-
" <attribute name='label' translatable='yes'>_File</attribute>"
84+
" <attribute name='label'>_File</attribute>"
8085
" <section>"
8186
" <item>"
82-
" <attribute name='label' translatable='yes'>_Export STL</attribute>"
87+
" <attribute name='label'>_Export STL</attribute>"
8388
" <attribute name='action'>pomelo.export_stl</attribute>"
8489
" <attribute name='accel'>&lt;Primary&gt;s</attribute>"
8590
" </item>"
8691
" <item>"
87-
" <attribute name='label' translatable='yes'>_Load SVG</attribute>"
92+
" <attribute name='label'>_Load SVG</attribute>"
8893
" <attribute name='action'>pomelo.load_svg</attribute>"
8994
" <attribute name='accel'>&lt;Primary&gt;s</attribute>"
9095
" </item>"
9196
" <item>"
92-
" <attribute name='label' translatable='yes'>_Quit</attribute>"
97+
" <attribute name='label'>_Quit</attribute>"
9398
" <attribute name='action'>pomelo.quit</attribute>"
9499
" <attribute name='accel'>&lt;Primary&gt;q</attribute>"
95100
" </item>"
96101
" </section>"
97102
" </submenu>"
98103
" <submenu>"
99-
" <attribute name='label' translatable='yes'>_View</attribute>"
104+
" <attribute name='label'>_View</attribute>"
100105
" <item>"
101-
" <attribute name='label' translatable='yes'>_Reset 3D View</attribute>"
106+
" <attribute name='label'>_Reset 3D View</attribute>"
102107
" <attribute name='action'>pomelo.reset_3d_view</attribute>"
103108
" </item>"
109+
" <item>"
110+
" <attribute name='label'>Show mesh edges</attribute>"
111+
" <attribute name='action'>pomelo.show_edge</attribute>"
112+
" </item>"
104113
" </submenu>"
105114
" <submenu>"
106-
" <attribute name='label' translatable='yes'>_Tools</attribute>"
115+
" <attribute name='label'>_Tools</attribute>"
107116
" <item>"
108-
" <attribute name='label' translatable='yes'>_View Skeleton</attribute>"
117+
" <attribute name='label'>_View Skeleton</attribute>"
109118
" <attribute name='action'>pomelo.view_skeleton</attribute>"
110119
" </item>"
111120
" <item>"
112-
" <attribute name='label' translatable='yes'>Settings</attribute>"
121+
" <attribute name='label'>Settings</attribute>"
113122
" <attribute name='action'>pomelo.settings</attribute>"
114123
" </item>"
115124
" </submenu>"
116125
" <submenu>"
117-
" <attribute name='label' translatable='yes'>_Help</attribute>"
126+
" <attribute name='label'>_Help</attribute>"
118127
" <item>"
119-
" <attribute name='label' translatable='yes'>_About</attribute>"
128+
" <attribute name='label'>_About</attribute>"
120129
" <attribute name='action'>pomelo.about</attribute>"
121130
" </item>"
122131
" </submenu>"
@@ -289,6 +298,22 @@ void Pomelo::on_action_view_skeleton()
289298
m_skeleton_viewer->show();
290299
}
291300

301+
void Pomelo::on_action_show_edge()
302+
{
303+
bool active = false;
304+
m_ref_show_edge_toggle->get_state(active);
305+
306+
//The toggle action's state does not change automatically:
307+
active = !active;
308+
m_ref_show_edge_toggle->change_state(active);
309+
310+
// Store the new state
311+
m_pomelo_settings->set_int("show_edge", int(active));
312+
m_pomelo_settings->save();
313+
314+
m_mesh_viewer.set_show_edge(active);
315+
}
316+
292317
void Pomelo::on_action_reset_3d_view()
293318
{
294319
m_mesh_viewer.reset_view();

src/pomelo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class Pomelo : public Gtk::Window
6060
void on_action_file_export_stl();
6161
void on_action_help_about();
6262
void on_action_view_skeleton();
63+
void on_action_show_edge();
6364
void on_action_reset_3d_view();
6465
void on_action_view_settings();
6566
void on_action_load_svg();
@@ -100,6 +101,7 @@ class Pomelo : public Gtk::Window
100101
std::unique_ptr<std::thread> m_worker_skeleton_thread;
101102
WorkerAction m_worker_action; // What is our worker doing
102103
std::shared_ptr<PomeloSettings> m_pomelo_settings;
104+
Glib::RefPtr<Gio::SimpleAction> m_ref_show_edge_toggle;
103105
};
104106

105107
#endif /* HELLO-WORLD */

src/resources.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
</gresource>
55
<gresource prefix="/shaders">
66
<file>fragment.glsl</file>
7+
<file>fragment-edge.glsl</file>
78
<file>vertex.glsl</file>
89
</gresource>
910
<gresource prefix="/about">

src/smooth-sharp-angles.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ static double calc_angle(const Point_2& p,
8383
Vector_2 v(q,p);
8484
Vector_2 w(q,r);
8585
double angle = acos(v*w/(CGAL::sqrt(v.squared_length())*CGAL::sqrt(w.squared_length())));
86-
print("angle = {} deg\n", angle*180/MY_PI);
86+
// print("angle = {} deg\n", angle*180/MY_PI);
8787
return angle;
8888
}
8989

0 commit comments

Comments
 (0)