use PMP for corefinement and intersection plugins

This commit is contained in:
Sébastien Loriot 2017-01-11 15:16:03 +01:00
parent 6368ae3784
commit 6ac45f820a
11 changed files with 358 additions and 1086 deletions

View File

@ -336,9 +336,9 @@ boolean_operation( TriangleMesh& tm1,
Corefinement::No_mark<TriangleMesh>//default
> ::type Ecm2;
Ecm1 ecm1 = boost::choose_param( get_param(np1, edge_is_constrained),
Ecm1 ecm1 = boost::choose_param( boost::get_param(np1, edge_is_constrained),
Corefinement::No_mark<TriangleMesh>() );
Ecm2 ecm2 = boost::choose_param( get_param(np2, edge_is_constrained),
Ecm2 ecm2 = boost::choose_param( boost::get_param(np2, edge_is_constrained),
Corefinement::No_mark<TriangleMesh>() );
typedef Corefinement::Ecm_bind<TriangleMesh, Ecm1, Ecm2> Ecm_in;

View File

@ -237,10 +237,6 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
# special
target_link_libraries(scene_polyhedron_transform_item scene_polyhedron_item)
add_item(scene_combinatorial_map_item Plugins/Operations_on_polyhedra/Scene_combinatorial_map_item.cpp)
# special
target_link_libraries(scene_combinatorial_map_item scene_polyhedron_item)
add_item(scene_polylines_item Scene_polylines_item.cpp)
target_link_libraries(scene_polylines_item scene_basic_objects)

View File

@ -2,9 +2,5 @@ include( polyhedron_demo_macros )
qt5_wrap_ui( clip_polyhedronUI_FILES Clip_polyhedron_plugin.ui )
polyhedron_demo_plugin(clip_polyhedron_plugin Clip_polyhedron_plugin ${clip_polyhedronUI_FILES})
target_link_libraries(clip_polyhedron_plugin scene_polyhedron_item scene_basic_objects)
polyhedron_demo_plugin(corefinement_plugin Corefinement_plugin)
target_link_libraries(corefinement_plugin scene_polyhedron_item scene_combinatorial_map_item scene_polylines_item)
polyhedron_demo_plugin(intersection_plugin Intersection_plugin)
target_link_libraries(intersection_plugin scene_polyhedron_item scene_polylines_item)
polyhedron_demo_plugin(point_set_from_vertices_plugin Point_set_from_vertices_plugin)
target_link_libraries(point_set_from_vertices_plugin scene_polyhedron_item scene_polygon_soup_item scene_points_with_normal_item)

View File

@ -1,181 +0,0 @@
#define CGAL_COREFINEMENT_DO_REPORT_SELF_INTERSECTIONS
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/corefinement_operations.h>
#include <CGAL/bounding_box.h>
#include "Scene_polyhedron_item.h"
#include "Scene_combinatorial_map_item.h"
#include "Polyhedron_type.h"
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include "Scene_polylines_item.h"
#include <QString>
#include <QAction>
#include <QMenu>
#include <QMainWindow>
#include <QApplication>
#include <QTime>
#include <QMessageBox>
//#define PRINT_EACH_VOLUME
using namespace CGAL::Three;
class Polyhedron_demo_corefinement_plugin :
public QObject,
public Polyhedron_demo_plugin_interface
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
public:
bool applicable(QAction*) const {
return qobject_cast<Scene_polyhedron_item*>(scene->item(scene->mainSelectionIndex()));
}
QList<QAction*> actions() const {
return QList<QAction*>() << actionPolyhedronCorefinement_3;
}
void init(QMainWindow* mw, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) {
this->scene = scene_interface;
actionPolyhedronCorefinement_3 = new QAction("Polyhedra Corefinement (A/B)", mw);
actionPolyhedronCorefinement_3->setProperty("subMenuName", "Operations on Polyhedra");
if(actionPolyhedronCorefinement_3) {
connect(actionPolyhedronCorefinement_3, SIGNAL(triggered()),
this, SLOT(corefinement()));
}
}
private:
QAction* actionPolyhedronCorefinement_3;
Scene_interface *scene;
public Q_SLOTS:
void corefinement();
}; // end class Polyhedron_demo_corefinement_plugin
struct Is_on_polyline{
bool operator()(Polyhedron::Halfedge_handle he) const {
return he->is_feature_edge();
}
};
struct Set_vertex_corner{
template <typename Info>
void add_info_to_node(int, Polyhedron*,const Info&) {
}
void operator()(Polyhedron::Vertex_handle v, int, Polyhedron*) {
++v->nb_of_feature_edges;
}
};
void Polyhedron_demo_corefinement_plugin::corefinement()
{
int indexA = scene->selectionAindex();
int indexB = scene->selectionBindex();
Scene_polyhedron_item* itemA =
qobject_cast<Scene_polyhedron_item*>(scene->item(indexA));
Scene_polyhedron_item* itemB =
qobject_cast<Scene_polyhedron_item*>(scene->item(indexB));
if(!itemA || !itemB || itemA == itemB)
{
Q_FOREACH(int index, scene->selectionIndices()) {
Scene_polyhedron_item* item =
qobject_cast<Scene_polyhedron_item*>(scene->item(index));
if(!item)
return;
}
if(scene->selectionIndices().size() == 2) {
indexA = scene->selectionIndices()[0];
indexB = scene->selectionIndices()[1];
itemA =
qobject_cast<Scene_polyhedron_item*>(scene->item(indexA));
itemB =
qobject_cast<Scene_polyhedron_item*>(scene->item(indexB));
}
}
std::vector<Polyhedron*> poly_ptrs;
Q_FOREACH(int index, scene->selectionIndices()) {
Scene_polyhedron_item* item =
qobject_cast<Scene_polyhedron_item*>(scene->item(index));
if(!item)
return;
else if(item != itemA) {
poly_ptrs.push_back(item->polyhedron());
if(poly_ptrs.back() == 0) return;
}
}
QApplication::setOverrideCursor(Qt::WaitCursor);
if(itemA && itemB && itemA != itemB) {
// perform Boolean operation
QTime time;
time.start();
//since the visitor modify input polyhedra, we make copies.
Polyhedron A( *itemA->polyhedron() );
Polyhedron B( *itemB->polyhedron() );
itemA->setVisible(false);
itemB->setVisible(false);
Scene_polylines_item* new_item = new Scene_polylines_item();
#ifdef _COREFINEMENT_OUTPUT_IS_POLYHEDRON
typedef CGAL::Polyhedron_corefinement<Polyhedron> Corefinement;
Corefinement corefinement;
typedef std::list<std::pair<Polyhedron*,int> > Decomposition;
Decomposition decomposition;
#ifndef PRINT_EACH_VOLUME
int features=Corefinement::Join_tag+Corefinement::Intersection_tag+Corefinement::P_minus_Q_tag+Corefinement::Q_minus_P_tag;
#else
int features=Corefinement::Decomposition_tag;
#endif
corefinement(A, B, std::back_inserter(new_item->polylines),std::back_inserter(decomposition),features);
for (Decomposition::iterator it=decomposition.begin();it!=decomposition.end();++it)
{
Polyhedron* new_poly=it->first;
Scene_polyhedron_item* new_item_bool= new Scene_polyhedron_item(new_poly);
new_item_bool->setName(
QString::fromStdString(
corefinement.get_type_str(itemA->name().toStdString(),itemB->name().toStdString(),it->second)
)
);
scene->addItem(new_item_bool);
}
#else
Scene_combinatorial_map_item* cmap_item = new Scene_combinatorial_map_item(scene,static_cast<void*>(&A));
typedef CGAL::Corefinement::Combinatorial_map_output_builder<Polyhedron,Kernel> Output_builder;
typedef CGAL::Node_visitor_refine_polyhedra<Polyhedron,Output_builder,Kernel> Split_visitor;
cmap_item->m_combinatorial_map=boost::shared_ptr<Combinatorial_map_3>( new Combinatorial_map_3() );
Split_visitor visitor( Output_builder(cmap_item->m_combinatorial_map) );
CGAL::Intersection_of_Polyhedra_3<Polyhedron,Kernel,Split_visitor> polyline_intersections(visitor);
polyline_intersections(A, B, std::back_inserter(new_item->polylines));
cmap_item->setName(QString("%1_and_%2_corefined").arg(itemA->name()).arg(itemB->name()));
scene->addItem(cmap_item);
#endif
new_item->setName(tr("boundary intersection"));
new_item->setColor(Qt::green);
new_item->setRenderingMode(Wireframe);
scene->addItem(new_item);
new_item->invalidateOpenGLBuffers();
std::cout << "ok (" << time.elapsed() << " ms)" << std::endl;
}
QApplication::restoreOverrideCursor();
}
#include "Corefinement_plugin.moc"

View File

@ -1,223 +0,0 @@
#define CGAL_COREFINEMENT_DO_REPORT_SELF_INTERSECTIONS
#define CGAL_USE_SEGMENT_APPROACH
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#ifdef CGAL_USE_SEGMENT_APPROACH
#include <CGAL/intersection_of_Polyhedra_3.h>
#else
#include <CGAL/intersection_Polyhedron_3_Polyhedron_3.h>
#endif
#include <CGAL/iterator.h>
#include <CGAL/bounding_box.h>
#include "Scene_polyhedron_item.h"
#include "Polyhedron_type.h"
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include "Scene_polylines_item.h"
#include <boost/foreach.hpp>
#include <QString>
#include <QAction>
#include <QMenu>
#include <QMainWindow>
#include <QApplication>
#include <QTime>
#include <QMessageBox>
using namespace CGAL::Three;
class Polyhedron_demo_intersection_plugin :
public QObject,
public Polyhedron_demo_plugin_interface
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
public:
bool applicable(QAction*) const {
return qobject_cast<Scene_polyhedron_item*>(scene->item(scene->mainSelectionIndex()));
}
QList<QAction*> actions() const {
return QList<QAction*>() << actionPolyhedronIntersection_3;
}
void init(QMainWindow* mw, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) {
this->scene = scene_interface;
actionPolyhedronIntersection_3 = new QAction("Intersect Polyhedra (A/B)", mw);
actionPolyhedronIntersection_3->setProperty("subMenuName", "Operations on Polyhedra");
if(actionPolyhedronIntersection_3) {
connect(actionPolyhedronIntersection_3, SIGNAL(triggered()),
this, SLOT(intersection()));
}
}
private:
QAction* actionPolyhedronIntersection_3;
Scene_interface *scene;
public Q_SLOTS:
void intersection();
}; // end class Polyhedron_demo_intersection_plugin
#ifdef CGAL_USE_SEGMENT_APPROACH
struct Is_on_polyline{
bool operator()(Polyhedron::Halfedge_handle he) const {
return he->is_feature_edge();
}
};
struct Set_vertex_corner{
template <typename Info>
void add_info_to_node(int, Polyhedron*,const Info&) {
}
void operator()(Polyhedron::Vertex_handle v, int, Polyhedron*) {
++v->nb_of_feature_edges;
}
};
#endif
void Polyhedron_demo_intersection_plugin::intersection()
{
int indexA = scene->selectionAindex();
int indexB = scene->selectionBindex();
Scene_polyhedron_item* itemA =
qobject_cast<Scene_polyhedron_item*>(scene->item(indexA));
Scene_polyhedron_item* itemB =
qobject_cast<Scene_polyhedron_item*>(scene->item(indexB));
if(!itemA || !itemB || itemA == itemB)
{
Q_FOREACH(int index, scene->selectionIndices()) {
Scene_polyhedron_item* item =
qobject_cast<Scene_polyhedron_item*>(scene->item(index));
if(!item)
return;
}
if(scene->selectionIndices().size() == 2) {
indexA = scene->selectionIndices()[0];
indexB = scene->selectionIndices()[1];
itemA =
qobject_cast<Scene_polyhedron_item*>(scene->item(indexA));
itemB =
qobject_cast<Scene_polyhedron_item*>(scene->item(indexB));
}
}
#ifndef CGAL_USE_SEGMENT_APPROACH
if(!itemA || !itemB || itemA == itemB)
return;
#else
std::vector<Polyhedron*> poly_ptrs;
Q_FOREACH(int index, scene->selectionIndices()) {
Scene_polyhedron_item* item =
qobject_cast<Scene_polyhedron_item*>(scene->item(index));
if(!item)
return;
else if(item != itemA) {
poly_ptrs.push_back(item->polyhedron());
if(poly_ptrs.back() == 0) return;
}
}
#endif
QApplication::setOverrideCursor(Qt::WaitCursor);
Scene_polylines_item* new_item = new Scene_polylines_item();
// perform Boolean operation
QTime time;
time.start();
#ifdef CGAL_USE_SEGMENT_APPROACH
typedef CGAL::Node_visitor_for_polyline_split<Polyhedron,
Is_on_polyline, Set_vertex_corner> Split_visitor;
CGAL::Intersection_of_Polyhedra_3<Polyhedron,
Kernel,
Split_visitor> polyline_intersections;
typedef std::pair<Polyhedron::Facet_handle,
Polyhedron::Facet_handle> Pair_of_facet_handles;
typedef std::vector<Pair_of_facet_handles> Polyline_info;
typedef std::vector<Polyline_info> Polylines_infos;
Polylines_infos polylines_infos;
typedef Scene_polylines_item::Polylines_container Polylines_container;
typedef std::back_insert_iterator<Polylines_container> To_container;
typedef std::back_insert_iterator<Polylines_infos> To_infos;
To_container to_container(new_item->polylines);
To_infos to_infos(polylines_infos);
CGAL::Dispatch_output_iterator<
CGAL::cpp11::tuple<Polylines_container::value_type,
Polyline_info>,
CGAL::cpp11::tuple<To_container,
To_infos> > out_iterator(to_container,
to_infos);
if(itemA && itemB && itemA != itemB) {
Polyhedron* A = itemA->polyhedron();
Polyhedron* B = itemB->polyhedron();
polyline_intersections(*A, *B, out_iterator);
} else {
if(itemA) {
Polyhedron* A = itemA->polyhedron();
polyline_intersections(*A,
poly_ptrs.begin(),
poly_ptrs.end(),
out_iterator,
0);
} else {
polyline_intersections(poly_ptrs.begin(),
poly_ptrs.end(),
out_iterator,
0);
}
}
QStringList polylines_metadata;
BOOST_FOREACH(Polyline_info& info, polylines_infos) {
std::set<int> indices;
BOOST_FOREACH(Pair_of_facet_handles p, info)
{
indices.insert(p.first->patch_id());
indices.insert(p.second->patch_id());
}
QString metadata;
BOOST_FOREACH(int index, indices) {
metadata = metadata + QString(" %1").arg(index);
}
std::cerr << "new polyline metadata: " << qPrintable(metadata) << "\n";
polylines_metadata << metadata;
}
new_item->setProperty("polylines metadata", polylines_metadata);
new_item->setName(tr("intersection"));
#else
Polyhedron* A = itemA->polyhedron();
Polyhedron* B = itemB->polyhedron();
CGAL::intersection_Polyhedron_3_Polyhedron_3(*A, *B, std::back_inserter(new_item->polylines));
QString name = tr("%1 intersection %2");
new_item->setName(name.arg(itemA->name(), itemB->name()));
itemA->setRenderingMode(Wireframe);
itemB->setRenderingMode(Wireframe);
scene->itemChanged(indexA);
scene->itemChanged(indexB);
#endif
std::cout << "ok (" << time.elapsed() << " ms)" << std::endl;
if (new_item->polylines.empty())
delete new_item;
else{
new_item->setColor(Qt::green);
new_item->setRenderingMode(Wireframe);
scene->addItem(new_item);
new_item->invalidateOpenGLBuffers();
}
QApplication::restoreOverrideCursor();
}
#include "Intersection_plugin.moc"

View File

@ -1,579 +0,0 @@
#include "Scene_combinatorial_map_item.h"
#include "Scene_polyhedron_item.h"
#include <CGAL/Three/Scene_interface.h>
#include <CGAL/Three/Viewer_interface.h>
#include <QObject>
#include <QMenu>
#include <QAction>
#include <QtDebug>
#include <QApplication>
#include <QDebug>
#include <QKeyEvent>
#include <CGAL/corefinement_operations.h>
struct Scene_combinatorial_map_item_priv
{
Scene_combinatorial_map_item_priv(CGAL::Three::Scene_interface* scene, void* ad_A, Scene_combinatorial_map_item* parent)
:last_known_scene(scene),volume_to_display(0),exportSelectedVolume(NULL),address_of_A(ad_A)
{
item = parent;
item->are_buffers_filled = false;
nb_points = 0;
nb_lines =0;
nb_facets =0;
}
Kernel::Vector_3 compute_face_normal(Combinatorial_map_3::Dart_const_handle adart) const;
template <class Predicate>
void export_as_polyhedron(Predicate,const QString&) const;
void initialize_buffers(CGAL::Three::Viewer_interface *viewer) const;
void compute_elements(void) const;
Scene_combinatorial_map_item *item;
enum VAOs {
Edges = 0,
Points,
Facets,
NbOfVaos
};
enum VBOs {
Edges_vertices = 0,
Points_vertices,
Facets_vertices,
Facets_normals,
NbOfVbos
};
CGAL::Three::Scene_interface* last_known_scene;
std::size_t volume_to_display;
QAction* exportSelectedVolume;
void* address_of_A;
mutable QOpenGLShaderProgram *program;
mutable std::vector<double> positions_lines;
mutable std::vector<double> positions_points;
mutable std::vector<double> positions_facets;
mutable std::vector<double> normals;
mutable std::size_t nb_lines;
mutable std::size_t nb_points;
mutable std::size_t nb_facets;
};
Scene_combinatorial_map_item::Scene_combinatorial_map_item(CGAL::Three::Scene_interface* scene,void* address){d = new Scene_combinatorial_map_item_priv(scene, address, this);}
Scene_combinatorial_map_item::~Scene_combinatorial_map_item(){delete d;}
Scene_combinatorial_map_item* Scene_combinatorial_map_item::clone() const{return NULL;}
Kernel::Vector_3 Scene_combinatorial_map_item_priv::compute_face_normal(Combinatorial_map_3::Dart_const_handle adart) const
{
typedef Combinatorial_map_3::Dart_of_orbit_const_range<1> Dart_in_facet_range;
typedef Kernel::Vector_3 Vector_3;
Vector_3 normal = CGAL::NULL_VECTOR;
Dart_in_facet_range vertices=item->combinatorial_map().darts_of_orbit<1>(adart);
Kernel::Point_3 points[3];
int index=0;
Dart_in_facet_range::const_iterator pit=vertices.begin();
for (;pit!=vertices.end() && index!=3;++pit,++index ){
points[index]=item->combinatorial_map().attribute<0>(pit)->point();
}
if (index!=3) return normal;
do{
Vector_3 n = CGAL::cross_product(points[2]-points[1],points[0]-points[1]);
if (n != Vector_3(0,0,0) )
normal = normal + (n / std::sqrt(n*n));
points[0]=points[1];
points[1]=points[2];
if ( pit==vertices.end() ) break;
points[2]=item->combinatorial_map().attribute<0>(pit)->point();
++pit;
}while(true);
return normal == Vector_3(0,0,0)? normal : normal / std::sqrt(normal * normal);
}
void Scene_combinatorial_map_item::set_next_volume(){
//Update des vectors faits ici
++d->volume_to_display;
d->volume_to_display=d->volume_to_display%(combinatorial_map().attributes<3>().size()+1);
are_buffers_filled = false;
invalidateOpenGLBuffers();
Q_EMIT itemChanged();
if (d->exportSelectedVolume!=NULL && ( d->volume_to_display==1 || d->volume_to_display==0 ) )
d->exportSelectedVolume->setEnabled(!d->exportSelectedVolume->isEnabled());
}
template <class Predicate>
void Scene_combinatorial_map_item_priv::export_as_polyhedron(Predicate pred,const QString& name) const {
typedef Combinatorial_map_3::Dart_const_handle Dart_handle;
typedef Combinatorial_map_3::One_dart_per_cell_range<3> One_dart_per_vol_range;
typedef CGAL::internal::Import_volume_as_polyhedron<Polyhedron::HalfedgeDS> Volume_import_modifier;
std::vector<Dart_handle> darts;
One_dart_per_vol_range cell_range=item->combinatorial_map().template one_dart_per_cell<3>();
for (One_dart_per_vol_range::const_iterator it = cell_range.begin();it!= cell_range.end() ; ++it )
if ( pred(it) ){
darts.push_back(it);
if (Predicate::only_one_run) break;
}
if (!darts.empty())
{
Volume_import_modifier modifier=Predicate::swap_orientation?
Volume_import_modifier(item->combinatorial_map(),darts.begin(),darts.end(),Predicate::swap_orientation):
Volume_import_modifier(item->combinatorial_map(),darts.begin(),darts.end());
Polyhedron* new_poly=new Polyhedron();
new_poly->delegate(modifier);
Scene_polyhedron_item* new_item = new Scene_polyhedron_item(new_poly);
new_item->setName(name);
last_known_scene->addItem(new_item);
}
}
struct Select_volume{
static const bool only_one_run=true;
static const bool swap_orientation=false;
Select_volume(std::size_t i):volume_to_select(i),index(0){}
template <class Dart_handle>
bool operator() (Dart_handle){
return ++index==volume_to_select;
}
private:
std::size_t volume_to_select;
std::size_t index;
};
void Scene_combinatorial_map_item::export_current_volume_as_polyhedron() const {
if (d->volume_to_display==0) return; //no volume selected
Select_volume predicate(d->volume_to_display);
d->export_as_polyhedron(predicate,QString("%1_%2").arg(this->name()).arg(d->volume_to_display-1));
}
struct Select_union{
const Combinatorial_map_3& map;
Select_union(const Combinatorial_map_3& m) : map(m) {}
static const bool only_one_run=false;
static const bool swap_orientation=true;
template <class Dart_handle>
bool operator() (Dart_handle d){ return map.template attribute<3>(d)->info().outside.size()==2; }
};
struct Select_inter{
const Combinatorial_map_3& map;
Select_inter(const Combinatorial_map_3& m) : map(m) {}
static const bool only_one_run=false;
static const bool swap_orientation=false;
template <class Dart_handle>
bool operator() (Dart_handle d){ return map.template attribute<3>(d)->info().inside.size()==2; }
};
struct Select_A_minus_B{
const Combinatorial_map_3& map;
static const bool only_one_run=false;
static const bool swap_orientation=false;
Select_A_minus_B(const Combinatorial_map_3& m, void* address):map(m), address_of_A(address){}
template <class Dart_handle>
bool operator() (Dart_handle d){
return map.template attribute<3>(d)->info().inside.size()==1 &&
static_cast<void*>(*map.template attribute<3>(d)->info().inside.begin())==address_of_A;
}
private:
void* address_of_A;
};
struct Select_B_minus_A{
const Combinatorial_map_3& map;
static const bool only_one_run=false;
static const bool swap_orientation=false;
Select_B_minus_A(const Combinatorial_map_3& m, void* address):map(m), address_of_A(address){}
template <class Dart_handle>
bool operator() (Dart_handle d){
return map.template attribute<3>(d)->info().inside.size()==1 &&
static_cast<void*>(*map.template attribute<3>(d)->info().inside.begin())!=address_of_A;
}
private:
void* address_of_A;
};
void Scene_combinatorial_map_item::export_union_as_polyhedron() const {
d->export_as_polyhedron(Select_union(this->combinatorial_map()),QString("%1_union_%2").arg("A").arg("B"));
}
void Scene_combinatorial_map_item::export_intersection_as_polyhedron() const{
d->export_as_polyhedron(Select_inter(this->combinatorial_map()),QString("%1_inter_%2").arg("A").arg("B"));
}
void Scene_combinatorial_map_item::export_A_minus_B_as_polyhedron() const{
Select_A_minus_B predicate(this->combinatorial_map(),d->address_of_A);
d->export_as_polyhedron(predicate,QString("%1_minus_%2").arg("A").arg("B"));
}
void Scene_combinatorial_map_item::export_B_minus_A_as_polyhedron() const{
Select_B_minus_A predicate(this->combinatorial_map(),d->address_of_A);
d->export_as_polyhedron(predicate,QString("%1_minus_%2").arg("B").arg("A"));
}
QMenu* Scene_combinatorial_map_item::contextMenu()
{
const char* prop_name = "Menu modified by Scene_combinatorial_map_item.";
QMenu* menu = Scene_item::contextMenu();
// Use dynamic properties:
// http://doc.qt.io/qt-5/qobject.html#property
bool menuChanged = menu->property(prop_name).toBool();
if(!menuChanged) {
QAction* actionSelectNextVolume =
menu->addAction(tr("Iterate over volumes"));
actionSelectNextVolume->setObjectName("actionSelectNextVolume");
connect(actionSelectNextVolume, SIGNAL(triggered()),this, SLOT(set_next_volume()));
d->exportSelectedVolume =
menu->addAction(tr("Export current volume as polyhedron"));
d->exportSelectedVolume->setObjectName("exportSelectedVolume");
connect(d->exportSelectedVolume, SIGNAL(triggered()),this, SLOT(export_current_volume_as_polyhedron()));
d->exportSelectedVolume->setEnabled(d->volume_to_display!=0);
menu->setProperty(prop_name, true);
if(is_from_corefinement()){
//Export union as polyhedron
QAction* exportUnion =
menu->addAction(tr("Export union as polyhedron"));
exportUnion->setObjectName("exportUnion");
connect(exportUnion, SIGNAL(triggered()),this, SLOT(export_union_as_polyhedron()));
//Export intersection as polyhedron
QAction* exportIntersection =
menu->addAction(tr("Export intersection as polyhedron"));
exportIntersection->setObjectName("exportIntersection");
connect(exportIntersection, SIGNAL(triggered()),this, SLOT(export_intersection_as_polyhedron()));
//Export A minus B as polyhedron
QAction* exportAMinusB =
menu->addAction(tr("Export A minus B as polyhedron"));
exportAMinusB->setObjectName("exportAMinusB");
connect(exportAMinusB, SIGNAL(triggered()),this, SLOT(export_A_minus_B_as_polyhedron()));
//Export B minus A as polyhedron
QAction* exportBMinusA =
menu->addAction(tr("Export B minus A as polyhedron"));
exportBMinusA->setObjectName("exportBMinusA");
connect(exportBMinusA, SIGNAL(triggered()),this, SLOT(export_B_minus_A_as_polyhedron()));
}
}
return menu;
}
bool Scene_combinatorial_map_item::keyPressEvent(QKeyEvent* e){
if (e->key()==Qt::Key_N){
set_next_volume();
return true;
}
return false;
}
void Scene_combinatorial_map_item_priv::compute_elements(void) const{
QApplication::setOverrideCursor(Qt::WaitCursor);
positions_facets.resize(0);
normals.resize(0);
positions_lines.resize(0);
positions_points.resize(0);
//Facets
{
std::size_t index = 0;
Combinatorial_map_3::size_type voltreated
= item->combinatorial_map().get_new_mark();
Combinatorial_map_3::size_type facetreated
= item->combinatorial_map().get_new_mark();
Combinatorial_map_3::Dart_const_range::const_iterator
darts_it=item->combinatorial_map().darts().begin(), darts_end=item->combinatorial_map().darts().end();
for( ; darts_it!=darts_end; ++darts_it)
{
if ( !item->combinatorial_map().is_marked(darts_it,voltreated) )
{
++index;
//iterate over all the darts of the volume
Combinatorial_map_3::Dart_of_cell_const_range<3>::const_iterator
vol_it=item->combinatorial_map().darts_of_cell<3>(darts_it).begin(),
vol_end=item->combinatorial_map().darts_of_cell<3>(darts_it).end();
if ( volume_to_display!=0 && index!=volume_to_display )
{
//only mark darts if the volume is not the one to display
for ( ;vol_it!=vol_end; ++vol_it )
{
item->combinatorial_map().mark(vol_it,facetreated);
item->combinatorial_map().mark(vol_it, voltreated);
}
}
else
{
for ( ;vol_it!=vol_end; ++vol_it )
{
if ( !item->combinatorial_map().is_marked(vol_it,facetreated) )
{
Kernel::Vector_3 normal = compute_face_normal(vol_it);
for(int i=0; i<3; i++)
{
normals.push_back(normal.x());
normals.push_back(normal.y());
normals.push_back(normal.z());
}
//iterate over all darts of facets
for ( Combinatorial_map_3::Dart_of_orbit_const_range<1>::const_iterator
face_it=item->combinatorial_map().darts_of_orbit<1>(vol_it).begin(),
face_end=item->combinatorial_map().darts_of_orbit<1>(vol_it).end();
face_it!=face_end; ++face_it)
{
const Kernel::Point_3& p= item->combinatorial_map().attribute<0>(face_it)->point();
positions_facets.push_back(p.x());
positions_facets.push_back(p.y());
positions_facets.push_back(p.z());
item->combinatorial_map().mark(face_it,facetreated);
item->combinatorial_map().mark(face_it, voltreated);
}
}
}
}
if ( index==volume_to_display ) break;
}
}
//mark remaining darts to have an O(1) free_mark
for( ; darts_it!=darts_end; ++darts_it)
{
item->combinatorial_map().mark(darts_it, facetreated);
item->combinatorial_map().mark(darts_it, voltreated);
}
item->combinatorial_map().free_mark(facetreated);
item->combinatorial_map().free_mark(voltreated);
}
//edges
{
typedef Combinatorial_map_3::One_dart_per_cell_range<1,3> Edge_darts;
Edge_darts darts=item->combinatorial_map().one_dart_per_cell<1>();
for (Edge_darts::const_iterator dit=darts.begin();dit!=darts.end();++dit){
CGAL_assertion(!item->combinatorial_map().is_free(dit,1));
const Kernel::Point_3& a = item->combinatorial_map().attribute<0>(dit)->point();
const Kernel::Point_3& b = item->combinatorial_map().attribute<0>(item->combinatorial_map().beta(dit,1))->point();
positions_lines.push_back(a.x());
positions_lines.push_back(a.y());
positions_lines.push_back(a.z());
positions_lines.push_back(b.x());
positions_lines.push_back(b.y());
positions_lines.push_back(b.z());
}
}
//points
{
typedef Combinatorial_map_3::Attribute_const_range<0>::type Point_range;
const Point_range& points=item->combinatorial_map().attributes<0>();
for(Point_range::const_iterator pit=boost::next(points.begin());pit!=points.end();++pit){
const Kernel::Point_3& p=pit->point();
positions_points.push_back(p.x());
positions_points.push_back(p.y());
positions_points.push_back(p.z());
}
}
QApplication::restoreOverrideCursor();
}
void Scene_combinatorial_map_item_priv::initialize_buffers(CGAL::Three::Viewer_interface *viewer) const
{
//vao for the edges
{
program = item->getShaderProgram(Scene_combinatorial_map_item::PROGRAM_WITHOUT_LIGHT, viewer);
program->bind();
item->vaos[Scene_combinatorial_map_item_priv::Edges]->bind();
item->buffers[Scene_combinatorial_map_item_priv::Edges_vertices].bind();
item->buffers[Scene_combinatorial_map_item_priv::Edges_vertices].allocate(positions_lines.data(),
static_cast<int>(positions_lines.size()*sizeof(double)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_DOUBLE,0,3);
item->buffers[Scene_combinatorial_map_item_priv::Edges_vertices].release();
nb_lines = positions_lines.size();
positions_lines.resize(0);
std::vector<double>(positions_lines).swap(positions_lines);
item->vaos[Scene_combinatorial_map_item_priv::Edges]->release();
program->release();
}
//vao for the points
{
program = item->getShaderProgram(Scene_combinatorial_map_item::PROGRAM_WITHOUT_LIGHT, viewer);
program->bind();
item->vaos[Scene_combinatorial_map_item_priv::Points]->bind();
item->buffers[Scene_combinatorial_map_item_priv::Points_vertices].bind();
item->buffers[Scene_combinatorial_map_item_priv::Points_vertices].allocate(positions_points.data(),
static_cast<int>(positions_points.size()*sizeof(double)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_DOUBLE,0,3);
item->buffers[Scene_combinatorial_map_item_priv::Points_vertices].release();
item->vaos[Scene_combinatorial_map_item_priv::Points]->release();
nb_points = positions_points.size();
positions_points.resize(0);
std::vector<double>(positions_points).swap(positions_points);
program->release();
}
//vao for the facets
{
program = item->getShaderProgram(Scene_combinatorial_map_item::PROGRAM_WITH_LIGHT, viewer);
program->bind();
item->vaos[Scene_combinatorial_map_item_priv::Facets]->bind();
item->buffers[Scene_combinatorial_map_item_priv::Facets_vertices].bind();
item->buffers[Scene_combinatorial_map_item_priv::Facets_vertices].allocate(positions_facets.data(),
static_cast<int>(positions_facets.size()*sizeof(double)));
program->enableAttributeArray("vertex");
program->setAttributeBuffer("vertex",GL_DOUBLE,0,3);
item->buffers[Scene_combinatorial_map_item_priv::Facets_vertices].release();
item->buffers[Scene_combinatorial_map_item_priv::Facets_normals].bind();
item->buffers[Scene_combinatorial_map_item_priv::Facets_normals].allocate(normals.data(),
static_cast<int>(normals.size()*sizeof(double)));
program->enableAttributeArray("normals");
program->setAttributeBuffer("normals",GL_DOUBLE,0,3);
item->buffers[Scene_combinatorial_map_item_priv::Facets_normals].release();
nb_facets = positions_facets.size();
positions_facets.resize(0);
std::vector<double>(positions_facets).swap(positions_facets);
normals.resize(0);
std::vector<double>(normals).swap(normals);
item->vaos[Scene_combinatorial_map_item_priv::Facets]->release();
program->release();
}
item->are_buffers_filled = true;
}
bool Scene_combinatorial_map_item::isEmpty() const {return combinatorial_map().number_of_darts()==0;}
void
Scene_combinatorial_map_item::compute_bbox() const {
typedef Combinatorial_map_3::Attribute_const_range<0>::type Point_range;
const Point_range& points=combinatorial_map().attributes<0>();
CGAL::Bbox_3 bbox=points.begin()->point().bbox();
for(Point_range::const_iterator pit=boost::next(points.begin());pit!=points.end();++pit)
bbox=bbox+pit->point().bbox();
_bbox = Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(),
bbox.xmax(),bbox.ymax(),bbox.zmax());
}
QString Scene_combinatorial_map_item::toolTip() const{
if(!m_combinatorial_map)
return QString();
std::vector<unsigned int> cells(5);
for (unsigned int i=0; i<=4; ++i)
cells[i]=i;
std::vector<unsigned int> res = combinatorial_map().count_cells(cells);
if (d->volume_to_display==0)
return QObject::tr("<p>Combinatorial_map_3 <b>%1</b> (mode: %8, color: %9)</p>"
"<p>Number of darts: %2<br />"
"Number of vertices: %3<br />"
"Number of edges: %4<br />"
"Number of facets: %5<br />"
"Number of volumes: %6<br />"
"Number of connected components: %7</p>")
.arg(this->name())
.arg(combinatorial_map().number_of_darts())
.arg(res[0])
.arg(res[1])
.arg(res[2])
.arg(res[3])
.arg(res[4])
.arg(this->renderingModeName())
.arg(this->color().name());
return QObject::tr("<p>Combinatorial_map_3 <b>%1</b> (mode: %8, color: %9)</p>"
"<p>Number of darts: %2<br />"
"Number of vertices: %3<br />"
"Number of edges: %4<br />"
"Number of facets: %5<br />"
"Number of volumes: %6<br />"
"Number of connected components: %7 <br />"
"Currently Displaying facets of volume: %10 </p>")
.arg(this->name())
.arg(combinatorial_map().number_of_darts())
.arg(res[0])
.arg(res[1])
.arg(res[2])
.arg(res[3])
.arg(res[4])
.arg(this->renderingModeName())
.arg(this->color().name())
.arg(d->volume_to_display-1);
}
void Scene_combinatorial_map_item::draw(CGAL::Three::Viewer_interface* viewer) const
{
if(!are_buffers_filled)
{
d->compute_elements();
d->initialize_buffers(viewer);
}
vaos[Scene_combinatorial_map_item_priv::Facets]->bind();
d->program=getShaderProgram(PROGRAM_WITH_LIGHT);
attribBuffers(viewer,PROGRAM_WITH_LIGHT);
d->program->bind();
d->program->setAttributeValue("colors", this->color());
viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(d->nb_facets/3));
vaos[Scene_combinatorial_map_item_priv::Facets]->release();
d->program->release();
}
void Scene_combinatorial_map_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const
{
if(!are_buffers_filled)
{
d->compute_elements();
d->initialize_buffers(viewer);
}
vaos[Scene_combinatorial_map_item_priv::Edges]->bind();
d->program=getShaderProgram(PROGRAM_WITHOUT_LIGHT);
attribBuffers(viewer,PROGRAM_WITHOUT_LIGHT);
d->program->bind();
d->program->setAttributeValue("colors", this->color());
viewer->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(d->nb_lines/3));
vaos[Scene_combinatorial_map_item_priv::Edges]->release();
d->program->release();
}
void Scene_combinatorial_map_item::drawPoints(CGAL::Three::Viewer_interface* viewer) const
{
if(!are_buffers_filled)
{
d->compute_elements();
d->initialize_buffers(viewer);
}
vaos[Scene_combinatorial_map_item_priv::Points]->bind();
d->program=getShaderProgram(PROGRAM_WITHOUT_LIGHT);
attribBuffers(viewer,PROGRAM_WITHOUT_LIGHT);
d->program->bind();
d->program->setAttributeValue("colors", this->color());
viewer->glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(d->nb_points/3));
vaos[Scene_combinatorial_map_item_priv::Points]->release();
d->program->release();
}
bool Scene_combinatorial_map_item::is_from_corefinement() const{return d->address_of_A!=NULL;}

