// Copyright (c) 2011 CNRS and LIRIS' Establishments (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // Author(s) : Guillaume Damiand // Contributor(s): Kumar Snehasish // Sylvain Brandel // #include "MainWindow.h" #include #include #include #include #include #include #include #include "import_moka.h" // Function defined in Linear_cell_complex_3_subivision.cpp void subdivide_lcc_3 (LCC & m); // Function defined in Linear_cell_complex_pqq_subivision.cpp void subdivide_lcc_pqq (LCC & m); #define DELAY_STATUSMSG 1500 MainWindow::MainWindow (QWidget * parent) : CGAL::Qt::DemosMainWindow (parent), nbcube (0), dialogmesh (this), dialogmenger(this), dialogsierpinskicarpet(this), dialogsierpinskitriangle(this) { setupUi (this); scene.lcc = new LCC; volumeListDock = new QDockWidget(QString(tr("Volume List")),this); volumeListDock->setAllowedAreas(Qt::RightDockWidgetArea | Qt::LeftDockWidgetArea); volumeList = new QTableWidget(0,4,volumeListDock); volumeList->verticalHeader()->hide(); volumeList->setColumnHidden(3,true); QObject::connect(this->volumeList, SIGNAL(cellChanged(int,int)), this, SLOT(onCellChanged(int,int))); QStringList labels(QString(tr("Color"))); labels.append(QString(tr("Filled"))); labels.append(QString(tr("Hidden"))); volumeList->setHorizontalHeaderLabels(labels); //volumeList->resizeColumnsToContents(); volumeList->setFixedWidth(220); /* volumeList->setColumnWidth(0,85); volumeList->setColumnWidth(1,35); volumeList->setColumnWidth(2,35);*/ volumeList->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); volumeList->setSelectionMode(QAbstractItemView::NoSelection); //volumeList->setSelectionBehavior(QAbstractItemView::SelectRows); volumeListDock->setWidget(volumeList); addDockWidget(Qt::RightDockWidgetArea,volumeListDock); menuView->addAction(volumeListDock->toggleViewAction()); QObject::connect(&dialogmesh, SIGNAL(accepted()), this, SLOT(onCreateMeshOk())); this->viewer->setScene(&scene, false); connect_actions (); this->addAboutDemo (":/cgal/help/about_Linear_cell_complex_3.html"); this->addAboutCGAL (); this->addRecentFiles (this->menuFile, this->actionQuit); connect (this, SIGNAL (openRecentFile (QString)), this, SLOT (load_depend_on_extension(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::connect_actions () { QObject::connect (this->actionQuit, SIGNAL (triggered ()), qApp, SLOT (quit ())); QObject::connect (this, SIGNAL (sceneChanged ()), this, SLOT (onSceneChanged ())); QObject::connect(this->volumeList->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(onHeaderClicked(int))); QObject::connect(dialogmenger.mengerLevel, SIGNAL(valueChanged(int)), this, SLOT(onMengerChange(int))); QObject::connect(dialogmenger.updateAttributes, SIGNAL(clicked(bool)), this, SLOT(onMengerUpdateAttributes(bool))); QObject::connect(&dialogmenger, SIGNAL(accepted()), this, SLOT(onMengerOk())); QObject::connect(&dialogmenger, SIGNAL(rejected()), this, SLOT(onMengerCancel())); QObject::connect(dialogsierpinskicarpet.level, SIGNAL(valueChanged(int)), this, SLOT(onSierpinskiCarpetChangeLevel(int))); QObject::connect(dialogsierpinskicarpet.updateAttributes, SIGNAL(clicked(bool)), this, SLOT(onSierpinskiCarpetUpdateAttributes(bool))); /* QObject::connect(dialogsierpinskicarpet.never, SIGNAL(clicked(bool)), this, SLOT(onSierpinskiCarpetNeverUpdateAttributes(bool))); QObject::connect(dialogsierpinskicarpet.during, SIGNAL(clicked(bool)), this, SLOT(onSierpinskiCarpetDuringConstructionUpdateAttributes(bool))); QObject::connect(dialogsierpinskicarpet.after, SIGNAL(clicked(bool)), this, SLOT(onSierpinskiCarpetAfterConstructionUpdateAttributes(bool))); QObject::connect(dialogsierpinskicarpet.stdmap, SIGNAL(clicked(bool)), this, SLOT(onSierpinskiCarpetUpdateAttributesMethodStdMap(bool))); QObject::connect(dialogsierpinskicarpet.traversal, SIGNAL(clicked(bool)), this, SLOT(onSierpinskiCarpetUpdateAttributesMethodTraversal(bool))); QObject::connect(dialogsierpinskicarpet.computeGeometry, SIGNAL(clicked(bool)), this, SLOT(onSierpinskiCarpetComputeGeometry(bool)));*/ QObject::connect(&dialogsierpinskicarpet, SIGNAL(accepted()), this, SLOT(onSierpinskiCarpetOk())); QObject::connect(&dialogsierpinskicarpet, SIGNAL(rejected()), this, SLOT(onSierpinskiCarpetCancel())); QObject::connect(dialogsierpinskitriangle.level, SIGNAL(valueChanged(int)), this, SLOT(onSierpinskiTriangleChangeLevel(int))); QObject::connect(dialogsierpinskitriangle.updateAttributes, SIGNAL(clicked(bool)), this, SLOT(onSierpinskiTriangleUpdateAttributes(bool))); QObject::connect(&dialogsierpinskitriangle, SIGNAL(accepted()), this, SLOT(onSierpinskiTriangleOk())); QObject::connect(&dialogsierpinskitriangle, SIGNAL(rejected()), this, SLOT(onSierpinskiTriangleCancel())); } void MainWindow::connectVolumeListHandlers() { QObject::connect(this->volumeList, SIGNAL(cellChanged(int,int)), this, SLOT(onCellChanged(int,int))); } void MainWindow::update_operations_entries(bool show) { actionImportOFF->setEnabled(show); actionImport3DTDS->setEnabled(show); actionCompute_Voronoi_3D->setEnabled(show); actionClear->setEnabled(show); menuCreations->setEnabled(show); menuOperations->setEnabled(show); } void MainWindow::onSceneChanged () { QApplication::setOverrideCursor( Qt::WaitCursor ); LCC::size_type mark = scene.lcc->get_new_mark (); scene.lcc->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.lcc->count_cells (cells); std::ostringstream os; os << "Darts: " << scene.lcc->number_of_darts () << ", Vertices:" << res[0] <<", (Points:"<number_of_attributes<0>()<<")" << ", Edges:" << res[1] << ", Facets:" << res[2] << ", Volumes:" << res[3] <<", (Vol color:"<number_of_attributes<3>()<<")" << ", Connected components:" << res[4] <<", Valid:"<<(scene.lcc->is_valid()?"true":"FALSE"); scene.lcc->negate_mark (mark); scene.lcc->free_mark (mark); // statusBar()->showMessage (QString ("Update OpenGL lists"), DELAY_STATUSMSG); viewer->sceneChanged (); statusMessage->setText (os.str().c_str ()); QApplication::restoreOverrideCursor(); } void MainWindow::clear_all() { scene.lcc->clear(); nbcube=0; volumeList->clearContents(); volumeList->setRowCount(0); } void MainWindow::on_new_volume(Dart_descriptor adart) { CGAL_assertion( scene.lcc->attribute<3>(adart)==LCC::null_descriptor); scene.lcc->set_attribute<3>(adart, scene.lcc->create_attribute<3>()); update_volume_list_add(scene.lcc->attribute<3>(adart)); } void MainWindow::init_all_new_volumes() { for (LCC::One_dart_per_cell_range<3>::iterator it(scene.lcc->one_dart_per_cell<3>().begin()); it.cont(); ++it) if ( scene.lcc->attribute<3>(it)==LCC::null_descriptor ) { on_new_volume(it); } } void MainWindow::on_actionSave_triggered () { QString fileName = QFileDialog::getSaveFileName (this, tr ("Save"), "save.3map", tr ("3-map files (*.3map)")); if (!fileName.isEmpty ()) { save(fileName); } } void MainWindow::on_actionLoad_triggered () { QString fileName = QFileDialog::getOpenFileName (this, tr ("Load"), "./3map", tr ("3-map files (*.3map)")); if (!fileName.isEmpty ()) { load(fileName, false); } } void MainWindow::on_actionImportOFF_triggered () { QString fileName = QFileDialog::getOpenFileName (this, tr ("Import OFF"), "./off", tr ("off files (*.off)")); if (!fileName.isEmpty ()) { load_off (fileName, false); } } void MainWindow::on_actionImportMoka_triggered() { QString fileName = QFileDialog::getOpenFileName (this, tr ("Import Moka"), "./moka", tr ("Moka files (*.moka)")); if (!fileName.isEmpty ()) { load_moka(fileName, false); } } void MainWindow::on_actionImport3DTDS_triggered () { QString fileName = QFileDialog::getOpenFileName (this, tr ("Import 3DTDS"), ".", tr ("Data file (*)")); if (!fileName.isEmpty ()) { load_3DTDS (fileName, false); statusBar ()->showMessage (QString ("Import 3DTDS file") + fileName, DELAY_STATUSMSG); } } void MainWindow::load_depend_on_extension(const QString & fileName, bool clear) { QString ext = QFileInfo(fileName).suffix(); if ( ext=="3map") { load(fileName, clear); } else if (ext=="off") { load_off(fileName, clear); } else if (ext=="moka") { load_moka(fileName, clear); } else { std::cout<<"Extension not considered."<clear_all(); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif bool res = load_combinatorial_map(fileName.toStdString().c_str(), *(scene.lcc)); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to load 3-map "<addToRecentFiles(fileName); QApplication::restoreOverrideCursor (); if (res) statusBar ()->showMessage (QString ("3-map loaded ") + fileName, DELAY_STATUSMSG); else statusBar ()->showMessage (QString ("Problem: 3-map not loaded ") + fileName, DELAY_STATUSMSG); Q_EMIT (sceneChanged ()); } void MainWindow::save(const QString & fileName) { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif if ( save_combinatorial_map(*(scene.lcc), fileName.toStdString().c_str()) ) statusBar ()->showMessage (QString ("3-map saved ") + fileName, DELAY_STATUSMSG); else statusBar ()->showMessage (QString ("Problem: 3-map not saved ") + fileName, DELAY_STATUSMSG); QApplication::restoreOverrideCursor (); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to save 3-map "<clear_all(); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif std::ifstream ifs (qPrintable (fileName)); CGAL::import_from_polyhedron_3_flux < LCC > (*scene.lcc, ifs); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to load off "<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); Q_EMIT (sceneChanged ()); } void MainWindow::load_3DTDS (const QString & fileName, bool clear) { QApplication::setOverrideCursor (Qt::WaitCursor); if (clear) this->clear_all(); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif typedef CGAL::Delaunay_triangulation_3 < LCC::Traits > Triangulation; Triangulation T; std::ifstream ifs (qPrintable (fileName)); T.insert (std::istream_iterator < Point_3 >(ifs), std::istream_iterator < Point_3 >() ); CGAL::import_from_triangulation_3 < LCC, Triangulation >(*scene.lcc, T); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to import the 3DTDS from "<clear_all(); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif CGAL::import_from_moka < LCC > (*scene.lcc, qPrintable (fileName)); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to load moka "<addToRecentFiles (fileName); QApplication::restoreOverrideCursor (); if (clear) statusBar ()->showMessage (QString ("Load moka file") + fileName, DELAY_STATUSMSG); else statusBar ()->showMessage (QString ("Add moka file") + fileName, DELAY_STATUSMSG); Q_EMIT (sceneChanged ()); } Dart_descriptor MainWindow::make_iso_cuboid(const Point_3 basepoint, LCC::FT lg) { Dart_descriptor dh = scene.lcc->make_hexahedron(basepoint, LCC::Traits::Construct_translated_point() (basepoint,LCC::Traits::Vector(lg,0,0)), LCC::Traits::Construct_translated_point() (basepoint,LCC::Traits::Vector(lg,lg,0)), LCC::Traits::Construct_translated_point() (basepoint,LCC::Traits::Vector(0,lg,0)), LCC::Traits::Construct_translated_point() (basepoint,LCC::Traits::Vector(0,lg,lg)), LCC::Traits::Construct_translated_point() (basepoint,LCC::Traits::Vector(0,0,lg)), LCC::Traits::Construct_translated_point() (basepoint,LCC::Traits::Vector(lg,0,lg)), LCC::Traits::Construct_translated_point() (basepoint,LCC::Traits::Vector(lg,lg,lg))); scene.lcc->reverse_orientation_connected_component(dh); return dh; } Dart_descriptor MainWindow::on_actionCreate_cube_triggered () { Point_3 basepoint(nbcube%5, (nbcube/5)%5, nbcube/25); Dart_descriptor d = make_iso_cuboid(basepoint, 1); on_new_volume(d); ++nbcube; statusBar ()->showMessage (QString ("Cube created"),DELAY_STATUSMSG); Q_EMIT (sceneChanged ()); return d; } void MainWindow::on_actionCreate3Cubes_triggered () { Dart_descriptor d1 = make_iso_cuboid (Point_3 (nbcube, nbcube, nbcube),1); Dart_descriptor d2 = make_iso_cuboid (Point_3 (nbcube + 1, nbcube, nbcube),1); Dart_descriptor d3 = make_iso_cuboid (Point_3 (nbcube, nbcube + 1, nbcube), 1); on_new_volume(d1); on_new_volume(d2); on_new_volume(d3); scene.lcc->sew<3>(scene.lcc->beta(d1,1,1,2), scene.lcc->beta(d2,2)); scene.lcc->sew<3>(scene.lcc->beta(d1,2,1,1,2), d3); ++nbcube; statusBar ()->showMessage (QString ("3 cubes were created"), DELAY_STATUSMSG); Q_EMIT (sceneChanged ()); } void MainWindow::on_actionCreate2Volumes_triggered () { Dart_descriptor d1 = make_iso_cuboid(Point_3(nbcube, nbcube, nbcube),1); Dart_descriptor d2 = make_iso_cuboid(Point_3(nbcube + 1, nbcube, nbcube), 1); Dart_descriptor d3 = make_iso_cuboid(Point_3(nbcube, nbcube + 1, nbcube), 1); Dart_descriptor d4 = make_iso_cuboid(Point_3(nbcube + 1, nbcube + 1, nbcube), 1); scene.lcc->sew<3>(scene.lcc->beta(d1,1,1,2), scene.lcc->beta(d2,2)); scene.lcc->sew<3>(scene.lcc->beta(d1,2,1,1,2), d3); scene.lcc->sew<3>(scene.lcc->beta(d3,1,1,2), scene.lcc->beta(d4,2)); scene.lcc->sew<3>(scene.lcc->beta(d2,2,1,1,2), d4); scene.lcc->remove_cell<2>(d3); scene.lcc->remove_cell<2>(scene.lcc->beta(d2,2)); on_new_volume(d1); on_new_volume(d4); ++nbcube; statusBar ()->showMessage (QString ("2 volumes were created"), DELAY_STATUSMSG); Q_EMIT (sceneChanged()); } void MainWindow::on_actionCreate_mesh_triggered () { dialogmesh.show(); } void MainWindow::onCreateMeshOk() { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif for (int x=0; xshowMessage (QString ("Mesh created"),DELAY_STATUSMSG); QApplication::restoreOverrideCursor (); Q_EMIT (sceneChanged ()); } void MainWindow::on_actionSubdivide_triggered () { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif subdivide_lcc_3(*(scene.lcc)); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to subdivide the current LCC: " <showMessage (QString ("Objects were subdivided"), DELAY_STATUSMSG); } void MainWindow::on_actionSubdivide_pqq_triggered () { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif subdivide_lcc_pqq (*(scene.lcc)); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to pqq-subdivide the current LCC: " <showMessage (QString ("Objects were subdivided"), DELAY_STATUSMSG); } void MainWindow::on_actionClear_triggered() { clear_all(); statusBar ()->showMessage (QString ("Scene cleared"), DELAY_STATUSMSG); Q_EMIT (sceneChanged ()); } void MainWindow::on_actionCompute_Voronoi_3D_triggered () { QString fileName = QFileDialog::getOpenFileName (this, tr ("Voronoi 3D"), ".", tr ("Data file (*)")); if (fileName.isEmpty ()) return; QApplication::setOverrideCursor (Qt::WaitCursor); this->clear_all(); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif typedef CGAL::Delaunay_triangulation_3 < LCC::Traits > Triangulation; Triangulation T; LCC delaunay_lcc; Dart_descriptor dh; std::ifstream ifs (qPrintable (fileName)); T.insert (std::istream_iterator < Point_3 >(ifs), std::istream_iterator < Point_3 >() ); std::map vol_to_dart; dh = CGAL::import_from_triangulation_3 < LCC, Triangulation > (delaunay_lcc, T, &vol_to_dart); Dart_descriptor ddh=delaunay_lcc.dual(*scene.lcc, dh); // We transform all the darts in vol_to_dart into their dual. { LCC::Dart_range::iterator it1=delaunay_lcc.darts().begin(); LCC::Dart_range::iterator it2=scene.lcc->darts().begin(); std::map dual; for ( ; it1!=delaunay_lcc.darts().end(); ++it1, ++it2 ) { dual[it1]=it2; } // We update the geometry of dual_lcc by using the std::map face_to_dart. for ( std::map ::iterator it=vol_to_dart.begin(), itend=vol_to_dart.end(); it!=itend; ++it) { vol_to_dart[it->first]=dual[it->second]; if ( !T.is_infinite(it->first) ) scene.lcc->set_vertex_attribute (it->second,scene.lcc->create_vertex_attribute(T.dual(it->first))); /* else alcc.set_vertex_attribute(it->second,alcc.create_vertex_attribute());*/ } } // We remove the infinite volume and all its adjacent volumes. { std::stack toremove; LCC::size_type mark_toremove=scene.lcc->get_new_mark(); toremove.push(ddh); CGAL::mark_cell(*scene.lcc, ddh, mark_toremove); for (LCC::Dart_of_cell_range<3>::iterator it=scene.lcc->darts_of_cell<3>(ddh).begin(), itend=scene.lcc->darts_of_cell<3>(ddh).end(); it!=itend; ++it) { if ( !scene.lcc->is_marked(scene.lcc->beta(it,3), mark_toremove) ) { CGAL::mark_cell(*scene.lcc, scene.lcc->beta(it,3), mark_toremove); toremove.push(scene.lcc->beta(it,3)); } } while( !toremove.empty() ) { scene.lcc->remove_cell<3>(toremove.top()); toremove.pop(); } CGAL_assertion(scene.lcc->is_whole_map_unmarked(mark_toremove)); scene.lcc->free_mark(mark_toremove); } #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to compute Voronoi 3D from "<showMessage (QString ("Voronoi 3D of points in ") + fileName, DELAY_STATUSMSG); } void MainWindow::on_actionDual_3_triggered () { if ( !scene.lcc->is_without_boundary(3) ) { statusBar()->showMessage (QString ("Dual impossible: the lcc has some 3-boundary"), DELAY_STATUSMSG); return; } QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif LCC* duallcc = new LCC; scene.lcc->dual_points_at_barycenter(*duallcc); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to compute the dual: " <clear_all(); delete scene.lcc; scene.lcc = duallcc; this->viewer->setScene(&scene); init_all_new_volumes(); statusBar ()->showMessage (QString ("Dual_3 computed"), DELAY_STATUSMSG); QApplication::restoreOverrideCursor (); Q_EMIT (sceneChanged ()); } void MainWindow::on_actionClose_volume_triggered() { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif if ( scene.lcc->close<3>() > 0 ) { init_all_new_volumes(); statusBar ()->showMessage (QString ("All volume(s) closed"), DELAY_STATUSMSG); Q_EMIT (sceneChanged ()); } else statusBar ()->showMessage (QString ("LCC already 3-closed"), DELAY_STATUSMSG); QApplication::restoreOverrideCursor (); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to 3-close the current lcc: " <get_new_mark(); mark_all_filled_and_visible_volumes(mymark); QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif if ( scene.lcc->sew3_same_facets(mymark) > 0 ) { statusBar()->showMessage (QString ("Same facets of visible and filled volume(s) are 3-sewn"), DELAY_STATUSMSG); Q_EMIT (sceneChanged ()); } else statusBar()->showMessage (QString ("No facets 3-sewn"), DELAY_STATUSMSG); scene.lcc->free_mark(mymark); QApplication::restoreOverrideCursor (); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to sew3 all same facets: " <darts().begin(); it!=scene.lcc->darts().end(); ++it) { if ( !scene.lcc->is_free(it,3) && scene.lcc->info<3>(it).is_filled_and_visible() && scene.lcc->info<3>(scene.lcc->beta(it,3)) .is_filled_and_visible()) { scene.lcc->unsew<3>(it); ++nb; } } #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to unsew3 all filled volumes: " < 0 ) { statusBar()->showMessage (QString ("Darts between visible and filled volume(s) are 3-unsewn"), DELAY_STATUSMSG); Q_EMIT (sceneChanged ()); } else statusBar()->showMessage (QString ("No dart 3-unsewn"), DELAY_STATUSMSG); } void MainWindow::on_actionInsideOut_triggered() { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif LCC::size_type mymark=scene.lcc->get_new_mark(); for (LCC::Attribute_range<3>::type::iterator it=scene.lcc->attributes<3>().begin(), itend=scene.lcc->attributes<3>().end(); it!=itend; ) { LCC::Attribute_descriptor<3>::type cur = it++; if( !scene.lcc->is_marked(scene.lcc->get_attribute<3>(cur).dart(), mymark) && scene.lcc->get_attribute<3>(cur).info().is_filled_and_visible() ) { scene.lcc->reverse_orientation_connected_component (scene.lcc->get_attribute<3>(cur).dart(), mymark); } } // unmark all the darts by iterating on all the darts // but we cannot do really better scene.lcc->free_mark(mymark); QApplication::restoreOverrideCursor (); Q_EMIT( sceneChanged()); statusBar()->showMessage (QString("Orientation of visible and filled volume(s) reversed"), DELAY_STATUSMSG); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to reverse the orientation of all filled volumes: " <::type::iterator it=scene.lcc->attributes<3>().begin(), itend=scene.lcc->attributes<3>().end(); it!=itend; ) { LCC::Attribute_descriptor<3>::type cur = it++; if( scene.lcc->get_attribute<3>(cur).info().is_filled_and_visible() ) { scene.lcc->remove_cell<3>(scene.lcc->get_attribute<3>(cur).dart()); ++count; } } #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to remove all filled volumes: " <showMessage (QString::number(count)+QString("Visible and filled volume(s) removed"), DELAY_STATUSMSG); } void MainWindow::on_actionInsert_center_vertices_triggered() { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif std::vector v; for (LCC::One_dart_per_cell_range<2>::iterator it(scene.lcc->one_dart_per_cell<2>().begin()); it.cont(); ++it) { if ( scene.lcc->info<3>(it).is_filled_and_visible() ) v.push_back(it); } for (std::vector::iterator itv(v.begin()); itv!=v.end(); ++itv) scene.lcc->insert_barycenter_in_cell<2>(*itv); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to insert center vertices in all filled faces: " <showMessage (QString ("Vertices are inserted in center of facets of visible and filled volume(s)"), DELAY_STATUSMSG); } double compute_angle3d(const Vector_3& v1, const Vector_3& v2) { double a = CGAL::to_double( (v1*v2) / ( sqrt(v1.squared_length()) * sqrt(v2.squared_length()) ) ) ; if (a < -1.0) return acos(-1.0)/CGAL_PI*180.0; else if (a > 1.0) return acos(1.0)/CGAL_PI*180.0; else return acos(a)/CGAL_PI*180.0; } void MainWindow::on_actionMerge_coplanar_faces_triggered() { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif scene.lcc->set_automatic_attributes_management(false); std::vector edges; LCC::size_type treated = scene.lcc->get_new_mark(); LCC::size_type treated2 = scene.lcc->get_new_mark(); for ( LCC::Dart_range::iterator it= scene.lcc->darts().begin(), itend = scene.lcc->darts().end(); it!=itend; ++it ) { if (!scene.lcc->is_marked(it, treated) ) { if ( scene.lcc->is_removable<1>(it) ) { LCC::Vector normal1 = CGAL::compute_normal_of_cell_2(*scene.lcc,it); LCC::Vector normal2 = CGAL::compute_normal_of_cell_2(*scene.lcc, scene.lcc->beta<2>(it) ); double angle = compute_angle3d(normal1, normal2); if ( ((angle<5.0 || angle>355.0) || (angle<185.0 && angle>175.0)) ) { edges.push_back(it); } } CGAL::mark_cell(*scene.lcc, it, treated); } } for (std::vector::iterator it=edges.begin(), itend=edges.end(); it!=itend; ++it) { CGAL::mark_cell(*scene.lcc, *it, treated2); if ( scene.lcc->beta<0, 2>(*it)==*it || scene.lcc->beta<1, 2>(*it)==*it) { // To process dangling edges Dart_descriptor actu = *it, prev=LCC::null_descriptor; do { if ( scene.lcc->beta<0, 2>(actu)==actu ) prev = scene.lcc->beta<1>(actu); else prev = scene.lcc->beta<0>(actu); if (scene.lcc->is_marked(actu, treated2) && (scene.lcc->beta<0, 2>(actu)!=actu || scene.lcc->beta<1, 2>(actu)!=actu) ) { scene.lcc->remove_cell<1>(actu); actu = prev; } else actu=LCC::null_descriptor; } while (actu!=LCC::null_descriptor && (scene.lcc->beta<0, 2>(actu)==actu || scene.lcc->beta<1, 2>(actu)==actu)); } else if ( !CGAL::belong_to_same_cell(*scene.lcc, *it, scene.lcc->beta<2>(*it)) ) scene.lcc->remove_cell<1>(*it); } assert(scene.lcc->is_whole_map_marked(treated)); scene.lcc->free_mark(treated); scene.lcc->free_mark(treated2); scene.lcc->set_automatic_attributes_management(true); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to merge all coplanar faces: " <showMessage (QString ("Coplanar face(s) merged"), DELAY_STATUSMSG); } void MainWindow::on_actionMerge_all_volumes_triggered() { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif LCC::Dart_range::iterator prev; bool first = true; scene.lcc->set_automatic_attributes_management(false); for (LCC::Dart_range::iterator it(scene.lcc->darts().begin()), itend=scene.lcc->darts().end(); it!=itend; ) { if ( !scene.lcc->is_free(it,3) && scene.lcc->info<3>(it).is_filled_and_visible() && scene.lcc->info<3>(scene.lcc->beta(it,3)) .is_filled_and_visible() ) { scene.lcc->remove_cell<2>(it); itend=scene.lcc->darts().end(); if ( first ) it=scene.lcc->darts().begin(); else { it=prev; if ( it!=itend ) ++it; } } else { first=false; prev=it; ++it; } } scene.lcc->set_automatic_attributes_management(true); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to merge all filled volumes: " <showMessage (QString ("Visible and filled volume(s) merged"), DELAY_STATUSMSG); } bool is_external(CDT::Face_handle fh) { return fh->info().is_external; } int number_of_existing_edge(CDT::Face_handle fh) { unsigned res=0; for (int i=0; i<3; ++i) if (fh->info().exist_edge[i]) ++res; return res; } int get_free_edge(CDT::Face_handle fh) { CGAL_assertion( number_of_existing_edge(fh)==2 ); for (int i=0; i<3; ++i) if (!fh->info().exist_edge[i]) return i; CGAL_assertion(false); return -1; } void constrained_delaunay_triangulation(LCC &lcc, Dart_descriptor d1) { Vector_3 normal = CGAL::compute_normal_of_cell_2(lcc,d1); P_traits cdt_traits(normal); CDT cdt(cdt_traits); //inserting the constraints edge by edge LCC::Dart_of_orbit_range<1>::iterator it(lcc.darts_of_orbit<1>(d1).begin()); CDT::Vertex_handle previous=nullptr, first=nullptr, vh=nullptr; for (LCC::Dart_of_orbit_range<1>::iterator itend(lcc.darts_of_orbit<1>(d1).end()); it!=itend; ++it) { vh = cdt.insert(lcc.point(it)); vh->info().dh=it; if(first==nullptr) { first=vh; } if(previous!=nullptr) { CGAL_assertion( previous !=vh ); cdt.insert_constraint(previous,vh); } previous=vh; } cdt.insert_constraint(previous,first); CGAL_assertion(cdt.is_valid()); // sets mark is_external for( CDT::All_faces_iterator fit = cdt.all_faces_begin(), fitend = cdt.all_faces_end(); fit != fitend; ++fit) { fit->info().is_external = true; fit->info().is_process = false; fit->info().exist_edge[0]=false; fit->info().exist_edge[1]=false; fit->info().exist_edge[2]=false; } std::queue face_queue; CDT::Face_handle face_internal=nullptr; face_queue.push(cdt.infinite_vertex()->face()); while(! face_queue.empty() ) { CDT::Face_handle fh = face_queue.front(); face_queue.pop(); if(!fh->info().is_process) { fh->info().is_process = true; for(int i = 0; i <3; ++i) { if(!cdt.is_constrained(std::make_pair(fh, i))) { face_queue.push(fh->neighbor(i)); } else if (face_internal==nullptr) { face_internal = fh->neighbor(i); } } } } if (face_internal!=nullptr) face_queue.push(face_internal); while(! face_queue.empty() ) { CDT::Face_handle fh = face_queue.front(); face_queue.pop(); if(!fh->info().is_process) { fh->info().is_process = true; fh->info().is_external = false; for(int i = 0; i <3; ++i) { if(!cdt.is_constrained(std::make_pair(fh, i))) { face_queue.push(fh->neighbor(i)); } } } } for( CDT::Finite_edges_iterator eit = cdt.finite_edges_begin(), eitend = cdt.finite_edges_end(); eit != eitend; ++eit) { CDT::Face_handle fh = eit->first; int index = eit->second; CDT::Face_handle opposite_fh = fh->neighbor(index); if(cdt.is_constrained(std::make_pair(fh, index))) { fh->info().exist_edge[index]=true; opposite_fh->info().exist_edge[cdt.mirror_index(fh,index)]=true; if ( !fh->info().is_external && number_of_existing_edge(fh)==2 ) face_queue.push(fh); if ( !opposite_fh->info().is_external && number_of_existing_edge(opposite_fh)==2 ) face_queue.push(opposite_fh); } } while( !face_queue.empty() ) { CDT::Face_handle fh = face_queue.front(); face_queue.pop(); CGAL_assertion( number_of_existing_edge(fh)>=2 ); // i.e. ==2 or ==3 CGAL_assertion( !fh->info().is_external ); if (number_of_existing_edge(fh)==2) { int index = get_free_edge(fh); CDT::Face_handle opposite_fh = fh->neighbor(index); CGAL_assertion( !fh->info().exist_edge[index] ); CGAL_assertion( !opposite_fh->info(). exist_edge[cdt.mirror_index(fh,index)] ); // triangle is (vc, vb, va) const CDT::Vertex_handle va = fh->vertex(cdt. cw(index)); const CDT::Vertex_handle vb = fh->vertex(cdt.ccw(index)); const CDT::Vertex_handle vc = fh->vertex(index); Dart_descriptor dd1 = LCC::null_descriptor; for (LCC::Dart_of_cell_range<0, 2>::iterator it(lcc.darts_of_cell<0, 2>(va->info().dh).begin()); dd1==LCC::null_descriptor && it.cont(); ++it) { if (lcc.point(lcc.beta<1>(it))==vc->point()) dd1=it; } Dart_descriptor dd2 = LCC::null_descriptor; for (LCC::Dart_of_cell_range<0, 2>::iterator it(lcc.darts_of_cell<0, 2>(vb->info().dh).begin()); dd2==LCC::null_descriptor && it.cont(); ++it) { if (lcc.point(lcc.beta<0>(it))==vc->point()) dd2=it; } // assert(((lcc.beta<0,0>(dd1)==dd2) || lcc.beta<1,1>(dd1)==dd2)); Dart_descriptor ndart=lcc.insert_cell_1_in_cell_2(dd1, dd2); va->info().dh=lcc.beta<2>(ndart); fh->info().exist_edge[index]=true; opposite_fh->info().exist_edge[cdt.mirror_index(fh,index)]=true; if ( !opposite_fh->info().is_external && number_of_existing_edge(opposite_fh)==2 ) face_queue.push(opposite_fh); } } } void MainWindow::on_actionTriangulate_all_facets_triggered() { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif std::vector v; for (LCC::One_dart_per_cell_range<2>::iterator it(scene.lcc->one_dart_per_cell<2>().begin()); it.cont(); ++it) { if ( scene.lcc->info<3>(it).is_filled_and_visible() || (!scene.lcc->is_free<3>(it) && scene.lcc->info<3>(scene.lcc->beta<3>(it)).is_filled_and_visible()) ) v.push_back(it); } for (std::vector::iterator itv(v.begin()); itv!=v.end(); ++itv) constrained_delaunay_triangulation(*scene.lcc, *itv); #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Time to triangulate all filled faces: " <showMessage (QString ("All visible and filled faces were triangulated"), DELAY_STATUSMSG); } bool MainWindow::is_volume_in_list(LCC::Attribute_descriptor<3>::type ah) { for(int row=0; row < volumeList->rowCount(); ++row) { LCC::Attribute_type<3>::type* ptr= reinterpret_cast::type*> ( volumeList->item(row,3)->data(Qt::UserRole).value() ); if(ptr==&(scene.lcc->get_attribute<3>(ah))) return true; } return false; } void MainWindow::update_volume_list_add(LCC::Attribute_descriptor<3>::type ah) { // CGAL_assertion( !is_volume_in_list(ah) ); volumeList->disconnect(this); int newRow = volumeList->rowCount(); volumeList->setRowCount(newRow+1); QTableWidgetItem* volumeLabel = new QTableWidgetItem (QString((scene.lcc->get_attribute<3>(ah).info().color_name().c_str()))); volumeLabel->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); volumeLabel->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); volumeList->setItem(newRow,0,volumeLabel); QTableWidgetItem* fillCB = new QTableWidgetItem; fillCB->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); if ( scene.lcc->get_attribute<3>(ah).info().is_filled() ) fillCB->setCheckState(Qt::Checked); else fillCB->setCheckState(Qt::Unchecked); volumeList->setItem(newRow,1, fillCB); QTableWidgetItem* hiddenCB = new QTableWidgetItem(); hiddenCB->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); if ( scene.lcc->get_attribute<3>(ah).info().is_visible() ) hiddenCB->setCheckState(Qt::Unchecked); else hiddenCB->setCheckState(Qt::Checked); volumeList->setItem(newRow,2,hiddenCB); QTableWidgetItem* attribHandle = new QTableWidgetItem; attribHandle->setData (Qt::UserRole, reinterpret_cast(&scene.lcc->get_attribute<3>(ah))); volumeList->setItem(newRow,3,attribHandle); connectVolumeListHandlers(); } void MainWindow::update_volume_list_remove(int i) { CGAL_assertion(irowCount()); volumeList->removeRow(i); } void MainWindow::update_volume_list_remove(LCC::Attribute_descriptor<3>::type ah) { for(int row=0; row < volumeList->rowCount(); ++row) { LCC::Attribute_type<3>::type* ptr= reinterpret_cast::type*> ( volumeList->item(row,3)->data(Qt::UserRole).value() ); if(ptr==&scene.lcc->get_attribute<3>(ah)) { update_volume_list_remove(row); return; } } } void MainWindow::update_volume_list_all_ckeckstates() { volumeList->disconnect(this); for(int row=0; row < volumeList->rowCount(); ++row) { LCC::Attribute_type<3>::type* ptr= reinterpret_cast::type*> ( volumeList->item(row,3)->data(Qt::UserRole).value() ); if ( ptr->info().is_filled() ) volumeList->item(row,1)->setCheckState(Qt::Checked); else volumeList->item(row,1)->setCheckState(Qt::Unchecked); if ( !ptr->info().is_visible() ) volumeList->item(row,2)->setCheckState(Qt::Checked); else volumeList->item(row,2)->setCheckState(Qt::Unchecked); } connectVolumeListHandlers(); } void MainWindow::recreate_whole_volume_list() { volumeList->clearContents(); volumeList->setRowCount(0); for (LCC::Attribute_range<3>::type::iterator it=scene.lcc->attributes<3>().begin(), itend=scene.lcc->attributes<3>().end(); it!=itend; ++it) update_volume_list_add(it); } void MainWindow::onCellChanged(int row, int col) { volumeList->disconnect(this); LCC::Attribute_type<3>::type* ptr= reinterpret_cast::type*> ( volumeList->item(row,3)->data(Qt::UserRole).value() ); if ( col==1 ) { ptr->info().negate_filled(); } else if ( col==2 ) { ptr->info().negate_visible(); if ( !ptr->info().is_visible() ) volumeList->item(row,1)->setFlags (volumeList->item(row,1)->flags()^Qt::ItemIsEnabled); else volumeList->item(row,1)->setFlags (volumeList->item(row,1)->flags()|Qt::ItemIsEnabled); } connectVolumeListHandlers(); Q_EMIT( sceneChanged()); } void MainWindow::onHeaderClicked(int col) { if(col != 0) { volumeList->disconnect(this); for(int i = 0; i < volumeList->rowCount(); ++i) { LCC::Attribute_type<3>::type* ptr= reinterpret_cast::type*> ( volumeList->item(i,3)->data(Qt::UserRole).value() ); switch(qApp->keyboardModifiers()) { case(Qt::ShiftModifier): if (col==1) ptr->info().set_filled(false); else if (col==2) { ptr->info().set_visible(true); volumeList->item(i,1)->setFlags (volumeList->item(i,1)->flags()|Qt::ItemIsEnabled); } volumeList->item(i,col)->setCheckState(Qt::Unchecked); break; case(Qt::ControlModifier): if (col==1) ptr->info().negate_filled(); else if (col==2) { ptr->info().negate_visible(); if ( !ptr->info().is_visible() ) volumeList->item(i,1)->setFlags (volumeList->item(i,1)->flags()^Qt::ItemIsEnabled); else volumeList->item(i,1)->setFlags (volumeList->item(i,1)->flags()|Qt::ItemIsEnabled); } volumeList->item(i,col)-> setCheckState(volumeList->item(i,col)->checkState() ? Qt::Unchecked: Qt::Checked); break; default: if (col==1) ptr->info().set_filled(true); else if (col==2) { if ( ptr->info().is_visible() ) { ptr->info().set_visible(false); volumeList->item(i,1)->setFlags (volumeList->item(i,1)->flags()^Qt::ItemIsEnabled); } } volumeList->item(i,col)->setCheckState(Qt::Checked); break; } } connectVolumeListHandlers(); Q_EMIT( sceneChanged()); } } void MainWindow::mark_all_filled_and_visible_volumes(LCC::size_type amark) { for (LCC::Attribute_range<3>::type::iterator it=scene.lcc->attributes<3>().begin(), itend=scene.lcc->attributes<3>().end(); it!=itend; ++it) { if ( scene.lcc->get_attribute<3>(it).info().is_filled_and_visible() && !scene.lcc->is_marked(it->dart(), amark) ) CGAL::mark_cell(*scene.lcc, scene.lcc->get_attribute<3>(it).dart(), amark); } } void MainWindow::on_actionExtend_filled_volumes_triggered() { volumeList->disconnect(this); std::vector::type> tofill; LCC::size_type mark_volume = scene.lcc->get_new_mark(); bool already_tofill; for (LCC::Attribute_range<3>::type::iterator it=scene.lcc->attributes<3>().begin(), itend=scene.lcc->attributes<3>().end(); it!=itend; ++it) { if ( !scene.lcc->is_marked(it->dart(), mark_volume) ) { if ( !scene.lcc->get_attribute<3>(it).info().is_filled() ) { already_tofill = false; for (LCC::Dart_of_cell_basic_range<3>::iterator it2= scene.lcc->darts_of_cell_basic<3>(it->dart(), mark_volume).begin(); it2.cont(); ++it2 ) { scene.lcc->mark(it2, mark_volume); if ( !scene.lcc->is_free(it2,3) && scene.lcc->info<3>(scene.lcc->beta(it2,3)). is_filled() && !already_tofill) { tofill.push_back(scene.lcc->attribute<3>(it2)); already_tofill = true; } } } else CGAL::mark_cell(*scene.lcc, it->dart(), mark_volume); } } CGAL_assertion( scene.lcc->is_whole_map_marked(mark_volume) ); scene.lcc->free_mark(mark_volume); if ( tofill.size()>0 ) { for ( std::vector::type>::iterator it=tofill.begin(), itend=tofill.end(); it!=itend; ++it ) { scene.lcc->get_attribute<3>(*it).info().set_filled(true); } update_volume_list_all_ckeckstates(); Q_EMIT( sceneChanged()); } connectVolumeListHandlers(); } void MainWindow::on_actionExtend_hidden_volumes_triggered() { volumeList->disconnect(this); std::vector::type> tohide; LCC::size_type mark_volume = scene.lcc->get_new_mark(); bool already_tohide; for (LCC::Attribute_range<3>::type::iterator it=scene.lcc->attributes<3>().begin(), itend=scene.lcc->attributes<3>().end(); it!=itend; ++it) { if ( !scene.lcc->is_marked(it->dart(), mark_volume) ) { if ( scene.lcc->get_attribute<3>(it).info().is_visible() ) { already_tohide = false; for (LCC::Dart_of_cell_basic_range<3>::iterator it2= scene.lcc->darts_of_cell_basic<3>(it->dart(), mark_volume).begin(); it2.cont(); ++it2 ) { scene.lcc->mark(it2, mark_volume); if ( !scene.lcc->is_free(it2,3) && !scene.lcc->info<3>(scene.lcc->beta(it2,3)). is_visible() && !already_tohide) { tohide.push_back(scene.lcc->attribute<3>(it2)); already_tohide = true; } } } else CGAL::mark_cell(*scene.lcc, it->dart(), mark_volume); } } CGAL_assertion( scene.lcc->is_whole_map_marked(mark_volume) ); scene.lcc->free_mark(mark_volume); if ( tohide.size()>0 ) { for ( std::vector::type>::iterator it=tohide.begin(), itend=tohide.end(); it!=itend; ++it ) { scene.lcc->get_attribute<3>(*it).info().set_visible(false); } update_volume_list_all_ckeckstates(); Q_EMIT( sceneChanged()); } connectVolumeListHandlers(); } void MainWindow::on_actionCreate_Menger_Sponge_triggered () { dialogmenger.mengerLevel->disconnect(this); mengerUpdateAttributes = dialogmenger.updateAttributes->isChecked(); dialogmenger.mengerLevel->setValue(0); mengerLevel=0; CGAL_assertion( mengerVolumes.empty() ); mengerVolumes.push_back(on_actionCreate_cube_triggered()); update_operations_entries(false); QObject::connect(dialogmenger.mengerLevel, SIGNAL(valueChanged(int)), this, SLOT(onMengerChange(int))); dialogmenger.show(); } void MainWindow::onMengerCancel() { for(std::vector::iterator it=mengerVolumes.begin(); it!=mengerVolumes.end(); ++it) { scene.lcc->remove_cell<3>(*it); } recreate_whole_volume_list(); mengerVolumes.clear(); update_operations_entries(true); statusBar()->showMessage (QString ("Menger sponge creation canceled"), DELAY_STATUSMSG); Q_EMIT( sceneChanged()); } void MainWindow::onMengerOk() { update_operations_entries(true); mengerVolumes.clear(); } void MainWindow::onMengerChange(int newLevel) { while ( newLevel > mengerLevel ) onMengerInc(); while ( newLevel < mengerLevel ) onMengerDec(); } void MainWindow::onMengerUpdateAttributes(bool newValue) { mengerUpdateAttributes = newValue; } void MainWindow::onMengerInc() { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif this->mengerLevel++; if (!mengerUpdateAttributes) { scene.lcc->set_automatic_attributes_management(false); } std::vector edges; std::vector faces; std::size_t nbvolinit = mengerVolumes.size(); LCC::size_type markEdges = (scene.lcc)->get_new_mark(); LCC::size_type markFaces = (scene.lcc)->get_new_mark(); LCC::size_type markVols = (scene.lcc)->get_new_mark(); for(std::vector::iterator itvol=mengerVolumes.begin(); itvol!=mengerVolumes.end(); ++itvol) { CGAL_assertion( !(scene.lcc)->is_marked(*itvol, markVols) ); for (LCC::Dart_of_cell_basic_range<3>::iterator it=(scene.lcc)->darts_of_cell_basic<3>(*itvol, markVols).begin(), itend=(scene.lcc)->darts_of_cell_basic<3>(*itvol, markVols).end(); it!=itend; ++it) { if ( !(scene.lcc)->is_marked(it, markEdges) ) { edges.push_back(it); CGAL::mark_cell(*(scene.lcc), it, markEdges); } if ( !(scene.lcc)->is_marked(it, markFaces) ) { faces.push_back(it); CGAL::mark_cell(*(scene.lcc), it, markFaces); } } } (scene.lcc)->negate_mark(markVols); for(std::vector::iterator itvol=mengerVolumes.begin(); itvol!=mengerVolumes.end(); ++itvol) { for (LCC::Dart_of_cell_basic_range<3>::iterator it=(scene.lcc)->darts_of_cell_basic<3>(*itvol, markVols).begin(), itend=(scene.lcc)->darts_of_cell_basic<3>(*itvol, markVols).end(); it!=itend; ++it) { (scene.lcc)->unmark(it, markEdges); (scene.lcc)->unmark(it, markFaces); } } (scene.lcc)->negate_mark(markVols); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markVols) ); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markFaces) ); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markEdges) ); (scene.lcc)->free_mark(markEdges); (scene.lcc)->free_mark(markFaces); (scene.lcc)->free_mark(markVols); for(std::size_t i = 0; i < edges.size(); i++) { split_edge_in_three(edges[i]); } edges.clear(); for(std::size_t i = 0; i < faces.size(); i++) { split_face_in_nine(faces[i]); } faces.clear(); for(std::size_t i = 0; i < nbvolinit; i++) { split_vol_in_twentyseven(mengerVolumes[i]); } if (!mengerUpdateAttributes) { for(std::size_t i = nbvolinit; i < mengerVolumes.size(); i++) { LCC::Attribute_descriptor<3>::type ah = (scene.lcc)->create_attribute<3>(); scene.lcc->set_attribute<3>(mengerVolumes[i], ah); scene.lcc->info<3>(mengerVolumes[i]).color()= (CGAL::IO::Color(myrandom.get_int(0,256), myrandom.get_int(0,256), myrandom.get_int(0,256))); update_volume_list_add(scene.lcc->attribute<3>(mengerVolumes[i])); } scene.lcc->set_automatic_attributes_management(true); } #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Menger sponge " <mengerLevel-1<<" -> "<mengerLevel<<", " <<"attributes updated " <<(mengerUpdateAttributes ? "DURING" : "AFTER") << " construction: " <is_valid() ); QApplication::restoreOverrideCursor (); statusBar()->showMessage(QString ("Menger sponge creation %1 -> %2"). arg(this->mengerLevel-1).arg(this->mengerLevel), DELAY_STATUSMSG); Q_EMIT( sceneChanged()); } void MainWindow::split_edge_in_three(Dart_descriptor dh) { LCC::Point p1 = scene.lcc->point(dh); LCC::Point p2 = scene.lcc->point(scene.lcc->other_extremity(dh)); LCC::Vector v1 = LCC::Traits::Construct_vector() (p1,p2); LCC::Vector v2 = LCC::Traits::Construct_scaled_vector() (v1,1.0/3); LCC::Vector v3 = LCC::Traits::Construct_scaled_vector() (v1,2.0/3); LCC::Point p3 = LCC::Traits::Construct_translated_point() (p1,v2); LCC::Point p4 = LCC::Traits::Construct_translated_point() (p1,v3); (scene.lcc)->insert_point_in_cell<1>(dh,p4); (scene.lcc)->insert_point_in_cell<1>(dh,p3); } void MainWindow::split_face_in_three(Dart_descriptor dh) { scene.lcc->insert_cell_1_in_cell_2(scene.lcc->beta(dh,1,1,1), scene.lcc->beta(dh,0,0)); scene.lcc->insert_cell_1_in_cell_2(scene.lcc->beta(dh,1,1), scene.lcc->beta(dh,0)); } void MainWindow::split_face_in_nine(Dart_descriptor dh) { Dart_descriptor d2 = scene.lcc->beta(dh,1,1,1,1,1,1,1); Dart_descriptor e2= scene.lcc->insert_cell_1_in_cell_2 (scene.lcc->beta(dh,1,1),d2); Dart_descriptor e1= scene.lcc->insert_cell_1_in_cell_2 (scene.lcc->beta(dh,1),scene.lcc->beta(d2,1)); split_edge_in_three(e1); split_edge_in_three(e2); split_face_in_three(dh); split_face_in_three(d2); split_face_in_three(scene.lcc->beta(e2,0)); } void MainWindow::split_vol_in_three(Dart_descriptor dh, bool removecenter) { std::vector edges1; std::vector edges2; Dart_descriptor curd = scene.lcc->beta(dh,2,1,1,2); for (unsigned int i=0;i<4;++i) { edges1.push_back(curd); curd=scene.lcc->beta(curd,1,2,1); } CGAL_assertion( curd==scene.lcc->beta(dh,2,1,1,2) ); curd = scene.lcc->beta(curd,1,1,2); for (unsigned int i=0;i<4;++i) { edges2.push_back(curd); curd=scene.lcc->beta(curd,1,2,1); } CGAL_assertion( curd== scene.lcc->beta(dh,2,1,1,2,1,1,2) ); Dart_descriptor f1= scene.lcc->insert_cell_2_in_cell_3(edges1.begin(),edges1.end()); Dart_descriptor f2= scene.lcc->insert_cell_2_in_cell_3(edges2.begin(),edges2.end()); if (scene.lcc->are_attributes_automatically_managed()) { scene.lcc->info<3>(f1).color()= (CGAL::IO::Color(myrandom.get_int(0,256), myrandom.get_int(0,256), myrandom.get_int(0,256))); scene.lcc->info<3>(f2).color()= (CGAL::IO::Color(myrandom.get_int(0,256), myrandom.get_int(0,256), myrandom.get_int(0,256))); update_volume_list_add(scene.lcc->attribute<3>(dh)); } if ( removecenter ) scene.lcc->remove_cell<3>(f1); else { mengerVolumes.push_back(f1); if (scene.lcc->are_attributes_automatically_managed()) update_volume_list_add(scene.lcc->attribute<3>(f1)); } mengerVolumes.push_back(f2); } void MainWindow::split_vol_in_nine(Dart_descriptor dh, bool removecenter) { std::vector edges1; std::vector edges2; Dart_descriptor curd = scene.lcc->beta(dh,1,2); for (unsigned int i=0;i<8;++i) { edges1.push_back(curd); curd=scene.lcc->beta(curd,1,2,1); } CGAL_assertion( curd==scene.lcc->beta(dh,1,2) ); curd = scene.lcc->beta(curd,1,1,2); for (unsigned int i=0;i<8;++i) { edges2.push_back(curd); curd=scene.lcc->beta(curd,1,2,1); } CGAL_assertion( curd==scene.lcc->beta(dh,1,2,1,1,2) ); Dart_descriptor f1= scene.lcc->insert_cell_2_in_cell_3(edges1.begin(),edges1.end()); Dart_descriptor f2= scene.lcc->insert_cell_2_in_cell_3(edges2.begin(),edges2.end()); if (scene.lcc->are_attributes_automatically_managed()) { scene.lcc->info<3>(f1).color()= (CGAL::IO::Color(myrandom.get_int(0,256), myrandom.get_int(0,256), myrandom.get_int(0,256))); scene.lcc->info<3>(f2).color()= (CGAL::IO::Color(myrandom.get_int(0,256), myrandom.get_int(0,256), myrandom.get_int(0,256))); update_volume_list_add(scene.lcc->attribute<3>(dh)); if ( !removecenter) update_volume_list_add(scene.lcc->attribute<3>(f1)); } split_face_in_three(f1); split_face_in_three(f2); split_vol_in_three(dh,removecenter); mengerVolumes.push_back(scene.lcc->beta(f2,2,1)); split_vol_in_three(scene.lcc->beta(f2,2,1),removecenter); if ( removecenter ) scene.lcc->remove_cell<3>(f1); else { mengerVolumes.push_back(scene.lcc->beta(f1,2,1)); split_vol_in_three(scene.lcc->beta(f1,2,1),true); } } void MainWindow::split_vol_in_twentyseven(Dart_descriptor dh) { std::vector edges1; std::vector edges2; Dart_descriptor curd = scene.lcc->beta(dh,1,1,2); for (unsigned int i=0;i<12;++i) { edges1.push_back(curd); curd=scene.lcc->beta(curd,1,2,1); } CGAL_assertion( curd==scene.lcc->beta(dh,1,1,2) ); curd = scene.lcc->beta(curd,1,1,2); for (unsigned int i=0;i<12;++i) { edges2.push_back(curd); curd=scene.lcc->beta(curd,1,2,1); } CGAL_assertion( curd==scene.lcc->beta(dh,1,1,2,1,1,2) ); Dart_descriptor f1= scene.lcc->insert_cell_2_in_cell_3(edges1.begin(),edges1.end()); Dart_descriptor f2= scene.lcc->insert_cell_2_in_cell_3(edges2.begin(),edges2.end()); if (scene.lcc->are_attributes_automatically_managed()) { scene.lcc->info<3>(f1).color()= (CGAL::IO::Color(myrandom.get_int(0,256), myrandom.get_int(0,256), myrandom.get_int(0,256))); scene.lcc->info<3>(f2).color()= (CGAL::IO::Color(myrandom.get_int(0,256), myrandom.get_int(0,256), myrandom.get_int(0,256))); update_volume_list_add(scene.lcc->attribute<3>(dh)); update_volume_list_add(scene.lcc->attribute<3>(f1)); } mengerVolumes.push_back(scene.lcc->beta(f1,2)); mengerVolumes.push_back(scene.lcc->beta(f2,2)); split_face_in_nine(scene.lcc->beta(f1,1)); split_face_in_nine(scene.lcc->beta(f2,1)); split_vol_in_nine(dh,false); split_vol_in_nine(scene.lcc->beta(f1,2),true); split_vol_in_nine(scene.lcc->beta(f2,2),false); } void MainWindow::process_full_slice(Dart_descriptor init, std::vector& faces, LCC::size_type markVols) { Dart_descriptor d[12]; d[0]=scene.lcc->beta(init,1,2); d[1]=scene.lcc->beta(d[0],3,1,2,1); d[2]=scene.lcc->beta(d[1],1,2,1); d[3]=scene.lcc->beta(d[2],3,1,2,1); d[4]=scene.lcc->beta(init,1,1,2); d[5]=scene.lcc->beta(d[4],3,0,2,0); d[6]=scene.lcc->beta(d[5],0,2,0); d[7]=scene.lcc->beta(d[6],3,0,2,0); d[8]=scene.lcc->beta(d[7],3,0,2,0); d[9]=scene.lcc->beta(d[8],0,2,0); d[10]=scene.lcc->beta(d[9],3,0,2,0); d[11]=scene.lcc->beta(d[10],3,0,2,0); for (unsigned int j=0; j<12; ++j) { if ( !(scene.lcc)->is_marked(d[j], markVols) ) { CGAL::mark_cell(*(scene.lcc), d[j], markVols); } faces.push_back(d[j]); } } void MainWindow::process_inter_slice(Dart_descriptor init, std::vector& faces, LCC::size_type markVols) { Dart_descriptor d[24]; d[0]=init; d[1]=scene.lcc->beta(d[0],0,2,3,2,0); d[2]=scene.lcc->beta(d[1],0,2,3,2,0); d[3]=scene.lcc->beta(d[2],1,1,2,3,2); d[4]=scene.lcc->beta(d[3],1,1,2,3,2); d[5]=scene.lcc->beta(d[0],1,1,2,3,2); d[6]=scene.lcc->beta(d[5],1,1,2,3,2); d[7]=scene.lcc->beta(d[6],0,2,3,2,0); init = scene.lcc->beta(init,3,2,1,1,2); d[8]=init; d[9]=scene.lcc->beta(d[8],3,1,2,3,2,1); d[10]=scene.lcc->beta(d[9],1,2,3,2,1,3); d[11]=scene.lcc->beta(d[10],3,0,0,2,3,2); d[12]=scene.lcc->beta(d[11],0,0,2,3,2,3); d[13]=scene.lcc->beta(d[8],3,0,0,2,3,2); d[14]=scene.lcc->beta(d[13],0,0,2,3,2,3); d[15]=scene.lcc->beta(d[14],3,1,2,3,2,1); d[16]=scene.lcc->beta(d[0],3,1,2); d[17]=scene.lcc->beta(d[0],3,1,1,2); d[18]=scene.lcc->beta(d[4],3,2); d[19]=scene.lcc->beta(d[4],3,0,2); d[20]=scene.lcc->beta(d[2],3,0,2); d[21]=scene.lcc->beta(d[2],3,1,1,2); d[22]=scene.lcc->beta(d[6],3,2); d[23]=scene.lcc->beta(d[6],3,1,2); for (unsigned int j=0; j<24; ++j) { CGAL_assertion( d[j]!=(scene.lcc)->null_dart_descriptor ); if ( !(scene.lcc)->is_marked(d[j], markVols) ) { CGAL::mark_cell(*(scene.lcc), d[j], markVols); } faces.push_back(d[j]); } } void MainWindow::onMengerDec() { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif this->mengerLevel--; // We know here the number of Menger volume: 20^mengerLevel // thus we can directly "cut" the std::vector to the correct size. mengerVolumes.resize(CGAL::ipower(20,mengerLevel)); LCC::size_type markVols = (scene.lcc)->get_new_mark(); LCC::size_type markVertices = (scene.lcc)->get_new_mark(); std::vector faces; std::vector edges; std::vector vertices; // First we remove faces. for ( std::vector::iterator itvol=mengerVolumes.begin(); itvol!=mengerVolumes.end(); ++itvol) { if ( !(scene.lcc)->is_marked(*itvol, markVols) ) { Dart_descriptor init=*itvol; CGAL::mark_cell(*(scene.lcc), init, markVols); process_full_slice(init, faces, markVols); init=scene.lcc->beta(init, 2,1,1,2); process_inter_slice(init, faces, markVols); init=scene.lcc->beta(init, 3,2,1,1,2,3); process_full_slice(init, faces, markVols); } } for(std::size_t i = 0; i < faces.size(); i++) { scene.lcc->remove_cell<2>(faces[i],mengerUpdateAttributes); } faces.clear(); // Now we remove edges. for ( std::vector::iterator itvol=mengerVolumes.begin(); itvol!=mengerVolumes.end(); ++itvol) { if ( (scene.lcc)->is_marked(*itvol, markVols) ) CGAL::unmark_cell(*(scene.lcc), *itvol, markVols); for (LCC::Dart_of_cell_range<3>::iterator it=scene.lcc->darts_of_cell<3>(*itvol).begin(), itend=scene.lcc->darts_of_cell<3>(*itvol).end(); it!=itend; ++it) { if ( scene.lcc->is_free(it,2) && ( scene.lcc->is_free(it,3) || itbeta(it,3) ) ) edges.push_back(it); } } CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markVols) ); for(std::size_t i = 0; i < edges.size(); i++) { scene.lcc->remove_cell<1>(scene.lcc->beta(edges[i],0),mengerUpdateAttributes); scene.lcc->remove_cell<1>(scene.lcc->beta(edges[i],1),mengerUpdateAttributes); scene.lcc->remove_cell<1>(edges[i],mengerUpdateAttributes); } edges.clear(); // Lastly we remove vertices. for ( std::vector::iterator itvol=mengerVolumes.begin(); itvol!=mengerVolumes.end(); ++itvol) { for (LCC::Dart_of_cell_basic_range<3>::iterator it=(scene.lcc)->darts_of_cell_basic<3> (*itvol, markVols).begin(), itend=(scene.lcc)->darts_of_cell_basic<3> (*itvol, markVols).end(); it!=itend; ++it) { if ( !(scene.lcc)->is_marked(it, markVertices) ) { if ( scene.lcc->is_removable<0>(it) ) vertices.push_back(it); CGAL::mark_cell(*scene.lcc, it, markVertices); } } } (scene.lcc)->negate_mark(markVols); for ( std::vector::iterator itvol=mengerVolumes.begin(); itvol!=mengerVolumes.end(); ++itvol) { for (LCC::Dart_of_cell_basic_range<3>::iterator it=(scene.lcc)->darts_of_cell_basic<3> (*itvol, markVols).begin(), itend=(scene.lcc)->darts_of_cell_basic<3> (*itvol, markVols).end(); it!=itend; ++it) { if ( (scene.lcc)->is_marked(it, markVertices) ) CGAL::unmark_cell(*scene.lcc, it, markVertices); } } (scene.lcc)->negate_mark(markVols); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markVols) ); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markVertices) ); for(std::size_t i = 0; i < vertices.size(); i++) { scene.lcc->remove_cell<0>(vertices[i],mengerUpdateAttributes); } vertices.clear(); (scene.lcc)->free_mark(markVols); (scene.lcc)->free_mark(markVertices); if (!mengerUpdateAttributes) { scene.lcc->correct_invalid_attributes(); } #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Menger sponge " <mengerLevel+1<<" -> "<mengerLevel<<", " <<"attributes updated " <<(mengerUpdateAttributes ? "DURING" : "AFTER") << " construction: " <showMessage(QString ("Menger sponge creation %1 -> %2"). arg(this->mengerLevel+1).arg(this->mengerLevel), DELAY_STATUSMSG); QApplication::restoreOverrideCursor (); Q_EMIT( sceneChanged()); } /////////////////////////////////////////////////////////////////////////////////// // SIERPINSKI CARPET /////////////////////////////////////////////////////////////////////////////////// void MainWindow::on_actionCreate_Sierpinski_Carpet_triggered () { /*neverUpdateAttributes = dialogsierpinskicarpet.never->isChecked(); duringConstructionUpdateAttributes = dialogsierpinskicarpet.during->isChecked(); afterConstructionUpdateAttributes = dialogsierpinskicarpet.after->isChecked(); updateAttributesMethodStdMap = dialogsierpinskicarpet.stdmap->isChecked(); updateAttributesMethodTraversal = dialogsierpinskicarpet.traversal->isChecked(); // By default, the geometry will be computed after the construction isComputableGeometry = true;*/ computeGeometry = false; sierpinskiCarpetUpdateAttributes = dialogsierpinskicarpet.updateAttributes->isChecked(); dialogsierpinskicarpet.level->disconnect(this); dialogsierpinskicarpet.level->setValue(0); sierpinskiCarpetLevel=0; CGAL_assertion( sierpinskiCarpetSurfaces.empty() ); Point_3 basepoint(nbcube%5, (nbcube/5)%5, nbcube/25); Dart_descriptor d = scene.lcc->make_quadrangle(basepoint, LCC::Traits::Construct_translated_point() (basepoint,LCC::Traits::Vector(1,0,0)), LCC::Traits::Construct_translated_point() (basepoint,LCC::Traits::Vector(1,1,0)), LCC::Traits::Construct_translated_point() (basepoint,LCC::Traits::Vector(0,1,0))); on_new_volume(d); ++nbcube; statusBar ()->showMessage (QString ("Square created"),DELAY_STATUSMSG); Q_EMIT (sceneChanged ()); sierpinskiCarpetSurfaces.push_back(d); update_operations_entries(false); QObject::connect(dialogsierpinskicarpet.level, SIGNAL(valueChanged(int)), this, SLOT(onSierpinskiCarpetChangeLevel(int))); dialogsierpinskicarpet.show(); } void MainWindow::onSierpinskiCarpetCancel() { QApplication::setOverrideCursor (Qt::WaitCursor); for(std::vector::iterator it=sierpinskiCarpetSurfaces.begin(); it!=sierpinskiCarpetSurfaces.end(); ++it) { scene.lcc->remove_cell<2>(*it); } recreate_whole_volume_list(); sierpinskiCarpetSurfaces.clear(); update_operations_entries(true); QApplication::restoreOverrideCursor (); Q_EMIT( sceneChanged()); } void MainWindow::onSierpinskiCarpetOk() { update_operations_entries(true); sierpinskiCarpetSurfaces.clear(); } void MainWindow::onSierpinskiCarpetChangeLevel(int newLevel) { while ( newLevel > sierpinskiCarpetLevel ) onSierpinskiCarpetInc(); while ( newLevel < sierpinskiCarpetLevel ) onSierpinskiCarpetDec(); } void MainWindow::onSierpinskiCarpetUpdateAttributes(bool newValue) { sierpinskiCarpetUpdateAttributes = newValue; } void MainWindow::onSierpinskiCarpetInc() { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif this->sierpinskiCarpetLevel++; /* if (computeGeometry) { // Here case where the geometry could be computed after the construction, but it was not updated. computeGeometry = false; dialogsierpinskicarpet.computeGeometry->setEnabled(false); // => geometry will not be computed later. isComputableGeometry = false; }*/ std::vector edges; nbfacesinit = sierpinskiCarpetSurfaces.size(); LCC::size_type markEdges = (scene.lcc)->get_new_mark(); LCC::size_type markFaces = (scene.lcc)->get_new_mark(); for(std::vector::iterator itfaces=sierpinskiCarpetSurfaces.begin(); itfaces!=sierpinskiCarpetSurfaces.end(); ++itfaces) { CGAL_assertion( !(scene.lcc)->is_marked(*itfaces, markFaces) ); for (LCC::Dart_of_cell_basic_range<2>::iterator it=(scene.lcc)->darts_of_cell_basic<2>(*itfaces, markFaces).begin(), itend=(scene.lcc)->darts_of_cell_basic<2>(*itfaces, markFaces).end(); it!=itend; ++it) { if ( !(scene.lcc)->is_marked(it, markEdges) ) { edges.push_back(it); CGAL::mark_cell(*(scene.lcc), it, markEdges); } } } (scene.lcc)->negate_mark(markFaces); for(std::vector::iterator itfaces=sierpinskiCarpetSurfaces.begin(); itfaces!=sierpinskiCarpetSurfaces.end(); ++itfaces) { for (LCC::Dart_of_cell_basic_range<2>::iterator it=(scene.lcc)->darts_of_cell_basic<2>(*itfaces, markFaces).begin(), itend=(scene.lcc)->darts_of_cell_basic<2>(*itfaces, markFaces).end(); it!=itend; ++it) { (scene.lcc)->unmark(it, markEdges); } } (scene.lcc)->negate_mark(markFaces); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markFaces) ); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markEdges) ); (scene.lcc)->free_mark(markEdges); (scene.lcc)->free_mark(markFaces); /* if (afterConstructionUpdateAttributes) { if (updateAttributesMethodStdMap) { // We create a map to associate embeddings to new darts for(std::size_t i = 0; i < edges.size(); i++) { dart_map.insert(std::pair (edges[i], scene.lcc->point(edges[i]))); if (!(scene.lcc)->is_free(edges[i],2)) { dart_map.insert(std::pair ((scene.lcc)->beta(edges[i],2), scene.lcc->point((scene.lcc)->beta(edges[i],2)))); } } } }*/ for(std::size_t i = 0; i < edges.size(); i++) { sierpinski_carpet_split_edge_in_three(edges[i]); } edges.clear(); for(std::size_t i = 0; i < nbfacesinit; i++) { sierpinski_carpet_split_face_in_nine(sierpinskiCarpetSurfaces[i]); } if (!sierpinskiCarpetUpdateAttributes) { sierpinski_carpet_update_geometry(); } /* if (neverUpdateAttributes) { scene.lcc->correct_invalid_attributes(); // Now that the map is valid, we can compute the geometry if (isComputableGeometry) { computeGeometry = true; dialogsierpinskicarpet.computeGeometry->setEnabled(true); } }*/ #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Sierpinski carpet " <sierpinskiCarpetLevel-1<<" -> " <sierpinskiCarpetLevel<<", " <<"attributes updated " <<(sierpinskiCarpetUpdateAttributes ? "DURING" : "AFTER") << " construction: " <is_valid() ); statusBar()->showMessage(QString ("Sierpinski carpet creation %1 -> %2"). arg(this->sierpinskiCarpetLevel-1). arg(this->sierpinskiCarpetLevel), DELAY_STATUSMSG); QApplication::restoreOverrideCursor (); Q_EMIT( sceneChanged()); } void MainWindow::sierpinski_carpet_update_geometry() { /* if (updateAttributesMethodStdMap) { for(std::size_t i = 0; i < new_darts.size(); i++) { sierpinski_carpet_copy_attributes_and_embed_vertex(new_darts[i], dart_map[new_darts[i]]); } dart_map.clear(); new_darts.clear(); } if (updateAttributesMethodTraversal)*/ { LCC::size_type markVertices = (scene.lcc)->get_new_mark(); for(std::size_t i = 0; i < nbfacesinit; i++) { // Geometry of the 4 corners of the current face LCC::Point p[4][4]; Dart_descriptor d00 = sierpinskiCarpetSurfaces[i]; Dart_descriptor d03 = scene.lcc->beta(d00,1,2,1,1,2,1,1); Dart_descriptor d33 = scene.lcc->beta(d03,1,2,1,1,2,1,1); Dart_descriptor d30 = scene.lcc->beta(d33,1,2,1,1,2,1,1); sierpinski_carpet_compute_4x4_geometry_matrix(p, scene.lcc->point(d00), scene.lcc->point(d03), scene.lcc->point(d33), scene.lcc->point(d30)); Dart_descriptor dh = sierpinskiCarpetSurfaces[i]; // bottom border dh = scene.lcc->beta(dh,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { sierpinski_carpet_copy_attributes_and_embed_vertex(dh, p[0][1]); CGAL::mark_cell(*(scene.lcc), dh, markVertices); } dh = scene.lcc->beta(dh,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { sierpinski_carpet_copy_attributes_and_embed_vertex(dh, p[0][2]); CGAL::mark_cell(*(scene.lcc), dh, markVertices); } // right border dh = scene.lcc->beta(dh,1,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { sierpinski_carpet_copy_attributes_and_embed_vertex(dh, p[1][3]); CGAL::mark_cell(*(scene.lcc), dh, markVertices); } dh = scene.lcc->beta(dh,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { sierpinski_carpet_copy_attributes_and_embed_vertex(dh, p[2][3]); CGAL::mark_cell(*(scene.lcc), dh, markVertices); } // top border dh = scene.lcc->beta(dh,1,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { sierpinski_carpet_copy_attributes_and_embed_vertex(dh, p[3][2]); CGAL::mark_cell(*(scene.lcc), dh, markVertices); } dh = scene.lcc->beta(dh,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { sierpinski_carpet_copy_attributes_and_embed_vertex(dh, p[3][1]); CGAL::mark_cell(*(scene.lcc), dh, markVertices); } // left border dh = scene.lcc->beta(dh,1,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { sierpinski_carpet_copy_attributes_and_embed_vertex(dh, p[2][0]); CGAL::mark_cell(*(scene.lcc), dh, markVertices); } dh = scene.lcc->beta(dh,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { sierpinski_carpet_copy_attributes_and_embed_vertex(dh, p[1][0]); CGAL::mark_cell(*(scene.lcc), dh, markVertices); } dh = sierpinskiCarpetSurfaces[i]; // middle vertex, bottom left dh = scene.lcc->beta(dh,1,1); sierpinski_carpet_copy_attributes_and_embed_vertex(dh, p[1][1]); // middle vertex, top left dh = scene.lcc->beta(dh,2,1,1); sierpinski_carpet_copy_attributes_and_embed_vertex(dh, p[2][1]); // middle vertex, top right dh = scene.lcc->beta(dh,2,1,2,1,1,2,1); sierpinski_carpet_copy_attributes_and_embed_vertex(dh, p[2][2]); // middle vertex, bottom right dh = scene.lcc->beta(dh,2,1,1); sierpinski_carpet_copy_attributes_and_embed_vertex(dh, p[1][2]); } scene.lcc->unmark_all(markVertices); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markVertices) ); } } void MainWindow::sierpinski_carpet_compute_geometry() { LCC::size_type markVertices = (scene.lcc)->get_new_mark(); for(std::size_t i = 0; i < nbfacesinit; i++) { // on récupère la géométrie des 4 coins de la face courante LCC::Point p[4][4]; Dart_descriptor d00 = sierpinskiCarpetSurfaces[i]; Dart_descriptor d03 = scene.lcc->beta(d00,1,2,1,1,2,1,1); Dart_descriptor d33 = scene.lcc->beta(d03,1,2,1,1,2,1,1); Dart_descriptor d30 = scene.lcc->beta(d33,1,2,1,1,2,1,1); sierpinski_carpet_compute_4x4_geometry_matrix(p, scene.lcc->point(d00), scene.lcc->point(d03), scene.lcc->point(d33), scene.lcc->point(d30)); Dart_descriptor dh = sierpinskiCarpetSurfaces[i]; // Geometry of the 4 corners of the current face // bottom border dh = scene.lcc->beta(dh,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { scene.lcc->point(dh) = p[0][1]; CGAL::mark_cell(*(scene.lcc), dh, markVertices); } dh = scene.lcc->beta(dh,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { scene.lcc->point(dh) = p[0][2]; CGAL::mark_cell(*(scene.lcc), dh, markVertices); } // right border dh = scene.lcc->beta(dh,1,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { scene.lcc->point(dh) = p[1][3]; CGAL::mark_cell(*(scene.lcc), dh, markVertices); } dh = scene.lcc->beta(dh,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { scene.lcc->point(dh) = p[2][3]; CGAL::mark_cell(*(scene.lcc), dh, markVertices); } // top border dh = scene.lcc->beta(dh,1,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { scene.lcc->point(dh) = p[3][2]; CGAL::mark_cell(*(scene.lcc), dh, markVertices); } dh = scene.lcc->beta(dh,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { scene.lcc->point(dh) = p[3][1]; CGAL::mark_cell(*(scene.lcc), dh, markVertices); } // left border dh = scene.lcc->beta(dh,1,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { scene.lcc->point(dh) = p[2][0]; CGAL::mark_cell(*(scene.lcc), dh, markVertices); } dh = scene.lcc->beta(dh,1,2,1); if ( ! (scene.lcc)->is_marked(dh, markVertices) ) { scene.lcc->point(dh) = p[1][0]; CGAL::mark_cell(*(scene.lcc), dh, markVertices); } dh = sierpinskiCarpetSurfaces[i]; // middle vertex, bottom left dh = scene.lcc->beta(dh,1,1); scene.lcc->point(dh) = p[1][1]; // middle vertex, top left dh = scene.lcc->beta(dh,2,1,1); scene.lcc->point(dh) = p[2][1]; // middle vertex, top right dh = scene.lcc->beta(dh,2,1,2,1,1,2,1); scene.lcc->point(dh) = p[2][2]; // middle vertex, bottom right dh = scene.lcc->beta(dh,2,1,1); scene.lcc->point(dh) = p[1][2]; } scene.lcc->unmark_all(markVertices); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markVertices) ); } void MainWindow::sierpinski_carpet_compute_4x4_geometry_matrix (LCC::Point p[4][4], LCC::Point& p00, LCC::Point& p03, LCC::Point& p33, LCC::Point& p30) { p[0][0] = p00; p[0][3] = p03; p[3][3] = p33; p[3][0] = p30; LCC::Vector v1, v2, v3; // bottom border v1 = LCC::Traits::Construct_vector() (p[0][0],p[0][3]); v2 = LCC::Traits::Construct_scaled_vector() (v1,1.0/3); v3 = LCC::Traits::Construct_scaled_vector() (v1,2.0/3); p[0][1] = LCC::Traits::Construct_translated_point() (p[0][0],v2); p[0][2] = LCC::Traits::Construct_translated_point() (p[0][0],v3); // right border v1 = LCC::Traits::Construct_vector() (p[0][3],p[3][3]); v2 = LCC::Traits::Construct_scaled_vector() (v1,1.0/3); v3 = LCC::Traits::Construct_scaled_vector() (v1,2.0/3); p[1][3] = LCC::Traits::Construct_translated_point() (p[0][3],v2); p[2][3] = LCC::Traits::Construct_translated_point() (p[0][3],v3); // top border v1 = LCC::Traits::Construct_vector() (p[3][3],p[3][0]); v2 = LCC::Traits::Construct_scaled_vector() (v1,1.0/3); v3 = LCC::Traits::Construct_scaled_vector() (v1,2.0/3); p[3][2] = LCC::Traits::Construct_translated_point() (p[3][3],v2); p[3][1] = LCC::Traits::Construct_translated_point() (p[3][3],v3); // left border v1 = LCC::Traits::Construct_vector() (p[3][0],p[0][0]); v2 = LCC::Traits::Construct_scaled_vector() (v1,1.0/3); v3 = LCC::Traits::Construct_scaled_vector() (v1,2.0/3); p[2][0] = LCC::Traits::Construct_translated_point() (p[3][0],v2); p[1][0] = LCC::Traits::Construct_translated_point() (p[3][0],v3); // middle, left column v1 = LCC::Traits::Construct_vector() (p[0][1],p[3][1]); v2 = LCC::Traits::Construct_scaled_vector() (v1,1.0/3); v3 = LCC::Traits::Construct_scaled_vector() (v1,2.0/3); p[1][1] = LCC::Traits::Construct_translated_point() (p[0][1],v2); p[2][1] = LCC::Traits::Construct_translated_point() (p[0][1],v3); // middle, right column v1 = LCC::Traits::Construct_vector() (p[3][2],p[0][2]); v2 = LCC::Traits::Construct_scaled_vector() (v1,1.0/3); v3 = LCC::Traits::Construct_scaled_vector() (v1,2.0/3); p[2][2] = LCC::Traits::Construct_translated_point() (p[3][2],v2); p[1][2] = LCC::Traits::Construct_translated_point() (p[3][2],v3); } void MainWindow::sierpinski_carpet_copy_attributes_and_embed_vertex (Dart_descriptor dh, LCC::Point& p) { LCC::Attribute_descriptor<0>::type ah = (scene.lcc)->create_vertex_attribute(p); for ( LCC::Dart_of_cell_range<0>::iterator it=(scene.lcc)->darts_of_cell<0>(dh).begin(); it != (scene.lcc)->darts_of_cell<0>(dh).end(); ++it ) { // We copy all the attributes except for dim=0 LCC::Helper::Foreach_enabled_attributes_except , 0>:: run(*(scene.lcc),sierpinskiCarpetSurfaces[0],it); // We initialize the 0-atttrib to ah scene.lcc->set_dart_attribute<0>(it, ah); } } void MainWindow::sierpinski_carpet_split_edge_in_three(Dart_descriptor dh) { if (sierpinskiCarpetUpdateAttributes) { LCC::Point p1 = scene.lcc->point(dh); LCC::Point p2 = scene.lcc->point(scene.lcc->other_extremity(dh)); LCC::Vector v1 = LCC::Traits::Construct_vector() (p1,p2); LCC::Vector v2 = LCC::Traits::Construct_scaled_vector() (v1,1.0/3); LCC::Vector v3 = LCC::Traits::Construct_scaled_vector() (v1,2.0/3); LCC::Point p3 = LCC::Traits::Construct_translated_point() (p1,v2); LCC::Point p4 = LCC::Traits::Construct_translated_point() (p1,v3); (scene.lcc)->insert_point_in_cell<1>(dh,p4); (scene.lcc)->insert_point_in_cell<1>(dh,p3); } else { LCC::Point p3, p4; /*if (afterConstructionUpdateAttributes && updateAttributesMethodStdMap) { LCC::Point p1 = dart_map[dh]; LCC::Point p2 = dart_map[scene.lcc->other_extremity(dh)]; LCC::Vector v1 = LCC::Traits::Construct_vector() (p1,p2); LCC::Vector v2 = LCC::Traits::Construct_scaled_vector() (v1,1.0/3); LCC::Vector v3 = LCC::Traits::Construct_scaled_vector() (v1,2.0/3); p3 = LCC::Traits::Construct_translated_point() (p1,v2); p4 = LCC::Traits::Construct_translated_point() (p1,v3); }*/ // Dart_descriptor d1= scene.lcc->insert_cell_0_in_cell_1 (dh, LCC::null_descriptor, false); /*if (afterConstructionUpdateAttributes && updateAttributesMethodStdMap) { dart_map.insert(std::pair(d1, p4)); if (!(scene.lcc)->is_free(d1,2)) { dart_map.insert(std::pair((scene.lcc)->beta(d1,2,1), p4)); } new_darts.push_back((scene.lcc)->beta(dh,1)); }*/ // Dart_descriptor d2= scene.lcc->insert_cell_0_in_cell_1 (dh,LCC::null_descriptor,false); /*if (afterConstructionUpdateAttributes && updateAttributesMethodStdMap) { dart_map.insert(std::pair(d2, p3)); if (!(scene.lcc)->is_free(d2,2)) { dart_map.insert(std::pair((scene.lcc)->beta(d2,2,1), p3)); } new_darts.push_back((scene.lcc)->beta(dh,1)); }*/ } } void MainWindow::sierpinski_carpet_split_face_in_three(Dart_descriptor dh, bool removecenter) { Dart_descriptor d1= scene.lcc->insert_cell_1_in_cell_2 (scene.lcc->beta(dh,1,1,1),scene.lcc->beta(dh,0,0), sierpinskiCarpetUpdateAttributes); Dart_descriptor d2= scene.lcc->insert_cell_1_in_cell_2 (scene.lcc->beta(dh,1,1),scene.lcc->beta(dh,0), sierpinskiCarpetUpdateAttributes); if ( removecenter ) { scene.lcc->remove_cell<2>(d2,sierpinskiCarpetUpdateAttributes); } else { sierpinskiCarpetSurfaces.push_back(d2); } sierpinskiCarpetSurfaces.push_back(d1); } void MainWindow::sierpinski_carpet_split_face_in_nine(Dart_descriptor dh) { Dart_descriptor d1 = scene.lcc->beta(dh,1,1); Dart_descriptor d2 = scene.lcc->beta(dh,1,1,1,1,1,1,1); Dart_descriptor d3 = scene.lcc->beta(dh,1); Dart_descriptor d4 = scene.lcc->beta(d2,1); Dart_descriptor e2= scene.lcc->insert_cell_1_in_cell_2 (d1,d2,sierpinskiCarpetUpdateAttributes); /*if (afterConstructionUpdateAttributes && updateAttributesMethodStdMap) { dart_map.insert(std::pair(e2, dart_map[d2])); dart_map.insert(std::pair((scene.lcc)->beta(e2,2), dart_map[d1])); }*/ Dart_descriptor e1= scene.lcc->insert_cell_1_in_cell_2 (d3,d4,sierpinskiCarpetUpdateAttributes); /*if (afterConstructionUpdateAttributes && updateAttributesMethodStdMap) { dart_map.insert(std::pair(e1, dart_map[d4])); dart_map.insert(std::pair((scene.lcc)->beta(e1,2), dart_map[d3])); }*/ sierpinskiCarpetSurfaces.push_back(e2); sierpinskiCarpetSurfaces.push_back(e1); // We give the beta2 to not insert in new_darts a dart that will be removed // during the removal of the middle face sierpinski_carpet_split_edge_in_three(scene.lcc->beta(e1,2)); sierpinski_carpet_split_edge_in_three(e2); sierpinski_carpet_split_face_in_three(dh, false); sierpinski_carpet_split_face_in_three(d2, true); sierpinski_carpet_split_face_in_three(scene.lcc->beta(e2,0), false); } void MainWindow::onSierpinskiCarpetDec() { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif this->sierpinskiCarpetLevel--; // We know here the number of Sierpinski surfaces: 8^sierpinskiCarpetLevel // thus we can directly "cut" the std::vector to the correct size. sierpinskiCarpetSurfaces.resize(CGAL::ipower(8,sierpinskiCarpetLevel)); LCC::size_type markSurfaces = (scene.lcc)->get_new_mark(); LCC::size_type markVertices = (scene.lcc)->get_new_mark(); std::vector edges; std::vector vertices; // First we remove edges. for ( std::vector::iterator itsurfaces=sierpinskiCarpetSurfaces.begin(); itsurfaces!=sierpinskiCarpetSurfaces.end(); ++itsurfaces) { Dart_descriptor dh = *itsurfaces; dh = scene.lcc->beta(dh,1,1,2,1); edges.push_back(dh); dh = scene.lcc->beta(dh,1,2,1,2,1); edges.push_back(dh); dh = scene.lcc->beta(dh,1,2,1,2,1); edges.push_back(dh); dh = scene.lcc->beta(dh,1,2,1,2,1); edges.push_back(dh); } for(std::size_t i = 0; i < edges.size(); i++) { scene.lcc->remove_cell<1>(scene.lcc->beta(edges[i],0), sierpinskiCarpetUpdateAttributes); scene.lcc->remove_cell<1>(scene.lcc->beta(edges[i],1), sierpinskiCarpetUpdateAttributes); scene.lcc->remove_cell<1>(edges[i], sierpinskiCarpetUpdateAttributes); } edges.clear(); // Lastly we remove vertices. for ( std::vector::iterator itsurfaces=sierpinskiCarpetSurfaces.begin(); itsurfaces!=sierpinskiCarpetSurfaces.end(); ++itsurfaces) { Dart_descriptor dh = scene.lcc->beta(*itsurfaces,1); // we proceed side by side for (unsigned int i = 0; i < 4; i++) { if ( !(scene.lcc)->is_marked(dh, markVertices) ) { vertices.push_back(dh); CGAL::mark_cell(*scene.lcc, dh, markVertices); } dh = scene.lcc->beta(dh,1); if ( !(scene.lcc)->is_marked(dh, markVertices) ) { vertices.push_back(dh); CGAL::mark_cell(*scene.lcc, dh, markVertices); } dh = scene.lcc->beta(dh,1,1); } } (scene.lcc)->negate_mark(markSurfaces); for ( std::vector::iterator itsurfaces=sierpinskiCarpetSurfaces.begin(); itsurfaces!=sierpinskiCarpetSurfaces.end(); ++itsurfaces) { Dart_descriptor dh = scene.lcc->beta(*itsurfaces,1); for (unsigned int i = 0; i < 4; i++) { if ( (scene.lcc)->is_marked(dh, markVertices) ) CGAL::unmark_cell(*scene.lcc, dh, markVertices); dh = scene.lcc->beta(dh,1); if ( (scene.lcc)->is_marked(dh, markVertices) ) CGAL::unmark_cell(*scene.lcc, dh, markVertices); dh = scene.lcc->beta(dh,1,1); } } (scene.lcc)->negate_mark(markSurfaces); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markSurfaces) ); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markVertices) ); for(std::size_t i = 0; i < vertices.size(); i++) { scene.lcc->remove_cell<0>(vertices[i], sierpinskiCarpetUpdateAttributes); } vertices.clear(); (scene.lcc)->free_mark(markSurfaces); (scene.lcc)->free_mark(markVertices); if (!sierpinskiCarpetUpdateAttributes) { scene.lcc->correct_invalid_attributes(); } #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Sierpinski carpet " <sierpinskiCarpetLevel+1<<" -> " <sierpinskiCarpetLevel<<", " <<"attributes updated " <<(sierpinskiCarpetUpdateAttributes ? "DURING" : "AFTER") << " construction: " <showMessage(QString ("Sierpinski carpet creation %1 -> %2"). arg(this->sierpinskiCarpetLevel+1). arg(this->sierpinskiCarpetLevel), DELAY_STATUSMSG); Q_EMIT( sceneChanged()); } /////////////////////////////////////////////////////////////////////////////////// // SIERPINSKI TRIANGLE /////////////////////////////////////////////////////////////////////////////////// void MainWindow::on_actionCreate_Sierpinski_Triangle_triggered () { sierpinskiTriangleUpdateAttributes = dialogsierpinskitriangle.updateAttributes->isChecked(); dialogsierpinskitriangle.level->disconnect(this); dialogsierpinskitriangle.level->setValue(0); sierpinskiTriangleLevel=0; CGAL_assertion( sierpinskiTriangleSurfaces.empty() ); CGAL_assertion( removedTriangles.empty() ); Point_3 basepoint(nbcube%5, (nbcube/5)%5, nbcube/25); Dart_descriptor d = scene.lcc->make_triangle(basepoint, LCC::Traits::Construct_translated_point() (basepoint,LCC::Traits::Vector(1,0,0)), LCC::Traits::Construct_translated_point() (basepoint,LCC::Traits::Vector(0.5f,CGAL::sqrt(3.f)/2.f,0))); on_new_volume(d); ++nbcube; statusBar ()->showMessage (QString ("Triangle created"),DELAY_STATUSMSG); Q_EMIT (sceneChanged ()); sierpinskiTriangleSurfaces.push_back(d); update_operations_entries(false); QObject::connect(dialogsierpinskitriangle.level, SIGNAL(valueChanged(int)), this, SLOT(onSierpinskiTriangleChangeLevel(int))); dialogsierpinskitriangle.show(); } void MainWindow::onSierpinskiTriangleCancel() { for(std::vector::iterator it=sierpinskiTriangleSurfaces.begin(); it!=sierpinskiTriangleSurfaces.end(); ++it) { scene.lcc->remove_cell<2>(*it); } recreate_whole_volume_list(); sierpinskiTriangleSurfaces.clear(); update_operations_entries(true); Q_EMIT( sceneChanged()); } void MainWindow::onSierpinskiTriangleOk() { update_operations_entries(true); sierpinskiTriangleSurfaces.clear(); } void MainWindow::onSierpinskiTriangleChangeLevel(int newLevel) { while ( newLevel > sierpinskiTriangleLevel ) onSierpinskiTriangleInc(); while ( newLevel < sierpinskiTriangleLevel ) onSierpinskiTriangleDec(); } void MainWindow::onSierpinskiTriangleUpdateAttributes(bool newValue) { sierpinskiTriangleUpdateAttributes = newValue; } void MainWindow::onSierpinskiTriangleInc() { QApplication::setOverrideCursor (Qt::WaitCursor); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif this->sierpinskiTriangleLevel++; std::vector edges; nbfacesinit = sierpinskiTriangleSurfaces.size(); LCC::size_type markEdges = (scene.lcc)->get_new_mark(); LCC::size_type markFaces = (scene.lcc)->get_new_mark(); for(std::vector::iterator itfaces=sierpinskiTriangleSurfaces.begin(); itfaces!=sierpinskiTriangleSurfaces.end(); ++itfaces) { CGAL_assertion( !(scene.lcc)->is_marked(*itfaces, markFaces) ); for (LCC::Dart_of_cell_basic_range<2>::iterator it=(scene.lcc)->darts_of_cell_basic<2>(*itfaces, markFaces).begin(), itend=(scene.lcc)->darts_of_cell_basic<2>(*itfaces, markFaces).end(); it!=itend; ++it) { if ( !(scene.lcc)->is_marked(it, markEdges) ) { edges.push_back(it); CGAL::mark_cell(*(scene.lcc), it, markEdges); } } } (scene.lcc)->negate_mark(markFaces); for(std::vector::iterator itfaces=sierpinskiTriangleSurfaces.begin(); itfaces!=sierpinskiTriangleSurfaces.end(); ++itfaces) { for (LCC::Dart_of_cell_basic_range<2>::iterator it=(scene.lcc)->darts_of_cell_basic<2>(*itfaces, markFaces).begin(), itend=(scene.lcc)->darts_of_cell_basic<2>(*itfaces, markFaces).end(); it!=itend; ++it) { (scene.lcc)->unmark(it, markEdges); } } (scene.lcc)->negate_mark(markFaces); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markFaces) ); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markEdges) ); (scene.lcc)->free_mark(markEdges); (scene.lcc)->free_mark(markFaces); for(std::size_t i = 0; i < edges.size(); i++) { sierpinski_triangle_split_edge_in_two(edges[i]); } edges.clear(); for(std::size_t i = 0; i < nbfacesinit; i++) { sierpinski_triangle_split_face_in_four(sierpinskiTriangleSurfaces[i],true); } if (!sierpinskiTriangleUpdateAttributes) { for(std::size_t i = nbfacesinit; i < sierpinskiTriangleSurfaces.size(); i++) { LCC::Attribute_descriptor<3>::type ah = (scene.lcc)->create_attribute<3>(); scene.lcc->set_attribute<3>(sierpinskiTriangleSurfaces[i], ah); scene.lcc->info<3>(sierpinskiTriangleSurfaces[i]).color()= (CGAL::IO::Color(myrandom.get_int(0,256), myrandom.get_int(0,256), myrandom.get_int(0,256))); update_volume_list_add(scene.lcc->attribute<3>(sierpinskiTriangleSurfaces[i])); } scene.lcc->correct_invalid_attributes(); } #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Sierpinski triangle " <sierpinskiTriangleLevel-1<<" -> " <sierpinskiTriangleLevel<<", " <<"attributes updated " <<(sierpinskiTriangleUpdateAttributes ? "DURING" : "AFTER") << " construction: " <is_valid() ); statusBar()->showMessage(QString ("Sierpinski triangle creation %1 -> %2"). arg(this->sierpinskiTriangleLevel-1). arg(this->sierpinskiTriangleLevel), DELAY_STATUSMSG); QApplication::restoreOverrideCursor (); Q_EMIT( sceneChanged()); } void MainWindow::sierpinski_triangle_split_edge_in_two(Dart_descriptor dh) { LCC::Point p1 = scene.lcc->point(dh); LCC::Point p2 = scene.lcc->point(scene.lcc->other_extremity(dh)); LCC::Vector v1 = LCC::Traits::Construct_vector() (p1,p2); LCC::Vector v2 = LCC::Traits::Construct_scaled_vector() (v1,1.0/2); LCC::Point p3 = LCC::Traits::Construct_translated_point() (p1,v2); (scene.lcc)->insert_point_in_cell<1>(dh,p3,sierpinskiTriangleUpdateAttributes); } void MainWindow::sierpinski_triangle_split_face_in_four(Dart_descriptor dh, bool removecenter) { Dart_descriptor d1= scene.lcc->insert_cell_1_in_cell_2 (scene.lcc->beta(dh,1),scene.lcc->beta(dh,1,1,1), sierpinskiTriangleUpdateAttributes); Dart_descriptor d2= scene.lcc->insert_cell_1_in_cell_2 (scene.lcc->beta(d1,2,1),scene.lcc->beta(d1,2,1,1,1), sierpinskiTriangleUpdateAttributes); Dart_descriptor d3= scene.lcc->insert_cell_1_in_cell_2 (scene.lcc->beta(d2,2,1),scene.lcc->beta(d2,2,1,1,1), sierpinskiTriangleUpdateAttributes); if ( removecenter ) { Triplet triplet(d1,d2,d3); removedTriangles.push_back(triplet); // at this step, the map is correctly 0-embedded, any other attribute is set // (call of insert_point_in_cell<1> with update_attributes set to true) scene.lcc->remove_cell<2>(scene.lcc->beta(d3,2),sierpinskiTriangleUpdateAttributes); if (sierpinskiTriangleUpdateAttributes) { update_volume_list_add(scene.lcc->attribute<3>(scene.lcc->beta(d2,0))); update_volume_list_add(scene.lcc->attribute<3>(scene.lcc->beta(d1,0))); } else { // we duplicate all 0-embeddings to set them to the split vertices (scene.lcc)->set_dart_attribute<0>(scene.lcc->beta(d2,1),(scene.lcc)->create_vertex_attribute(scene.lcc->point(d1))); (scene.lcc)->set_dart_attribute<0>(scene.lcc->beta(d3,1),(scene.lcc)->create_vertex_attribute(scene.lcc->point(d2))); (scene.lcc)->set_dart_attribute<0>(scene.lcc->beta(d1,1),(scene.lcc)->create_vertex_attribute(scene.lcc->point(d3))); } } else { sierpinskiTriangleSurfaces.push_back(scene.lcc->beta(d3,2)); } sierpinskiTriangleSurfaces.push_back(scene.lcc->beta(d2,0)); sierpinskiTriangleSurfaces.push_back(scene.lcc->beta(d1,0)); } void MainWindow::onSierpinskiTriangleDec() { QApplication::setOverrideCursor( Qt::WaitCursor ); #ifdef CGAL_PROFILE_LCC_DEMO CGAL::Timer timer; timer.start(); #endif this->sierpinskiTriangleLevel--; int nbt = CGAL::ipower(3,this->sierpinskiTriangleLevel); // First we add triangles removed during construction process for ( std::size_t i = removedTriangles.size() - nbt; i < removedTriangles.size(); i++) { Dart_descriptor d1 = scene.lcc->create_dart(); Dart_descriptor d2 = scene.lcc->create_dart(); Dart_descriptor d3 = scene.lcc->create_dart(); scene.lcc->sew<1>(d1,d2); scene.lcc->sew<1>(d2,d3); scene.lcc->sew<1>(d3,d1); scene.lcc->sew<2>(d1, removedTriangles[i].first); scene.lcc->sew<2>(d2, removedTriangles[i].second); scene.lcc->sew<2>(d3, removedTriangles[i].third); } removedTriangles.resize(removedTriangles.size() - nbt); // We know here the number of Sierpinski surfaces: 3^sierpinskiTriangleLevel // thus we can directly "cut" the std::vector to the correct size. sierpinskiTriangleSurfaces.resize(CGAL::ipower(3,sierpinskiTriangleLevel)); LCC::size_type markSurfaces = (scene.lcc)->get_new_mark(); LCC::size_type markVertices = (scene.lcc)->get_new_mark(); std::vector edges; std::vector vertices; // Now we remove edges. for ( std::vector::iterator itsurfaces=sierpinskiTriangleSurfaces.begin(); itsurfaces!=sierpinskiTriangleSurfaces.end(); ++itsurfaces) { Dart_descriptor dh = *itsurfaces; dh = scene.lcc->beta(dh,1); edges.push_back(dh); dh = scene.lcc->beta(dh,2,1,2); edges.push_back(dh); dh = scene.lcc->beta(dh,2,1,2); edges.push_back(dh); } for(std::size_t i = 0; i < edges.size(); i++) { scene.lcc->remove_cell<1>(edges[i], sierpinskiTriangleUpdateAttributes); } edges.clear(); // Lastly we remove vertices. for ( std::vector::iterator itsurfaces=sierpinskiTriangleSurfaces.begin(); itsurfaces!=sierpinskiTriangleSurfaces.end(); ++itsurfaces) { Dart_descriptor dh = scene.lcc->beta(*itsurfaces,1); if ( !(scene.lcc)->is_marked(dh, markVertices) ) { vertices.push_back(dh); CGAL::mark_cell(*scene.lcc, dh, markVertices); } dh = scene.lcc->beta(dh,1,1); if ( !(scene.lcc)->is_marked(dh, markVertices) ) { vertices.push_back(dh); CGAL::mark_cell(*scene.lcc, dh, markVertices); } dh = scene.lcc->beta(dh,1,1); if ( !(scene.lcc)->is_marked(dh, markVertices) ) { vertices.push_back(dh); CGAL::mark_cell(*scene.lcc, dh, markVertices); } } (scene.lcc)->negate_mark(markSurfaces); for ( std::vector::iterator itsurfaces=sierpinskiTriangleSurfaces.begin(); itsurfaces!=sierpinskiTriangleSurfaces.end(); ++itsurfaces) { Dart_descriptor dh = scene.lcc->beta(*itsurfaces,1); if ( (scene.lcc)->is_marked(dh, markVertices) ) CGAL::unmark_cell(*scene.lcc, dh, markVertices); dh = scene.lcc->beta(dh,1,1); if ( (scene.lcc)->is_marked(dh, markVertices) ) CGAL::unmark_cell(*scene.lcc, dh, markVertices); dh = scene.lcc->beta(dh,1,1); if ( (scene.lcc)->is_marked(dh, markVertices) ) CGAL::unmark_cell(*scene.lcc, dh, markVertices); } (scene.lcc)->negate_mark(markSurfaces); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markSurfaces) ); CGAL_assertion( (scene.lcc)->is_whole_map_unmarked(markVertices) ); for(std::size_t i = 0; i < vertices.size(); i++) { scene.lcc->remove_cell<0>(vertices[i], sierpinskiTriangleUpdateAttributes); } vertices.clear(); (scene.lcc)->free_mark(markSurfaces); (scene.lcc)->free_mark(markVertices); if (!sierpinskiTriangleUpdateAttributes) { scene.lcc->correct_invalid_attributes(); } #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); std::cout<<"Sierpinski triangle " <sierpinskiTriangleLevel+1<<" -> " <sierpinskiTriangleLevel<<", " <<"attributes updated " <<(sierpinskiTriangleUpdateAttributes ? "DURING" : "AFTER") << " construction: " <showMessage(QString ("Sierpinski triangle creation %1 -> %2"). arg(this->sierpinskiTriangleLevel+1). arg(this->sierpinskiTriangleLevel), DELAY_STATUSMSG); QApplication::restoreOverrideCursor (); Q_EMIT( sceneChanged()); } #undef DELAY_STATUSMSG