Add a SM version for the Parameterization_plugin.

This commit is contained in:
Maxime Gimeno 2017-07-10 17:01:49 +02:00
parent a0803ff800
commit 0520e53d07
5 changed files with 724 additions and 84 deletions

View File

@ -279,9 +279,12 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
target_link_libraries(scene_sm_shortest_path_item scene_surface_mesh_item_decorator scene_surface_mesh_item scene_polylines_item) target_link_libraries(scene_sm_shortest_path_item scene_surface_mesh_item_decorator scene_surface_mesh_item scene_polylines_item)
if(EIGEN3_FOUND ) if(EIGEN3_FOUND )
qt5_wrap_ui( editionUI_FILES Plugins/Surface_mesh_deformation/Deform_mesh.ui )
add_item(scene_textured_polyhedron_item Scene_textured_polyhedron_item.cpp texture.cpp) add_item(scene_textured_polyhedron_item Scene_textured_polyhedron_item.cpp texture.cpp)
qt5_use_modules( scene_textured_polyhedron_item Svg ) qt5_use_modules( scene_textured_polyhedron_item Svg )
add_item(scene_textured_surface_mesh_item Scene_textured_surface_mesh_item.cpp texture.cpp)
qt5_use_modules( scene_textured_surface_mesh_item Svg )
qt5_wrap_ui( editionUI_FILES Plugins/Surface_mesh_deformation/Deform_mesh.ui )
add_item(scene_edit_polyhedron_item Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp add_item(scene_edit_polyhedron_item Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp
${editionUI_FILES}) ${editionUI_FILES})
target_link_libraries(scene_edit_polyhedron_item scene_polyhedron_item scene_surface_mesh_item scene_polyhedron_and_sm_item_k_ring_selection target_link_libraries(scene_edit_polyhedron_item scene_polyhedron_item scene_surface_mesh_item scene_polyhedron_and_sm_item_k_ring_selection

View File

@ -9,6 +9,11 @@ if(EIGEN3_FOUND)
qt5_wrap_ui( parameterizationUI_FILES Parameterization_widget.ui ARAP_dialog.ui OTE_dialog.ui) qt5_wrap_ui( parameterizationUI_FILES Parameterization_widget.ui ARAP_dialog.ui OTE_dialog.ui)
polyhedron_demo_plugin(parameterization_plugin Parameterization_plugin ${parameterizationUI_FILES}) polyhedron_demo_plugin(parameterization_plugin Parameterization_plugin ${parameterizationUI_FILES})
target_link_libraries(parameterization_plugin ${CGAL_Core_LIBRARY} ${CGAL_Core_3RD_PARTY_LIBRARIES} scene_polyhedron_item scene_textured_polyhedron_item scene_polyhedron_selection_item) target_link_libraries(parameterization_plugin ${CGAL_Core_LIBRARY} ${CGAL_Core_3RD_PARTY_LIBRARIES} scene_polyhedron_item scene_textured_polyhedron_item scene_polyhedron_selection_item)
polyhedron_demo_plugin(parameterization_sm_plugin Parameterization_plugin ${parameterizationUI_FILES})
target_link_libraries(parameterization_sm_plugin ${CGAL_Core_LIBRARY} ${CGAL_Core_3RD_PARTY_LIBRARIES} scene_surface_mesh_item scene_textured_surface_mesh_item scene_surface_mesh_selection_item)
target_compile_definitions(parameterization_sm_plugin PUBLIC "-DUSE_SURFACE_MESH" )
else(CGAL_Core_FOUND) else(CGAL_Core_FOUND)
message(STATUS "NOTICE: CGAL Core was not found. The Parameterization plugin will not be available.") message(STATUS "NOTICE: CGAL Core was not found. The Parameterization plugin will not be available.")
endif(CGAL_Core_FOUND) endif(CGAL_Core_FOUND)

View File

@ -2,13 +2,26 @@
#include <QAction> #include <QAction>
#include <QMainWindow> #include <QMainWindow>
#include <QStringList> #include <QStringList>
#ifdef USE_SURFACE_MESH
#include "Scene_surface_mesh_item.h"
#include "Scene_textured_surface_mesh_item.h"
#include "Scene_polyhedron_selection_item.h"
#include "SMesh_type.h"
#else
#include "Scene_polyhedron_item.h" #include "Scene_polyhedron_item.h"
#include "Scene_textured_polyhedron_item.h" #include "Scene_textured_polyhedron_item.h"
#include "Scene_polyhedron_selection_item.h" #include "Scene_polyhedron_selection_item.h"
#include "Textured_polyhedron_type.h" #include "Textured_polyhedron_type.h"
#include "Polyhedron_type.h" #include "Polyhedron_type.h"
#include <CGAL/Polyhedron_3.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include <CGAL/Textured_polyhedron_builder.h>
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include <CGAL/Polyhedron_items_with_id_3.h>
#endif
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include "Scene.h" #include "Scene.h"
#include <QTime> #include <QTime>
#include <QGraphicsScene> #include <QGraphicsScene>
@ -16,13 +29,10 @@
#include <QPen> #include <QPen>
#include <QDockWidget> #include <QDockWidget>
#include <Messages_interface.h> #include <Messages_interface.h>
#include <CGAL/Polygon_mesh_processing/border.h> #include <CGAL/Polygon_mesh_processing/border.h>
#include <CGAL/Polygon_mesh_processing/measure.h> #include <CGAL/Polygon_mesh_processing/measure.h>
#include <CGAL/property_map.h> #include <CGAL/property_map.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include <CGAL/boost/graph/Seam_mesh.h> #include <CGAL/boost/graph/Seam_mesh.h>
#include <CGAL/boost/graph/graph_traits_Seam_mesh.h> #include <CGAL/boost/graph/graph_traits_Seam_mesh.h>
@ -38,40 +48,64 @@
#include <CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h> #include <CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h>
#include <CGAL/Surface_mesh_parameterization/parameterize.h> #include <CGAL/Surface_mesh_parameterization/parameterize.h>
#include <CGAL/Textured_polyhedron_builder.h>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
#include <boost/container/flat_map.hpp>
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
#include <vector> #include <vector>
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include <CGAL/boost/graph/properties.h> #include <CGAL/boost/graph/properties.h>
#include <CGAL/Qt/GraphicsViewNavigation.h> #include <CGAL/Qt/GraphicsViewNavigation.h>
#include <CGAL/Polyhedron_items_with_id_3.h>
#include "ui_Parameterization_widget.h" #include "ui_Parameterization_widget.h"
#include "ui_ARAP_dialog.h" #include "ui_ARAP_dialog.h"
#include "ui_OTE_dialog.h" #include "ui_OTE_dialog.h"
#ifdef USE_SURFACE_MESH
typedef Scene_surface_mesh_item Scene_facegraph_item;
typedef Scene_textured_surface_mesh_item Scene_textured_facegraph_item;
typedef SMesh Textured_face_graph;
typedef SMesh Base_face_graph;
typedef SMesh Face_graph;
typedef EPICK Traits;
#else
typedef Scene_polyhedron_item Scene_facegraph_item;
typedef Scene_textured_polyhedron_item Scene_textured_facegraph_item;
typedef Textured_polyhedron Textured_face_graph;
typedef Textured_face_graph::Base Base_face_graph;
typedef Polyhedron Face_graph;
typedef Kernel Traits;
#endif
namespace SMP = CGAL::Surface_mesh_parameterization; namespace SMP = CGAL::Surface_mesh_parameterization;
typedef boost::unordered_set<Textured_polyhedron::Base::Facet_handle> Component; typedef boost::unordered_set<boost::graph_traits<Base_face_graph>::face_descriptor> Component;
typedef std::vector<Component> Components; typedef std::vector<Component> Components;
struct Is_selected_property_map{
typedef boost::graph_traits<Textured_polyhedron::Base>::edge_descriptor edge_descriptor;
std::vector<bool>* is_selected_ptr;
Is_selected_property_map()
: is_selected_ptr(NULL) {}
Is_selected_property_map(std::vector<bool>& is_selected)
: is_selected_ptr( &is_selected) {}
std::size_t id(edge_descriptor ed) { return ed.halfedge()->id()/2; } struct Is_selected_property_map{
typedef boost::graph_traits<Base_face_graph>::edge_descriptor edge_descriptor;
typedef boost::property_map<Base_face_graph, boost::halfedge_index_t>::type HIndexMap;
std::vector<bool>* is_selected_ptr;
Base_face_graph* graph;
HIndexMap idmap;
Is_selected_property_map()
: is_selected_ptr(NULL), graph(NULL) {}
Is_selected_property_map(std::vector<bool>& is_selected,
Base_face_graph* graph)
: is_selected_ptr( &is_selected), graph(graph)
{
idmap = get(boost::halfedge_index, *graph);
}
std::size_t id(edge_descriptor ed) { return get(idmap, halfedge(ed, *graph))/2; }
friend bool get(Is_selected_property_map map, edge_descriptor ed) friend bool get(Is_selected_property_map map, edge_descriptor ed)
{ {
@ -162,18 +196,18 @@ private:
namespace SMP = CGAL::Surface_mesh_parameterization; namespace SMP = CGAL::Surface_mesh_parameterization;
typedef Kernel::FT FT; typedef Traits::FT FT;
typedef boost::graph_traits<Polyhedron>::vertex_descriptor P_vertex_descriptor; typedef boost::graph_traits<Face_graph>::vertex_descriptor P_vertex_descriptor;
typedef Kernel::Point_2 Point_2; typedef Traits::Point_2 Point_2;
typedef boost::graph_traits<Polyhedron>::edge_descriptor P_edge_descriptor; typedef boost::graph_traits<Face_graph>::edge_descriptor P_edge_descriptor;
typedef boost::graph_traits<Polyhedron>::halfedge_descriptor P_halfedge_descriptor; typedef boost::graph_traits<Face_graph>::halfedge_descriptor P_halfedge_descriptor;
// Textured polyhedron // Textured polyhedron
typedef boost::graph_traits<Textured_polyhedron::Base>:: typedef boost::graph_traits<Base_face_graph>::
edge_descriptor T_edge_descriptor; edge_descriptor T_edge_descriptor;
typedef boost::graph_traits<Textured_polyhedron::Base>:: typedef boost::graph_traits<Base_face_graph>::
halfedge_descriptor T_halfedge_descriptor; halfedge_descriptor T_halfedge_descriptor;
typedef boost::graph_traits<Textured_polyhedron::Base>:: typedef boost::graph_traits<Base_face_graph>::
vertex_descriptor T_vertex_descriptor; vertex_descriptor T_vertex_descriptor;
// Seam // Seam
@ -185,28 +219,32 @@ typedef boost::associative_property_map<UV_uhm> UV_pmap;
typedef boost::associative_property_map<Seam_edge_uhm> Seam_edge_pmap; typedef boost::associative_property_map<Seam_edge_uhm> Seam_edge_pmap;
typedef boost::associative_property_map<Seam_vertex_uhm> Seam_vertex_pmap; typedef boost::associative_property_map<Seam_vertex_uhm> Seam_vertex_pmap;
typedef CGAL::Seam_mesh<Textured_polyhedron::Base, Seam_edge_pmap, Seam_vertex_pmap> Seam_mesh; typedef CGAL::Seam_mesh<Base_face_graph,
Seam_edge_pmap, Seam_vertex_pmap> Seam_mesh;
typedef boost::graph_traits<Seam_mesh>::vertex_descriptor vertex_descriptor; typedef boost::graph_traits<Seam_mesh>::vertex_descriptor s_vertex_descriptor;
typedef boost::graph_traits<Seam_mesh>::halfedge_descriptor halfedge_descriptor; typedef boost::graph_traits<Seam_mesh>::halfedge_descriptor s_halfedge_descriptor;
typedef boost::graph_traits<Seam_mesh>::face_descriptor face_descriptor; typedef boost::graph_traits<Seam_mesh>::face_descriptor s_face_descriptor;
typedef boost::unordered_set<Textured_polyhedron::Base::Facet_handle> Component; typedef boost::unordered_set<boost::graph_traits<Base_face_graph>::
typedef std::vector<Component> Components; face_descriptor> Component;
typedef std::vector<Component> Components;
typedef boost::unordered_set<face_descriptor> SComponent; typedef boost::unordered_set<s_face_descriptor> SComponent;
typedef std::vector<SComponent> SComponents; typedef std::vector<SComponent> SComponents;
class UVItem : public QGraphicsItem class UVItem : public QGraphicsItem
{ {
public : public :
UVItem(Components* components, UVItem(Components* components,
Base_face_graph* graph,
std::vector<std::vector<float> >uv_borders, std::vector<std::vector<float> >uv_borders,
QRectF brect) QRectF brect)
: :
QGraphicsItem(), QGraphicsItem(),
bounding_rect(brect), bounding_rect(brect),
components(components), components(components),
graph(graph),
m_borders(uv_borders), m_borders(uv_borders),
m_concatenated_borders(), m_concatenated_borders(),
m_current_component(0) m_current_component(0)
@ -250,16 +288,30 @@ public :
pen.setWidth(0); pen.setWidth(0);
painter->setPen(pen); painter->setPen(pen);
painter->setBrush(brush); painter->setBrush(brush);
#ifdef USE_SURFACE_MESH
SMesh::Property_map<halfedge_descriptor,std::pair<float, float> > uv;
uv = graph->add_property_map<halfedge_descriptor,std::pair<float, float> >("h:uv",std::make_pair(0.0f,0.0f)).first;
#endif
for( Component::iterator for( Component::iterator
fi = components->at(m_current_component).begin(); fi = components->at(m_current_component).begin();
fi != components->at(m_current_component).end(); fi != components->at(m_current_component).end();
++fi) ++fi)
{ {
Textured_polyhedron::Facet_handle f(*fi); boost::graph_traits<Base_face_graph>::face_descriptor f(*fi);
#ifdef USE_SURFACE_MESH
QPointF points[3];
boost::graph_traits<Base_face_graph>::halfedge_descriptor h = halfedge(f, *graph);;
points[0] = QPointF(get(uv, h).first, get(uv, h).second);
h = next(halfedge(f, *graph), *graph);
points[1] = QPointF(get(uv, h).first, get(uv, h).second);
h = next(next(halfedge(f, *graph), *graph), *graph);
points[2] = QPointF(get(uv, h).first, get(uv, h).second);
#else
QPointF points[3]; QPointF points[3];
points[0] = QPointF(f->halfedge()->u(), f->halfedge()->v()); points[0] = QPointF(f->halfedge()->u(), f->halfedge()->v());
points[1] = QPointF(f->halfedge()->next()->u(), f->halfedge()->next()->v()); points[1] = QPointF(f->halfedge()->next()->u(), f->halfedge()->next()->v());
points[2] = QPointF(f->halfedge()->next()->next()->u(), f->halfedge()->next()->next()->v()); points[2] = QPointF(f->halfedge()->next()->next()->u(), f->halfedge()->next()->next()->v());
#endif
painter->drawPolygon(points,3); painter->drawPolygon(points,3);
} }
@ -273,6 +325,7 @@ private:
QString texMesh_name; QString texMesh_name;
QRectF bounding_rect; QRectF bounding_rect;
Components* components; Components* components;
Base_face_graph* graph;
std::vector<std::vector<float> > m_borders; std::vector<std::vector<float> > m_borders;
std::vector<float> m_concatenated_borders; std::vector<float> m_concatenated_borders;
int m_current_component; int m_current_component;
@ -351,14 +404,14 @@ public:
{ {
if (scene->selectionIndices().size() == 1) if (scene->selectionIndices().size() == 1)
{ {
return qobject_cast<Scene_polyhedron_item*>(scene->item(scene->mainSelectionIndex())) return qobject_cast<Scene_facegraph_item*>(scene->item(scene->mainSelectionIndex()))
|| qobject_cast<Scene_polyhedron_selection_item*>(scene->item(scene->mainSelectionIndex())); || qobject_cast<Scene_polyhedron_selection_item*>(scene->item(scene->mainSelectionIndex()));
} }
Q_FOREACH(CGAL::Three::Scene_interface::Item_id id, scene->selectionIndices()) Q_FOREACH(CGAL::Three::Scene_interface::Item_id id, scene->selectionIndices())
{ {
//if one polyhedron is found in the selection, it's fine //if one facegraph is found in the selection, it's fine
if (qobject_cast<Scene_polyhedron_item*>(scene->item(id))) if (qobject_cast<Scene_facegraph_item*>(scene->item(id)))
return true; return true;
} }
return false; return false;
@ -383,7 +436,7 @@ public Q_SLOTS:
void replacePolyline() void replacePolyline()
{ {
if(current_uv_item) if(current_uv_item)
qobject_cast<Scene_textured_polyhedron_item*>(projections.key(current_uv_item))->add_border_edges(std::vector<float>(0)); qobject_cast<Scene_textured_facegraph_item*>(projections.key(current_uv_item))->add_border_edges(std::vector<float>(0));
int id = scene->mainSelectionIndex(); int id = scene->mainSelectionIndex();
@ -409,7 +462,7 @@ public Q_SLOTS:
ui_widget.graphicsView->fitInView(current_uv_item->boundingRect(), Qt::KeepAspectRatio); ui_widget.graphicsView->fitInView(current_uv_item->boundingRect(), Qt::KeepAspectRatio);
ui_widget.component_numberLabel->setText(QString("Component : %1/%2").arg(current_uv_item->current_component()+1).arg(current_uv_item->number_of_components())); ui_widget.component_numberLabel->setText(QString("Component : %1/%2").arg(current_uv_item->current_component()+1).arg(current_uv_item->number_of_components()));
dock_widget->setWindowTitle(tr("UVMapping for %1").arg(current_uv_item->item_name())); dock_widget->setWindowTitle(tr("UVMapping for %1").arg(current_uv_item->item_name()));
qobject_cast<Scene_textured_polyhedron_item*>(projections.key(current_uv_item))->add_border_edges(current_uv_item->concatenated_borders()); qobject_cast<Scene_textured_facegraph_item*>(projections.key(current_uv_item))->add_border_edges(current_uv_item->concatenated_borders());
} }
} }
@ -491,11 +544,11 @@ void Polyhedron_demo_parameterization_plugin::on_nextButton_pressed()
void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterization_method method) void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterization_method method)
{ {
// get active polyhedron // get active polyhedron
Scene_polyhedron_item* poly_item = NULL; Scene_facegraph_item* poly_item = NULL;
CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex(); CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex();
Q_FOREACH(CGAL::Three::Scene_interface::Item_id id, scene->selectionIndices()) Q_FOREACH(CGAL::Three::Scene_interface::Item_id id, scene->selectionIndices())
{ {
poly_item = qobject_cast<Scene_polyhedron_item*>(scene->item(id)); poly_item = qobject_cast<Scene_facegraph_item*>(scene->item(id));
if(!poly_item) if(!poly_item)
{ {
continue; continue;
@ -513,14 +566,15 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
return; return;
} }
Polyhedron* pMesh = poly_item->polyhedron(); Face_graph* pMesh = poly_item->face_graph();
if(!pMesh) if(!pMesh)
{ {
messages->error("Selected item has no valid polyhedron."); messages->error("Selected item has no valid polyhedron.");
return; return;
} }
#ifndef USE_SURFACE_MESH
pMesh->normalize_border(); pMesh->normalize_border();
#endif
Scene_polyhedron_selection_item* sel_item = NULL; Scene_polyhedron_selection_item* sel_item = NULL;
bool is_seamed = false; bool is_seamed = false;
Q_FOREACH(CGAL::Three::Scene_interface::Item_id id, scene->selectionIndices()) Q_FOREACH(CGAL::Three::Scene_interface::Item_id id, scene->selectionIndices())
@ -548,7 +602,7 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
Seam_vertex_uhm seam_vertex_uhm(false); Seam_vertex_uhm seam_vertex_uhm(false);
Seam_vertex_pmap seam_vertex_pm(seam_vertex_uhm); Seam_vertex_pmap seam_vertex_pm(seam_vertex_uhm);
if(!is_seamed && pMesh->is_closed()) if(!is_seamed && is_closed(*pMesh))
{ {
messages->error("The selected mesh has no (real or virtual) border."); messages->error("The selected mesh has no (real or virtual) border.");
return; return;
@ -563,12 +617,13 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
QTime time; QTime time;
time.start(); time.start();
// add textured polyhedon to the scene // add textured polyhedon to the scene
#ifndef USE_SURFACE_MESH
Textured_polyhedron *tpMesh = new Textured_polyhedron(); Textured_polyhedron *tpMesh = new Textured_polyhedron();
Textured_polyhedron_builder<Polyhedron,Textured_polyhedron,Kernel> builder; Textured_polyhedron_builder<Polyhedron,Textured_polyhedron,Kernel> builder;
builder.run(*pMesh,*tpMesh); builder.run(*pMesh,*tpMesh);
tpMesh->compute_normals(); tpMesh->compute_normals();
tpMesh->normalize_border(); tpMesh->normalize_border();
Textured_polyhedron::Base tMesh = static_cast<Textured_polyhedron::Base&>(*tpMesh); Base_face_graph tMesh = static_cast<Base_face_graph&>(*tpMesh);
CGAL::set_halfedgeds_items_id(tMesh); CGAL::set_halfedgeds_items_id(tMesh);
std::vector<bool> mark(tpMesh->size_of_halfedges()/2,false); std::vector<bool> mark(tpMesh->size_of_halfedges()/2,false);
@ -627,7 +682,71 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
} }
} }
} }
#else
// \todo for surface_mesh
Base_face_graph tMesh = *pMesh;
std::vector<bool> mark(num_halfedges(tMesh)/2,false);
std::vector<T_edge_descriptor> seam_edges;
typedef boost::property_map<Base_face_graph, boost::vertex_index_t>::type VIDMap;
VIDMap vidmap = get(boost::vertex_index, tMesh);
if(is_seamed)
{
//create a textured_polyhedron edges selection from the ids of the corresponding vertices
typedef boost::property_map<Base_face_graph, boost::halfedge_index_t>::type HIDMap;
HIDMap hidmap = get(boost::halfedge_index, tMesh);
BOOST_FOREACH(P_edge_descriptor ed, sel_item->selected_edges)
{
boost::graph_traits<Face_graph>::vertex_descriptor a(source(ed, *pMesh)), b(target(ed, *pMesh));
for(boost::graph_traits<Textured_face_graph>::edge_iterator it =
edges(tMesh).begin(); it != edges(tMesh).end();
++it)
{
boost::graph_traits<Textured_face_graph>::vertex_descriptor ta(source(*it, tMesh)), tb(target(*it, tMesh));
if((get(vidmap, ta) == get(vidmap, a) && get(vidmap,tb) == get(vidmap,b))
||
(get(vidmap,ta) == get(vidmap,b) && get(vidmap,tb) == get(vidmap,a)))
{
T_edge_descriptor ted(*it);
seam_edges.push_back(ted);
break;
}
}
}
qDebug() << sel_item->selected_edges.size() << ", " << seam_edges.size();
//fill seam mesh pmaps
BOOST_FOREACH(T_edge_descriptor ed, seam_edges)
{
T_halfedge_descriptor hd = halfedge(ed, tMesh);
T_vertex_descriptor svd(source(hd, tMesh)), tvd(target(hd, tMesh));
if(!is_border(ed, tMesh))
{
put(seam_edge_pm, ed, true);
put(seam_vertex_pm, svd, true);
put(seam_vertex_pm, tvd, true);
mark[get(hidmap, hd)/2] = true;
}
}
}
// map the cones from the selection plugin to the textured polyhedron
boost::unordered_set<T_vertex_descriptor> unordered_cones;
if(method == PARAM_OTE) {
BOOST_FOREACH(P_vertex_descriptor vd, sel_item->selected_vertices) {
boost::graph_traits<Face_graph>::vertex_descriptor pvd(vd);
boost::graph_traits<Textured_face_graph>::vertex_iterator it = vertices(tMesh).begin(),
end = vertices(tMesh).end();
for(; it!=end; ++it) {
boost::graph_traits<Textured_face_graph>::vertex_descriptor tvd(*it);
if(get(vidmap, *it) == get(vidmap, pvd)) {
unordered_cones.insert(tvd);
}
}
}
}
#endif
Seam_mesh sMesh(tMesh, seam_edge_pm, seam_vertex_pm); Seam_mesh sMesh(tMesh, seam_edge_pm, seam_vertex_pm);
sMesh.set_seam_edges_number(seam_edges.size()); sMesh.set_seam_edges_number(seam_edges.size());
@ -637,13 +756,11 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
QString new_item_name; QString new_item_name;
//determine the different connected_components //determine the different connected_components
boost::property_map<Textured_polyhedron::Base, boost::container::flat_map<boost::graph_traits<Base_face_graph>::face_descriptor, int> face_component_map;
boost::face_external_index_t>::type fim = get(boost::face_external_index, tMesh); boost::associative_property_map< boost::container::flat_map<face_descriptor, int> >
boost::vector_property_map<int, fccmap(face_component_map);
boost::property_map<Textured_polyhedron::Base,
boost::face_external_index_t>::type> fccmap(fim);
Is_selected_property_map edge_pmap(mark); Is_selected_property_map edge_pmap(mark, &tMesh);
int number_of_components = int number_of_components =
CGAL::Polygon_mesh_processing::connected_components( CGAL::Polygon_mesh_processing::connected_components(
@ -663,9 +780,9 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
// the SEAM MESH faces of each connected component // the SEAM MESH faces of each connected component
SComponents s_components(number_of_components); SComponents s_components(number_of_components);
Textured_polyhedron::Base::Facet_iterator fit; for(boost::graph_traits<Base_face_graph>::face_iterator fit = faces(tMesh).begin();
for(fit = tMesh.facets_begin(); fit != tMesh.facets_end(); ++fit) { fit != faces(tMesh).end(); ++fit) {
s_components.at(fccmap[fit]).insert(face_descriptor(fit)); s_components.at(fccmap[*fit]).insert(s_face_descriptor(*fit));
} }
// once per component // once per component
@ -677,7 +794,7 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
for(int current_component=0; current_component<number_of_components; ++current_component) for(int current_component=0; current_component<number_of_components; ++current_component)
{ {
std::vector<halfedge_descriptor> border; std::vector<s_halfedge_descriptor> border;
PMP::border_halfedges(s_components.at(current_component), PMP::border_halfedges(s_components.at(current_component),
sMesh, std::back_inserter(border)); sMesh, std::back_inserter(border));
@ -686,17 +803,17 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
std::cout << border.size() << " border halfedges" << std::endl; std::cout << border.size() << " border halfedges" << std::endl;
// find longest border in the connected component // find longest border in the connected component
halfedge_descriptor bhd; // a halfedge on the (possibly virtual) border s_halfedge_descriptor bhd; // a halfedge on the (possibly virtual) border
boost::unordered_set<halfedge_descriptor> visited; boost::unordered_set<s_halfedge_descriptor> visited;
FT result_len = 0; FT result_len = 0;
BOOST_FOREACH(halfedge_descriptor hd, border) BOOST_FOREACH(s_halfedge_descriptor hd, border)
{ {
assert(is_border(hd, sMesh)); assert(is_border(hd, sMesh));
if(visited.find(hd) == visited.end()) if(visited.find(hd) == visited.end())
{ {
FT len = 0; FT len = 0;
BOOST_FOREACH(halfedge_descriptor haf, halfedges_around_face(hd, sMesh)) BOOST_FOREACH(s_halfedge_descriptor haf, halfedges_around_face(hd, sMesh))
{ {
len += PMP::edge_length(haf, sMesh); len += PMP::edge_length(haf, sMesh);
visited.insert(haf); visited.insert(haf);
@ -709,19 +826,21 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
} }
} }
} }
CGAL_postcondition(bhd != halfedge_descriptor()); CGAL_postcondition(bhd != s_halfedge_descriptor());
CGAL_postcondition(is_border(bhd, sMesh)); CGAL_postcondition(is_border(bhd, sMesh));
typedef boost::property_map<Base_face_graph, boost::vertex_point_t>::type VPMap;
VPMap vpmap =get(boost::vertex_point, tMesh);
// collect the border edges for that connected component // collect the border edges for that connected component
BOOST_FOREACH(halfedge_descriptor haf, halfedges_around_face(bhd, sMesh)) BOOST_FOREACH(s_halfedge_descriptor haf, halfedges_around_face(bhd, sMesh))
{ {
uv_borders[current_component].push_back(source(haf, tMesh)->point().x()); uv_borders[current_component].push_back(get(vpmap, source(haf, tMesh)).x());
uv_borders[current_component].push_back(source(haf, tMesh)->point().y()); uv_borders[current_component].push_back(get(vpmap, source(haf, tMesh)).y());
uv_borders[current_component].push_back(source(haf, tMesh)->point().z()); uv_borders[current_component].push_back(get(vpmap, source(haf, tMesh)).z());
uv_borders[current_component].push_back(target(haf, tMesh)->point().x()); uv_borders[current_component].push_back(get(vpmap, target(haf, tMesh)).x());
uv_borders[current_component].push_back(target(haf, tMesh)->point().y()); uv_borders[current_component].push_back(get(vpmap, target(haf, tMesh)).y());
uv_borders[current_component].push_back(target(haf, tMesh)->point().z()); uv_borders[current_component].push_back(get(vpmap, target(haf, tMesh)).z());
} }
switch(method) switch(method)
@ -829,7 +948,7 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
Parameterizer parameterizer(orb); Parameterizer parameterizer(orb);
// mark cones in the seam mesh // mark cones in the seam mesh
typedef boost::unordered_map<vertex_descriptor, SMP::Cone_type> Cones; typedef boost::unordered_map<s_vertex_descriptor, SMP::Cone_type> Cones;
Cones cmap; Cones cmap;
if(!SMP::internal::locate_unordered_cones<Seam_mesh, if(!SMP::internal::locate_unordered_cones<Seam_mesh,
@ -838,7 +957,7 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
return; return;
// vimap and uvmap // vimap and uvmap
typedef boost::unordered_map<vertex_descriptor, int> Indices; typedef boost::unordered_map<s_vertex_descriptor, int> Indices;
Indices indices; Indices indices;
CGAL::Polygon_mesh_processing::connected_component( CGAL::Polygon_mesh_processing::connected_component(
face(opposite(bhd, sMesh), sMesh), face(opposite(bhd, sMesh), sMesh),
@ -875,10 +994,10 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
} //end for each component } //end for each component
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();
Textured_polyhedron::Base::Halfedge_iterator it1;
Textured_polyhedron::Halfedge_iterator it2;
QPointF min(FLT_MAX, FLT_MAX), max(-FLT_MAX, -FLT_MAX); QPointF min(FLT_MAX, FLT_MAX), max(-FLT_MAX, -FLT_MAX);
#ifndef USE_SURFACE_MESH
Base_face_graph::Halfedge_iterator it1;
Textured_polyhedron::Halfedge_iterator it2;
for(it1 = tMesh.halfedges_begin(), for(it1 = tMesh.halfedges_begin(),
it2 = tpMesh->halfedges_begin(); it2 = tpMesh->halfedges_begin();
it1 != tMesh.halfedges_end()&& it1 != tMesh.halfedges_end()&&
@ -899,21 +1018,57 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
if(v>max.y()) if(v>max.y())
max.setY(v); max.setY(v);
} }
#else
SMesh::Property_map<halfedge_descriptor,std::pair<float, float> > uv;
uv = tMesh.add_property_map<halfedge_descriptor,std::pair<float, float> >("h:uv",std::make_pair(0.0f,0.0f)).first;
Base_face_graph::Halfedge_iterator it;
for(it = tMesh.halfedges_begin();
it != tMesh.halfedges_end();
++it)
{
Seam_mesh::halfedge_descriptor hd(*it);
FT u = uv_pm[target(hd, sMesh)].x();
FT v = uv_pm[target(hd, sMesh)].y();
put(uv, *it, std::make_pair(u,v));
if(u<min.x())
min.setX(u);
if(u>max.x())
max.setX(u);
if(v<min.y())
min.setY(v);
if(v>max.y())
max.setY(v);
}
#endif
Components* components = new Components(0); Components* components = new Components(0);
components->resize(number_of_components); components->resize(number_of_components);
Textured_polyhedron::Base::Facet_iterator bfit; boost::graph_traits<Base_face_graph>::face_iterator bfit;
Textured_polyhedron::Facet_iterator tfit; #ifdef USE_SURFACE_MESH
for(bfit = tMesh.facets_begin(), tfit = tpMesh->facets_begin(); for(bfit = faces(tMesh).begin();
bfit != tMesh.facets_end() && tfit != tpMesh->facets_end(); bfit != faces(tMesh).end();
++bfit, ++tfit) ++bfit)
{ {
components->at(fccmap[bfit]).insert(tfit); components->at(fccmap[*bfit]).insert(*bfit);
} }
UVItem *projection = new UVItem(components, uv_borders, QRectF(min, max)); Scene_textured_facegraph_item* new_item = new Scene_textured_facegraph_item(tMesh);
UVItem *projection = new UVItem(components,new_item->textured_face_graph(), uv_borders, QRectF(min, max));
projection->set_item_name(new_item_name); projection->set_item_name(new_item_name);
Scene_textured_polyhedron_item* new_item = new Scene_textured_polyhedron_item(tpMesh); #else
boost::graph_traits<Base_face_graph>::face_iterator tfit;
for(bfit = faces(tMesh).begin(), tfit = faces(*tpMesh).begin();
bfit != faces(tMesh).end() && tfit != faces(*tpMesh).end();
++bfit, ++tfit)
{
components->at(fccmap[*bfit]).insert(*tfit);
}
UVItem *projection = new UVItem(components,tpMesh, uv_borders, QRectF(min, max));
projection->set_item_name(new_item_name);
Scene_textured_facegraph_item* new_item = new Scene_textured_facegraph_item(tpMesh);
#endif
new_item->setName(new_item_name); new_item->setName(new_item_name);
new_item->setColor(Qt::white); new_item->setColor(Qt::white);
new_item->setRenderingMode(poly_item->renderingMode()); new_item->setRenderingMode(poly_item->renderingMode());
@ -927,9 +1082,9 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio
graphics_scene->addItem(projection); graphics_scene->addItem(projection);
projections[new_item] = projection; projections[new_item] = projection;
if(current_uv_item) if(current_uv_item)
qobject_cast<Scene_textured_polyhedron_item*>(projections.key(current_uv_item))->add_border_edges(std::vector<float>(0)); qobject_cast<Scene_textured_facegraph_item*>(projections.key(current_uv_item))->add_border_edges(std::vector<float>(0));
current_uv_item = projection; current_uv_item = projection;
qobject_cast<Scene_textured_polyhedron_item*>(projections.key(current_uv_item))->add_border_edges(current_uv_item->concatenated_borders()); qobject_cast<Scene_textured_facegraph_item*>(projections.key(current_uv_item))->add_border_edges(current_uv_item->concatenated_borders());
if(dock_widget->isHidden()) if(dock_widget->isHidden())
dock_widget->setVisible(true); dock_widget->setVisible(true);
dock_widget->setWindowTitle(tr("UVMapping for %1").arg(new_item->name())); dock_widget->setWindowTitle(tr("UVMapping for %1").arg(new_item->name()));

View File

@ -0,0 +1,412 @@
#include "Scene_textured_surface_mesh_item.h"
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
#include <QApplication>
#include <QObject>
typedef EPICK ::Point_3 Point;
struct Scene_textured_surface_mesh_item_priv
{
Scene_textured_surface_mesh_item_priv(Scene_textured_surface_mesh_item* parent)
:sm(new SMesh), textureId(-1)
{
item = parent;
texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255);
uv = sm->add_property_map<halfedge_descriptor,std::pair<float, float> >("h:uv",std::make_pair(0.0f,0.0f)).first;
}
Scene_textured_surface_mesh_item_priv(const SMesh& p, Scene_textured_surface_mesh_item* parent)
: sm(new SMesh(p)),textureId(-1),smooth_shading(true)
{
item = parent;
texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255);
uv = sm->add_property_map<halfedge_descriptor,std::pair<float, float> >("h:uv",std::make_pair(0.0f,0.0f)).first;
}
Scene_textured_surface_mesh_item_priv(SMesh* const p,Scene_textured_surface_mesh_item* parent)
:sm(p),textureId(-1),smooth_shading(true)
{
item = parent;
texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255);
uv = sm->add_property_map<halfedge_descriptor,std::pair<float, float> >("h:uv",std::make_pair(0.0f,0.0f)).first;
}
~Scene_textured_surface_mesh_item_priv()
{
delete sm;
}
void initializeBuffers(CGAL::Three::Viewer_interface *viewer) const;
void compute_normals_and_vertices(void) const;
enum VAOs {
Facets=0,
Edges,
Border_edges,
NbOfVaos
};
enum VBOs {
B_Facets=0,
B_Edges,
B_Border_Edges,
NbOfVbos
};
SMesh* sm;
Texture texture;
SMesh::Property_map<halfedge_descriptor,std::pair<float, float> > uv;
mutable GLuint textureId;
mutable QOpenGLShaderProgram* program;
//[Px][Py][Pz][Nx][Ny][Nz][u][v]
mutable std::vector<float> faces_buffer;
//[Px][Py][Pz][u][v]
mutable std::vector<float> edges_buffer;
//[Px][Py][Pz]
mutable std::vector<float> border_edges_buffer;
bool smooth_shading;
Scene_textured_surface_mesh_item* item;
typedef Scene_textured_surface_mesh_item I;
};
void Scene_textured_surface_mesh_item_priv::initializeBuffers(CGAL::Three::Viewer_interface *viewer = 0) const
{
if(GLuint(-1) == textureId) {
viewer->glGenTextures(1, &textureId);
}
//Faces
program = item->getShaderProgram(I::PROGRAM_WITH_TEXTURE, viewer);
program->bind();
item->vaos[Facets]->bind();
item->buffers[B_Facets].bind();
item->buffers[B_Facets].allocate(faces_buffer.data(),
static_cast<int>(faces_buffer.size()*sizeof(float)));
program->enableAttributeArray("vertex");
program->enableAttributeArray("normal");
program->enableAttributeArray("v_texCoord");
program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3, 8 * sizeof(float));
program->setAttributeBuffer("normal", GL_FLOAT, 3 * sizeof(float), 3, 8 * sizeof(float));
program->setAttributeBuffer("v_texCoord", GL_FLOAT, 6 * sizeof(float), 2, 8 * sizeof(float));
item->buffers[B_Facets].release();
item->vaos[Facets]->release();
program->release();
//Edges
program = item->getShaderProgram(I::PROGRAM_WITH_TEXTURED_EDGES, viewer);
program->bind();
item->vaos[Edges]->bind();
item->buffers[B_Edges].bind();
item->buffers[B_Edges].allocate(edges_buffer.data(),
static_cast<int>(edges_buffer.size()*sizeof(float)));
program->enableAttributeArray("vertex");
program->enableAttributeArray("v_texCoord");
program->setAttributeBuffer("vertex", GL_FLOAT, 0, 3, 5 * sizeof(float));
program->setAttributeBuffer("v_texCoord", GL_FLOAT, 3 * sizeof(float), 2, 5 * sizeof(float));
item->buffers[B_Edges].release();
item->vaos[Edges]->release();
program->release();
viewer->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
viewer->glActiveTexture(GL_TEXTURE0);
viewer->glBindTexture(GL_TEXTURE_2D, textureId);
viewer->glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
texture.GetWidth(),
texture.GetHeight(),
0,
GL_RGB,
GL_UNSIGNED_BYTE,
texture.GetData());
viewer->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
viewer->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
viewer->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
viewer->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
item->are_buffers_filled = true;
}
void
Scene_textured_surface_mesh_item_priv::compute_normals_and_vertices(void) const
{
QApplication::setOverrideCursor(Qt::WaitCursor);
faces_buffer.resize(0);
typedef boost::graph_traits<SMesh>::face_iterator face_iterator;
typedef boost::graph_traits<SMesh>::face_iterator face_iterator;
const qglviewer::Vec offset = static_cast<CGAL::Three::Viewer_interface*>(QGLViewer::QGLViewerPool().first())->offset();
//Faces
SMesh::Property_map<vertex_descriptor, Point> positions =
sm->points();
SMesh::Property_map<face_descriptor, EPICK::Vector_3 > fnormals =
sm->add_property_map<face_descriptor, EPICK::Vector_3 >("f:normal").first;
CGAL::Polygon_mesh_processing::compute_face_normals(*sm,fnormals);
for(face_iterator f = faces(*sm).begin();
f != faces(*sm).end();
++f)
{
SMesh::Halfedge_around_face_circulator he(halfedge(*f, *sm), *sm);
SMesh::Halfedge_around_face_circulator end = he;
CGAL_For_all(he,end)
{
//position [3]
const Point& p = get(positions, target(*he, *sm));
faces_buffer.push_back(p.x() + offset.x);
faces_buffer.push_back(p.y() + offset.y);
faces_buffer.push_back(p.z() + offset.z);
//normals [3]
const EPICK::Vector_3& n = get(fnormals, face(*he, *sm));
faces_buffer.push_back(n[0]);
faces_buffer.push_back(n[1]);
faces_buffer.push_back(n[2]);
//uvs [2]
const float u = get(uv, *he).first;
const float v = get(uv, *he).second;
faces_buffer.push_back(u);
faces_buffer.push_back(v);
}
}
//Edges
typedef EPICK::Point_3 Point;
typedef SMesh::Edge_iterator Edge_iterator;
Edge_iterator he;
for(he = edges(*sm).begin();
he != edges(*sm).end();
++he)
{
//position [3]
const Point& a = sm->point(target(*he, *sm));
const Point& b = sm->point(source(*he, *sm));
edges_buffer.push_back(a.x() + offset.x);
edges_buffer.push_back(a.y() + offset.y);
edges_buffer.push_back(a.z() + offset.z);
//uvs [2]
float u = get(uv, halfedge(*he, *sm)).first;
float v = get(uv, halfedge(*he, *sm)).second;
edges_buffer.push_back(u);
edges_buffer.push_back(v);
//position [3]
edges_buffer.push_back(b.x() + offset.x);
edges_buffer.push_back(b.y() + offset.y);
edges_buffer.push_back(b.z() + offset.z);
//uvs [2]
u = get(uv, opposite(halfedge(*he, *sm), *sm)).first;
v = get(uv, opposite(halfedge(*he, *sm), *sm)).second;
edges_buffer.push_back(u);
edges_buffer.push_back(v);
}
QApplication::restoreOverrideCursor();
}
Scene_textured_surface_mesh_item::Scene_textured_surface_mesh_item()
: Scene_item(Scene_textured_surface_mesh_item_priv::NbOfVbos,Scene_textured_surface_mesh_item_priv::NbOfVaos)
{
cur_shading=FlatPlusEdges;
is_selected=false;
d = new Scene_textured_surface_mesh_item_priv(this);
invalidateOpenGLBuffers();
}
Scene_textured_surface_mesh_item::Scene_textured_surface_mesh_item(SMesh* const p)
: Scene_item(Scene_textured_surface_mesh_item_priv::NbOfVbos,Scene_textured_surface_mesh_item_priv::NbOfVaos)
{
cur_shading=FlatPlusEdges;
is_selected=false;
d = new Scene_textured_surface_mesh_item_priv(p,this);
invalidateOpenGLBuffers();
}
Scene_textured_surface_mesh_item::Scene_textured_surface_mesh_item(const SMesh& p)
: Scene_item(Scene_textured_surface_mesh_item_priv::NbOfVbos,Scene_textured_surface_mesh_item_priv::NbOfVaos)
{
cur_shading=FlatPlusEdges;
is_selected=false;
d = new Scene_textured_surface_mesh_item_priv(p,this);
invalidateOpenGLBuffers();
}
Scene_textured_surface_mesh_item::~Scene_textured_surface_mesh_item()
{
delete d;
}
Scene_textured_surface_mesh_item*
Scene_textured_surface_mesh_item::clone() const {
return new Scene_textured_surface_mesh_item(*d->sm);
}
// Load textured_polyhedron from .OFF file
bool
Scene_textured_surface_mesh_item::load(std::istream& in)
{
std::cout<<"LOAD"<<std::endl;
in >> *d->sm;
invalidateOpenGLBuffers();
return in && !isEmpty();
}
// Write textured_polyhedron to .OFF file
bool
Scene_textured_surface_mesh_item::save(std::ostream& out) const
{
out << *d->sm;
return (bool) out;
}
QString
Scene_textured_surface_mesh_item::toolTip() const
{
if(!d->sm)
return QString();
return QObject::tr("<p>Textured polyhedron <b>%1</b> (mode: %5, color: %6)</p>"
"<p>Number of vertices: %2<br />"
"Number of edges: %3<br />"
"Number of facets: %4</p>")
.arg(this->name())
.arg(num_vertices(*d->sm))
.arg(num_halfedges(*d->sm)/2)
.arg(num_faces(*d->sm))
.arg(this->renderingModeName())
.arg(this->color().name());
}
// Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list
void Scene_textured_surface_mesh_item::draw(CGAL::Three::Viewer_interface* viewer) const {
if(!are_buffers_filled)
{
d->compute_normals_and_vertices();
d->initializeBuffers(viewer);
}
vaos[Scene_textured_surface_mesh_item_priv::Facets]->bind();
viewer->glActiveTexture(GL_TEXTURE0);
viewer->glBindTexture(GL_TEXTURE_2D, d->textureId);
attribBuffers(viewer, PROGRAM_WITH_TEXTURE);
d->program=getShaderProgram(PROGRAM_WITH_TEXTURE);
d->program->bind();
viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(d->faces_buffer.size()/8));
//Clean-up
d->program->release();
vaos[Scene_textured_surface_mesh_item_priv::Facets]->release();
}
void Scene_textured_surface_mesh_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const {
if(!are_buffers_filled)
d->initializeBuffers(viewer);
vaos[Scene_textured_surface_mesh_item_priv::Edges]->bind();
viewer->glActiveTexture(GL_TEXTURE0);
viewer->glBindTexture(GL_TEXTURE_2D, d->textureId);
attribBuffers(viewer, PROGRAM_WITH_TEXTURED_EDGES);
d->program=getShaderProgram(PROGRAM_WITH_TEXTURED_EDGES);
d->program->bind();
viewer->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(d->edges_buffer.size()/5));
vaos[Scene_textured_surface_mesh_item_priv::Edges]->release();
d->program->release();
vaos[Scene_textured_surface_mesh_item_priv::Border_edges]->bind();
attribBuffers(viewer, PROGRAM_NO_SELECTION);
d->program=getShaderProgram(PROGRAM_NO_SELECTION);
d->program->bind();
viewer->glLineWidth(4.0);
d->program->setAttributeValue("colors", QColor(Qt::blue));
viewer->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(d->border_edges_buffer.size()/3));
viewer->glLineWidth(1.0);
//Clean-up
d->program->release();
vaos[Scene_textured_surface_mesh_item_priv::Border_edges]->release();
}
SMesh*
Scene_textured_surface_mesh_item::textured_face_graph() { return d->sm; }
const SMesh*
Scene_textured_surface_mesh_item::textured_face_graph() const { return d->sm; }
bool
Scene_textured_surface_mesh_item::isEmpty() const {
return (d->sm == 0) || d->sm->is_empty();
}
void
Scene_textured_surface_mesh_item::compute_bbox() const {
const Point& p = d->sm->point(*vertices(*d->sm).begin());
CGAL::Bbox_3 bbox(p.x(), p.y(), p.z(), p.x(), p.y(), p.z());
for(boost::graph_traits<SMesh>::vertex_iterator it = vertices(*d->sm).begin();
it != vertices(*d->sm).end();
++it) {
bbox = bbox + d->sm->point(*it).bbox();
}
_bbox = Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(),
bbox.xmax(),bbox.ymax(),bbox.zmax());
}
void
Scene_textured_surface_mesh_item::invalidateOpenGLBuffers()
{
are_buffers_filled = false;
compute_bbox();
}
void
Scene_textured_surface_mesh_item::selection_changed(bool p_is_selected)
{
if(p_is_selected != is_selected)
{
is_selected = p_is_selected;
initializeBuffers();
//to be replaced by a functor in the d-pointer when the merging is done
if(p_is_selected)
Q_EMIT selectionChanged();
}
else
is_selected = p_is_selected;
}
void Scene_textured_surface_mesh_item::add_border_edges(std::vector<float> border_edges)
{
d->border_edges_buffer = border_edges;
d->program=getShaderProgram(PROGRAM_NO_SELECTION);
d->program->bind();
vaos[Scene_textured_surface_mesh_item_priv::Border_edges]->bind();
buffers[Scene_textured_surface_mesh_item_priv::B_Border_Edges].bind();
buffers[Scene_textured_surface_mesh_item_priv::B_Border_Edges].allocate(d->border_edges_buffer.data(),
static_cast<int>(d->border_edges_buffer.size()*sizeof(float)));
d->program->enableAttributeArray("vertex");
d->program->setAttributeBuffer("vertex",GL_FLOAT,0,3);
d->program->disableAttributeArray("colors");
buffers[Scene_textured_surface_mesh_item_priv::B_Border_Edges].release();
vaos[Scene_textured_surface_mesh_item_priv::Border_edges]->release();
d->program->release();
itemChanged();
}

View File

@ -0,0 +1,65 @@
#ifndef SCENE_TEXTURED_SURFACE_MESH_ITEM_H
#define SCENE_TEXTURED_SURFACE_MESH_ITEM_H
#include <CGAL/Three/Scene_item.h>
#include <CGAL/Three/Viewer_interface.h>
#include "SMesh_type.h"
#include <iostream>
#include "texture.h"
#ifdef scene_textured_surface_mesh_item_EXPORTS
# define SCENE_TEXTURED_SURFACE_MESH_ITEM_EXPORT Q_DECL_EXPORT
#else
# define SCENE_TEXTURED_SURFACE_MESH_ITEM_EXPORT Q_DECL_IMPORT
#endif
struct Scene_textured_surface_mesh_item_priv;
// This class represents a textured polyhedron in the OpenGL scene
class SCENE_TEXTURED_SURFACE_MESH_ITEM_EXPORT Scene_textured_surface_mesh_item
: public CGAL::Three::Scene_item {
Q_OBJECT
public:
Scene_textured_surface_mesh_item();
// Scene_textured_surface_mesh_item(const Scene_textured_surface_mesh_item&);
Scene_textured_surface_mesh_item(const SMesh& p);
Scene_textured_surface_mesh_item(SMesh* const p);
~Scene_textured_surface_mesh_item();
Scene_textured_surface_mesh_item* clone() const;
// IO
bool load(std::istream& in);
bool save(std::ostream& out) const;
// Function for displaying meta-data of the item
virtual QString toolTip() const;
// Indicate if rendering mode is supported
virtual bool supportsRenderingMode(RenderingMode m) const { return (m != Splatting && m != PointsPlusNormals && m != Points && m != Gouraud && m != ShadedPoints); }
// Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list
void draw() const {}
virtual void draw(CGAL::Three::Viewer_interface*) const;
virtual void drawEdges() const {}
virtual void drawEdges(CGAL::Three::Viewer_interface* viewer) const;
// Get wrapped textured_polyhedron
SMesh* textured_face_graph();
const SMesh* textured_face_graph() const;
// Get dimensions
bool isFinite() const { return true; }
bool isEmpty() const;
void compute_bbox() const;
virtual void invalidateOpenGLBuffers();
virtual void selection_changed(bool);
void add_border_edges(std::vector<float> border_edges);
Q_SIGNALS:
void selectionChanged();
protected:
friend struct Scene_textured_surface_mesh_item_priv;
Scene_textured_surface_mesh_item_priv* d;
}; // end class Scene_textured_surface_mesh_item
#endif // SCENE_TEXTURED_SURFACE_MESH_ITEM_H