View File

@ -1,83 +0,0 @@
#ifndef SCENE_COMBINATORIAL_MAP_ITEM_H
#define SCENE_COMBINATORIAL_MAP_ITEM_H
//=========
#include <CGAL/internal/corefinement/Combinatorial_map_for_corefinement.h>
#include "Scene_combinatorial_map_item_config.h"
#include <iostream>
#include <QOpenGLBuffer>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include "Polyhedron_type.h"
#include <CGAL/Three/Scene_item.h>
typedef CGAL::internal_IOP::Item_with_points_and_volume_info<Kernel,Polyhedron> Items;
typedef CGAL::Combinatorial_map<3,Items> Combinatorial_map_3;
//=========
struct Scene_combinatorial_map_item_priv;
class QMenu;
class QAction;
namespace CGAL { namespace Three{
class Scene_interface;
}}
class Scene_polyhedron_item;
class Viewer_interface;
class SCENE_COMBINATORIAL_MAP_ITEM_EXPORT Scene_combinatorial_map_item
: public CGAL::Three::Scene_item
{
Q_OBJECT
public:
Scene_combinatorial_map_item(CGAL::Three::Scene_interface*,void* ad_A=NULL);
~Scene_combinatorial_map_item();
Scene_combinatorial_map_item* clone() const;
// Function to override the context menu
QMenu* contextMenu();
// bool load(std::istream& in);
// void load(Scene_polyhedron_item*);
// bool save(std::ostream& out) const;
QString toolTip() const;
// Indicate if rendering mode is supported
virtual bool supportsRenderingMode(RenderingMode m) const { return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting && m!=ShadedPoints); } // CHECK THIS!
//Event handling
virtual bool keyPressEvent(QKeyEvent*);
//drawing of the scene
virtual void drawEdges(CGAL::Three::Viewer_interface* viewer) const;
virtual void drawPoints(CGAL::Three::Viewer_interface*) const;
virtual void draw(CGAL::Three::Viewer_interface*) const;
bool isFinite() const { return true; }
bool is_from_corefinement() const;
bool isEmpty() const;
void compute_bbox() const;
const Combinatorial_map_3& combinatorial_map() const
{
return *m_combinatorial_map;
}
Combinatorial_map_3& combinatorial_map()
{
return *m_combinatorial_map;
}
boost::shared_ptr<Combinatorial_map_3> m_combinatorial_map;
public Q_SLOTS:
void set_next_volume();
void export_current_volume_as_polyhedron() const;
void export_union_as_polyhedron() const;
void export_intersection_as_polyhedron() const;
void export_A_minus_B_as_polyhedron() const;
void export_B_minus_A_as_polyhedron() const;
protected:
friend struct Scene_combinatorial_map_item_priv;
Scene_combinatorial_map_item_priv* d;
}; // end class Scene_combinatorial_map_item
#endif // SCENE_COMBINATORIAL_MAP_ITEM_H

