mirror of https://github.com/CGAL/cgal
1331 lines
38 KiB
C++
1331 lines
38 KiB
C++
#include "Scene.h"
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
|
|
#include <QtCore/qglobal.h>
|
|
#include <QString>
|
|
#include <QTextStream>
|
|
#include <QFileInfo>
|
|
#include <QInputDialog>
|
|
|
|
#include "Refiner.h"
|
|
//#include "render_edges.h"
|
|
|
|
#include <CGAL/Timer.h>
|
|
#include <CGAL/IO/Polyhedron_iostream.h>
|
|
#include <CGAL/subdivision_method_3.h>
|
|
|
|
#include <QOpenGLShader>
|
|
#include <QDebug>
|
|
#include "Viewer.h"
|
|
|
|
|
|
// constants
|
|
const int slow_distance_grid_size = 100;
|
|
const int fast_distance_grid_size = 20;
|
|
#define _SIGNED 0
|
|
#define _UNSIGNED 1
|
|
|
|
Scene::Scene()
|
|
: m_frame (new ManipulatedFrame())
|
|
, m_view_plane(false)
|
|
, m_grid_size(slow_distance_grid_size)
|
|
, m_cut_plane(NONE)
|
|
{
|
|
m_pPolyhedron = nullptr;
|
|
|
|
// view options
|
|
m_view_points = true;
|
|
m_view_segments = true;
|
|
m_view_polyhedron = true;
|
|
|
|
// distance function
|
|
m_red_ramp.build_red();
|
|
m_blue_ramp.build_blue();
|
|
m_max_distance_function = static_cast<FT>(0.0);
|
|
texture = new Texture(m_grid_size,m_grid_size);
|
|
ready_to_cut = true;
|
|
are_buffers_initialized = false;
|
|
gl_init = false;
|
|
|
|
}
|
|
|
|
Scene::~Scene()
|
|
{
|
|
delete m_pPolyhedron;
|
|
delete m_frame;
|
|
|
|
buffers[0].destroy();
|
|
buffers[1].destroy();
|
|
buffers[2].destroy();
|
|
buffers[3].destroy();
|
|
buffers[4].destroy();
|
|
buffers[5].destroy();
|
|
buffers[6].destroy();
|
|
buffers[7].destroy();
|
|
vao[0].destroy();
|
|
vao[1].destroy();
|
|
vao[2].destroy();
|
|
vao[3].destroy();
|
|
vao[4].destroy();
|
|
vao[5].destroy();
|
|
vao[6].destroy();
|
|
|
|
|
|
}
|
|
|
|
void Scene::compile_shaders()
|
|
{
|
|
if(! buffers[0].create() || !buffers[1].create() || !buffers[2].create() || !buffers[3].create() || !buffers[4].create() || !buffers[5].create() || !buffers[6].create() || !buffers[7].create())
|
|
{
|
|
std::cerr<<"VBO Creation FAILED"<<std::endl;
|
|
}
|
|
|
|
if(!vao[0].create() || !vao[1].create() || !vao[2].create() || !vao[3].create() || !vao[4].create() || !vao[5].create() || !vao[6].create())
|
|
{
|
|
std::cerr<<"VAO Creation FAILED"<<std::endl;
|
|
}
|
|
|
|
|
|
//Vertex source code
|
|
const char vertex_source[] =
|
|
{
|
|
"#version 150 \n"
|
|
"in highp vec4 vertex;\n"
|
|
"uniform highp mat4 mvp_matrix;\n"
|
|
"uniform highp mat4 f_matrix;\n"
|
|
"void main(void)\n"
|
|
"{\n"
|
|
" gl_Position = mvp_matrix * f_matrix * vertex;\n"
|
|
"}"
|
|
};
|
|
//Vertex source code
|
|
const char fragment_source[] =
|
|
{
|
|
"#version 150 \n"
|
|
"uniform highp vec4 color; \n"
|
|
"out highp vec4 out_color; \n"
|
|
"void main(void) { \n"
|
|
"out_color = color; \n"
|
|
"} \n"
|
|
"\n"
|
|
};
|
|
QOpenGLShader *vertex_shader = new QOpenGLShader(QOpenGLShader::Vertex);
|
|
if(!vertex_shader->compileSourceCode(vertex_source))
|
|
{
|
|
std::cerr<<"Compiling vertex source FAILED"<<std::endl;
|
|
}
|
|
|
|
QOpenGLShader *fragment_shader= new QOpenGLShader(QOpenGLShader::Fragment);
|
|
if(!fragment_shader->compileSourceCode(fragment_source))
|
|
{
|
|
std::cerr<<"Compiling fragmentsource FAILED"<<std::endl;
|
|
}
|
|
|
|
if(!rendering_program.addShader(vertex_shader))
|
|
{
|
|
std::cerr<<"adding vertex shader FAILED"<<std::endl;
|
|
}
|
|
if(!rendering_program.addShader(fragment_shader))
|
|
{
|
|
std::cerr<<"adding fragment shader FAILED"<<std::endl;
|
|
}
|
|
if(!rendering_program.link())
|
|
{
|
|
std::cerr<<"linking Program FAILED"<<std::endl;
|
|
}
|
|
rendering_program.bind();
|
|
|
|
//Vertex source code
|
|
const char tex_vertex_source[] =
|
|
{
|
|
"#version 150 \n"
|
|
"in highp vec4 vertex;\n"
|
|
"in highp vec2 tex_coord; \n"
|
|
"uniform highp mat4 mvp_matrix;\n"
|
|
"uniform highp mat4 f_matrix;\n"
|
|
"out highp vec2 texc;\n"
|
|
"void main(void)\n"
|
|
"{\n"
|
|
" gl_Position = mvp_matrix * f_matrix * vertex;\n"
|
|
" texc = tex_coord;\n"
|
|
"}"
|
|
};
|
|
//Vertex source code
|
|
const char tex_fragment_source[] =
|
|
{
|
|
"#version 150 \n"
|
|
"uniform sampler2D s_texture;\n"
|
|
"in highp vec2 texc;\n"
|
|
"out highp vec4 out_color; \n"
|
|
"void main(void) { \n"
|
|
"out_color = vec4(texture(s_texture, texc));\n"
|
|
"} \n"
|
|
"\n"
|
|
};
|
|
QOpenGLShader *tex_vertex_shader = new QOpenGLShader(QOpenGLShader::Vertex);
|
|
if(!tex_vertex_shader->compileSourceCode(tex_vertex_source))
|
|
{
|
|
std::cerr<<"Compiling vertex source FAILED"<<std::endl;
|
|
}
|
|
|
|
QOpenGLShader *tex_fragment_shader= new QOpenGLShader(QOpenGLShader::Fragment);
|
|
if(!tex_fragment_shader->compileSourceCode(tex_fragment_source))
|
|
{
|
|
std::cerr<<"Compiling fragmentsource FAILED"<<std::endl;
|
|
}
|
|
|
|
if(!tex_rendering_program.addShader(tex_vertex_shader))
|
|
{
|
|
std::cerr<<"adding vertex shader FAILED"<<std::endl;
|
|
}
|
|
if(!tex_rendering_program.addShader(tex_fragment_shader))
|
|
{
|
|
std::cerr<<"adding fragment shader FAILED"<<std::endl;
|
|
}
|
|
if(!tex_rendering_program.link())
|
|
{
|
|
std::cerr<<"linking Program FAILED"<<std::endl;
|
|
}
|
|
tex_rendering_program.bind();
|
|
|
|
}
|
|
|
|
void Scene::initialize_buffers()
|
|
{
|
|
//Points
|
|
vao[0].bind();
|
|
buffers[0].bind();
|
|
buffers[0].allocate(pos_points.data(),
|
|
static_cast<int>(pos_points.size()*sizeof(float)));
|
|
points_vertexLocation = rendering_program.attributeLocation("vertex");
|
|
rendering_program.bind();
|
|
rendering_program.enableAttributeArray(points_vertexLocation);
|
|
rendering_program.setAttributeBuffer(points_vertexLocation,GL_FLOAT,0,3);
|
|
buffers[0].release();
|
|
rendering_program.release();
|
|
vao[0].release();
|
|
|
|
//Lines
|
|
vao[1].bind();
|
|
buffers[1].bind();
|
|
buffers[1].allocate(pos_lines.data(),
|
|
static_cast<int>(pos_lines.size()*sizeof(float)));
|
|
lines_vertexLocation = rendering_program.attributeLocation("vertex");
|
|
rendering_program.bind();
|
|
rendering_program.setAttributeBuffer(lines_vertexLocation,GL_FLOAT,0,3);
|
|
buffers[1].release();
|
|
rendering_program.enableAttributeArray(lines_vertexLocation);
|
|
rendering_program.release();
|
|
vao[1].release();
|
|
|
|
//Polyhedron's edges
|
|
vao[2].bind();
|
|
buffers[2].bind();
|
|
buffers[2].allocate(pos_poly.data(),
|
|
static_cast<int>(pos_poly.size()*sizeof(float)));
|
|
poly_vertexLocation = rendering_program.attributeLocation("vertex");
|
|
rendering_program.bind();
|
|
rendering_program.setAttributeBuffer(poly_vertexLocation,GL_FLOAT,0,3);
|
|
rendering_program.enableAttributeArray(poly_vertexLocation);
|
|
buffers[2].release();
|
|
rendering_program.release();
|
|
vao[2].release();
|
|
|
|
//cutting segments
|
|
vao[3].bind();
|
|
buffers[3].bind();
|
|
buffers[3].allocate(pos_cut_segments.data(),
|
|
static_cast<int>(pos_cut_segments.size()*sizeof(float)));
|
|
poly_vertexLocation = rendering_program.attributeLocation("vertex");
|
|
rendering_program.bind();
|
|
rendering_program.setAttributeBuffer(poly_vertexLocation,GL_FLOAT,0,3);
|
|
rendering_program.enableAttributeArray(poly_vertexLocation);
|
|
buffers[3].release();
|
|
rendering_program.release();
|
|
vao[3].release();
|
|
|
|
//cutting plane
|
|
vao[4].bind();
|
|
buffers[4].bind();
|
|
buffers[4].allocate(pos_plane.data(), static_cast<int>(pos_plane.size()*sizeof(float)));
|
|
poly_vertexLocation = rendering_program.attributeLocation("vertex");
|
|
rendering_program.bind();
|
|
rendering_program.setAttributeBuffer(poly_vertexLocation,GL_FLOAT,0,3);
|
|
rendering_program.enableAttributeArray(poly_vertexLocation);
|
|
buffers[4].release();
|
|
rendering_program.release();
|
|
|
|
vao[4].release();
|
|
|
|
//grid
|
|
vao[5].bind();
|
|
buffers[5].bind();
|
|
buffers[5].allocate(pos_grid.data(), static_cast<int>(pos_grid.size()*sizeof(float)));
|
|
poly_vertexLocation = rendering_program.attributeLocation("vertex");
|
|
rendering_program.bind();
|
|
rendering_program.setAttributeBuffer(poly_vertexLocation,GL_FLOAT,0,3);
|
|
rendering_program.enableAttributeArray(poly_vertexLocation);
|
|
buffers[5].release();
|
|
rendering_program.release();
|
|
vao[5].release();
|
|
|
|
//cutting plane
|
|
vao[6].bind();
|
|
buffers[6].bind();
|
|
buffers[6].allocate(pos_plane.data(), static_cast<int>(pos_plane.size()*sizeof(float)));
|
|
poly_vertexLocation = tex_rendering_program.attributeLocation("vertex");
|
|
tex_rendering_program.bind();
|
|
tex_rendering_program.setAttributeBuffer(poly_vertexLocation,GL_FLOAT,0,3);
|
|
tex_rendering_program.enableAttributeArray(poly_vertexLocation);
|
|
buffers[6].release();
|
|
tex_rendering_program.release();
|
|
|
|
buffers[7].bind();
|
|
buffers[7].allocate(tex_map.data(), static_cast<int>(tex_map.size()*sizeof(float)));
|
|
tex_Location = tex_rendering_program.attributeLocation("tex_coord");
|
|
tex_rendering_program.bind();
|
|
tex_rendering_program.setAttributeBuffer(tex_Location,GL_FLOAT,0,2);
|
|
tex_rendering_program.enableAttributeArray(tex_Location);
|
|
buffers[7].release();
|
|
tex_rendering_program.release();
|
|
|
|
gl->glBindTexture(GL_TEXTURE_2D, textureId);
|
|
gl->glTexImage2D(GL_TEXTURE_2D,
|
|
0,
|
|
GL_RGB,
|
|
texture->getWidth(),
|
|
texture->getHeight(),
|
|
0,
|
|
GL_RGB,
|
|
GL_UNSIGNED_BYTE,
|
|
texture->getData());
|
|
gl->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
gl->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
gl->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE );
|
|
gl->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE );
|
|
vao[6].release();
|
|
|
|
are_buffers_initialized = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
void Scene::compute_elements(int mode)
|
|
{
|
|
pos_points.resize(0);
|
|
pos_lines.resize(0);
|
|
pos_poly.resize(0);
|
|
pos_cut_segments.resize(0);
|
|
tex_map.resize(0);
|
|
pos_grid.resize(66);
|
|
pos_plane.resize(18);
|
|
float diag = .6f * float(bbox_diag());
|
|
//The Points
|
|
{
|
|
std::list<Point>::iterator pit;
|
|
for(pit = m_points.begin(); pit != m_points.end(); pit++)
|
|
{
|
|
const Point& p = *pit;
|
|
pos_points.push_back(p.x());
|
|
pos_points.push_back(p.y());
|
|
pos_points.push_back(p.z());
|
|
}
|
|
}
|
|
//The segments
|
|
{
|
|
std::list<Segment>::iterator sit;
|
|
for(sit = m_segments.begin(); sit != m_segments.end(); sit++)
|
|
{
|
|
const Segment& s = *sit;
|
|
const Point& p = s.source();
|
|
const Point& q = s.target();
|
|
|
|
pos_lines.push_back(p.x());
|
|
pos_lines.push_back(p.y());
|
|
pos_lines.push_back(p.z());
|
|
|
|
pos_lines.push_back(q.x());
|
|
pos_lines.push_back(q.y());
|
|
pos_lines.push_back(q.z());
|
|
}
|
|
}
|
|
//The Polygon's edges
|
|
{
|
|
Polyhedron::Edge_iterator he;
|
|
for(he = m_pPolyhedron->edges_begin();
|
|
he != m_pPolyhedron->edges_end();
|
|
he++)
|
|
{
|
|
const Point& a = he->vertex()->point();
|
|
const Point& b = he->opposite()->vertex()->point();
|
|
pos_poly.push_back(a.x());
|
|
pos_poly.push_back(a.y());
|
|
pos_poly.push_back(a.z());
|
|
|
|
pos_poly.push_back(b.x());
|
|
pos_poly.push_back(b.y());
|
|
pos_poly.push_back(b.z());
|
|
}
|
|
}
|
|
//The cutting segments
|
|
{
|
|
for ( std::vector<Segment>::const_iterator csit = m_cut_segments.begin(),
|
|
end = m_cut_segments.end() ; csit != end ; ++csit )
|
|
{
|
|
const Point& a = csit->source();
|
|
const Point& b = csit->target();
|
|
|
|
pos_cut_segments.push_back(a.x());
|
|
pos_cut_segments.push_back(a.y());
|
|
pos_cut_segments.push_back(a.z());
|
|
|
|
pos_cut_segments.push_back(b.x());
|
|
pos_cut_segments.push_back(b.y());
|
|
pos_cut_segments.push_back(b.z());
|
|
}
|
|
}
|
|
//The cutting plane
|
|
{
|
|
|
|
pos_plane[0]= -diag; pos_plane[1]=-diag; pos_plane[2]=0.0;
|
|
pos_plane[3]= -diag; pos_plane[4]= diag; pos_plane[5]=0.;
|
|
pos_plane[6]= diag; pos_plane[7]= diag; pos_plane[8]=0.;
|
|
pos_plane[9]= -diag; pos_plane[10]= -diag; pos_plane[11]=0.;
|
|
pos_plane[12]= diag; pos_plane[13]= diag; pos_plane[14]= 0.;
|
|
pos_plane[15]= diag; pos_plane[16]= -diag; pos_plane[17]= 0.;
|
|
|
|
//UV Mapping
|
|
tex_map.push_back(-0.11f);
|
|
tex_map.push_back(-0.11f);
|
|
|
|
tex_map.push_back(-0.11f);
|
|
tex_map.push_back(1.11f);
|
|
|
|
tex_map.push_back(1.11f);
|
|
tex_map.push_back(1.11f);
|
|
|
|
tex_map.push_back(-0.11f);
|
|
tex_map.push_back(-0.11f);
|
|
|
|
tex_map.push_back(1.11f);
|
|
tex_map.push_back(1.11f);
|
|
|
|
tex_map.push_back(1.11f);
|
|
tex_map.push_back(-0.11f);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
//The grid
|
|
{
|
|
float z = 0;
|
|
float x = (2 * diag)/10.0;
|
|
float y = (2 * diag)/10.0;
|
|
for(int u = 0; u < 11; u++)
|
|
{
|
|
|
|
pos_grid.push_back(-diag + x* u);
|
|
pos_grid.push_back(-diag);
|
|
pos_grid.push_back(z);
|
|
|
|
pos_grid.push_back(-diag + x* u);
|
|
pos_grid.push_back(diag);
|
|
pos_grid.push_back(z);
|
|
}
|
|
for(int v=0; v<11; v++)
|
|
{
|
|
|
|
pos_grid.push_back(-diag);
|
|
pos_grid.push_back(-diag + v * y);
|
|
pos_grid.push_back(z);
|
|
|
|
pos_grid.push_back(diag);
|
|
pos_grid.push_back(-diag + v * y);
|
|
pos_grid.push_back(z);
|
|
|
|
}
|
|
|
|
}
|
|
//The texture
|
|
switch(mode)
|
|
{
|
|
case _SIGNED:
|
|
for( int i=0 ; i < texture->getWidth(); i++ )
|
|
{
|
|
for( int j=0 ; j < texture->getHeight() ; j++)
|
|
{
|
|
compute_texture(i,j,m_red_ramp,m_blue_ramp);
|
|
}
|
|
}
|
|
break;
|
|
case _UNSIGNED:
|
|
for( int i=0 ; i < texture->getWidth(); i++ )
|
|
{
|
|
for( int j=0 ; j < texture->getHeight() ; j++)
|
|
{
|
|
compute_texture(i,j,m_thermal_ramp,m_thermal_ramp);
|
|
}
|
|
}
|
|
break;}
|
|
sampler_location = tex_rendering_program.attributeLocation("texture");
|
|
}
|
|
|
|
void Scene::compute_texture(int i, int j,Color_ramp pos_ramp ,Color_ramp neg_ramp)
|
|
{
|
|
|
|
|
|
const FT& d00 = m_distance_function[i][j].second;
|
|
// determines grey level
|
|
unsigned int i00 = 255-static_cast<unsigned>(255.0 * std::fabs(d00) / m_max_distance_function);
|
|
|
|
if(d00 > 0.0)
|
|
texture->setData(i,j,pos_ramp.r(i00),pos_ramp.g(i00),pos_ramp.b(i00));
|
|
else
|
|
texture->setData(i,j,neg_ramp.r(i00),neg_ramp.g(i00),neg_ramp.b(i00));
|
|
|
|
|
|
}
|
|
|
|
void Scene::attrib_buffers(CGAL::QGLViewer* viewer)
|
|
{
|
|
QMatrix4x4 mvpMatrix;
|
|
double mat[16];
|
|
viewer->camera()->getModelViewProjectionMatrix(mat);
|
|
for(int i=0; i < 16; i++)
|
|
{
|
|
mvpMatrix.data()[i] = static_cast<float>(mat[i]);
|
|
}
|
|
rendering_program.bind();
|
|
mvpLocation = rendering_program.uniformLocation("mvp_matrix");
|
|
fLocation = rendering_program.uniformLocation("f_matrix");
|
|
colorLocation = rendering_program.uniformLocation("color");
|
|
rendering_program.setUniformValue(mvpLocation, mvpMatrix);
|
|
rendering_program.release();
|
|
|
|
tex_rendering_program.bind();
|
|
tex_mvpLocation = tex_rendering_program.uniformLocation("mvp_matrix");
|
|
tex_fLocation = tex_rendering_program.uniformLocation("f_matrix");
|
|
tex_rendering_program.setUniformValue(tex_mvpLocation, mvpMatrix);
|
|
tex_rendering_program.release();
|
|
}
|
|
|
|
void Scene::changed()
|
|
{
|
|
if(m_cut_plane == UNSIGNED_FACETS || m_cut_plane == UNSIGNED_EDGES)
|
|
compute_elements(_UNSIGNED);
|
|
else
|
|
compute_elements(_SIGNED);
|
|
ready_to_cut=false;
|
|
are_buffers_initialized = false;
|
|
|
|
}
|
|
|
|
int Scene::open(QString filename)
|
|
{
|
|
QTextStream cerr(stderr);
|
|
cerr << QString("Opening file \"%1\"\n").arg(filename);
|
|
QApplication::setOverrideCursor(QCursor(::Qt::WaitCursor));
|
|
|
|
QFileInfo fileinfo(filename);
|
|
std::ifstream in(filename.toUtf8());
|
|
|
|
if(!in || !fileinfo.isFile() || ! fileinfo.isReadable())
|
|
{
|
|
std::cerr << "unable to open file" << std::endl;
|
|
QApplication::restoreOverrideCursor();
|
|
return -1;
|
|
}
|
|
|
|
if(m_pPolyhedron != nullptr)
|
|
delete m_pPolyhedron;
|
|
|
|
// allocate new polyhedron
|
|
m_pPolyhedron = new Polyhedron;
|
|
in >> *m_pPolyhedron;
|
|
if(!in)
|
|
{
|
|
std::cerr << "invalid OFF file" << std::endl;
|
|
QApplication::restoreOverrideCursor();
|
|
|
|
delete m_pPolyhedron;
|
|
m_pPolyhedron = nullptr;
|
|
|
|
return -1;
|
|
}
|
|
|
|
// clear tree
|
|
clear_internal_data();
|
|
|
|
QApplication::restoreOverrideCursor();
|
|
changed();
|
|
return 0;
|
|
}
|
|
|
|
void Scene::update_bbox()
|
|
{
|
|
std::cout << "Compute bbox...";
|
|
m_bbox = Bbox();
|
|
|
|
if(m_pPolyhedron == nullptr)
|
|
{
|
|
std::cout << "failed (no polyhedron)." << std::endl;
|
|
return;
|
|
}
|
|
|
|
if(m_pPolyhedron->empty())
|
|
{
|
|
std::cout << "failed (empty polyhedron)." << std::endl;
|
|
return;
|
|
}
|
|
|
|
Polyhedron::Point_iterator it = m_pPolyhedron->points_begin();
|
|
m_bbox = (*it).bbox();
|
|
for(; it != m_pPolyhedron->points_end();it++)
|
|
m_bbox = m_bbox + (*it).bbox();
|
|
std::cout << "done (" << m_pPolyhedron->size_of_facets()
|
|
<< " facets)" << std::endl;
|
|
}
|
|
|
|
void Scene::draw(CGAL::QGLViewer* viewer)
|
|
{
|
|
if(!gl_init)
|
|
initGL();
|
|
if(!are_buffers_initialized)
|
|
initialize_buffers();
|
|
gl->glEnable(GL_DEPTH_TEST);
|
|
QColor color;
|
|
QMatrix4x4 fMatrix;
|
|
fMatrix.setToIdentity();
|
|
if(m_view_polyhedron && pos_poly.size()>0)
|
|
{
|
|
vao[2].bind();
|
|
attrib_buffers(viewer);
|
|
rendering_program.bind();
|
|
color.setRgbF(0.0,0.0,0.0);
|
|
rendering_program.setUniformValue(colorLocation, color);
|
|
rendering_program.setUniformValue(fLocation, fMatrix);
|
|
gl->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(pos_poly.size()/3));
|
|
rendering_program.release();
|
|
vao[2].release();
|
|
}
|
|
if(m_view_points && pos_points.size()>0)
|
|
{
|
|
vao[0].bind();
|
|
attrib_buffers(viewer);
|
|
rendering_program.bind();
|
|
color.setRgbF(0.7f,0.0f,0.0f);
|
|
rendering_program.setUniformValue(colorLocation, color);
|
|
rendering_program.setUniformValue(fLocation, fMatrix);
|
|
gl->glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(pos_points.size()/3));
|
|
rendering_program.release();
|
|
vao[0].release();
|
|
}
|
|
|
|
if(m_view_segments && pos_lines.size()>0)
|
|
{
|
|
vao[1].bind();
|
|
attrib_buffers(viewer);
|
|
rendering_program.bind();
|
|
color.setRgbF(0.0f,0.7f,0.0f);
|
|
rendering_program.setUniformValue(colorLocation, color);
|
|
rendering_program.setUniformValue(fLocation, fMatrix);
|
|
gl->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(pos_lines.size()/3));
|
|
rendering_program.release();
|
|
vao[1].release();
|
|
}
|
|
if (m_view_plane && pos_plane.size()>0)
|
|
{
|
|
switch( m_cut_plane )
|
|
{
|
|
case UNSIGNED_EDGES:
|
|
case UNSIGNED_FACETS:
|
|
case SIGNED_FACETS:
|
|
|
|
gl->glActiveTexture(GL_TEXTURE0);
|
|
gl->glBindTexture(GL_TEXTURE_2D, textureId);
|
|
|
|
for(int i=0; i< 16 ; i++)
|
|
fMatrix.data()[i] = m_frame->matrix()[i];
|
|
vao[6].bind();
|
|
attrib_buffers(viewer);
|
|
tex_rendering_program.bind();
|
|
tex_rendering_program.setUniformValue(tex_fLocation, fMatrix);
|
|
|
|
gl->glDrawArrays(GL_TRIANGLES, 0,static_cast<GLsizei>(pos_plane.size()/3));
|
|
tex_rendering_program.release();
|
|
vao[6].release();
|
|
break;
|
|
|
|
case CUT_SEGMENTS:
|
|
|
|
//cutting_segments
|
|
fMatrix.setToIdentity();
|
|
gl->glLineWidth(2.0f);
|
|
vao[3].bind();
|
|
attrib_buffers(viewer);
|
|
rendering_program.bind();
|
|
color.setRgbF(1.0f,0.0f,0.0f);
|
|
rendering_program.setUniformValue(colorLocation, color);
|
|
rendering_program.setUniformValue(fLocation, fMatrix);
|
|
gl->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(pos_cut_segments.size()/3));
|
|
gl->glLineWidth(1.0f);
|
|
rendering_program.release();
|
|
vao[3].release();
|
|
//grid
|
|
for(int i=0; i< 16 ; i++)
|
|
fMatrix.data()[i] = m_frame->matrix()[i];
|
|
vao[5].bind();
|
|
attrib_buffers(viewer);
|
|
rendering_program.bind();
|
|
color.setRgbF(.6f, .6f, .6f);
|
|
rendering_program.setUniformValue(colorLocation, color);
|
|
rendering_program.setUniformValue(fLocation, fMatrix);
|
|
gl->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(pos_grid.size()/3));
|
|
rendering_program.release();
|
|
vao[5].release();
|
|
|
|
//cutting_plane
|
|
// for(int i=0; i< 16 ; i++)
|
|
// fMatrix.data()[i] = m_frame->matrix()[i];
|
|
gl->glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
|
gl->glEnable(GL_BLEND);
|
|
vao[4].bind();
|
|
attrib_buffers(viewer);
|
|
rendering_program.bind();
|
|
color.setRgbF(.6f, .85f, 1.f, .65f);
|
|
rendering_program.setUniformValue(colorLocation, color);
|
|
rendering_program.setUniformValue(fLocation, fMatrix);
|
|
gl->glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(pos_plane.size()/3));
|
|
gl->glDisable(GL_BLEND);
|
|
rendering_program.release();
|
|
vao[4].release();
|
|
|
|
break;
|
|
case NONE: // do nothing
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
FT Scene::random_in(const double a,
|
|
const double b)
|
|
{
|
|
double r = rand() / static_cast<double>(RAND_MAX);
|
|
return static_cast<FT>(a + (b - a) * r);
|
|
}
|
|
|
|
Point Scene::random_point(const CGAL::Bbox_3& bbox)
|
|
{
|
|
FT x = random_in(bbox.xmin(),bbox.xmax());
|
|
FT y = random_in(bbox.ymin(),bbox.ymax());
|
|
FT z = random_in(bbox.zmin(),bbox.zmax());
|
|
return Point(x,y,z);
|
|
}
|
|
|
|
Vector Scene::random_vector()
|
|
{
|
|
FT x = random_in(0.0,1.0);
|
|
FT y = random_in(0.0,1.0);
|
|
FT z = random_in(0.0,1.0);
|
|
return Vector(x,y,z);
|
|
}
|
|
|
|
Ray Scene::random_ray(const CGAL::Bbox_3& bbox)
|
|
{
|
|
Point p = random_point(bbox);
|
|
Point q = random_point(bbox);
|
|
return Ray(p,q);
|
|
}
|
|
|
|
Segment Scene::random_segment(const CGAL::Bbox_3& bbox)
|
|
{
|
|
Point p = random_point(bbox);
|
|
Point q = random_point(bbox);
|
|
return Segment(p,q);
|
|
}
|
|
|
|
Line Scene::random_line(const CGAL::Bbox_3& bbox)
|
|
{
|
|
Point p = random_point(bbox);
|
|
Point q = random_point(bbox);
|
|
return Line(p,q);
|
|
}
|
|
|
|
Plane Scene::random_plane(const CGAL::Bbox_3& bbox)
|
|
{
|
|
Point p = random_point(bbox);
|
|
Vector vec = random_vector();
|
|
return Plane(p,vec);
|
|
}
|
|
|
|
Plane Scene::frame_plane() const
|
|
{
|
|
const CGAL::qglviewer::Vec& pos = m_frame->position();
|
|
const CGAL::qglviewer::Vec& n = m_frame->inverseTransformOf(CGAL::qglviewer::Vec(0.f, 0.f, 1.f));
|
|
|
|
return Plane(n[0], n[1], n[2], - n * pos);
|
|
}
|
|
|
|
Aff_transformation Scene::frame_transformation() const
|
|
{
|
|
const ::GLdouble* m = m_frame->matrix();
|
|
|
|
// OpenGL matrices are row-major matrices
|
|
return Aff_transformation (m[0], m[4], m[8], m[12],
|
|
m[1], m[5], m[9], m[13],
|
|
m[2], m[6], m[10], m[14]);
|
|
}
|
|
|
|
FT Scene::bbox_diag() const
|
|
{
|
|
double dx = m_bbox.xmax()-m_bbox.xmin();
|
|
double dy = m_bbox.ymax()-m_bbox.ymin();
|
|
double dz = m_bbox.zmax()-m_bbox.zmin();
|
|
|
|
return FT(std::sqrt(dx*dx + dy*dy + dz*dz));
|
|
}
|
|
|
|
void Scene::build_facet_tree()
|
|
{
|
|
if ( nullptr == m_pPolyhedron )
|
|
{
|
|
std::cerr << "Build facet tree failed: load polyhedron first." << std::endl;
|
|
return;
|
|
}
|
|
|
|
// Don't rebuild tree if it is already built
|
|
if ( !m_facet_tree.empty() ) { return; }
|
|
|
|
// build tree
|
|
CGAL::Timer timer;
|
|
timer.start();
|
|
std::cout << "Construct Facet AABB tree...";
|
|
m_facet_tree.rebuild(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second,*m_pPolyhedron);
|
|
std::cout << "done (" << timer.time() << " s)" << std::endl;
|
|
}
|
|
|
|
void Scene::build_edge_tree()
|
|
{
|
|
if ( nullptr == m_pPolyhedron )
|
|
{
|
|
std::cerr << "Build edge tree failed: load polyhedron first." << std::endl;
|
|
return;
|
|
}
|
|
|
|
// Don't rebuild tree if it is already built
|
|
if ( !m_edge_tree.empty() ) { return; }
|
|
|
|
// build tree
|
|
CGAL::Timer timer;
|
|
timer.start();
|
|
std::cout << "Construct Edge AABB tree...";
|
|
m_edge_tree.rebuild(edges(*m_pPolyhedron).first,edges(*m_pPolyhedron).second,*m_pPolyhedron);
|
|
std::cout << "done (" << timer.time() << " s)" << std::endl;
|
|
}
|
|
|
|
void Scene::clear_internal_data()
|
|
{
|
|
m_facet_tree.clear();
|
|
m_edge_tree.clear();
|
|
|
|
clear_points();
|
|
clear_segments();
|
|
clear_cutting_plane();
|
|
}
|
|
|
|
void Scene::clear_cutting_plane()
|
|
{
|
|
m_cut_segments.clear();
|
|
m_cut_plane = NONE;
|
|
|
|
deactivate_cutting_plane();
|
|
changed();
|
|
}
|
|
|
|
void Scene::update_grid_size()
|
|
{
|
|
m_grid_size = m_fast_distance ? fast_distance_grid_size
|
|
: slow_distance_grid_size;
|
|
texture = new Texture(m_grid_size,m_grid_size);
|
|
}
|
|
|
|
void Scene::generate_points_in(const unsigned int nb_points,
|
|
const double vmin,
|
|
const double vmax)
|
|
{
|
|
if(m_pPolyhedron == nullptr)
|
|
{
|
|
std::cout << "Load polyhedron first." << std::endl;
|
|
return;
|
|
}
|
|
|
|
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
|
|
typedef CGAL::AABB_traits_3<Kernel, Primitive> Traits;
|
|
typedef CGAL::AABB_tree<Traits> Tree;
|
|
|
|
std::cout << "Construct AABB tree...";
|
|
Tree tree(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second, *m_pPolyhedron);
|
|
std::cout << "done." << std::endl;
|
|
|
|
CGAL::Timer timer;
|
|
timer.start();
|
|
std::cout << "Generate " << nb_points << " points in interval ["
|
|
<< vmin << ";" << vmax << "]";
|
|
|
|
unsigned int nb_trials = 0;
|
|
Vector vec = random_vector();
|
|
while(m_points.size() < nb_points)
|
|
{
|
|
Point p = random_point(tree.bbox());
|
|
|
|
// measure distance
|
|
FT signed_distance = std::sqrt(tree.squared_distance(p));
|
|
|
|
// measure sign
|
|
Ray ray(p,vec);
|
|
int nb_intersections = static_cast<int>(tree.number_of_intersected_primitives(ray));
|
|
if(nb_intersections % 2 != 0)
|
|
signed_distance *= -1.0;
|
|
|
|
if(signed_distance >= vmin &&
|
|
signed_distance <= vmax)
|
|
{
|
|
m_points.push_back(p);
|
|
if(m_points.size()%(nb_points/10) == 0)
|
|
std::cout << "."; // ASCII progress bar
|
|
}
|
|
nb_trials++;
|
|
}
|
|
double speed = static_cast<double>(nb_trials) / timer.time();
|
|
std::cout << "done (" << nb_trials << " trials, "
|
|
<< timer.time() << " s, "
|
|
<< speed << " queries/s)" << std::endl;
|
|
changed();
|
|
}
|
|
|
|
|
|
void Scene::generate_inside_points(const unsigned int nb_points)
|
|
{
|
|
if(m_pPolyhedron == nullptr)
|
|
{
|
|
std::cout << "Load polyhedron first." << std::endl;
|
|
return;
|
|
}
|
|
|
|
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
|
|
typedef CGAL::AABB_traits_3<Kernel, Primitive> Traits;
|
|
typedef CGAL::AABB_tree<Traits> Tree;
|
|
|
|
std::cout << "Construct AABB tree...";
|
|
Tree tree(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second,*m_pPolyhedron);
|
|
std::cout << "done." << std::endl;
|
|
|
|
CGAL::Timer timer;
|
|
timer.start();
|
|
std::cout << "Generate " << nb_points << " inside points";
|
|
|
|
unsigned int nb_trials = 0;
|
|
Vector vec = random_vector();
|
|
while(m_points.size() < nb_points)
|
|
{
|
|
Point p = random_point(tree.bbox());
|
|
Ray ray(p,vec);
|
|
int nb_intersections = static_cast<int>(tree.number_of_intersected_primitives(ray));
|
|
if(nb_intersections % 2 != 0)
|
|
{
|
|
m_points.push_back(p);
|
|
if(m_points.size()%(nb_points/10) == 0)
|
|
std::cout << "."; // ASCII progress bar
|
|
}
|
|
nb_trials++;
|
|
}
|
|
double speed = static_cast<double>(nb_trials) / timer.time();
|
|
std::cout << "done (" << nb_trials << " trials, "
|
|
<< timer.time() << " s, "
|
|
<< speed << " queries/s)" << std::endl;
|
|
changed();
|
|
}
|
|
|
|
void Scene::generate_boundary_segments(const unsigned int nb_slices)
|
|
{
|
|
if(m_pPolyhedron == nullptr)
|
|
{
|
|
std::cout << "Load polyhedron first." << std::endl;
|
|
return;
|
|
}
|
|
|
|
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
|
|
typedef CGAL::AABB_traits_3<Kernel, Primitive> Traits;
|
|
typedef CGAL::AABB_tree<Traits> Tree;
|
|
typedef Tree::Object_and_primitive_id Object_and_primitive_id;
|
|
|
|
std::cout << "Construct AABB tree...";
|
|
Tree tree(faces(*m_pPolyhedron).first,faces(*m_pPolyhedron).second,*m_pPolyhedron);
|
|
std::cout << "done." << std::endl;
|
|
|
|
CGAL::Timer timer;
|
|
timer.start();
|
|
std::cout << "Generate boundary segments from " << nb_slices << " slices: ";
|
|
|
|
Vector normal(static_cast<FT>(0.0),static_cast<FT>(0.0),static_cast<FT>(1.0));
|
|
unsigned int i;
|
|
|
|
const double dz = m_bbox.zmax() - m_bbox.zmin();
|
|
for(i=0;i<nb_slices;i++)
|
|
{
|
|
FT z = m_bbox.zmin() + static_cast<FT>(i) / static_cast<FT>(nb_slices) * dz;
|
|
Point p(static_cast<FT>(0.0), static_cast<FT>(0.0), z);
|
|
Plane plane(p,normal);
|
|
|
|
std::list<Object_and_primitive_id> intersections;
|
|
tree.all_intersections(plane,std::back_inserter(intersections));
|
|
|
|
std::list<Object_and_primitive_id>::iterator it;
|
|
for(it = intersections.begin();
|
|
it != intersections.end();
|
|
it++)
|
|
{
|
|
Object_and_primitive_id op = *it;
|
|
CGAL::Object object = op.first;
|
|
Segment segment;
|
|
if(CGAL::assign(segment,object))
|
|
m_segments.push_back(segment);
|
|
}
|
|
}
|
|
std::cout << m_segments.size() << " segments, " << timer.time() << " s." << std::endl;
|
|
changed();
|
|
}
|
|
|
|
void Scene::generate_boundary_points(const unsigned int nb_points)
|
|
{
|
|
if(m_pPolyhedron == nullptr)
|
|
{
|
|
std::cout << "Load polyhedron first." << std::endl;
|
|
return;
|
|
}
|
|
|
|
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
|
|
typedef CGAL::AABB_traits_3<Kernel, Primitive> Traits;
|
|
typedef CGAL::AABB_tree<Traits> Tree;
|
|
typedef Tree::Object_and_primitive_id Object_and_primitive_id;
|
|
|
|
std::cout << "Construct AABB tree...";
|
|
Tree tree(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second,*m_pPolyhedron);
|
|
std::cout << "done." << std::endl;
|
|
|
|
CGAL::Timer timer;
|
|
timer.start();
|
|
std::cout << "Generate boundary points: ";
|
|
|
|
unsigned int nb = 0;
|
|
unsigned int nb_lines = 0;
|
|
while(nb < nb_points)
|
|
{
|
|
Line line = random_line(tree.bbox());
|
|
|
|
std::list<Object_and_primitive_id> intersections;
|
|
tree.all_intersections(line,std::back_inserter(intersections));
|
|
nb_lines++;
|
|
|
|
std::list<Object_and_primitive_id>::iterator it;
|
|
for(it = intersections.begin();
|
|
it != intersections.end();
|
|
it++)
|
|
{
|
|
Object_and_primitive_id op = *it;
|
|
CGAL::Object object = op.first;
|
|
Point point;
|
|
if(CGAL::assign(point,object))
|
|
{
|
|
m_points.push_back(point);
|
|
nb++;
|
|
}
|
|
}
|
|
}
|
|
std::cout << nb_lines << " line queries, " << timer.time() << " s." << std::endl;
|
|
changed();
|
|
}
|
|
|
|
void Scene::generate_edge_points(const unsigned int nb_points)
|
|
{
|
|
if(m_pPolyhedron == nullptr)
|
|
{
|
|
std::cout << "Load polyhedron first." << std::endl;
|
|
return;
|
|
}
|
|
|
|
typedef CGAL::AABB_halfedge_graph_segment_primitive<Polyhedron> Primitive;
|
|
typedef CGAL::AABB_traits_3<Kernel, Primitive> Traits;
|
|
typedef CGAL::AABB_tree<Traits> Tree;
|
|
typedef Tree::Object_and_primitive_id Object_and_primitive_id;
|
|
|
|
std::cout << "Construct AABB tree...";
|
|
Tree tree( CGAL::edges(*m_pPolyhedron).first,
|
|
CGAL::edges(*m_pPolyhedron).second,
|
|
*m_pPolyhedron);
|
|
std::cout << "done." << std::endl;
|
|
|
|
CGAL::Timer timer;
|
|
timer.start();
|
|
std::cout << "Generate edge points: ";
|
|
|
|
unsigned int nb = 0;
|
|
unsigned int nb_planes = 0;
|
|
while(nb < nb_points)
|
|
{
|
|
Plane plane = random_plane(tree.bbox());
|
|
|
|
std::list<Object_and_primitive_id> intersections;
|
|
tree.all_intersections(plane,std::back_inserter(intersections));
|
|
nb_planes++;
|
|
|
|
std::list<Object_and_primitive_id>::iterator it;
|
|
for(it = intersections.begin();
|
|
it != intersections.end();
|
|
it++)
|
|
{
|
|
Object_and_primitive_id op = *it;
|
|
CGAL::Object object = op.first;
|
|
Point point;
|
|
if(CGAL::assign(point,object))
|
|
{
|
|
m_points.push_back(point);
|
|
nb++;
|
|
}
|
|
}
|
|
}
|
|
std::cout << nb_planes << " plane queries, " << timer.time() << " s." << std::endl;
|
|
changed();
|
|
}
|
|
|
|
|
|
template <typename Tree>
|
|
void Scene::compute_distance_function(const Tree& tree)
|
|
{
|
|
// Get transformation
|
|
Aff_transformation t = frame_transformation();
|
|
m_max_distance_function = FT(0);
|
|
FT diag = bbox_diag();
|
|
|
|
const FT dx = diag;
|
|
const FT dy = diag;
|
|
const FT z (0);
|
|
const FT fd = FT(2);
|
|
for(int i=0 ; i<m_grid_size ; ++i)
|
|
{
|
|
FT x = -diag/fd + FT(i)/FT(m_grid_size) * dx;
|
|
|
|
for(int j=0 ; j<m_grid_size ; ++j)
|
|
{
|
|
FT y = -diag/fd + FT(j)/FT(m_grid_size) * dy;
|
|
Point query = t( Point(x,y,z) );
|
|
FT dist = CGAL::sqrt( tree.squared_distance(query) );
|
|
|
|
m_distance_function[i][j] = Point_distance(query,dist);
|
|
m_max_distance_function = (std::max)(dist, m_max_distance_function);
|
|
}
|
|
}
|
|
}
|
|
|
|
template <typename Tree>
|
|
void Scene::sign_distance_function(const Tree& tree)
|
|
{
|
|
typedef typename Tree::size_type size_type;
|
|
Vector random_vec = random_vector();
|
|
|
|
for(int i=0 ; i<m_grid_size ; ++i)
|
|
{
|
|
for(int j=0 ; j<m_grid_size ; ++j)
|
|
{
|
|
const Point& p = m_distance_function[i][j].first;
|
|
const FT unsigned_distance = m_distance_function[i][j].second;
|
|
|
|
// get sign through ray casting (random vector)
|
|
Ray ray(p, random_vec);
|
|
size_type nbi = tree.number_of_intersected_primitives(ray);
|
|
|
|
FT sign ( (nbi&1) == 0 ? 1 : -1);
|
|
m_distance_function[i][j].second = sign * unsigned_distance;
|
|
}
|
|
}
|
|
changed();
|
|
}
|
|
|
|
|
|
void Scene::unsigned_distance_function()
|
|
{
|
|
// Build tree (if build fail, exit)
|
|
build_facet_tree();
|
|
if ( m_facet_tree.empty() ) { return; }
|
|
|
|
compute_distance_function(m_facet_tree);
|
|
|
|
m_cut_plane = UNSIGNED_FACETS;
|
|
changed();
|
|
}
|
|
|
|
|
|
void Scene::unsigned_distance_function_to_edges()
|
|
{
|
|
// Build tree (if build fail, exit)
|
|
build_edge_tree();
|
|
if ( m_edge_tree.empty() ) { return; }
|
|
|
|
compute_distance_function(m_edge_tree);
|
|
|
|
m_cut_plane = UNSIGNED_EDGES;
|
|
changed();
|
|
}
|
|
|
|
|
|
void Scene::signed_distance_function()
|
|
{
|
|
// Build tree (if build fail, exit)
|
|
build_facet_tree();
|
|
if ( m_facet_tree.empty() ) { return; }
|
|
|
|
compute_distance_function(m_facet_tree);
|
|
sign_distance_function(m_facet_tree);
|
|
|
|
m_cut_plane = SIGNED_FACETS;
|
|
changed();
|
|
}
|
|
|
|
|
|
void Scene::cut_segment_plane()
|
|
{
|
|
// Build tree (if build fail, exit)
|
|
build_facet_tree();
|
|
if ( m_facet_tree.empty() ) { return; }
|
|
|
|
Plane plane = frame_plane();
|
|
|
|
// Compute intersections
|
|
typedef std::vector<Facet_tree::Object_and_primitive_id> Intersections;
|
|
Intersections intersections;
|
|
m_facet_tree.all_intersections(plane, std::back_inserter(intersections));
|
|
|
|
// Fill data structure
|
|
m_cut_segments.clear();
|
|
for ( Intersections::iterator it = intersections.begin(),
|
|
end = intersections.end() ; it != end ; ++it )
|
|
{
|
|
const Segment* inter_seg = CGAL::object_cast<Segment>(&(it->first));
|
|
|
|
if ( nullptr != inter_seg )
|
|
{
|
|
m_cut_segments.push_back(*inter_seg);
|
|
}
|
|
}
|
|
|
|
m_cut_plane = CUT_SEGMENTS;
|
|
changed();
|
|
}
|
|
void Scene::updateCutPlane()
|
|
{
|
|
ready_to_cut = true;
|
|
QTimer::singleShot(0,this,SLOT(cutting_plane()));
|
|
}
|
|
|
|
void Scene::cutting_plane(bool override)
|
|
{
|
|
if(ready_to_cut || override)
|
|
{
|
|
switch( m_cut_plane )
|
|
{
|
|
case UNSIGNED_FACETS:
|
|
return unsigned_distance_function();
|
|
case SIGNED_FACETS:
|
|
return signed_distance_function();
|
|
case UNSIGNED_EDGES:
|
|
return unsigned_distance_function_to_edges();
|
|
case CUT_SEGMENTS:
|
|
return cut_segment_plane();
|
|
case NONE: // do nothing
|
|
return;
|
|
}
|
|
|
|
// Should not be here
|
|
std::cerr << "Unknown cut_plane type" << std::endl;
|
|
CGAL_assertion(false);
|
|
}
|
|
}
|
|
|
|
void Scene::toggle_view_poyhedron()
|
|
{
|
|
m_view_polyhedron = !m_view_polyhedron;
|
|
}
|
|
|
|
void Scene::toggle_view_segments()
|
|
{
|
|
m_view_segments = !m_view_segments;
|
|
}
|
|
|
|
void Scene::toggle_view_points()
|
|
{
|
|
m_view_points = !m_view_points;
|
|
}
|
|
|
|
void Scene::toggle_view_plane()
|
|
{
|
|
m_view_plane = !m_view_plane;
|
|
}
|
|
|
|
void Scene::refine_bisection(const FT max_sqlen)
|
|
{
|
|
if(m_pPolyhedron == nullptr)
|
|
{
|
|
std::cout << "Load polyhedron first." << std::endl;
|
|
return;
|
|
}
|
|
std::cout << "Refine through recursive longest edge bisection...";
|
|
Refiner<Kernel,Polyhedron> refiner(m_pPolyhedron);
|
|
refiner(max_sqlen);
|
|
std::cout << "done (" << m_pPolyhedron->size_of_facets() << " facets)" << std::endl;
|
|
|
|
clear_internal_data();
|
|
}
|
|
|
|
void Scene::refine_loop()
|
|
{
|
|
if(m_pPolyhedron == nullptr)
|
|
{
|
|
std::cout << "Load polyhedron first." << std::endl;
|
|
return;
|
|
}
|
|
std::cout << "Loop subdivision...";
|
|
CGAL::Subdivision_method_3::Loop_subdivision(*m_pPolyhedron);
|
|
std::cout << "done (" << m_pPolyhedron->size_of_facets() << " facets)" << std::endl;
|
|
|
|
clear_internal_data();
|
|
}
|
|
|
|
|
|
void Scene::activate_cutting_plane()
|
|
{
|
|
connect(m_frame, SIGNAL(modified()), this, SLOT(updateCutPlane()));
|
|
m_view_plane = true;
|
|
}
|
|
|
|
void Scene::deactivate_cutting_plane()
|
|
{
|
|
disconnect(m_frame, SIGNAL(modified()), this, SLOT(updateCutPlane()));
|
|
m_view_plane = false;
|
|
}
|
|
void Scene::initGL()
|
|
{
|
|
gl = new QOpenGLFunctions();
|
|
gl->initializeOpenGLFunctions();
|
|
|
|
gl->glGenTextures(1, &textureId);
|
|
compile_shaders();
|
|
gl_init = true;
|
|
}
|