// Copyright (c) 2010 CNRS, LIRIS, http://liris.cnrs.fr/, All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; version 2.1 of the License. // See the file LICENSE.LGPL distributed with CGAL. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // Author(s) : Guillaume Damiand // #include "MainWindow.h" #include // Function defined in map_3_subivision.cpp void subdivide_map_3 (Map & m); #define DELAY_STATUSMSG 1500 MainWindow::MainWindow (QWidget * parent):CGAL::Qt::DemosMainWindow (parent), nbcube (0), tdsdart(NULL), dialogmesh(this) { setupUi (this); scene.map = new Map; this->viewer->setScene (&scene); connectActions (); this->addAboutDemo (":/cgal/help/about_Combinatorial_map_3.html"); this->addAboutCGAL (); this->addRecentFiles (this->menuFile, this->actionQuit); connect (this, SIGNAL (openRecentFile (QString)), this, SLOT (load_off (QString))); statusMessage = new QLabel ("Darts: 0, Vertices: 0 (Points: 0), Edges: 0, Facets: 0," " Volume: 0 (Vol color: 0), Connected components: 0"); statusBar ()->addWidget (statusMessage); } void MainWindow::connectActions () { QObject::connect (this->actionImportOFF, SIGNAL (triggered ()), this, SLOT (import_off ())); QObject::connect (this->actionAddOFF, SIGNAL (triggered ()), this, SLOT (add_off ())); QObject::connect (this->actionImport3DTDS, SIGNAL (triggered ()), this, SLOT (import_3DTDS ())); QObject::connect (this->actionQuit, SIGNAL (triggered ()), qApp, SLOT (quit ())); QObject::connect (this->actionSubdivide, SIGNAL (triggered ()), this, SLOT (subdivide ())); QObject::connect (this->actionCreate_cube, SIGNAL (triggered ()), this, SLOT (create_cube ())); QObject::connect (this->actionCreate_mesh, SIGNAL (triggered ()), this, SLOT (create_mesh ())); QObject::connect (this->actionCreate3Cubes, SIGNAL (triggered ()), this, SLOT (create_3cubes ())); QObject::connect (this->actionCreate2Volumes, SIGNAL (triggered ()), this, SLOT (create_2volumes ())); QObject::connect (this, SIGNAL (sceneChanged ()), this, SLOT (onSceneChanged ())); QObject::connect (this->actionClear, SIGNAL (triggered ()), this, SLOT (clear ())); QObject::connect (this->actionDual_3, SIGNAL (triggered ()), this, SLOT (dual_3 ())); QObject::connect (this->actionClose_volume, SIGNAL (triggered ()), this, SLOT (close_volume ())); QObject::connect (this->actionRemove_current_volume, SIGNAL (triggered ()), this, SLOT (remove_current_volume ())); QObject::connect (this->actionSew3_same_facets, SIGNAL (triggered ()), this, SLOT (sew3_same_facets ())); QObject::connect (this->actionUnsew3_all, SIGNAL (triggered ()), this, SLOT (unsew3_all ())); QObject::connect (this->actionTriangulate_all_facets, SIGNAL (triggered ()), this, SLOT (triangulate_all_facets ())); } void MainWindow::onSceneChanged () { int mark = scene.map->get_new_mark (); scene.map->negate_mark (mark); std::vector cells; cells.push_back(0); cells.push_back(1); cells.push_back(2); cells.push_back(3); cells.push_back(4); std::vector res = scene.map->count_cells (cells); std::ostringstream os; os << "Darts: " << scene.map->number_of_darts () << ", Vertices:" << res[0] <<", (Points:"<number_of_attributes<0>()<<")" << ", Edges:" << res[1] << ", Facets:" << res[2] << ", Volumes:" << res[3] #ifdef COLOR_VOLUME <<", (Vol color:"<number_of_attributes<3>()<<")" #endif << ", Connected components:" << res[4] <<", Valid:"<<(scene.map->is_valid()?"true":"FALSE"); scene.map->negate_mark (mark); scene.map->free_mark (mark); viewer->sceneChanged (); statusMessage->setText (os.str().c_str ()); } void MainWindow::import_off () { QString fileName = QFileDialog::getOpenFileName (this, tr ("Import OFF"), "./off", tr ("off files (*.off)")); if (!fileName.isEmpty ()) { load_off (fileName, true); } } void MainWindow::import_3DTDS () { QString fileName = QFileDialog::getOpenFileName (this, tr ("Import 3DTDS"), ".", tr ("Data file (*)")); if (!fileName.isEmpty ()) { load_3DTDS (fileName, true); statusBar ()->showMessage (QString ("Import 3DTDS file") + fileName, DELAY_STATUSMSG); } } void MainWindow::add_off () { QString fileName = QFileDialog::getOpenFileName (this, tr ("Add OFF"), "./off", tr ("off files (*.off)")); if (!fileName.isEmpty ()) { load_off (fileName, false); } } void MainWindow::load_off (const QString & fileName, bool clear) { QApplication::setOverrideCursor (Qt::WaitCursor); if (clear) scene.map->clear (); std::ifstream ifs (qPrintable (fileName)); CGAL::import_from_polyhedron_flux < Map > (*scene.map, ifs); initAllVolumesRandomColor(); this->addToRecentFiles (fileName); QApplication::restoreOverrideCursor (); if (clear) statusBar ()->showMessage (QString ("Load off file") + fileName, DELAY_STATUSMSG); else statusBar ()->showMessage (QString ("Add off file") + fileName, DELAY_STATUSMSG); tdsdart = NULL; emit (sceneChanged ()); } void MainWindow::initVolumeRandomColor(Dart_handle adart) { #ifdef COLOR_VOLUME scene.map->set_attribute<3>(adart,scene.map->create_attribute<3>(CGAL::Color(random.get_int(0,256), random.get_int(0,256), random.get_int(0,256)))); #endif } void MainWindow::initAllVolumesRandomColor() { #ifdef COLOR_VOLUME for (Map::One_dart_per_cell_range<3>::iterator it(scene.map->one_dart_per_cell<3>().begin()); it.cont(); ++it) if ( it->attribute<3>()==NULL ) initVolumeRandomColor(it); #endif } void MainWindow::load_3DTDS (const QString & fileName, bool clear) { QApplication::setOverrideCursor (Qt::WaitCursor); if (clear) scene.map->clear (); typedef CGAL::Delaunay_triangulation_3 < Map::Traits > Triangulation; Triangulation T; std::ifstream ifs (qPrintable (fileName)); std::istream_iterator < Point_3 > begin (ifs), end; T.insert (begin, end); tdsdart = CGAL::import_from_triangulation_3 < Map, Triangulation > (*scene.map, T); initAllVolumesRandomColor(); QApplication::restoreOverrideCursor (); emit (sceneChanged ()); } Dart_handle MainWindow::make_iso_cuboid(const Point_3 basepoint, Map::FT lg) { return make_hexahedron(*scene.map, basepoint, Map::Construct_translated_point()(basepoint,Map::Vector(lg,0,0)), Map::Construct_translated_point()(basepoint,Map::Vector(lg,lg,0)), Map::Construct_translated_point()(basepoint,Map::Vector(0,lg,0)), Map::Construct_translated_point()(basepoint,Map::Vector(0,lg,lg)), Map::Construct_translated_point()(basepoint,Map::Vector(0,0,lg)), Map::Construct_translated_point()(basepoint,Map::Vector(lg,0,lg)), Map::Construct_translated_point()(basepoint,Map::Vector(lg,lg,lg))); } void MainWindow::create_cube () { Point_3 basepoint(nbcube%5, (nbcube/5)%5, nbcube/25); Dart_handle d = make_iso_cuboid(basepoint, 1); // scene.map->display_characteristics(std::cout)<showMessage (QString ("Cube created"),DELAY_STATUSMSG); emit (sceneChanged ()); } void MainWindow::create_3cubes () { Dart_handle d1 = make_iso_cuboid (Point_3 (nbcube, nbcube, nbcube),1); Dart_handle d2 = make_iso_cuboid (Point_3 (nbcube + 1, nbcube, nbcube),1); Dart_handle d3 = make_iso_cuboid (Point_3 (nbcube, nbcube + 1, nbcube), 1); initVolumeRandomColor(d1); initVolumeRandomColor(d2); initVolumeRandomColor(d3); scene.map->sew<3> (d1->beta(1)->beta(1)->beta(2), d2->beta(2)); scene.map->sew<3> (d1->beta(2)->beta(1)->beta(1)->beta(2), d3); ++nbcube; tdsdart = NULL; statusBar ()->showMessage (QString ("3 cubes were created"), DELAY_STATUSMSG); emit (sceneChanged ()); } void MainWindow::create_2volumes () { Dart_handle d1 = make_iso_cuboid (Point_3 (nbcube, nbcube, nbcube),1); Dart_handle d2 = make_iso_cuboid (Point_3 (nbcube + 1, nbcube, nbcube), 1); Dart_handle d3 = make_iso_cuboid (Point_3 (nbcube, nbcube + 1, nbcube), 1); Dart_handle d4 = make_iso_cuboid (Point_3 (nbcube + 1, nbcube + 1, nbcube), 1); initVolumeRandomColor(d1); initVolumeRandomColor(d2); initVolumeRandomColor(d3); initVolumeRandomColor(d4); scene.map->sew<3>(d1->beta(1)->beta(1)->beta(2), d2->beta (2)); scene.map->sew<3>(d1->beta(2)->beta(1)->beta(1)->beta (2), d3); scene.map->sew<3>(d3->beta(1)->beta(1)->beta(2), d4->beta (2)); scene.map->sew<3>(d2->beta(2)->beta(1)->beta(1)->beta (2), d4); /* scene.map->display_characteristics(std::cout) <<" is_valid="<is_valid()<display_darts(std::cout)<display_darts(std::cout)<showMessage (QString ("mesh created"),DELAY_STATUSMSG); emit (sceneChanged ()); } } void MainWindow::subdivide () { subdivide_map_3 (*(scene.map)); tdsdart = NULL; emit (sceneChanged ()); statusBar ()->showMessage (QString ("Objects were subdivided"), DELAY_STATUSMSG); } void MainWindow::clear () { scene.map->clear (); tdsdart = NULL; statusBar ()->showMessage (QString ("Scene was cleared"), DELAY_STATUSMSG); emit (sceneChanged ()); } void MainWindow::dual_3 () { if ( !scene.map->is_without_boundary(3) ) { statusBar()->showMessage (QString ("Dual impossible: the map has some 3-boundary"), DELAY_STATUSMSG); return; } Map* dualmap = new Map; Dart_handle infinitevolume = CGAL::dual(*scene.map,*dualmap,tdsdart); if ( tdsdart!=NULL ) CGAL::remove_cell(*dualmap,infinitevolume); delete scene.map; scene.map = dualmap; this->viewer->setScene (&scene); initAllVolumesRandomColor(); statusBar ()->showMessage (QString ("Dual_3 computed"), DELAY_STATUSMSG); emit (sceneChanged ()); } void MainWindow::close_volume() { tdsdart = NULL; if ( scene.map->close(3) > 0 ) { initAllVolumesRandomColor(); statusBar ()->showMessage (QString ("Volume are closed"), DELAY_STATUSMSG); emit (sceneChanged ()); } else statusBar ()->showMessage (QString ("Map already 3-closed"), DELAY_STATUSMSG); } void MainWindow::sew3_same_facets() { tdsdart = NULL; // timer.reset(); // timer.start(); if ( scene.map->sew3_same_facets() > 0 ) { statusBar()->showMessage (QString ("Same facets are 3-sewn"), DELAY_STATUSMSG); emit (sceneChanged ()); } else statusBar()->showMessage (QString ("No facets 3-sewn"), DELAY_STATUSMSG); // timer.stop(); // std::cout<<"sew3_same_facets in "<darts().begin(); it!=scene.map->darts().end(); ++it) { if ( !it->is_free(3) ) { scene.map->unsew<3>(it); ++nb; } } if ( nb > 0 ) { statusBar()->showMessage (QString ("All darts are 3-unsewn"), DELAY_STATUSMSG); emit (sceneChanged ()); } else statusBar()->showMessage (QString ("No dart 3-unsewn"), DELAY_STATUSMSG); } void MainWindow::remove_current_volume() { if ( this->viewer->getCurrentDart()!=scene.map->darts().end() ) { CGAL::remove_cell(*scene.map,this->viewer->getCurrentDart()); emit (sceneChanged ()); statusBar()->showMessage (QString ("Current volume removed"), DELAY_STATUSMSG); } else statusBar()->showMessage (QString ("No volume removed"), DELAY_STATUSMSG); } void MainWindow::triangulate_all_facets() { std::vector v; for (Map::One_dart_per_cell_range<2>::iterator it(scene.map->one_dart_per_cell<2>().begin()); it.cont(); ++it) { v.push_back(it); } for (std::vector::iterator itv(v.begin()); itv!=v.end(); ++itv) CGAL::insert_center_cell_0_in_cell_2(*scene.map,*itv); emit (sceneChanged ()); statusBar()->showMessage (QString ("All facets were triangulated"), DELAY_STATUSMSG); } #undef DELAY_STATUSMSG #include "MainWindow.moc"