View File

@ -1,10 +0,0 @@
#ifndef SCENE_COMBINATORIAL_MAP_ITEM_CONFIG_H
#define SCENE_COMBINATORIAL_MAP_ITEM_CONFIG_H
#ifdef scene_combinatorial_map_item_EXPORTS
# define SCENE_COMBINATORIAL_MAP_ITEM_EXPORT Q_DECL_EXPORT
#else
# define SCENE_COMBINATORIAL_MAP_ITEM_EXPORT Q_DECL_IMPORT
#endif
#endif // SCENE_COMBINATORIAL_MAP_ITEM_CONFIG_H

View File

@ -69,6 +69,12 @@ target_link_libraries(self_intersection_plugin scene_polyhedron_item scene_polyh
polyhedron_demo_plugin(triangulate_facets_plugin Triangulate_facets_plugin)
target_link_libraries(triangulate_facets_plugin scene_polyhedron_item)
polyhedron_demo_plugin(corefinement_plugin Corefinement_plugin)
target_link_libraries(corefinement_plugin scene_polyhedron_item)
polyhedron_demo_plugin(surface_intersection_plugin Surface_intersection_plugin)
target_link_libraries(surface_intersection_plugin scene_polyhedron_item scene_polylines_item)
polyhedron_demo_plugin(repair_polyhedron_plugin Repair_polyhedron_plugin)
target_link_libraries(repair_polyhedron_plugin scene_polyhedron_item)

View File

@ -0,0 +1,228 @@
#include <QApplication>
#include <QMainWindow>
#include <QAction>
#include "Messages_interface.h"
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
#include "Scene_polyhedron_item.h"
#include "Polyhedron_type.h"
#include <CGAL/Polygon_mesh_processing/corefinement.h>
using namespace CGAL::Three;
namespace PMP = CGAL::Polygon_mesh_processing;
class Polyhedron_demo_corefinement_plugin :
public QObject,
public Polyhedron_demo_plugin_helper
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
enum bool_op {CRF_UNION, CRF_INTER, CRF_MINUS, CRF_MINUS_OP};
public:
void init(QMainWindow* mainWindow,
CGAL::Three::Scene_interface* scene_interface,
Messages_interface* m) {
this->scene = scene_interface;
this->mw = mainWindow;
this->messages = m;
actionCorefine = new QAction("Corefine", mw);
actionCorefine->setProperty("subMenuName","Polygon Mesh Processing/Corefinement");
if(actionCorefine)
connect(actionCorefine, SIGNAL(triggered()), this, SLOT(corefine()));
actionUnion = new QAction("Compute Union", mw);
actionUnion->setProperty("subMenuName","Polygon Mesh Processing/Corefinement");
if(actionUnion)
connect(actionUnion, SIGNAL(triggered()), this, SLOT(corefine_and_union()));
actionInter = new QAction("Compute Intersection", mw);
actionInter->setProperty("subMenuName","Polygon Mesh Processing/Corefinement");
if(actionInter)
connect(actionInter, SIGNAL(triggered()), this, SLOT(corefine_and_inter()));
actionDiff = new QAction("Compute Difference", mw);
actionDiff->setProperty("subMenuName","Polygon Mesh Processing/Corefinement");
if(actionDiff)
connect(actionDiff, SIGNAL(triggered()), this, SLOT(corefine_and_diff()));
actionDiffRev = new QAction("Compute Opposite Difference", mw);
actionDiffRev->setProperty("subMenuName","Polygon Mesh Processing/Corefinement");
if(actionDiffRev)
connect(actionDiffRev, SIGNAL(triggered()), this, SLOT(corefine_and_diff_rev()));
};
QList<QAction*> actions() const {
return QList<QAction*>() << actionCorefine
<< actionUnion
<< actionInter
<< actionDiff
<< actionDiffRev;
}
bool applicable(QAction*) const {
int nb_selected=0;
Q_FOREACH(CGAL::Three::Scene_interface::Item_id index, scene->selectionIndices())
if ( qobject_cast<Scene_polyhedron_item*>(scene->item(index)) )
++nb_selected;
return nb_selected==2;
}
public Q_SLOTS:
void corefine() {
Scene_polyhedron_item* first_item = NULL;
Q_FOREACH(CGAL::Three::Scene_interface::Item_id index, scene->selectionIndices())
{
Scene_polyhedron_item* item =
qobject_cast<Scene_polyhedron_item*>(scene->item(index));
if(item)
{
if (first_item==NULL)
{
first_item = item;
continue;
}
if(!first_item->polyhedron()->is_pure_triangle()) {
messages->warning(tr("The polyhedron \"%1\" is not triangulated.")
.arg(first_item->name()));
return;
}
if(!item->polyhedron()->is_pure_triangle()) {
messages->warning(tr("The polyhedron \"%1\" is not triangulated.")
.arg(item->name()));
return;
}
QApplication::setOverrideCursor(Qt::WaitCursor);
PMP::corefine(*first_item->polyhedron(), *item->polyhedron());
first_item->invalidateOpenGLBuffers();
item->invalidateOpenGLBuffers();
scene->itemChanged(item);
scene->itemChanged(first_item);
// default cursor
QApplication::restoreOverrideCursor();
break;
} // end of if(item)
} // end of the loop on the selected items
}
void corefine_and_bool_op(bool_op op)
{
Scene_polyhedron_item* first_item = NULL;
Q_FOREACH(CGAL::Three::Scene_interface::Item_id index, scene->selectionIndices())
{
Scene_polyhedron_item* item =
qobject_cast<Scene_polyhedron_item*>(scene->item(index));
if(item)
{
if (first_item==NULL)
{
first_item = item;
continue;
}
if(!first_item->polyhedron()->is_pure_triangle()) {
messages->warning(tr("The polyhedron \"%1\" is not triangulated.")
.arg(first_item->name()));
return;
}
if(!item->polyhedron()->is_pure_triangle()) {
messages->warning(tr("The polyhedron \"%1\" is not triangulated.")
.arg(item->name()));
return;
}
QApplication::setOverrideCursor(Qt::WaitCursor);
Polyhedron* new_poly = new Polyhedron();
QString str_op;
Polyhedron P, Q;
switch(op)
{
case CRF_UNION:
P = *first_item->polyhedron(), Q = *item->polyhedron();
if (! PMP::corefine_and_compute_union(P, Q, *new_poly) )
{
delete new_poly;
messages->warning(tr("The result of the requested operation is not manifold and has not been computed."));
return;
}
str_op = "Union";
break;
case CRF_INTER:
P = *first_item->polyhedron(), Q = *item->polyhedron();
if (! PMP::corefine_and_compute_intersection(P, Q, *new_poly) )
{
delete new_poly;
messages->warning(tr("The result of the requested operation is not manifold and has not been computed."));
return;
}
str_op = "Intersection";
break;
case CRF_MINUS_OP:
std::swap(first_item, item);
case CRF_MINUS:
P = *first_item->polyhedron(), Q = *item->polyhedron();
if (! PMP::corefine_and_compute_difference(P, Q, *new_poly) )
{
delete new_poly;
messages->warning(tr("The result of the requested operation is not manifold and has not been computed."));
return;
}
str_op = "Difference";
break;
}
first_item->invalidateOpenGLBuffers();
item->invalidateOpenGLBuffers();
scene->itemChanged(item);
scene->itemChanged(first_item);
Scene_polyhedron_item* new_item = new Scene_polyhedron_item(new_poly);
new_item->setName(QString("%1 of %2 and %3").arg(str_op).arg(first_item->name()).arg(item->name()));
new_item->setColor(first_item->color());
new_item->setRenderingMode(first_item->renderingMode());
new_item->setVisible(first_item->visible());
scene->addItem(new_item);
new_item->invalidateOpenGLBuffers();
// default cursor
QApplication::restoreOverrideCursor();
break;
} // end of if(item)
} // end of the loop on the selected items
}
void corefine_and_union()
{
corefine_and_bool_op(CRF_UNION);
}
void corefine_and_inter()
{
corefine_and_bool_op(CRF_INTER);
}
void corefine_and_diff()
{
corefine_and_bool_op(CRF_MINUS);
}
void corefine_and_diff_rev()
{
corefine_and_bool_op(CRF_MINUS_OP);
}
private:
QAction* actionCorefine;
QAction* actionUnion;
QAction* actionInter;
QAction* actionDiff;
QAction* actionDiffRev;
Messages_interface* messages;
};
#include "Corefinement_plugin.moc"

