Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Matena <lukasmatena@seznam.cz>2018-10-26 16:45:52 +0300
committerLukas Matena <lukasmatena@seznam.cz>2018-10-26 16:45:52 +0300
commit7681d00ee50c58a06b0ab61f776a08a693a6e510 (patch)
treef9bb0a57375af93113e52e31d05bc4f86f1a3907 /src/igl/opengl/ViewerCore.cpp
parentc1e6eda554813763378f959435df766a600b896c (diff)
parentf65118210124d460d9cb6478a84976bb98160595 (diff)
Merged branch 'dev_native' into lm_sla_supports_auto
Added igl library files
Diffstat (limited to 'src/igl/opengl/ViewerCore.cpp')
-rw-r--r--src/igl/opengl/ViewerCore.cpp391
1 files changed, 391 insertions, 0 deletions
diff --git a/src/igl/opengl/ViewerCore.cpp b/src/igl/opengl/ViewerCore.cpp
new file mode 100644
index 000000000..fc5f4664b
--- /dev/null
+++ b/src/igl/opengl/ViewerCore.cpp
@@ -0,0 +1,391 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+//
+// Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@gmail.com>
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
+// obtain one at http://mozilla.org/MPL/2.0/.
+
+#include "ViewerCore.h"
+#include "gl.h"
+#include "../quat_to_mat.h"
+#include "../snap_to_fixed_up.h"
+#include "../look_at.h"
+#include "../frustum.h"
+#include "../ortho.h"
+#include "../massmatrix.h"
+#include "../barycenter.h"
+#include "../PI.h"
+#include <Eigen/Geometry>
+#include <iostream>
+
+IGL_INLINE void igl::opengl::ViewerCore::align_camera_center(
+ const Eigen::MatrixXd& V,
+ const Eigen::MatrixXi& F)
+{
+ if(V.rows() == 0)
+ return;
+
+ get_scale_and_shift_to_fit_mesh(V,F,camera_base_zoom,camera_base_translation);
+ // Rather than crash on empty mesh...
+ if(V.size() > 0)
+ {
+ object_scale = (V.colwise().maxCoeff() - V.colwise().minCoeff()).norm();
+ }
+}
+
+IGL_INLINE void igl::opengl::ViewerCore::get_scale_and_shift_to_fit_mesh(
+ const Eigen::MatrixXd& V,
+ const Eigen::MatrixXi& F,
+ float& zoom,
+ Eigen::Vector3f& shift)
+{
+ if (V.rows() == 0)
+ return;
+
+ Eigen::MatrixXd BC;
+ if (F.rows() <= 1)
+ {
+ BC = V;
+ } else
+ {
+ igl::barycenter(V,F,BC);
+ }
+ return get_scale_and_shift_to_fit_mesh(BC,zoom,shift);
+}
+
+IGL_INLINE void igl::opengl::ViewerCore::align_camera_center(
+ const Eigen::MatrixXd& V)
+{
+ if(V.rows() == 0)
+ return;
+
+ get_scale_and_shift_to_fit_mesh(V,camera_base_zoom,camera_base_translation);
+ // Rather than crash on empty mesh...
+ if(V.size() > 0)
+ {
+ object_scale = (V.colwise().maxCoeff() - V.colwise().minCoeff()).norm();
+ }
+}
+
+IGL_INLINE void igl::opengl::ViewerCore::get_scale_and_shift_to_fit_mesh(
+ const Eigen::MatrixXd& V,
+ float& zoom,
+ Eigen::Vector3f& shift)
+{
+ if (V.rows() == 0)
+ return;
+
+ auto min_point = V.colwise().minCoeff();
+ auto max_point = V.colwise().maxCoeff();
+ auto centroid = (0.5*(min_point + max_point)).eval();
+ shift.setConstant(0);
+ shift.head(centroid.size()) = -centroid.cast<float>();
+ zoom = 2.0 / (max_point-min_point).array().abs().maxCoeff();
+}
+
+
+IGL_INLINE void igl::opengl::ViewerCore::clear_framebuffers()
+{
+ glClearColor(background_color[0],
+ background_color[1],
+ background_color[2],
+ background_color[3]);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+IGL_INLINE void igl::opengl::ViewerCore::draw(
+ ViewerData& data,
+ bool update_matrices)
+{
+ using namespace std;
+ using namespace Eigen;
+
+ if (depth_test)
+ glEnable(GL_DEPTH_TEST);
+ else
+ glDisable(GL_DEPTH_TEST);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ /* Bind and potentially refresh mesh/line/point data */
+ if (data.dirty)
+ {
+ data.updateGL(data, data.invert_normals,data.meshgl);
+ data.dirty = MeshGL::DIRTY_NONE;
+ }
+ data.meshgl.bind_mesh();
+
+ // Initialize uniform
+ glViewport(viewport(0), viewport(1), viewport(2), viewport(3));
+
+ if(update_matrices)
+ {
+ view = Eigen::Matrix4f::Identity();
+ proj = Eigen::Matrix4f::Identity();
+ norm = Eigen::Matrix4f::Identity();
+
+ float width = viewport(2);
+ float height = viewport(3);
+
+ // Set view
+ look_at( camera_eye, camera_center, camera_up, view);
+ view = view
+ * (trackball_angle * Eigen::Scaling(camera_zoom * camera_base_zoom)
+ * Eigen::Translation3f(camera_translation + camera_base_translation)).matrix();
+
+ norm = view.inverse().transpose();
+
+ // Set projection
+ if (orthographic)
+ {
+ float length = (camera_eye - camera_center).norm();
+ float h = tan(camera_view_angle/360.0 * igl::PI) * (length);
+ ortho(-h*width/height, h*width/height, -h, h, camera_dnear, camera_dfar,proj);
+ }
+ else
+ {
+ float fH = tan(camera_view_angle / 360.0 * igl::PI) * camera_dnear;
+ float fW = fH * (double)width/(double)height;
+ frustum(-fW, fW, -fH, fH, camera_dnear, camera_dfar,proj);
+ }
+ }
+
+ // Send transformations to the GPU
+ GLint viewi = glGetUniformLocation(data.meshgl.shader_mesh,"view");
+ GLint proji = glGetUniformLocation(data.meshgl.shader_mesh,"proj");
+ GLint normi = glGetUniformLocation(data.meshgl.shader_mesh,"normal_matrix");
+ glUniformMatrix4fv(viewi, 1, GL_FALSE, view.data());
+ glUniformMatrix4fv(proji, 1, GL_FALSE, proj.data());
+ glUniformMatrix4fv(normi, 1, GL_FALSE, norm.data());
+
+ // Light parameters
+ GLint specular_exponenti = glGetUniformLocation(data.meshgl.shader_mesh,"specular_exponent");
+ GLint light_position_eyei = glGetUniformLocation(data.meshgl.shader_mesh,"light_position_eye");
+ GLint lighting_factori = glGetUniformLocation(data.meshgl.shader_mesh,"lighting_factor");
+ GLint fixed_colori = glGetUniformLocation(data.meshgl.shader_mesh,"fixed_color");
+ GLint texture_factori = glGetUniformLocation(data.meshgl.shader_mesh,"texture_factor");
+
+ glUniform1f(specular_exponenti, data.shininess);
+ glUniform3fv(light_position_eyei, 1, light_position.data());
+ glUniform1f(lighting_factori, lighting_factor); // enables lighting
+ glUniform4f(fixed_colori, 0.0, 0.0, 0.0, 0.0);
+
+ if (data.V.rows()>0)
+ {
+ // Render fill
+ if (data.show_faces)
+ {
+ // Texture
+ glUniform1f(texture_factori, data.show_texture ? 1.0f : 0.0f);
+ data.meshgl.draw_mesh(true);
+ glUniform1f(texture_factori, 0.0f);
+ }
+
+ // Render wireframe
+ if (data.show_lines)
+ {
+ glLineWidth(data.line_width);
+ glUniform4f(fixed_colori,
+ data.line_color[0],
+ data.line_color[1],
+ data.line_color[2], 1.0f);
+ data.meshgl.draw_mesh(false);
+ glUniform4f(fixed_colori, 0.0f, 0.0f, 0.0f, 0.0f);
+ }
+ }
+
+ if (data.show_overlay)
+ {
+ if (data.show_overlay_depth)
+ glEnable(GL_DEPTH_TEST);
+ else
+ glDisable(GL_DEPTH_TEST);
+
+ if (data.lines.rows() > 0)
+ {
+ data.meshgl.bind_overlay_lines();
+ viewi = glGetUniformLocation(data.meshgl.shader_overlay_lines,"view");
+ proji = glGetUniformLocation(data.meshgl.shader_overlay_lines,"proj");
+
+ glUniformMatrix4fv(viewi, 1, GL_FALSE, view.data());
+ glUniformMatrix4fv(proji, 1, GL_FALSE, proj.data());
+ // This must be enabled, otherwise glLineWidth has no effect
+ glEnable(GL_LINE_SMOOTH);
+ glLineWidth(data.line_width);
+
+ data.meshgl.draw_overlay_lines();
+ }
+
+ if (data.points.rows() > 0)
+ {
+ data.meshgl.bind_overlay_points();
+ viewi = glGetUniformLocation(data.meshgl.shader_overlay_points,"view");
+ proji = glGetUniformLocation(data.meshgl.shader_overlay_points,"proj");
+
+ glUniformMatrix4fv(viewi, 1, GL_FALSE, view.data());
+ glUniformMatrix4fv(proji, 1, GL_FALSE, proj.data());
+ glPointSize(data.point_size);
+
+ data.meshgl.draw_overlay_points();
+ }
+
+ glEnable(GL_DEPTH_TEST);
+ }
+
+}
+
+IGL_INLINE void igl::opengl::ViewerCore::draw_buffer(ViewerData& data,
+ bool update_matrices,
+ Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& R,
+ Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& G,
+ Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& B,
+ Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic>& A)
+{
+ assert(R.rows() == G.rows() && G.rows() == B.rows() && B.rows() == A.rows());
+ assert(R.cols() == G.cols() && G.cols() == B.cols() && B.cols() == A.cols());
+
+ unsigned width = R.rows();
+ unsigned height = R.cols();
+
+ // https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing
+ unsigned int framebuffer;
+ glGenFramebuffers(1, &framebuffer);
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+ // create a multisampled color attachment texture
+ unsigned int textureColorBufferMultiSampled;
+ glGenTextures(1, &textureColorBufferMultiSampled);
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled);
+ glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA, width, height, GL_TRUE);
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textureColorBufferMultiSampled, 0);
+ // create a (also multisampled) renderbuffer object for depth and stencil attachments
+ unsigned int rbo;
+ glGenRenderbuffers(1, &rbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbo);
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, width, height);
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
+ assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ // configure second post-processing framebuffer
+ unsigned int intermediateFBO;
+ glGenFramebuffers(1, &intermediateFBO);
+ glBindFramebuffer(GL_FRAMEBUFFER, intermediateFBO);
+ // create a color attachment texture
+ unsigned int screenTexture;
+ glGenTextures(1, &screenTexture);
+ glBindTexture(GL_TEXTURE_2D, screenTexture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, screenTexture, 0); // we only need a color buffer
+ assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+
+ // Clear the buffer
+ glClearColor(background_color(0), background_color(1), background_color(2), 0.f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ // Save old viewport
+ Eigen::Vector4f viewport_ori = viewport;
+ viewport << 0,0,width,height;
+ // Draw
+ draw(data,update_matrices);
+ // Restore viewport
+ viewport = viewport_ori;
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediateFBO);
+ glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, intermediateFBO);
+ // Copy back in the given Eigen matrices
+ GLubyte* pixels = (GLubyte*)calloc(width*height*4,sizeof(GLubyte));
+ glReadPixels(0, 0,width, height,GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ // Clean up
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glDeleteTextures(1, &screenTexture);
+ glDeleteTextures(1, &textureColorBufferMultiSampled);
+ glDeleteFramebuffers(1, &framebuffer);
+ glDeleteFramebuffers(1, &intermediateFBO);
+ glDeleteRenderbuffers(1, &rbo);
+
+ int count = 0;
+ for (unsigned j=0; j<height; ++j)
+ {
+ for (unsigned i=0; i<width; ++i)
+ {
+ R(i,j) = pixels[count*4+0];
+ G(i,j) = pixels[count*4+1];
+ B(i,j) = pixels[count*4+2];
+ A(i,j) = pixels[count*4+3];
+ ++count;
+ }
+ }
+ // Clean up
+ free(pixels);
+}
+
+IGL_INLINE void igl::opengl::ViewerCore::set_rotation_type(
+ const igl::opengl::ViewerCore::RotationType & value)
+{
+ using namespace Eigen;
+ using namespace std;
+ const RotationType old_rotation_type = rotation_type;
+ rotation_type = value;
+ if(rotation_type == ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP &&
+ old_rotation_type != ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP)
+ {
+ snap_to_fixed_up(Quaternionf(trackball_angle),trackball_angle);
+ }
+}
+
+
+IGL_INLINE igl::opengl::ViewerCore::ViewerCore()
+{
+ // Default colors
+ background_color << 0.3f, 0.3f, 0.5f, 1.0f;
+
+ // Default lights settings
+ light_position << 0.0f, 0.3f, 0.0f;
+ lighting_factor = 1.0f; //on
+
+ // Default trackball
+ trackball_angle = Eigen::Quaternionf::Identity();
+ set_rotation_type(ViewerCore::ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP);
+
+ // Camera parameters
+ camera_base_zoom = 1.0f;
+ camera_zoom = 1.0f;
+ orthographic = false;
+ camera_view_angle = 45.0;
+ camera_dnear = 1.0;
+ camera_dfar = 100.0;
+ camera_base_translation << 0, 0, 0;
+ camera_translation << 0, 0, 0;
+ camera_eye << 0, 0, 5;
+ camera_center << 0, 0, 0;
+ camera_up << 0, 1, 0;
+
+ depth_test = true;
+
+ is_animating = false;
+ animation_max_fps = 30.;
+
+ viewport.setZero();
+}
+
+IGL_INLINE void igl::opengl::ViewerCore::init()
+{
+}
+
+IGL_INLINE void igl::opengl::ViewerCore::shut()
+{
+}