19 #include <GL/freeglut.h>
24 #include "scalar_view.h"
26 #define GL_BUFFER_OFFSET(i) ((char *)NULL + (i))
29 #define MIN_CONT_STEP 1.0E-2
30 #define CONT_CHANGE 1.0E-2
31 #define D3DV_SCALE_STEP_COEF 1.1
43 void ScalarView::init()
46 pmode = mode3d =
false;
69 ScalarView::ScalarView(
const char* title, WinGeom* wg) :
72 pointed_vertex_node(NULL),
73 allow_node_selection(false),
74 pointed_node_widget(0),
75 selected_node_widget(0),
76 node_pixel_radius(10),
77 node_widget_vert_cnt(32),
79 show_element_info(false)
84 ScalarView::ScalarView(WinGeom* wg) :
85 View(
"ScalarView", wg),
87 pointed_vertex_node(NULL),
88 allow_node_selection(false),
89 pointed_node_widget(0),
90 selected_node_widget(0),
91 node_pixel_radius(10),
92 node_widget_vert_cnt(32),
94 show_element_info(false)
100 ScalarView::ScalarView(
char* title, WinGeom* wg) :
103 pointed_vertex_node(NULL),
104 allow_node_selection(false),
105 pointed_node_widget(0),
106 selected_node_widget(0),
107 node_pixel_radius(10),
108 node_widget_vert_cnt(32),
109 element_id_widget(0),
110 show_element_info(false)
115 ScalarView::~ScalarView()
118 vertex_nodes.clear();
122 void ScalarView::on_close()
125 if(pointed_node_widget != 0)
127 glDeleteLists(pointed_node_widget, 1);
128 pointed_node_widget = 0;
130 if(selected_node_widget != 0)
132 glDeleteLists(selected_node_widget, 1);
133 selected_node_widget = 0;
135 if(element_id_widget != 0)
137 glDeleteLists(element_id_widget, 1);
138 element_id_widget = 0;
140 if(gl_coord_buffer != 0)
142 glDeleteBuffersARB(1, &gl_coord_buffer);
145 if(gl_index_buffer != 0)
147 glDeleteBuffersARB(1, &gl_index_buffer);
155 void ScalarView::show(MeshFunction<double>* sln,
double eps,
int item,
156 MeshFunction<double>* xdisp, MeshFunction<double>* ydisp,
double dmult)
159 Element* active_element = sln->get_active_element();
162 lin->set_max_absolute_value(std::max(fabs(range_min), fabs(range_max)));
164 lin->set_displacement(xdisp, ydisp, dmult);
167 lin->process_solution(sln, item, eps);
172 init_vertex_nodes(sln->get_mesh());
175 init_element_info(sln->get_mesh());
190 if(
dynamic_cast<Solution<double>*
>(sln) != NULL)
191 if(active_element != NULL)
194 if(active_element->active)
195 sln->set_active_element(active_element);
198 void ScalarView::show_linearizer_data(
double eps,
int item)
211 void ScalarView::update_mesh_info()
215 calculate_normals(lin->get_vertices(), lin->get_num_vertices(), lin->get_triangles(), lin->get_num_triangles());
223 double vert_min = lin->get_min_value();
224 double vert_max = lin->get_max_value();
227 if((vert_max - vert_min) < 1e-8)
235 range_min = vert_min;
236 range_max = vert_max;
239 if(fabs(range_max - range_min) < 1e-8)
242 value_irange = 1.0 / (range_max - range_min);
245 lin->calc_vertices_aabb(&vertices_min_x, &vertices_max_x, &vertices_min_y, &vertices_max_y);
248 value_range_avg = 0.0;
249 double3* verts = lin->get_vertices();
250 const int num_verts = lin->get_num_vertices();
251 for(
int i = 0; i < num_verts; i++)
252 if(verts[i][2] > range_max)
253 value_range_avg += range_max;
254 else if(verts[i][2] < range_min)
255 value_range_avg += range_min;
257 value_range_avg += verts[i][2];
258 value_range_avg /= num_verts;
268 void ScalarView::init_vertex_nodes(
const Mesh* mesh)
271 pointed_vertex_node = NULL;
272 vertex_nodes.clear();
275 int active_nodes = 0;
277 for(
int i = 0; i < max_node_id; i++)
285 vertex_nodes.clear();
286 vertex_nodes.reserve(active_nodes);
289 for(
int i = 0; i < max_node_id; i++)
293 vertex_nodes.push_back(
VertexNodeInfo(node->
id, (
float)node->x, (
float)node->
y));
297 std::sort(vertex_nodes.begin(), vertex_nodes.end(), compare_vertex_nodes_x);
303 Hermes::vector<VertexNodeInfo>::iterator found_iter = std::lower_bound(vertex_nodes.begin(), vertex_nodes.end(), node_info, compare_vertex_nodes_x);
304 Hermes::vector<VertexNodeInfo>::iterator found_nearest = vertex_nodes.end();
305 float found_nearest_dist = -1;
306 while (found_iter != vertex_nodes.end() && abs(found_iter->x - x) <= radius)
308 if(abs(found_iter->y - y) <= radius)
310 float dist = std::min(found_iter->x - x, found_iter->y - y);
311 if(found_nearest_dist < 0 || dist < found_nearest_dist)
313 found_nearest_dist = dist;
314 found_nearest = found_iter;
320 if(found_nearest != vertex_nodes.end())
321 return found_nearest.operator->();
330 glTranslatef(node.x, node.
y, 0.0f);
331 glScalef(1/(
float)scale, 1/(
float)scale, 1.0f);
334 void* font = GLUT_BITMAP_HELVETICA_10;
335 unsigned char buffer[128];
336 sprintf((
char*)buffer,
"%d", node.
id);
337 int width_px = glutBitmapLength(font, buffer);
338 int height_px = glutBitmapHeight(font);
341 if(width_px > (2*node_pixel_radius))
344 float coef = width_px / (2.0f * node_pixel_radius);
345 glScalef(coef, coef, 1.0f);
346 glCallList(selected_node_widget);
350 glCallList(selected_node_widget);
353 glTranslatef(-width_px/2.0f, -height_px/3.0f, 0.0f);
354 glColor3f(1.0f, 1.0f, 1.0f);
355 glRasterPos2f(0.0f, 0.0f);
356 glutBitmapString(font, buffer);
362 void ScalarView::draw_vertex_nodes()
365 create_nodes_widgets();
368 glMatrixMode(GL_MODELVIEW);
369 glDisable(GL_TEXTURE_1D);
370 glDisable(GL_LIGHTING);
374 Hermes::vector<VertexNodeInfo>::const_iterator iter = vertex_nodes.begin();
375 while (iter != vertex_nodes.end())
378 draw_single_vertex_node(*iter);
383 if(pointed_vertex_node != NULL)
386 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
388 glTranslatef(pointed_vertex_node->x, pointed_vertex_node->y, 0.0f);
389 glScalef(1/(
float)scale, 1/(
float)scale, 1.0f);
390 glCallList(pointed_node_widget);
396 void ScalarView::create_nodes_widgets()
399 if(pointed_node_widget == 0)
401 pointed_node_widget = glGenLists(1);
402 glNewList(pointed_node_widget, GL_COMPILE);
405 glColor4f(1.0f, 1.0f, 1.0f, 0.5f);
406 glBegin(GL_TRIANGLE_FAN);
407 glVertex2f(0.0f, 0.0f);
408 float radius = 1.3f * node_pixel_radius;
409 for(
int i = 0; i < node_widget_vert_cnt; i++)
411 float angle = (float)((i / (
float)(node_widget_vert_cnt-1)) * (2.0f * M_PI));
412 glVertex2f(radius * cos(angle), radius * sin(angle));
417 glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
418 glBegin(GL_LINE_STRIP);
419 radius = (float)node_pixel_radius;
420 for(
int i = 0; i < node_widget_vert_cnt; i++)
422 float angle = (float)((i / (
float)(node_widget_vert_cnt-1)) * (2.0f * M_PI));
423 glVertex2f(radius * cos(angle), radius * sin(angle));
431 if(selected_node_widget == 0)
433 selected_node_widget = glGenLists(1);
434 glNewList(selected_node_widget, GL_COMPILE);
437 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
438 glBegin(GL_TRIANGLE_FAN);
439 glVertex2f(0.0f, 0.0f);
440 float radius = 1.3f * node_pixel_radius;
441 for(
int i = 0; i < node_widget_vert_cnt; i++)
443 float angle = (float)((i / (
float)(node_widget_vert_cnt-1)) * (2.0f * M_PI));
444 glVertex2f(radius * cos(angle), radius * sin(angle));
449 glColor4f(0.4f, 0.4f, 0.2f, 1.0f);
450 glBegin(GL_TRIANGLE_FAN);
451 glVertex2f(0.0f, 0.0f);
452 radius = (float)node_pixel_radius;
453 for(
int i = 0; i < node_widget_vert_cnt; i++)
455 float angle = (float)((i / (
float)(node_widget_vert_cnt-1)) * (2.0f * M_PI));
456 glVertex2f(radius * cos(angle), radius * sin(angle));
464 void ScalarView::init_element_info(
const Mesh* mesh)
467 element_infos.clear();
474 for_all_active_elements(element, mesh)
476 double sum_x = 0.0, sum_y = 0.0;
477 double max_x, max_y, min_x, min_y;
478 max_x = min_x = element->
vn[0]->x;
479 max_y = min_y = element->
vn[0]->
y;
480 for(
unsigned int i = 0; i < element->get_nvert(); i++)
482 sum_x += element->
vn[i]->x;
483 sum_y += element->
vn[i]->
y;
485 if(element->
vn[i]->x > max_x)
486 max_x = element->
vn[i]->x;
487 if(element->
vn[i]->x < min_x)
488 min_x = element->
vn[i]->x;
489 if(element->
vn[i]->
y > max_y)
490 max_y = element->
vn[i]->
y;
491 if(element->
vn[i]->
y < min_y)
492 min_y = element->
vn[i]->
y;
495 (
float)(sum_x / element->get_nvert()), (
float)(sum_y / element->get_nvert()),
496 (
float)(max_x - min_x), (
float)(max_y - min_y)));
505 void ScalarView::draw_element_infos_2d()
508 create_element_info_widgets();
511 glMatrixMode(GL_MODELVIEW);
512 glDisable(GL_TEXTURE_1D);
513 glDisable(GL_LIGHTING);
517 Hermes::vector<ElementInfo>::const_iterator iter = element_infos.begin();
518 while (iter != element_infos.end())
521 float width = (float)(iter->width * scale);
522 float height = (float)(iter->height * scale);
525 if(width > 6*node_pixel_radius && height > 3*node_pixel_radius)
529 glTranslatef(iter->x, iter->y, 0.0f);
530 glScalef(1/(
float)scale, 1/(
float)scale, 1.0f);
533 void* font = GLUT_BITMAP_HELVETICA_10;
534 unsigned char buffer[128];
535 sprintf((
char*)buffer,
"%d", iter->id);
536 int width_px = glutBitmapLength(font, buffer);
537 int height_px = glutBitmapHeight(font);
540 glCallList(element_id_widget);
543 glTranslatef(-width_px/2.0f, -height_px/3.0f, 0.0f);
544 glColor3f(1.0f, 1.0f, 1.0f);
545 glRasterPos2f(0.0f, 0.0f);
546 glutBitmapString(font, buffer);
557 void ScalarView::create_element_info_widgets()
559 if(element_id_widget == 0)
561 element_id_widget = glGenLists(1);
562 glNewList(element_id_widget, GL_COMPILE);
567 float radius = 2.0f * node_pixel_radius;
568 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
569 glVertex2f(-radius*1.1, radius*0.5);
570 glVertex2f( radius*1.1, radius*0.5);
571 glVertex2f( radius*1.1, -radius*0.5);
572 glVertex2f(-radius*1.1, -radius*0.5);
575 radius = 1.8f * node_pixel_radius;
576 glColor4f(0.2f, 0.2f, 0.4f, 1.0f);
577 glVertex2f(-radius*1.1, radius*0.5);
578 glVertex2f( radius*1.1, radius*0.5);
579 glVertex2f( radius*1.1, -radius*0.5);
580 glVertex2f(-radius*1.1, -radius*0.5);
588 void ScalarView::show_contours(
double step,
double orig)
591 throw Exceptions::ValueException(
"step", step, 0.0);
595 set_palette_filter(
true);
599 static double my_ceil(
double x)
606 void ScalarView::draw_tri_contours(double3* vert, int3* tri)
609 int i, idx[3], perm = 0;
610 memcpy(idx, tri,
sizeof(idx));
611 for (i = 0; i < 2; i++)
613 if(vert[idx[0]][2] > vert[idx[1]][2]) { std::swap(idx[0], idx[1]); perm++; }
614 if(vert[idx[1]][2] > vert[idx[2]][2]) { std::swap(idx[1], idx[2]); perm++; }
616 if(fabs(vert[idx[0]][2] - vert[idx[2]][2]) < 1e-3 * fabs(cont_step))
return;
619 double val = vert[idx[0]][2];
620 val = my_ceil((val - cont_orig) / cont_step) * cont_step + cont_orig;
633 while (val < vert[idx[r2]][2])
635 double ld = vert[idx[l2]][2] - vert[idx[l1]][2];
636 double rd = vert[idx[r2]][2] - vert[idx[r1]][2];
639 while (val < vert[idx[l2]][2])
641 double lt = (val - vert[idx[l1]][2]) / ld;
642 double rt = (val - vert[idx[r1]][2]) / rd;
644 double x1 = (1.0 - lt) * vert[idx[l1]][0] + lt * vert[idx[l2]][0];
645 double y1 = (1.0 - lt) * vert[idx[l1]][1] + lt * vert[idx[l2]][1];
646 double x2 = (1.0 - rt) * vert[idx[r1]][0] + rt * vert[idx[r2]][0];
647 double y2 = (1.0 - rt) * vert[idx[r1]][1] + rt * vert[idx[r2]][1];
649 if(perm & 1) { glVertex2d(x1, y1); glVertex2d(x2, y2); }
650 else { glVertex2d(x2, y2); glVertex2d(x1, y1); }
659 void ScalarView::prepare_gl_geometry()
668 int vert_cnt = lin->get_num_vertices();
669 double3* verts = lin->get_vertices();
670 int tri_cnt = lin->get_num_triangles();
671 int3* tris = lin->get_triangles();
674 if(!GLEW_ARB_vertex_buffer_object)
675 throw std::runtime_error(
"ARB_vertex_buffer_object not supported");
678 if(gl_index_buffer == 0 || tri_cnt > max_gl_tris)
680 if(gl_index_buffer == 0)
681 glGenBuffersARB(1, &gl_index_buffer);
682 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, gl_index_buffer);
683 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
sizeof(GLint) * tri_cnt * 3, NULL, GL_DYNAMIC_DRAW_ARB);
684 GLenum err = glGetError();
685 if(err != GL_NO_ERROR)
686 throw std::runtime_error(
"unable to allocate vertex buffer: " + err);
687 max_gl_tris = tri_cnt;
691 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, gl_index_buffer);
695 GLuint* gl_triangle = (GLuint*)glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
696 if(gl_triangle == NULL)
697 throw std::runtime_error(
"unable to map index buffer: " + glGetError());
699 for(
int i = 0; i < tri_cnt; i++)
701 const int3& triangle = tris[i];
702 const double3& vert_a = verts[triangle[0]];
703 const double3& vert_b = verts[triangle[1]];
704 const double3& vert_c = verts[triangle[2]];
705 if(finite(vert_a[2]) && finite(vert_b[2]) && finite(vert_c[2]))
707 gl_triangle[0] = (GLint)triangle[0];
708 gl_triangle[1] = (GLint)triangle[1];
709 gl_triangle[2] = (GLint)triangle[2];
714 glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
717 if(gl_coord_buffer == 0 || vert_cnt > max_gl_verts)
719 if(gl_coord_buffer == 0)
720 glGenBuffersARB(1, &gl_coord_buffer);
721 glBindBufferARB(GL_ARRAY_BUFFER_ARB, gl_coord_buffer);
722 glBufferDataARB(GL_ARRAY_BUFFER_ARB,
sizeof(
GLVertex2) * vert_cnt, NULL, GL_DYNAMIC_DRAW_ARB);
723 GLenum err = glGetError();
724 if(err != GL_NO_ERROR)
725 throw std::runtime_error(
"unable to allocate coord buffer: " + err);
726 max_gl_verts = vert_cnt;
730 glBindBufferARB(GL_ARRAY_BUFFER_ARB, gl_coord_buffer);
734 GLVertex2* gl_verts = (
GLVertex2*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
736 throw std::runtime_error(
"unable to map coord buffer: " + glGetError());
737 for(
int i = 0; i < vert_cnt; i++)
738 gl_verts[i] =
GLVertex2((
float)verts[i][0], (
float)verts[i][1], (
float)((verts[i][2] - range_min) * value_irange));
739 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
742 if(gl_edge_inx_buffer == 0)
744 glGenBuffersARB(1, &gl_edge_inx_buffer);
745 glBindBufferARB(GL_ARRAY_BUFFER_ARB, gl_edge_inx_buffer);
746 glBufferDataARB(GL_ARRAY_BUFFER_ARB,
sizeof(GLuint) * H2DV_GL_MAX_EDGE_BUFFER * 2, NULL, GL_DYNAMIC_DRAW_ARB);
747 GLenum err = glGetError();
748 if(err != GL_NO_ERROR) {
749 glDeleteBuffersARB(1, &gl_edge_inx_buffer);
750 gl_edge_inx_buffer = 0;
753 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
757 if(gl_coord_buffer) { glDeleteBuffersARB(1, &gl_coord_buffer); gl_coord_buffer = 0; }
758 if(gl_index_buffer) { glDeleteBuffersARB(1, &gl_index_buffer); gl_index_buffer = 0; }
759 if(gl_edge_inx_buffer) { glDeleteBuffersARB(1, &gl_edge_inx_buffer); gl_edge_inx_buffer = 0; }
764 void ScalarView::draw_values_2d()
767 glEnable(GL_TEXTURE_1D);
768 glBindTexture(GL_TEXTURE_1D, gl_pallete_tex_id);
769 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
773 glMatrixMode(GL_TEXTURE);
775 glTranslated(tex_shift, 0.0, 0.0);
776 glScaled(tex_scale, 0.0, 0.0);
779 if(gl_coord_buffer == 0 || gl_index_buffer == 0)
782 int tri_cnt = lin->get_num_triangles();
783 const double3* vert = lin->get_vertices();
784 const int3* tris = lin->get_triangles();
787 glBegin(GL_TRIANGLES);
788 for (
int i = 0; i < tri_cnt; i++)
790 const int3& triangle = tris[i];
791 const double3& vert_a = vert[triangle[0]];
792 const double3& vert_b = vert[triangle[1]];
793 const double3& vert_c = vert[triangle[2]];
795 if(finite(vert_a[2]) && finite(vert_b[2]) && finite(vert_c[2]))
797 glTexCoord1d((vert_a[2] - range_min) * value_irange);
798 glVertex2d(vert_a[0], vert_a[1]);
799 glTexCoord1d((vert_b[2] - range_min) * value_irange);
800 glVertex2d(vert_b[0], vert_b[1]);
801 glTexCoord1d((vert_c[2] - range_min) * value_irange);
802 glVertex2d(vert_c[0], vert_c[1]);
811 glBindBufferARB(GL_ARRAY_BUFFER_ARB, gl_coord_buffer);
812 glVertexPointer(2, GL_FLOAT,
sizeof(
GLVertex2), GL_BUFFER_OFFSET(0));
813 glTexCoordPointer(1, GL_FLOAT,
sizeof(
GLVertex2), GL_BUFFER_OFFSET(GLVertex2::H2D_OFFSETOF_COORD));
814 glEnableClientState(GL_VERTEX_ARRAY);
815 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
818 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, gl_index_buffer);
821 glDrawElements(GL_TRIANGLES, 3*gl_tri_cnt, GL_UNSIGNED_INT, GL_BUFFER_OFFSET(0));
824 glDisableClientState(GL_VERTEX_ARRAY);
825 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
830 glMatrixMode(GL_TEXTURE);
832 glMatrixMode(GL_MODELVIEW);
835 void ScalarView::draw_edges_2d()
837 glColor3fv(edges_color);
838 bool displayed =
false;
839 if(gl_edge_inx_buffer != 0) {
841 glEnableClientState(GL_VERTEX_ARRAY);
844 glBindBufferARB(GL_ARRAY_BUFFER_ARB, gl_edge_inx_buffer);
845 GLuint *gl_inx_buffer = (GLuint*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY);
846 GLenum err = glGetError();
847 if(err == GL_NO_ERROR) {
848 unsigned int buffer_inx = 0;
849 int2* edges = lin->get_edges();
850 int* edge_markers = lin->get_edge_markers();
851 int edge_cnt = lin->get_num_edges();
852 for (
int i = 0; i < edge_cnt; i++)
854 const int2 &edge = edges[i];
855 const int &edge_marker = edge_markers[i];
856 if(show_edges || edge_marker != 0) {
857 gl_inx_buffer[buffer_inx] = (GLuint)edge[0];
858 gl_inx_buffer[buffer_inx + 1] = (GLuint)edge[1];
863 if(buffer_inx == (2*H2DV_GL_MAX_EDGE_BUFFER) || (buffer_inx > 0 && i == (edge_cnt-1)))
865 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
868 glBindBufferARB(GL_ARRAY_BUFFER_ARB, gl_coord_buffer);
869 glVertexPointer(2, GL_FLOAT,
sizeof(
GLVertex2), GL_BUFFER_OFFSET(0));
870 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, gl_edge_inx_buffer);
873 glDrawElements(GL_LINES, buffer_inx, GL_UNSIGNED_INT, GL_BUFFER_OFFSET(0));
876 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
877 glBindBufferARB(GL_ARRAY_BUFFER_ARB, gl_edge_inx_buffer);
878 gl_inx_buffer = (GLuint*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY);
882 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
885 glDisableClientState(GL_VERTEX_ARRAY);
894 draw_edges(&draw_gl_edge, NULL, !show_edges);
899 void ScalarView::draw_normals_3d()
901 double normal_xzscale = 1.0 / xzscale, normal_yscale = 1.0 / yscale;
903 glPushAttrib(GL_ENABLE_BIT);
906 const int num_vert = lin->get_num_vertices();
907 double3* vert = lin->get_vertices();
909 glDisable(GL_LIGHTING);
910 glDisable(GL_TEXTURE_1D);
912 glColor3f(0.8f, 0.5f, 0.5f);
914 for(
int i = 0; i < num_vert; i++)
916 double x = (vert[i][0] - xctr) * xzscale;
917 double y = (vert[i][2] - yctr) * yscale;
918 double z = (vert[i][1] - zctr) * xzscale;
920 glVertex3d(x + 0.1*normals[i][0]*normal_xzscale, y + 0.1*normals[i][2]*normal_yscale, z + 0.1*normals[i][1]*normal_xzscale);
928 void ScalarView::draw_gl_edge(
int inx_vert_a,
int inx_vert_b,
ScalarView* viewer,
void* param)
930 double3* verts = viewer->
lin->get_vertices();
931 glVertex2d(verts[inx_vert_a][0], verts[inx_vert_a][1]);
932 glVertex2d(verts[inx_vert_b][0], verts[inx_vert_b][1]);
935 void ScalarView::draw_edges(DrawSingleEdgeCallback draw_single_edge,
void* param,
bool boundary_only)
937 int2* edges = lin->get_edges();
938 int* edge_markers = lin->get_edge_markers();
939 int edge_cnt = lin->get_num_edges();
940 for (
int i = 0; i < edge_cnt; i++)
942 const int2 &edge = edges[i];
943 const int &edge_marker = edge_markers[i];
944 if(!boundary_only || edge_marker != 0)
945 draw_single_edge(edge[0], edge[1],
this, param);
949 #define V0 vertices_min_x - xctr, range_min - yctr, -(vertices_min_y - zctr)
950 #define V1 vertices_max_x - xctr, range_min - yctr, -(vertices_min_y - zctr)
951 #define V2 vertices_max_x - xctr, range_min - yctr, -(vertices_max_y - zctr)
952 #define V3 vertices_min_x - xctr, range_min - yctr, -(vertices_max_y - zctr)
953 #define V4 vertices_min_x - xctr, range_max - yctr, -(vertices_min_y - zctr)
954 #define V5 vertices_max_x - xctr, range_max - yctr, -(vertices_min_y - zctr)
955 #define V6 vertices_max_x - xctr, range_max - yctr, -(vertices_max_y - zctr)
956 #define V7 vertices_min_x - xctr, range_max - yctr, -(vertices_max_y - zctr)
958 void ScalarView::draw_aabb()
972 glColor3fv(edges_color);
975 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
979 glScaled(xzscale, yscale, xzscale);
982 glEnableClientState(GL_VERTEX_ARRAY);
983 glVertexPointer(3, GL_DOUBLE, 0, aabb);
986 glDrawArrays(GL_QUADS, 0, 24);
989 glDisableClientState(GL_VERTEX_ARRAY);
995 void ScalarView::on_display()
1001 int3* tris = lin->get_triangles();
1002 double3* vert = lin->get_vertices();
1003 int2* edges = lin->get_edges();
1005 glPolygonMode(GL_FRONT_AND_BACK, pmode ? GL_LINE : GL_FILL);
1008 prepare_gl_geometry();
1012 set_ortho_projection();
1013 glDisable(GL_LIGHTING);
1014 glDisable(GL_DEPTH_TEST);
1015 glDisable(GL_TEXTURE_2D);
1016 glDisable(GL_BLEND);
1019 glMatrixMode(GL_MODELVIEW);
1022 glTranslated(center_x, center_y, 0.0);
1023 glScaled(1.0, -1.0, 1.0);
1024 glTranslated(trans_x, trans_y, 0.0);
1025 glScaled(scale, scale, 1.0);
1032 glDisable(GL_TEXTURE_1D);
1035 tris = lin->get_contour_triangles();
1036 glColor3fv(cont_color);
1038 for (i = 0; i < lin->get_num_contour_triangles(); i++)
1040 if(finite(vert[tris[i][0]][2]) && finite(vert[tris[i][1]][2]) && finite(vert[tris[i][2]][2]))
1042 draw_tri_contours(vert, &tris[i]);
1045 tris = lin->get_triangles();
1053 if(show_element_info)
1054 draw_element_infos_2d();
1057 if(show_edges && allow_node_selection)
1058 draw_vertex_nodes();
1065 set_3d_projection(fovy, znear, zfar);
1067 glClear(GL_DEPTH_BUFFER_BIT);
1068 glEnable(GL_DEPTH_TEST);
1071 glMatrixMode(GL_MODELVIEW);
1081 ztrans = calculate_ztrans_to_fit_view();
1082 do_zoom_to_fit =
false;
1086 glTranslated(xtrans, ytrans, ztrans);
1087 glRotated(xrot, 1, 0, 0);
1088 glRotated(yrot, 0, 1, 0);
1091 glEnable(GL_LIGHTING);
1092 glEnable(GL_TEXTURE_1D);
1093 glBindTexture(GL_TEXTURE_1D, gl_pallete_tex_id);
1094 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1095 glEnable(GL_NORMALIZE);
1096 glEnable(GL_POLYGON_OFFSET_FILL);
1097 glPolygonOffset(1.0, 1.0);
1098 glBegin(GL_TRIANGLES);
1099 double normal_xzscale = 1.0 / xzscale, normal_yscale = 1.0 / yscale;
1100 for (i = 0; i < lin->get_num_triangles(); i++)
1102 for (j = 0; j < 3; j++)
1104 glNormal3d(normals[tris[i][j]][0] * normal_xzscale, normals[tris[i][j]][2] * normal_yscale, -normals[tris[i][j]][1] * normal_xzscale);
1105 glTexCoord2d((vert[tris[i][j]][2] - range_min) * value_irange * tex_scale + tex_shift, 0.0);
1106 glVertex3d((vert[tris[i][j]][0] - xctr) * xzscale,
1107 (vert[tris[i][j]][2] - yctr) * yscale,
1108 -(vert[tris[i][j]][1] - zctr) * xzscale);
1112 glDisable(GL_POLYGON_OFFSET_FILL);
1115 glDisable(GL_LIGHTING);
1116 glDisable(GL_TEXTURE_1D);
1119 glColor3fv(edges_color);
1121 for (i = 0; i < lin->get_num_edges(); i++)
1123 glVertex3d((vert[edges[i][0]][0] - xctr) * xzscale,
1124 (vert[edges[i][0]][2] - yctr) * yscale,
1125 -(vert[edges[i][0]][1] - zctr) * xzscale);
1126 glVertex3d((vert[edges[i][1]][0] - xctr) * xzscale,
1127 (vert[edges[i][1]][2] - yctr) * yscale,
1128 -(vert[edges[i][1]][1] - zctr) * xzscale);
1138 glColor3fv(edges_color);
1140 for (i = 0; i < lin->get_num_edges(); i++)
1143 double y_coord = (range_min - yctr) * yscale;
1144 int2& edge = edges[i];
1145 int& edge_marker = lin->get_edge_markers()[i];
1148 glVertex3d((vert[edge[0]][0] - xctr) * xzscale, y_coord,
1149 -(vert[edge[0]][1] - zctr) * xzscale);
1150 glVertex3d((vert[edge[1]][0] - xctr) * xzscale, y_coord,
1151 -(vert[edge[1]][1] - zctr) * xzscale);
1161 static inline void normalize(
double& x,
double& y,
double& z)
1163 double l = 1.0 / sqrt(sqr(x) + sqr(y) + sqr(z));
1164 x *= l; y *= l; z *= l;
1167 void ScalarView::calculate_normals(double3* vert,
int num_verts, int3* tris,
int num_tris)
1171 normals =
new double3[num_verts];
1172 memset(normals, 0,
sizeof(double3) * num_verts);
1173 for (
int i = 0; i < num_tris; i++)
1175 int3 &tri = tris[i];
1176 double ax = (vert[tri[1]][0] - vert[tri[0]][0]);
1177 double ay = (vert[tri[1]][1] - vert[tri[0]][1]);
1178 double az = (vert[tri[1]][2] - vert[tri[0]][2]);
1180 double bx = (vert[tri[2]][0] - vert[tri[0]][0]);
1181 double by = (vert[tri[2]][1] - vert[tri[0]][1]);
1182 double bz = (vert[tri[2]][2] - vert[tri[0]][2]);
1184 double nx = ay * bz - az * by;
1185 double ny = az * bx - ax * bz;
1186 double nz = ax * by - ay * bx;
1187 normalize(nx, ny, nz);
1189 for (
int j = 0; j < 3; j++)
1191 normals[tri[j]][0] += nx;
1192 normals[tri[j]][1] += ny;
1193 normals[tri[j]][2] += nz;
1197 for (
int i = 0; i < num_verts; i++)
1198 normalize(normals[i][0], normals[i][1], normals[i][2]);
1201 void ScalarView::update_layout()
1203 View::update_layout();
1207 xctr = (vertices_max_x + vertices_min_x) / 2.0;
1208 yctr = value_range_avg;
1209 zctr = (vertices_max_y + vertices_min_y) / 2.0;
1212 void ScalarView::reset_view(
bool force_reset)
1214 if(force_reset || view_not_reset) {
1215 xrot = 40.0; yrot = 0.0;
1216 xtrans = ytrans = ztrans = 0.0;
1222 double max_radial = std::max(vertices_max_x - vertices_min_x, vertices_max_y - vertices_min_y);
1223 xzscale = 2.0 / max_radial;
1226 double max_axial = std::max(range_max - yctr, fabs(range_min - yctr));
1237 double tan_fovy_half = tan((
double) fovy / 2.0 / 180.0 * M_PI);
1238 double max_allowed_height = (zfar-3)*tan_fovy_half;
1239 if(max_axial * xzscale > max_allowed_height || (max_axial * xzscale < 0.1 && !is_constant) )
1240 yscale = (znear + zfar) / 3.0 * tan_fovy_half * value_irange;
1244 do_zoom_to_fit =
true;
1246 View::reset_view(force_reset);
1249 double ScalarView::calculate_ztrans_to_fit_view()
1252 GLdouble aabb[2][16] =
1267 GLdouble aabb_base[16];
1270 double tan_fovy_half = tan((
double) fovy / 2.0 / 180.0 * M_PI);
1271 double tan_fovx_half = tan_fovy_half * (double) output_width / output_height;
1274 double optimal_viewpoint_pos = 0.0;
1281 glTranslated(xtrans, ytrans, ztrans);
1282 glRotated(xrot, 1, 0, 0);
1283 glRotated(yrot, 0, 1, 0);
1284 glScaled(xzscale, yscale, xzscale);
1289 for (
int i = 0; i < 2; i++)
1292 glMultMatrixd(aabb[i]);
1293 glGetDoublev( GL_MODELVIEW_MATRIX, aabb_base );
1297 GLdouble *coord_ptr = &aabb_base[0];
1298 for (
int j = 0; j < 4; j++)
1300 double perspective_center_to_origin_dist = fabs(coord_ptr[0]) / tan_fovx_half + coord_ptr[2];
1301 if(perspective_center_to_origin_dist > optimal_viewpoint_pos)
1302 optimal_viewpoint_pos = perspective_center_to_origin_dist;
1304 perspective_center_to_origin_dist = fabs(coord_ptr[1]) / tan_fovy_half + coord_ptr[2];
1305 if(perspective_center_to_origin_dist > optimal_viewpoint_pos)
1306 optimal_viewpoint_pos = perspective_center_to_origin_dist;
1315 return -optimal_viewpoint_pos;
1318 void ScalarView::set_vertical_scaling(
double sc)
1327 void ScalarView::set_min_max_range(
double min,
double max)
1330 if(fabs(max-min) < 1e-8)
1332 this->warn(
"Range (%f, %f) is too narrow: adjusted to (%f, %f)", min, max, min-0.5, max);
1335 View::set_min_max_range(min, max);
1338 void ScalarView::init_lighting()
1340 float light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
1341 float light_ambient[] = { 0.1f, 0.1f, 0.1f, 1.0f };
1342 float light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
1344 glEnable(GL_LIGHT0);
1345 glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
1346 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
1347 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
1350 float material_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
1351 float material_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
1352 float material_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
1354 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material_ambient);
1355 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material_diffuse);
1356 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_specular);
1357 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 128);
1358 glDisable(GL_COLOR_MATERIAL);
1360 glShadeModel(GL_SMOOTH);
1361 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
1362 if(GLEW_EXT_separate_specular_color)
1364 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT);
1368 void ScalarView::set_3d_mode(
bool enable)
1370 mode3d = enable; dragging = scaling =
false;
1375 calculate_normals(lin->get_vertices(), lin->get_num_vertices(), lin->get_triangles(), lin->get_num_triangles());
1381 void ScalarView::on_key_down(
unsigned char key,
int x,
int y)
1386 show_edges = !show_edges;
1403 set_palette_filter(pal_filter != GL_LINEAR);
1407 contours = !contours;
1412 show_element_info = !show_element_info;
1418 show_aabb = !show_aabb;
1426 dragging = scaling =
false;
1431 calculate_normals(lin->get_vertices(), lin->get_num_vertices(), lin->get_triangles(), lin->get_num_triangles());
1441 yscale *= D3DV_SCALE_STEP_COEF;
1443 cont_step *= D3DV_SCALE_STEP_COEF;
1451 yscale /= D3DV_SCALE_STEP_COEF;
1453 cont_step /= D3DV_SCALE_STEP_COEF;
1459 View::on_key_down(key, x, y);
1465 void ScalarView::on_mouse_move(
int x,
int y)
1467 if(mode3d && (dragging || scaling || panning))
1471 yrot += 0.4 * (x - mouse_x);
1472 xrot += 0.4 * (y - mouse_y);
1474 if(xrot < -90) xrot = -90;
1475 else if(xrot > 90) xrot = 90;
1479 ztrans += 0.01 * (mouse_y - y);
1480 if(ztrans > -0.25) ztrans = -0.25;
1481 else if(ztrans < -7) ztrans = -7;
1485 xtrans += 0.002 * (x - mouse_x);
1486 ytrans += 0.002 * (mouse_y - y);
1496 if(!mode3d && show_edges && !dragging && !scaling && !panning)
1498 if(allow_node_selection)
1500 VertexNodeInfo* found_node = find_nearest_node_in_range((
float)untransform_x(x), (
float)untransform_y(y), (
float)(node_pixel_radius / scale));
1501 if(found_node != pointed_vertex_node)
1502 pointed_vertex_node = found_node;
1505 pointed_vertex_node = NULL;
1510 View::on_mouse_move(x, y);
1515 void ScalarView::on_right_mouse_down(
int x,
int y)
1518 if(allow_node_selection && pointed_vertex_node != NULL)
1520 if(pointed_vertex_node->selected)
1522 pointed_vertex_node->selected =
false;
1525 pointed_vertex_node->selected =
true;
1530 View::on_right_mouse_down(x, y);
1534 void ScalarView::on_middle_mouse_down(
int x,
int y)
1537 dragging = scaling =
false;
1541 void ScalarView::on_middle_mouse_up(
int x,
int y)
1547 const char* ScalarView::get_help_text()
const
1552 " Left mouse - pan\n"
1553 " Right mouse - zoom\n"
1554 " 3 - toggle 3D mode\n"
1555 " C - center image\n"
1556 " F - toggle smooth palette\n"
1557 " H - render high-quality frame\n"
1558 " K - toggle contours\n"
1559 " M - toggle mesh\n"
1560 " B - toggle bounding box\n"
1561 " I - toggle element IDs (2d only)\n"
1562 " P - cycle palettes\n"
1563 " S - save screenshot\n"
1564 " * - increase contour density\n"
1565 " / - decrease contour density\n"
1567 " Esc, Q - quit\n\n"
1569 " Left mouse - rotate\n"
1570 " Right mouse - zoom\n"
1571 " Middle mouse - pan\n"
1572 " * - increase Z scale\n"
1573 " / - decrease Z scale";