View File

@ -0,0 +1,122 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polygon_mesh_processing/intersection.h>
#include "Scene_polyhedron_item.h"
#include "Polyhedron_type.h"
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include "Scene_polylines_item.h"
#include <boost/foreach.hpp>
#include <QString>
#include <QAction>
#include <QMenu>
#include <QMainWindow>
#include <QApplication>
#include <QTime>
#include <QMessageBox>
using namespace CGAL::Three;
namespace PMP = CGAL::Polygon_mesh_processing;
class Polyhedron_demo_intersection_plugin :
public QObject,
public Polyhedron_demo_plugin_interface
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
public:
bool applicable(QAction*) const {
int nb_selected=0;
Q_FOREACH(CGAL::Three::Scene_interface::Item_id index, scene->selectionIndices())
if ( qobject_cast<Scene_polyhedron_item*>(scene->item(index)) )
++nb_selected;
return nb_selected==2;
}
QList<QAction*> actions() const {
return QList<QAction*>() << actionPolyhedronIntersection_3;
}
void init(QMainWindow* mw, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) {
this->scene = scene_interface;
actionPolyhedronIntersection_3 = new QAction("Surface Intersection", mw);
actionPolyhedronIntersection_3->setProperty("subMenuName", "Polygon Mesh Processing");
if(actionPolyhedronIntersection_3) {
connect(actionPolyhedronIntersection_3, SIGNAL(triggered()),
this, SLOT(intersection()));
}
}
private:
QAction* actionPolyhedronIntersection_3;
Scene_interface *scene;
public Q_SLOTS:
void intersection();
}; // end class Polyhedron_demo_intersection_plugin
void Polyhedron_demo_intersection_plugin::intersection()
{
Scene_polyhedron_item* itemA = NULL;
Q_FOREACH(CGAL::Three::Scene_interface::Item_id index, scene->selectionIndices())
{
Scene_polyhedron_item* itemB =
qobject_cast<Scene_polyhedron_item*>(scene->item(index));
if(itemB)
{
if (itemA==NULL)
{
itemA = itemB;
continue;
}
QApplication::setOverrideCursor(Qt::WaitCursor);
Scene_polylines_item* new_item = new Scene_polylines_item();
// perform Boolean operation
QTime time;
time.start();
try{
PMP::surface_intersection(*itemA->polyhedron(),
*itemB->polyhedron(),
std::back_inserter(new_item->polylines),
true);
}
catch(CGAL::Corefinement::Self_intersection_exception)
{
QMessageBox::warning((QWidget*)NULL,
tr("Self-intersections Found"),
tr("Some self-intersections were found amongst intersecting facets"));
delete new_item;
QApplication::restoreOverrideCursor();
return;
}
QString name = tr("%1 intersection %2");
new_item->setName(name.arg(itemA->name(), itemB->name()));
std::cout << "ok (" << time.elapsed() << " ms)" << std::endl;
if (new_item->polylines.empty())
delete new_item;
else{
new_item->setColor(Qt::green);
new_item->setRenderingMode(Wireframe);
scene->addItem(new_item);
new_item->invalidateOpenGLBuffers();
}
QApplication::restoreOverrideCursor();
}
}
}
#include "Surface_intersection_plugin.moc"