diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index 34cdaf7f0b3..6a84b6ba0a5 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -350,6 +349,18 @@ namespace CGAL { bool is_empty() const { return mdarts.empty(); } + friend std::ostream& operator<< (std::ostream& os, const Self& amap) + { + save_combinatorial_map(amap, os); + return os; + } + + friend std::ifstream& operator>> (std::ifstream& is, Self& amap) + { + load_combinatorial_map(is, amap); + return is; + } + /** Create a new dart and add it to the map. * The marks of the darts are initialised with mmask_marks, i.e. the dart * is unmarked for all the marks. diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h b/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h new file mode 100644 index 00000000000..debd26b66e8 --- /dev/null +++ b/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h @@ -0,0 +1,800 @@ +// Copyright (c) 2010-2011 CNRS and LIRIS' Establishments (France). +// 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; either version 3 of the License, +// or (at your option) any later version. +// +// 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 +// Guillaume Castano +// Pascal Khieu +// +#ifndef CGAL_COMBINATORIAL_MAP_SAVE_LOAD_H +#define CGAL_COMBINATORIAL_MAP_SAVE_LOAD_H + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace CGAL { + + typedef Exact_predicates_inexact_constructions_kernel::Point_3 RPoint_3; + typedef Exact_predicates_exact_constructions_kernel::Point_3 EPoint_3; + + // Tags used in xml tree: + // For darts: + // + // // new dart + // neighbor dart index for beta1 + // ... + // value of dart (optional) + // + // ... + // + // For attributes: + // + // // new type of non void attribute + // type of the info associated + // // new attribute + // dart index + // value of attribute + // + // ... + // + + // Here T is a Dart_const_handle so we don't need & + template + void write_cmap_dart_node(boost::property_tree::ptree & /*node*/, T) + {} + + template + void write_cmap_attribute_node(boost::property_tree::ptree & /*node*/, const T&) + {} + + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + char val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + unsigned char val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + short int val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + unsigned short int val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + int val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + unsigned int val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + long int val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + unsigned long int val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + float val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + double val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + long double val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + bool val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + const std::string& val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + const RPoint_3& val) + { + node.add("p.x",val.x()); + node.add("p.y",val.y()); + node.add("p.z",val.z()); + } + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + const EPoint_3& val) + { + node.add("p.x",CGAL::to_double(val.x())); + node.add("p.y",CGAL::to_double(val.y())); + node.add("p.z",CGAL::to_double(val.z())); + } + + template::type>::value, + bool WithPoint=CGAL::Is_attribute_has_point + ::type >::value > + struct My_functor_cmap_save_one_attrib; + + // An attrib with point and with info + template + struct My_functor_cmap_save_one_attrib + { + static void run(const CMap* amap, boost::property_tree::ptree* ptree, + std::map* myDarts) + { + // to check all i-cells of the map + typename CMap::template Attribute_range::type::const_iterator + it_attrib, itend_attrib; + it_attrib=amap->template attributes().begin(); + itend_attrib=amap->template attributes().end(); + + // add dimension & type + boost::property_tree::ptree & ndim = ptree->add("dimension", ""); + ndim.put(".index", i); + ndim.add("type", typeid(typename CMap::template Attribute_type::type::Info).name()); + ndim.add("type_point", typeid(RPoint_3).name()); + + // for every attribute of the dimension + for (; it_attrib!=itend_attrib; ++it_attrib) + { + // make composant, dart and property node + boost::property_tree::ptree & nattr = ndim.add("a", ""); + /* boost::property_tree::ptree & ndarts = */ + nattr.add("d", (*myDarts)[it_attrib->dart()]); + + // update property node to add a value node (from basic or custom type + write_cmap_attribute_node(nattr, it_attrib->info()); + write_cmap_attribute_node(nattr, it_attrib->point()); + } + } + }; + + // An attribute with point and without info + template + struct My_functor_cmap_save_one_attrib + { + static void run(const CMap* amap, boost::property_tree::ptree* ptree, + std::map* myDarts) + { + // to check all i-cells of the map + typename CMap::template Attribute_range::type::const_iterator + it_attrib, itend_attrib; + it_attrib=amap->template attributes().begin(); + itend_attrib=amap->template attributes().end(); + + // add dimension & type + boost::property_tree::ptree & ndim = ptree->add("dimension", ""); + ndim.put(".index", i); + ndim.add("type", "void"); + ndim.add("type_point", typeid(RPoint_3).name()); + + // for every attribute of the dimension + for (; it_attrib!=itend_attrib; ++it_attrib) + { + // make composant, dart and property node + boost::property_tree::ptree & nattr = ndim.add("a", ""); + /* boost::property_tree::ptree & ndarts = */ + nattr.add("d", (*myDarts)[it_attrib->dart()]); + + // update property node to add a value node (from basic or custom type + write_cmap_attribute_node(nattr, it_attrib->point()); + } + } + }; + + // An attribute without point and with info + template + struct My_functor_cmap_save_one_attrib + { + static void run(const CMap* amap, boost::property_tree::ptree* ptree, + std::map* myDarts) + { + // to check all i-cells of the map + typename CMap::template Attribute_range::type::const_iterator + it_attrib, itend_attrib; + it_attrib=amap->template attributes().begin(); + itend_attrib=amap->template attributes().end(); + + // add dimension & type + boost::property_tree::ptree & ndim = ptree->add("dimension", ""); + ndim.put(".index", i); + ndim.add("type", typeid(typename CMap::template Attribute_type::type::Info).name()); + ndim.add("type_point", "void"); + + // for every attribute of the dimension + for (; it_attrib!=itend_attrib; ++it_attrib) + { + // make composant, dart and property node + boost::property_tree::ptree & nattr = ndim.add("a", ""); + /* boost::property_tree::ptree & ndarts = */ + nattr.add("d", (*myDarts)[it_attrib->dart()]); + + // update property node to add a value node (from basic or custom type + write_cmap_attribute_node(nattr, it_attrib->info()); + } + } + }; + + // An attrib without point and without info + template + struct My_functor_cmap_save_one_attrib + { + static void run(const CMap* amap, boost::property_tree::ptree* ptree, + std::map* myDarts) + { + // to check all i-cells of the map + typename CMap::template Attribute_range::type::const_iterator + it_attrib, itend_attrib; + it_attrib=amap->template attributes().begin(); + itend_attrib=amap->template attributes().end(); + + // add dimension & type + boost::property_tree::ptree & ndim = ptree->add("dimension", ""); + ndim.put(".index", i); + ndim.add("type", "void"); + ndim.add("type_point", "void"); + + // for every attribute of the dimension + for (; it_attrib!=itend_attrib; ++it_attrib) + { + // make composant, dart and property node + boost::property_tree::ptree & nattr = ndim.add("a", ""); + /* boost::property_tree::ptree & ndarts = */ + nattr.add("d", (*myDarts)[it_attrib->dart()]); + } + } + }; + + template + struct My_functor_cmap_save_attrib + { + template + static void run(const CMap* amap, boost::property_tree::ptree* ptree, + std::map* myDarts) + { + My_functor_cmap_save_one_attrib::run(amap, ptree, myDarts); + } + }; + + template < class CMap > + boost::property_tree::ptree cmap_save_darts + (const CMap& amap, std::map& myDarts) + { + assert( myDarts.empty() ); + + // First we numbered each dart by using the std::map. + typename CMap::Dart_range::const_iterator it(amap.darts().begin()); + for(typename CMap::size_type num=1; num<=amap.number_of_darts(); + ++num, ++it) + { + myDarts[it] = num; + } + + // make a tree + using boost::property_tree::ptree; + ptree pt; + + // Now we save each dart, and its neighbors. + it=amap.darts().begin(); + for(typename CMap::size_type num=0; num.i", dim); + } + } + + // update property node to add a value node (if user defined its own + // function) + write_cmap_dart_node(ndart, it); + } + + return pt; + } + + template < class CMap > + boost::property_tree::ptree cmap_save_attributes + (const CMap& amap, std::map& myDarts) + { + using boost::property_tree::ptree; + ptree pt; + + // update pt adding nodes containing attributes informations + CMap::Helper::template Foreach_enabled_attributes + >::run(&amap, &pt, &myDarts); + + return pt; + } + + template < class CMap > + bool save_combinatorial_map(const CMap& amap, std::ostream & output) + { + using boost::property_tree::ptree; + ptree data; + + // map dart => number + std::map myDarts; + + // Get darts + ptree pt_darts; + pt_darts = cmap_save_darts(amap, myDarts); + data.add_child("data.darts",pt_darts); + + // Get attributes + ptree pt_attr; + pt_attr = cmap_save_attributes(amap, myDarts); + data.add_child("data.attributes", pt_attr); + + // save data in output + write_xml(output, data); + + return true; + } + + template < class CMap > + bool save_combinatorial_map(const CMap& amap, const char* filename) + { + std::ofstream output(filename); + if (!output) return false; + return save_combinatorial_map(amap, output); + } + + // Here T is a Dart_handle so no need of & + template + void read_cmap_dart_node + (const boost::property_tree::ptree::value_type &/*v*/, T /*val*/) + {} + template + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &/*v*/, T &/*val*/) + {} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,char &val) + {val=boost::lexical_cast< char >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,unsigned char &val) + {val=boost::lexical_cast< unsigned char >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,short int &val) + {val=boost::lexical_cast< short int >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,unsigned short int &val) + {val=boost::lexical_cast< unsigned short int >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,int &val) + {val=boost::lexical_cast< int >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,unsigned int &val) + {val=boost::lexical_cast< unsigned int >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,long int &val) + {val=boost::lexical_cast< long int >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,unsigned long int &val) + {val=boost::lexical_cast< unsigned long int >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,float &val) + {val=boost::lexical_cast< float >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,double &val) + {val=boost::lexical_cast< double >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,long double &val) + {val=boost::lexical_cast< long double >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,bool &val) + {val=boost::lexical_cast< bool >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,std::string &val) + {val=boost::lexical_cast< std::string >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,RPoint_3 &val) + { + double x=v.second.get("x"); + double y=v.second.get("y"); + double z=v.second.get("z"); + val = RPoint_3(x,y,z); + } + + template::type>::value, + bool WithPoint=CGAL::Is_attribute_has_point + ::type >::value > + struct My_functor_cmap_load_one_attrib; + + // An attrib with point and with info + template + struct My_functor_cmap_load_one_attrib + { + static void run(const boost::property_tree::ptree& pt, CMap* amap, + const std::vector& myDarts) + { + BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0, + pt.get_child("data.attributes") ) + { + // + if (v0.first == "dimension") + { + int dimension=v0.second.get(".index", -1); + + // if map.dimension == dimension saved in the xml file + if (dimension==i) + { + unsigned int id_dart_cellule=0; + std::string type = v0.second.get("type"); + std::string type_map=std::string + (typeid(typename CMap::template Attribute_type::type::Info).name()); + + std::string ptype = v0.second.get("type_point"); + std::string ptype_map= std::string + (typeid(typename CMap::template Attribute_type::type::Point).name()); + + // std::cout<<"ptype="<("d")-1; + + BOOST_FOREACH(const boost::property_tree::ptree::value_type &v2, + v1.second ) + { + if( type==type_map && v2.first == "v" ) + { + if (myDarts[id_dart_cellule]-> + template attribute()==NULL ) + amap->template set_attribute + (myDarts[id_dart_cellule], + amap->template create_attribute()); + read_cmap_attribute_node + (v2, + myDarts[id_dart_cellule]-> + template attribute()->info()); + } + if( ptype==ptype_map && v2.first == "p" ) + { + if (myDarts[id_dart_cellule]-> + template attribute()==NULL ) + amap->template set_attribute + (myDarts[id_dart_cellule], + amap->template create_attribute()); + read_cmap_attribute_node + (v2, + myDarts[id_dart_cellule]-> + template attribute()->point()); + } + } + } + } + } + } + } + } + }; + + // An attribute with point and without info + template + struct My_functor_cmap_load_one_attrib + { + static void run(const boost::property_tree::ptree& pt, CMap* amap, + const std::vector& myDarts) + { + BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0, + pt.get_child("data.attributes") ) + { + // + if (v0.first == "dimension") + { + int dimension=v0.second.get(".index", -1); + + // if map.dimension == dimension saved in the xml file + if (dimension==i) + { + unsigned int id_dart_cellule=0; + std::string ptype = v0.second.get("type_point"); + std::string type_map= typeid + (typename CMap::template Attribute_type::type::Point).name(); + // std::cout<<"ptype="<("d")-1; + + BOOST_FOREACH(const boost::property_tree::ptree::value_type &v2, + v1.second ) + { + if( v2.first == "p" ) + { + if (myDarts[id_dart_cellule]-> + template attribute()==NULL ) + amap->template set_attribute + (myDarts[id_dart_cellule], + amap->template create_attribute()); + + read_cmap_attribute_node + (v2, + myDarts[id_dart_cellule]-> + template attribute()->point()); + } + } + } + } + } + } + } + } + }; + + // An attribute without point and with info + template + struct My_functor_cmap_load_one_attrib + { + static void run(const boost::property_tree::ptree& pt, CMap* amap, + const std::vector& myDarts) + { + BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0, + pt.get_child("data.attributes") ) + { + // + if (v0.first == "dimension") + { + int dimension=v0.second.get(".index", -1); + + // if map.dimension == dimension saved in the xml file + if (dimension==i) + { + unsigned int id_dart_cellule=0; + std::string ptype = v0.second.get("type"); + std::string type_map= typeid + (typename CMap::template Attribute_type::type::Info).name(); + // std::cout<<"ptype="<("d")-1; + + BOOST_FOREACH(const boost::property_tree::ptree::value_type &v2, + v1.second ) + { + if( v2.first == "v" ) + { + if (myDarts[id_dart_cellule]-> + template attribute()==NULL ) + amap->template set_attribute + (myDarts[id_dart_cellule], + amap->template create_attribute()); + read_cmap_attribute_node + (v2, + myDarts[id_dart_cellule]-> + template attribute()->info()); + } + } + } + } + } + } + } + } + }; + + // An attribute without point and without info + template + struct My_functor_cmap_load_one_attrib + { + static void run(const boost::property_tree::ptree& pt, CMap* amap, + const std::vector& myDarts) + { + BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0, + pt.get_child("data.attributes") ) + { + // + if (v0.first == "dimension") + { + int dimension=v0.second.get(".index", -1); + + // if map.dimension == dimension saved in the xml file + if (dimension==i) + { + unsigned int id_dart_cellule=0; + + BOOST_FOREACH(const boost::property_tree::ptree::value_type &v1, + v0.second ) + { + if( v1.first == "a" ) + { + id_dart_cellule=v1.second.get("d")-1; + + if (myDarts[id_dart_cellule]-> + template attribute()==NULL ) + amap->template set_attribute + (myDarts[id_dart_cellule], + amap->template create_attribute()); + } + } + } + } + } + } + }; + + /** Functor called to load i-attributes. + * @param pt a boost::property_tree::ptree load from an xml file + * @param amap a pointer to the map to load into + * @param myDarts an array of Dart_handle st myDarts[i] is the ith dart. + */ + template + struct My_functor_cmap_load_attrib + { + template + static void run(const boost::property_tree::ptree& pt, CMap* amap, + const std::vector& myDarts) + { + My_functor_cmap_load_one_attrib::run(pt, amap, myDarts); + } + }; + + template < class CMap > + bool cmap_load_darts(boost::property_tree::ptree &pt, CMap& amap, + std::vector& myDarts) + { + // use a boost::property_tree + using boost::property_tree::ptree; + + // make darts + BOOST_FOREACH( const ptree::value_type &v, pt.get_child("data.darts") ) + { + if( v.first == "d" ) + myDarts.push_back(amap.create_dart()); + } + + // update beta links + unsigned int index; + unsigned int currentDartInt = 0; + unsigned int nextDartInt; + + BOOST_FOREACH( const ptree::value_type &v, pt.get_child("data.darts") ) + { + if( v.first == "d" ) + { + BOOST_FOREACH( const ptree::value_type &v2, v.second ) + { + if (v2.first == "b") + { + index = v2.second.get(".i", 0); + nextDartInt = boost::lexical_cast< int >(v2.second.data())-1; + + if ( index<=amap.dimension ) + { + // A->B + amap.basic_link_beta(myDarts[currentDartInt], + myDarts[nextDartInt], + index); + + //B->A + amap.basic_link_beta(myDarts[nextDartInt], + myDarts[currentDartInt], + CGAL_BETAINV(index)); + } + } + else if (v2.first=="v") + read_cmap_dart_node(v2,myDarts[currentDartInt]); + } + } + ++currentDartInt; + } + + return true; + } + + template < class CMap > + void cmap_load_attributes(const boost::property_tree::ptree& pt, CMap& amap, + const std::vector& myDarts) + { + CMap::Helper::template Foreach_enabled_attributes + >::run(pt,&amap,myDarts); + } + + template < class CMap > + bool load_combinatorial_map(std::ifstream & input, CMap& amap) + { + using boost::property_tree::ptree; + ptree pt; + read_xml(input, pt); + std::vector myDarts; + cmap_load_darts(pt,amap,myDarts); + cmap_load_attributes(pt,amap,myDarts); + return true; + } + + template < class CMap > + bool load_combinatorial_map(const char* filename, CMap& amap) + { + std::ifstream input(filename); + if (!input) return false; + return load_combinatorial_map(input, amap); + } + +} // namespace CGAL + +#endif // CGAL_COMBINATORIAL_MAP_SAVE_LOAD_H // +// EOF // diff --git a/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt b/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt index 00a9cb20db1..763c25d968e 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt +++ b/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt @@ -16,6 +16,7 @@ endif() ## To add expensive tests # add_definitions("-DCGAL_CHECK_EXPENSIVE") +# add_definitions("-Wall -Wextra") ## For profilling with gprof # add_definitions("-pg") @@ -72,7 +73,6 @@ target_link_libraries(Linear_cell_complex_3_demo ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES}) target_link_libraries(Linear_cell_complex_3_demo ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ) -target_link_libraries(Linear_cell_complex_3_demo ${OPENGL_gl_LIBRARY} - ${OPENGL_glu_LIBRARY} ) +target_link_libraries(Linear_cell_complex_3_demo ${OPENGL_gl_LIBRARY} ) endif() diff --git a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp index 6d7dcbee5bd..34b0fb2a1cf 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp +++ b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp @@ -24,6 +24,8 @@ #include #include #include +#include "MainWindow.moc" +#include "import_moka.h" // Function defined in Linear_cell_complex_3_subivision.cpp void subdivide_lcc_3 (LCC & m); @@ -58,7 +60,7 @@ MainWindow::MainWindow (QWidget * parent):CGAL::Qt::DemosMainWindow (parent), labels.append(QString(tr("Hidden"))); volumeList->setHorizontalHeaderLabels(labels); //volumeList->resizeColumnsToContents(); - volumeList->setFixedWidth(200); + volumeList->setFixedWidth(220); /* volumeList->setColumnWidth(0,85); volumeList->setColumnWidth(1,35); volumeList->setColumnWidth(2,35);*/ @@ -82,7 +84,7 @@ MainWindow::MainWindow (QWidget * parent):CGAL::Qt::DemosMainWindow (parent), this->addRecentFiles (this->menuFile, this->actionQuit); connect (this, SIGNAL (openRecentFile (QString)), - this, SLOT (load_off (QString))); + this, SLOT (load_depend_on_extension(QString))); statusMessage = new QLabel ("Darts: 0, Vertices: 0 (Points: 0), Edges: 0, Facets: 0," @@ -223,6 +225,32 @@ void MainWindow::init_all_new_volumes() { 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, true); + } +} + void MainWindow::on_actionImportOFF_triggered () { QString fileName = QFileDialog::getOpenFileName (this, @@ -236,6 +264,19 @@ void MainWindow::on_actionImportOFF_triggered () } } +void MainWindow::on_actionImportMoka_triggered() +{ + QString fileName = QFileDialog::getOpenFileName (this, + tr ("Import Moka"), + "./moka", + tr ("Moka files (*.moka)")); + + if (!fileName.isEmpty ()) + { + load_moka(fileName, true); + } +} + void MainWindow::on_actionImport3DTDS_triggered () { QString fileName = QFileDialog::getOpenFileName (this, @@ -264,6 +305,84 @@ void MainWindow::on_actionAddOFF_triggered() } } +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 + + CGAL::import_from_moka < LCC > (*scene.lcc, qPrintable (fileName)); + +#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 ()); +} + Dart_handle MainWindow::make_iso_cuboid(const Point_3 basepoint, LCC::FT lg) { return scene.lcc->make_hexahedron(basepoint, @@ -783,7 +936,7 @@ void MainWindow::on_actionRemove_filled_volumes_triggered() DELAY_STATUSMSG); } -void MainWindow::on_actionTriangulate_all_facets_triggered() +void MainWindow::on_actionInsert_center_vertices_triggered() { QApplication::setOverrideCursor (Qt::WaitCursor); @@ -805,17 +958,113 @@ void MainWindow::on_actionTriangulate_all_facets_triggered() #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); - std::cout<<"Time to triangulate all filled faces: " + std::cout<<"Time to insert center vertices in all filled faces: " <showMessage - (QString ("Facets of visible and filled volume(s) triangulated"), + (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)/M_PI*180.0; + else if (a > 1.0) return acos(1.0)/M_PI*180.0; + else return acos(a)/M_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_update_attributes(false); + + std::vector edges; + int treated = scene.lcc->get_new_mark(); + int 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 ( CGAL::is_removable(*scene.lcc, 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_handle actu = *it, prev=NULL; + 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) ) + { + CGAL::remove_cell(*scene.lcc, actu); + actu = prev; + } + else + actu = NULL; + } + while (actu!=NULL && (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)) ) + CGAL::remove_cell(*scene.lcc, *it); + } + + assert(scene.lcc->is_whole_map_marked(treated)); + scene.lcc->free_mark(treated); + scene.lcc->free_mark(treated2); + + scene.lcc->set_update_attributes(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); @@ -861,6 +1110,179 @@ void MainWindow::on_actionMerge_all_volumes_triggered() (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_handle 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=LCC::null_handle, first=LCC::null_handle, + vh=LCC::null_handle; + + 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()=it; + if( first==NULL ) + { + first=vh; + } + if( previous!=NULL) + { + 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 = false; + fit->info().exist_edge[0]=false; + fit->info().exist_edge[1]=false; + fit->info().exist_edge[2]=false; + } + + std::queue face_queue; + + 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_external) + { + fh->info().is_external = true; + 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)] ); + const CDT::Vertex_handle va = fh->vertex(cdt. cw(index)); + const CDT::Vertex_handle vb = fh->vertex(cdt.ccw(index)); + + Dart_handle ndart= + CGAL::insert_cell_1_in_cell_2(lcc,va->info(),vb->info()); + va->info()=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_handle<3>::type ah) { for(int row=0; row < volumeList->rowCount(); ++row) @@ -975,6 +1397,8 @@ void MainWindow::recreate_whole_volume_list() 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() ); @@ -994,6 +1418,7 @@ void MainWindow::onCellChanged(int row, int col) (volumeList->item(row,1)->flags()|Qt::ItemIsEnabled); } + connectVolumeListHandlers(); Q_EMIT( sceneChanged()); } @@ -1875,64 +2300,6 @@ void MainWindow::onSierpinskiCarpetUpdateAttributes(bool newValue) sierpinskiCarpetUpdateAttributes = newValue; } -/*void MainWindow::onSierpinskiCarpetNeverUpdateAttributes(bool newValue) -{ - if (afterConstructionUpdateAttributes) - { - dialogsierpinskicarpet.groupBox2->setEnabled(false); - } - - neverUpdateAttributes = true; - duringConstructionUpdateAttributes = false; - afterConstructionUpdateAttributes = false; -} - -void MainWindow::onSierpinskiCarpetDuringConstructionUpdateAttributes(bool newValue) -{ - if (afterConstructionUpdateAttributes) - { - dialogsierpinskicarpet.groupBox2->setEnabled(false); - } - - neverUpdateAttributes = false; - duringConstructionUpdateAttributes = true; - afterConstructionUpdateAttributes = false; -} - -void MainWindow::onSierpinskiCarpetAfterConstructionUpdateAttributes(bool newValue) -{ - if (!afterConstructionUpdateAttributes) - { - dialogsierpinskicarpet.groupBox2->setEnabled(true); - } - - neverUpdateAttributes = false; - duringConstructionUpdateAttributes = false; - afterConstructionUpdateAttributes = true; -} - -void MainWindow::onSierpinskiCarpetUpdateAttributesMethodStdMap(bool newValue) -{ - updateAttributesMethodStdMap = true; - updateAttributesMethodTraversal = false; -} - -void MainWindow::onSierpinskiCarpetUpdateAttributesMethodTraversal(bool newValue) -{ - updateAttributesMethodStdMap = false; - updateAttributesMethodTraversal = true; -} - -void MainWindow::onSierpinskiCarpetComputeGeometry(bool newValue) -{ - sierpinski_carpet_compute_geometry(); - - computeGeometry = false; - dialogsierpinskicarpet.computeGeometry->setEnabled(false); - - Q_EMIT( sceneChanged()); -}*/ - void MainWindow::onSierpinskiCarpetInc() { QApplication::setOverrideCursor (Qt::WaitCursor); diff --git a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.h b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.h index 4f4d5c751a1..2e58379a474 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.h +++ b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.h @@ -110,9 +110,12 @@ public: public Q_SLOTS: // File menu + void on_actionSave_triggered(); + void on_actionLoad_triggered(); void on_actionImportOFF_triggered(); void on_actionAddOFF_triggered(); void on_actionImport3DTDS_triggered(); + void on_actionImportMoka_triggered(); void on_actionCompute_Voronoi_3D_triggered(); void on_actionClear_triggered(); @@ -130,19 +133,25 @@ public Q_SLOTS: void on_actionSubdivide_pqq_triggered(); void on_actionDual_3_triggered(); void on_actionClose_volume_triggered(); - void on_actionTriangulate_all_facets_triggered(); void on_actionSew3_same_facets_triggered(); void on_actionUnsew3_all_triggered(); + void on_actionMerge_coplanar_faces_triggered(); void on_actionMerge_all_volumes_triggered(); void on_actionRemove_filled_volumes_triggered(); + void on_actionInsert_center_vertices_triggered(); + void on_actionTriangulate_all_facets_triggered(); // View menu void on_actionExtend_filled_volumes_triggered(); void on_actionExtend_hidden_volumes_triggered(); // Other slots + void load_depend_on_extension(const QString& fileName, bool clear=true); + void load(const QString& fileName, bool clear=true); + void save(const QString& fileName); void load_off(const QString& fileName, bool clear=true); void load_3DTDS(const QString& fileName, bool clear=true); + void load_moka(const QString& fileName, bool clear=true); void onSceneChanged(); diff --git a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.ui b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.ui index 3a6b68d7f72..321dc4f3bc1 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.ui +++ b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.ui @@ -33,15 +33,19 @@ 0 0 635 - 22 + 25 &File + + + + @@ -54,12 +58,15 @@ &Operations + - - + + + + @@ -221,6 +228,31 @@ Create Sierpinski Triangle + + + &Load + + + + + &Save + + + + + Import Moka + + + + + Merge coplanar faces + + + + + Insert center vertices in faces + + diff --git a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp index 48569ec0990..d1ad8b71ebf 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp +++ b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp @@ -16,646 +16,585 @@ // $Id$ // // Author(s) : Guillaume Damiand -// Kumar Snehasish +// Contributor(s): Kumar Snehasish // #include "Viewer.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include + +#include #include -typedef LCC::Traits Traits; -typedef CGAL::Triangulation_2_filtered_projection_traits_3 P_traits; -struct Face_info { - LCC::Dart_handle e[3]; - bool is_external; -}; -typedef CGAL::Triangulation_vertex_base_with_info_2 Vb; -typedef CGAL::Triangulation_face_base_with_info_2 Fb1; -typedef CGAL::Constrained_triangulation_face_base_2 Fb; -typedef CGAL::Triangulation_data_structure_2 TDS; -typedef CGAL::No_intersection_tag Itag; -typedef CGAL::Constrained_Delaunay_triangulation_2 CDTbase; -typedef CGAL::Constrained_triangulation_plus_2 CDT; - Viewer::Viewer(QWidget* parent) - : QGLViewer(CGAL::Qt::createOpenGLContext(),parent), wireframe(false), flatShading(true), - edges(true), vertices(true), m_displayListCreated(false) + : QGLViewer(CGAL::Qt::createOpenGLContext(),parent), wireframe(false), + flatShading(true), edges(true), vertices(true), + m_previous_scene_empty(true), are_buffers_initialized(false) + { QGLFormat newFormat = this->format(); newFormat.setSampleBuffers(true); newFormat.setSamples(16); this->setFormat(newFormat); - are_buffers_initialized = false; -} -//Make sure all the facets are triangles -bool -Viewer::is_Triangulated() -{ - - LCC &lcc = *scene->lcc; - for (LCC::Attribute_range<3>::type::iterator - it=lcc.attributes<3>().begin(), - itend=lcc.attributes<3>().end(); it!=itend; ++it ) - { - - for(LCC::One_dart_per_incident_cell_range<2,3>::iterator - dartIter=lcc.one_dart_per_incident_cell<2,3> - (lcc.dart_of_attribute<3>(it)).begin(); dartIter.cont(); ++dartIter) - { - int nb_points_per_facet =0; - for (LCC::Dart_of_orbit_range<1>::const_iterator - orbitIter = lcc.darts_of_orbit<1>(dartIter).begin(); - orbitIter.cont(); ++orbitIter) - { - nb_points_per_facet++; - } - if(nb_points_per_facet != 3) - { - return false; - } - - } - } - return true; } -void Viewer::triangulate_facet() +Viewer::~Viewer() { - - - pos_facets.resize(0); - flat_normals.resize(0); - smooth_normals.resize(0); - colors.resize(0); - - LCC &lcc = *scene->lcc; - - for (LCC::Attribute_range<3>::type::iterator - it=lcc.attributes<3>().begin(), - itend=lcc.attributes<3>().end(); it!=itend; ++it ) - { - if ( it->info().is_visible() ) - { - for(LCC::One_dart_per_incident_cell_range<2,3>::iterator - dartIter=lcc.one_dart_per_incident_cell<2,3> - (lcc.dart_of_attribute<3>(it)).begin(); dartIter.cont(); ++dartIter) - { - - //Computes the normal of the facet - Traits::Vector_3 normal = CGAL::compute_normal_of_cell_2(lcc,dartIter); - normal = normal/(CGAL::sqrt(normal*normal)); - - P_traits cdt_traits(normal); - CDT cdt(cdt_traits); - - LCC::Dart_of_orbit_range<1>::const_iterator - he_circ = lcc.darts_of_orbit<1>(dartIter).begin(), - he_circ_end = lcc.darts_of_orbit<1>(dartIter).end(); - - // Iterates on the vector of facet handles - CDT::Vertex_handle previous, first; - do { - CDT::Vertex_handle vh = cdt.insert(lcc.point(he_circ)); - if(first == 0) { - first = vh; - } - //vh->info() = he_circ; - if(previous != 0 && previous != vh) { - cdt.insert_constraint(previous, vh); - } - previous = vh; - } while( ++he_circ != he_circ_end ); - cdt.insert_constraint(previous, first); - - // sets mark is_external - for(CDT::All_faces_iterator - fit = cdt.all_faces_begin(), - end = cdt.all_faces_end(); - fit != end; ++fit) - { - fit->info().is_external = false; - } - //check if the facet is external or internal - std::queue face_queue; - 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_external) continue; - fh->info().is_external = true; - for(int i = 0; i <3; ++i) { - if(!cdt.is_constrained(std::make_pair(fh, i))) - { - face_queue.push(fh->neighbor(i)); - } - } - } - - //iterates on the internal faces to add the vertices to the positions - //and the normals to the appropriate vectors - for(CDT::Finite_faces_iterator - ffit = cdt.finite_faces_begin(), - end = cdt.finite_faces_end(); - ffit != end; ++ffit) - { - if(ffit->info().is_external) - continue; - - //compute normals (no smooth for non-triangle facets objects - LCC::Vector normal = CGAL::compute_normal_of_cell_2(lcc,dartIter); - normal = normal/(CGAL::sqrt(normal*normal)); - - smooth_normals.push_back(normal.x());smooth_normals.push_back(normal.y());smooth_normals.push_back(normal.z()); - smooth_normals.push_back(normal.x());smooth_normals.push_back(normal.y());smooth_normals.push_back(normal.z()); - smooth_normals.push_back(normal.x());smooth_normals.push_back(normal.y());smooth_normals.push_back(normal.z()); - - flat_normals.push_back(normal.x());flat_normals.push_back(normal.y());flat_normals.push_back(normal.z()); - flat_normals.push_back(normal.x());flat_normals.push_back(normal.y());flat_normals.push_back(normal.z()); - flat_normals.push_back(normal.x());flat_normals.push_back(normal.y());flat_normals.push_back(normal.z()); - - - - pos_facets.push_back(ffit->vertex(0)->point().x()); pos_facets.push_back(ffit->vertex(0)->point().y()); pos_facets.push_back(ffit->vertex(0)->point().z()); - pos_facets.push_back(ffit->vertex(1)->point().x()); pos_facets.push_back(ffit->vertex(1)->point().y()); pos_facets.push_back(ffit->vertex(1)->point().z()); - pos_facets.push_back(ffit->vertex(2)->point().x()); pos_facets.push_back(ffit->vertex(2)->point().y()); pos_facets.push_back(ffit->vertex(2)->point().z()); - - double r = (double)lcc.info<3>(dartIter).color().r()/255.0; - double g = (double)lcc.info<3>(dartIter).color().g()/255.0; - double b = (double)lcc.info<3>(dartIter).color().b()/255.0; - if ( !lcc.is_free(dartIter, 3) ) - { - r += (double)lcc.info<3>(lcc.beta(dartIter,3)).color().r()/255.0; - g += (double)lcc.info<3>(lcc.beta(dartIter,3)).color().g()/255.0; - b += (double)lcc.info<3>(lcc.beta(dartIter,3)).color().b()/255.0; - r /= 2; g /= 2; b /= 2; - } - colors.push_back(r);colors.push_back(g);colors.push_back(b); - colors.push_back(r);colors.push_back(g);colors.push_back(b); - colors.push_back(r);colors.push_back(g);colors.push_back(b); - - - } - } - } - } + buffers[0].destroy(); + buffers[1].destroy(); + buffers[2].destroy(); + buffers[3].destroy(); + buffers[4].destroy(); + buffers[5].destroy(); + buffers[6].destroy(); + buffers[7].destroy(); + vao[0].destroy(); + vao[1].destroy(); + vao[2].destroy(); + vao[3].destroy(); } void Viewer::compile_shaders() { - if(! buffers[0].create() || !buffers[1].create() || !buffers[2].create() || !buffers[3].create() - || !buffers[4].create() || !buffers[5].create() || !buffers[6].create() - || !buffers[7].create()) + if(!buffers[0].create() || !buffers[1].create() || !buffers[2].create() || + !buffers[3].create() || !buffers[4].create() || !buffers[5].create() || + !buffers[6].create() || !buffers[7].create()) + { + std::cerr<<"VBO Creation FAILED"<compileSourceCode(vertex_source)) - { - std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(fragment_source)) - { - std::cerr<<"Compiling fragmentsource FAILED"<compileSourceCode(vertex_source)) + { + std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(fragment_source)) + { + std::cerr<<"Compiling fragmentsource FAILED"<compileSourceCode(vertex_source_p_l)) - { - std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(fragment_source_p_l)) - { - std::cerr<<"Compiling fragmentsource FAILED"<compileSourceCode(vertex_source_p_l)) + { + std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(fragment_source_p_l)) + { + std::cerr<<"Compiling fragmentsource FAILED"<(pos_facets.size()*sizeof(float))); - vertexLocation[0] = rendering_program.attributeLocation("vertex"); - rendering_program.bind(); - rendering_program.enableAttributeArray(vertexLocation[0]); - rendering_program.setAttributeBuffer(vertexLocation[0],GL_FLOAT,0,3); - rendering_program.release(); - buffers[0].release(); - //normals of the facets - buffers[1].bind(); - buffers[1].allocate(flat_normals.data(), static_cast(flat_normals.size()*sizeof(float))); - normalsLocation = rendering_program.attributeLocation("normal"); - rendering_program.bind(); - rendering_program.enableAttributeArray(normalsLocation); - rendering_program.setAttributeBuffer(normalsLocation,GL_FLOAT,0,3); - buffers[1].release(); - //colors of the facets - buffers[2].bind(); - buffers[2].allocate(colors.data(), static_cast(colors.size()*sizeof(float))); - colorsLocation = rendering_program.attributeLocation("color"); - rendering_program.bind(); - rendering_program.enableAttributeArray(colorsLocation); - rendering_program.setAttributeBuffer(colorsLocation,GL_FLOAT,0,3); - buffers[2].release(); - rendering_program.release(); - vao[0].release(); + //points of the facets + vao[0].bind(); + buffers[0].bind(); + buffers[0].allocate(pos_facets.data(), + static_cast(pos_facets.size()*sizeof(float))); + vertexLocation[0] = rendering_program.attributeLocation("vertex"); + rendering_program.bind(); + rendering_program.enableAttributeArray(vertexLocation[0]); + rendering_program.setAttributeBuffer(vertexLocation[0],GL_FLOAT,0,3); + rendering_program.release(); + buffers[0].release(); - vao[1].bind(); - //points of the facets - buffers[3].bind(); - buffers[3].allocate(pos_facets.data(), static_cast(pos_facets.size()*sizeof(float))); - vertexLocation[0] = rendering_program.attributeLocation("vertex"); - rendering_program.bind(); - rendering_program.enableAttributeArray(vertexLocation[0]); - rendering_program.setAttributeBuffer(vertexLocation[0],GL_FLOAT,0,3); - rendering_program.release(); - buffers[3].release(); - //normals of the facets - buffers[4].bind(); - buffers[4].allocate(smooth_normals.data(), static_cast(smooth_normals.size()*sizeof(float))); - normalsLocation = rendering_program.attributeLocation("normal"); - rendering_program.bind(); - rendering_program.enableAttributeArray(normalsLocation); - rendering_program.setAttributeBuffer(normalsLocation,GL_FLOAT,0,3); - buffers[4].release(); - //colors of the facets - buffers[5].bind(); - buffers[5].allocate(colors.data(), static_cast(colors.size()*sizeof(float))); - colorsLocation = rendering_program.attributeLocation("color"); - rendering_program.bind(); - rendering_program.enableAttributeArray(colorsLocation); - rendering_program.setAttributeBuffer(colorsLocation,GL_FLOAT,0,3); - buffers[5].release(); - rendering_program.release(); - vao[1].release(); + //normals of the facets + buffers[1].bind(); + buffers[1].allocate(flat_normals.data(), + static_cast(flat_normals.size()*sizeof(float))); + normalsLocation = rendering_program.attributeLocation("normal"); + rendering_program.bind(); + rendering_program.enableAttributeArray(normalsLocation); + rendering_program.setAttributeBuffer(normalsLocation,GL_FLOAT,0,3); + buffers[1].release(); - //The lines - vao[2].bind(); - buffers[6].bind(); - buffers[6].allocate(pos_lines.data(), static_cast(pos_lines.size()*sizeof(float))); - vertexLocation[2] = rendering_program_p_l.attributeLocation("vertex"); - rendering_program_p_l.bind(); - rendering_program_p_l.enableAttributeArray(vertexLocation[2]); - rendering_program_p_l.setAttributeBuffer(vertexLocation[2],GL_FLOAT,0,3); - buffers[6].release(); - rendering_program_p_l.release(); - vao[2].release(); + //colors of the facets + buffers[2].bind(); + buffers[2].allocate(colors.data(), + static_cast(colors.size()*sizeof(float))); + colorsLocation = rendering_program.attributeLocation("color"); + rendering_program.bind(); + rendering_program.enableAttributeArray(colorsLocation); + rendering_program.setAttributeBuffer(colorsLocation,GL_FLOAT,0,3); + buffers[2].release(); + rendering_program.release(); - //The points - vao[3].bind(); - buffers[7].bind(); - buffers[7].allocate(pos_points.data(), static_cast(pos_points.size()*sizeof(float))); - vertexLocation[2] = rendering_program_p_l.attributeLocation("vertex"); - rendering_program_p_l.bind(); - rendering_program_p_l.enableAttributeArray(vertexLocation[2]); - rendering_program_p_l.setAttributeBuffer(vertexLocation[2],GL_FLOAT,0,3); - buffers[7].release(); - rendering_program_p_l.release(); - vao[3].release(); + vao[0].release(); + vao[1].bind(); - are_buffers_initialized = true; + //points of the facets + buffers[3].bind(); + buffers[3].allocate(pos_facets.data(), static_cast(pos_facets.size()*sizeof(float))); + vertexLocation[0] = rendering_program.attributeLocation("vertex"); + rendering_program.bind(); + rendering_program.enableAttributeArray(vertexLocation[0]); + rendering_program.setAttributeBuffer(vertexLocation[0],GL_FLOAT,0,3); + rendering_program.release(); + buffers[3].release(); + //normals of the facets + buffers[4].bind(); + buffers[4].allocate(smooth_normals.data(), + static_cast(smooth_normals.size()*sizeof(float))); + normalsLocation = rendering_program.attributeLocation("normal"); + rendering_program.bind(); + rendering_program.enableAttributeArray(normalsLocation); + rendering_program.setAttributeBuffer(normalsLocation,GL_FLOAT,0,3); + buffers[4].release(); + + //colors of the facets + buffers[5].bind(); + buffers[5].allocate(colors.data(), static_cast(colors.size()*sizeof(float))); + colorsLocation = rendering_program.attributeLocation("color"); + rendering_program.bind(); + rendering_program.enableAttributeArray(colorsLocation); + rendering_program.setAttributeBuffer(colorsLocation,GL_FLOAT,0,3); + buffers[5].release(); + rendering_program.release(); + + vao[1].release(); + + //The lines + vao[2].bind(); + buffers[6].bind(); + buffers[6].allocate(pos_lines.data(), static_cast(pos_lines.size()*sizeof(float))); + vertexLocation[2] = rendering_program_p_l.attributeLocation("vertex"); + rendering_program_p_l.bind(); + rendering_program_p_l.enableAttributeArray(vertexLocation[2]); + rendering_program_p_l.setAttributeBuffer(vertexLocation[2],GL_FLOAT,0,3); + buffers[6].release(); + rendering_program_p_l.release(); + vao[2].release(); + + //The points + vao[3].bind(); + buffers[7].bind(); + buffers[7].allocate(pos_points.data(), static_cast(pos_points.size()*sizeof(float))); + vertexLocation[2] = rendering_program_p_l.attributeLocation("vertex"); + rendering_program_p_l.bind(); + rendering_program_p_l.enableAttributeArray(vertexLocation[2]); + rendering_program_p_l.setAttributeBuffer(vertexLocation[2],GL_FLOAT,0,3); + buffers[7].release(); + rendering_program_p_l.release(); + vao[3].release(); + + are_buffers_initialized = true; +} + +void Viewer::compute_faces(Dart_handle dh) +{ + LCC &lcc = *scene->lcc; + for(LCC::One_dart_per_incident_cell_range<2,3>::iterator + dartIter=lcc.one_dart_per_incident_cell<2,3>(dh).begin(); + dartIter.cont(); ++dartIter) + { + double r = (double)lcc.info<3>(dartIter).color().r()/255.0; + double g = (double)lcc.info<3>(dartIter).color().g()/255.0; + double b = (double)lcc.info<3>(dartIter).color().b()/255.0; + if ( !lcc.is_free(dartIter, 3) ) + { + r += (double)lcc.info<3>(lcc.beta(dartIter,3)).color().r()/255.0; + g += (double)lcc.info<3>(lcc.beta(dartIter,3)).color().g()/255.0; + b += (double)lcc.info<3>(lcc.beta(dartIter,3)).color().b()/255.0; + r /= 2; g /= 2; b /= 2; + } + + //compute flat normals + LCC::Vector normal = CGAL::compute_normal_of_cell_2(lcc,dartIter); + normal = normal/(CGAL::sqrt(normal*normal)); + + if (lcc.beta<1,1,1>(dartIter)!=dartIter) + { + P_traits cdt_traits(normal); + CDT cdt(cdt_traits); + + // Iterates on the vector of facet handles + CDT::Vertex_handle previous = NULL, first = NULL; + for (LCC::Dart_of_orbit_range<1>::const_iterator + he_circ = lcc.darts_of_orbit<1>(dartIter).begin(), + he_circ_end = lcc.darts_of_orbit<1>(dartIter).end(); + he_circ!=he_circ_end; ++he_circ) + { + CDT::Vertex_handle vh = cdt.insert(lcc.point(he_circ)); + if(first == NULL) + { first = vh; } + //vh->info() = he_circ; + if(previous!=NULL && previous != vh) + { cdt.insert_constraint(previous, vh); } + previous = vh; + } + cdt.insert_constraint(previous, first); + + // 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 = false; + } + //check if the facet is external or internal + std::queue face_queue; + 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_external) + { + fh->info().is_external = true; + for(int i = 0; i <3; ++i) + { + if(!cdt.is_constrained(std::make_pair(fh, i))) + { + face_queue.push(fh->neighbor(i)); + } + } + } + } + + //iterates on the internal faces to add the vertices to the positions + //and the normals to the appropriate vectors + for(CDT::Finite_faces_iterator ffit = cdt.finite_faces_begin(), + ffitend = cdt.finite_faces_end(); ffit != ffitend; ++ffit) + { + if(!ffit->info().is_external) + { + smooth_normals.push_back(normal.x()); + smooth_normals.push_back(normal.y()); + smooth_normals.push_back(normal.z()); + + smooth_normals.push_back(normal.x()); + smooth_normals.push_back(normal.y()); + smooth_normals.push_back(normal.z()); + + smooth_normals.push_back(normal.x()); + smooth_normals.push_back(normal.y()); + smooth_normals.push_back(normal.z()); + + flat_normals.push_back(normal.x()); + flat_normals.push_back(normal.y()); + flat_normals.push_back(normal.z()); + + flat_normals.push_back(normal.x()); + flat_normals.push_back(normal.y()); + flat_normals.push_back(normal.z()); + + flat_normals.push_back(normal.x()); + flat_normals.push_back(normal.y()); + flat_normals.push_back(normal.z()); + + pos_facets.push_back(ffit->vertex(0)->point().x()); + pos_facets.push_back(ffit->vertex(0)->point().y()); + pos_facets.push_back(ffit->vertex(0)->point().z()); + + pos_facets.push_back(ffit->vertex(1)->point().x()); + pos_facets.push_back(ffit->vertex(1)->point().y()); + pos_facets.push_back(ffit->vertex(1)->point().z()); + + pos_facets.push_back(ffit->vertex(2)->point().x()); + pos_facets.push_back(ffit->vertex(2)->point().y()); + pos_facets.push_back(ffit->vertex(2)->point().z()); + + colors.push_back(r);colors.push_back(g);colors.push_back(b); + colors.push_back(r);colors.push_back(g);colors.push_back(b); + colors.push_back(r);colors.push_back(g);colors.push_back(b); + } + } + } + else + { + colors.push_back(r);colors.push_back(g);colors.push_back(b); + colors.push_back(r);colors.push_back(g);colors.push_back(b); + colors.push_back(r);colors.push_back(g);colors.push_back(b); + + flat_normals.push_back(normal.x()); + flat_normals.push_back(normal.y()); + flat_normals.push_back(normal.z()); + + flat_normals.push_back(normal.x()); + flat_normals.push_back(normal.y()); + flat_normals.push_back(normal.z()); + + flat_normals.push_back(normal.x()); + flat_normals.push_back(normal.y()); + flat_normals.push_back(normal.z()); + + for (LCC::Dart_of_orbit_range<1>::const_iterator + orbitIter = lcc.darts_of_orbit<1>(dartIter).begin(); + orbitIter.cont(); ++orbitIter) + { + //compute Smooth normals + LCC::Vector normal = CGAL::compute_normal_of_cell_0(lcc,orbitIter); + normal = normal/(CGAL::sqrt(normal*normal)); + + smooth_normals.push_back(normal.x()); + smooth_normals.push_back(normal.y()); + smooth_normals.push_back(normal.z()); + + const LCC::Point& p = lcc.point(orbitIter); + pos_facets.push_back(p.x()); + pos_facets.push_back(p.y()); + pos_facets.push_back(p.z()); + } + } + } +} + +void Viewer::compute_edges(Dart_handle dh) +{ + LCC &lcc = *scene->lcc; + for(LCC::One_dart_per_incident_cell_range<1,3>::iterator + dartIter=lcc.one_dart_per_incident_cell<1,3>(dh).begin(); + dartIter.cont(); ++dartIter) + { + const LCC::Point& p = lcc.point(dartIter); + Dart_handle d2 = lcc.other_extremity(dartIter); + if ( d2!=NULL ) + { + const LCC::Point& p2 = lcc.point(d2); + pos_lines.push_back(p.x()); + pos_lines.push_back(p.y()); + pos_lines.push_back(p.z()); + + pos_lines.push_back(p2.x()); + pos_lines.push_back(p2.y()); + pos_lines.push_back(p2.z()); + } + } +} + +void Viewer::compute_vertices(Dart_handle dh, bool empty) +{ + LCC &lcc = *scene->lcc; + for(LCC::One_dart_per_incident_cell_range<0,3>::iterator + dartIter=lcc.one_dart_per_incident_cell<0,3>(dh).begin(); + dartIter.cont(); ++dartIter) + { + const LCC::Point& p = lcc.point(dartIter); + pos_points.push_back(p.x()); + pos_points.push_back(p.y()); + pos_points.push_back(p.z()); + + if ( empty ) + { + bb = p.bbox(); + empty = false; + } + else + bb = bb + p.bbox(); + } } void Viewer::compute_elements() { + LCC &lcc = *scene->lcc; - //Facets - if(is_Triangulated()) + pos_facets.clear(); + flat_normals.clear(); + smooth_normals.clear(); + colors.clear(); + pos_lines.clear(); + pos_points.clear(); + + if ( lcc.is_empty() ) + { + bb = LCC::Point(CGAL::ORIGIN).bbox(); + bb = bb + LCC::Point(1,1,1).bbox(); // To avoid a warning from Qglviewer + return; + } + + bool empty = true; + for (LCC::Attribute_range<3>::type::iterator it=lcc.attributes<3>().begin(), + itend=lcc.attributes<3>().end(); it!=itend; ++it ) + { + if ( it->info().is_visible() ) { - pos_facets.resize(0); - flat_normals.resize(0); - smooth_normals.resize(0); - colors.resize(0); - LCC &lcc = *scene->lcc; - - for (LCC::Attribute_range<3>::type::iterator - it=lcc.attributes<3>().begin(), - itend=lcc.attributes<3>().end(); it!=itend; ++it ) - { - if ( it->info().is_visible() ) - { - for(LCC::One_dart_per_incident_cell_range<2,3>::iterator - dartIter=lcc.one_dart_per_incident_cell<2,3> - (lcc.dart_of_attribute<3>(it)).begin(); dartIter.cont(); ++dartIter) - { - // We draw the polygon - - - // double r = (double)dartIter->attribute<3>()->info().r()/255.0; - float r = (float)lcc.info<3>(dartIter).color().r()/255.0; - float g = (float)lcc.info<3>(dartIter).color().g()/255.0; - float b = (float)lcc.info<3>(dartIter).color().b()/255.0; - if ( !lcc.is_free(dartIter, 3) ) - { - r += (float)lcc.info<3>(lcc.beta(dartIter,3)).color().r()/255.0; - g += (float)lcc.info<3>(lcc.beta(dartIter,3)).color().g()/255.0; - b += (float)lcc.info<3>(lcc.beta(dartIter,3)).color().b()/255.0; - r /= 2; g /= 2; b /= 2; - } - - colors.push_back(r);colors.push_back(g);colors.push_back(b); - colors.push_back(r);colors.push_back(g);colors.push_back(b); - colors.push_back(r);colors.push_back(g);colors.push_back(b); - //compute flat normals - LCC::Vector normal = CGAL::compute_normal_of_cell_2(lcc,dartIter); - normal = normal/(CGAL::sqrt(normal*normal)); - flat_normals.push_back(normal.x());flat_normals.push_back(normal.y());flat_normals.push_back(normal.z()); - flat_normals.push_back(normal.x());flat_normals.push_back(normal.y());flat_normals.push_back(normal.z()); - flat_normals.push_back(normal.x());flat_normals.push_back(normal.y());flat_normals.push_back(normal.z()); - - - - for (LCC::Dart_of_orbit_range<1>::const_iterator - orbitIter = lcc.darts_of_orbit<1>(dartIter).begin(); - orbitIter.cont(); ++orbitIter) - { - //compute Smooth normals - LCC::Vector normal = CGAL::compute_normal_of_cell_0(lcc,orbitIter); - normal = normal/(CGAL::sqrt(normal*normal)); - smooth_normals.push_back(normal.x());smooth_normals.push_back(normal.y());smooth_normals.push_back(normal.z()); - - const LCC::Point& p = lcc.point(orbitIter); - pos_facets.push_back(p.x()); pos_facets.push_back(p.y()); pos_facets.push_back(p.z()); - } - - } - } - } - - } - else - triangulate_facet(); - - //Edges - { - pos_lines.resize(0); - LCC &lcc = *scene->lcc; - - if ( !lcc.is_empty() ) - { - - for (LCC::Attribute_range<3>::type::iterator - it=lcc.attributes<3>().begin(), - itend=lcc.attributes<3>().end(); it!=itend; ++it ) - { - if ( it->info().is_visible() ) - { - for(LCC::One_dart_per_incident_cell_range<1,3>::iterator - dartIter=lcc.one_dart_per_incident_cell<1,3> - (lcc.dart_of_attribute<3>(it)).begin(); dartIter.cont(); ++dartIter) - { - const LCC::Point& p = lcc.point(dartIter); - Dart_handle d2 = lcc.other_extremity(dartIter); - if ( d2!=NULL ) - { - const LCC::Point& p2 = lcc.point(d2); - pos_lines.push_back(p.x()); pos_lines.push_back(p.y()); pos_lines.push_back(p.z()); - pos_lines.push_back(p2.x()); pos_lines.push_back(p2.y()); pos_lines.push_back(p2.z()); - } - } - } - } - - } - } - //Points - { - pos_points.resize(0); - LCC &lcc = *scene->lcc; - - if ( lcc.is_empty() ) - { - bb = LCC::Point(CGAL::ORIGIN).bbox(); - bb = bb + LCC::Point(1,1,1).bbox(); // To avoid a warning from Qglviewer - return; - } - - bool empty = true; - for (LCC::Attribute_range<3>::type::iterator - it=lcc.attributes<3>().begin(), - itend=lcc.attributes<3>().end(); it!=itend; ++it ) - { - if ( it->info().is_visible() ) - { - for(LCC::One_dart_per_incident_cell_range<0,3>::iterator - dartIter=lcc.one_dart_per_incident_cell<0,3> - (lcc.dart_of_attribute<3>(it)).begin(); - dartIter.cont(); ++dartIter) - { - const LCC::Point& p = lcc.point(dartIter); - pos_points.push_back(p.x()); pos_points.push_back(p.y()); pos_points.push_back(p.z()); - - if ( empty ) - { - bb = p.bbox(); - empty = false; - } - else - bb = bb + p.bbox(); - } - } - } - - - if ( lcc.is_empty() ) - { - bb = LCC::Point(CGAL::ORIGIN).bbox(); - bb = bb + LCC::Point(1,1,1).bbox(); // To avoid a warning from Qglviewer - } + if (it->info().is_filled()) + compute_faces(lcc.dart_of_attribute<3>(it)); + compute_edges(lcc.dart_of_attribute<3>(it)); + compute_vertices(lcc.dart_of_attribute<3>(it), empty); + empty = false; } + } + if ( empty ) + { + bb = LCC::Point(CGAL::ORIGIN).bbox(); + bb = bb + LCC::Point(1,1,1).bbox(); // To avoid a warning from Qglviewer + } } void Viewer::attrib_buffers(QGLViewer* viewer) { - QMatrix4x4 mvpMatrix; - QMatrix4x4 mvMatrix; - double mat[16]; - viewer->camera()->getModelViewProjectionMatrix(mat); - for(int i=0; i < 16; i++) - { - mvpMatrix.data()[i] = (float)mat[i]; - } - viewer->camera()->getModelViewMatrix(mat); - for(int i=0; i < 16; i++) - { - mvMatrix.data()[i] = (float)mat[i]; - } - // define material - QVector4D ambient(0.1f, 0.1f, 0.1f, 1.0f); - QVector4D diffuse( 0.9f, - 0.9f, - 0.9f, - 0.0f ); + QMatrix4x4 mvpMatrix; + QMatrix4x4 mvMatrix; + double mat[16]; + viewer->camera()->getModelViewProjectionMatrix(mat); + for(int i=0; i < 16; i++) + { + mvpMatrix.data()[i] = (float)mat[i]; + } + viewer->camera()->getModelViewMatrix(mat); + for(int i=0; i < 16; i++) + { + mvMatrix.data()[i] = (float)mat[i]; + } + // define material + QVector4D ambient(0.4f, 0.4f, 0.4f, 0.4f); + QVector4D diffuse( 0.9f, + 0.9f, + 0.9f, + 0.9f ); - QVector4D specular( 0.0f, - 0.0f, - 0.0f, - 0.0f ); + QVector4D specular( 0.0f, + 0.0f, + 0.0f, + 1.0f ); - QVector4D position( 0.0f, -10.0f, -10.0f, 0.0f ); - GLfloat shininess = 1.0f; + QVector4D position( 10.0f, 10.0f, 10.0f, 0.0f ); + GLfloat shininess = 1.0f; + rendering_program.bind(); + mvpLocation[0] = rendering_program.uniformLocation("mvp_matrix"); + mvLocation = rendering_program.uniformLocation("mv_matrix"); + lightLocation[0] = rendering_program.uniformLocation("light_pos"); + lightLocation[1] = rendering_program.uniformLocation("light_diff"); + lightLocation[2] = rendering_program.uniformLocation("light_spec"); + lightLocation[3] = rendering_program.uniformLocation("light_amb"); + lightLocation[4] = rendering_program.uniformLocation("spec_power"); - rendering_program.bind(); - mvpLocation[0] = rendering_program.uniformLocation("mvp_matrix"); - mvLocation = rendering_program.uniformLocation("mv_matrix"); - lightLocation[0] = rendering_program.uniformLocation("light_pos"); - lightLocation[1] = rendering_program.uniformLocation("light_diff"); - lightLocation[2] = rendering_program.uniformLocation("light_spec"); - lightLocation[3] = rendering_program.uniformLocation("light_amb"); - lightLocation[4] = rendering_program.uniformLocation("spec_power"); + rendering_program.setUniformValue(lightLocation[0], position); + rendering_program.setUniformValue(lightLocation[1], diffuse); + rendering_program.setUniformValue(lightLocation[2], specular); + rendering_program.setUniformValue(lightLocation[3], ambient); + rendering_program.setUniformValue(lightLocation[4], shininess); + rendering_program.setUniformValue(mvpLocation[0], mvpMatrix); + rendering_program.setUniformValue(mvLocation, mvMatrix); - rendering_program.setUniformValue(lightLocation[0], position); - rendering_program.setUniformValue(lightLocation[1], diffuse); - rendering_program.setUniformValue(lightLocation[2], specular); - rendering_program.setUniformValue(lightLocation[3], ambient); - rendering_program.setUniformValue(lightLocation[4], shininess); - rendering_program.setUniformValue(mvpLocation[0], mvpMatrix); - rendering_program.setUniformValue(mvLocation, mvMatrix); - - - rendering_program.release(); - rendering_program_p_l.bind(); - mvpLocation[1] = rendering_program_p_l.uniformLocation("mvp_matrix"); - colorLocation = rendering_program_p_l.uniformLocation("color"); - rendering_program.setUniformValue(mvpLocation[1], mvpMatrix); - rendering_program_p_l.release(); - are_buffers_initialized = true; + rendering_program.release(); + rendering_program_p_l.bind(); + mvpLocation[1] = rendering_program_p_l.uniformLocation("mvp_matrix"); + colorLocation = rendering_program_p_l.uniformLocation("color"); + rendering_program.setUniformValue(mvpLocation[1], mvpMatrix); + rendering_program_p_l.release(); } -void -Viewer::sceneChanged() +void Viewer::sceneChanged() { compute_elements(); this->camera()->setSceneBoundingBox(qglviewer::Vec(bb.xmin(), @@ -665,62 +604,66 @@ Viewer::sceneChanged() bb.ymax(), bb.zmax())); are_buffers_initialized = false; - this->showEntireScene(); + + if (m_previous_scene_empty) + this->showEntireScene(); + else + this->updateGL(); + + m_previous_scene_empty = scene->lcc->is_empty(); // for the next call to sceneChanged } void Viewer::draw() { - glEnable(GL_DEPTH_TEST); -if(!are_buffers_initialized) + glEnable(GL_DEPTH_TEST); + if(!are_buffers_initialized) initialize_buffers(); - -QColor color; - if ( !wireframe ) + QColor color; + if ( !wireframe ) + { + if(flatShading) { - if(flatShading) - { - - vao[0].bind(); - attrib_buffers(this); - rendering_program.bind(); - glDrawArrays(GL_TRIANGLES, 0, static_cast(pos_facets.size()/3)); - rendering_program.release(); - vao[0].release(); - } - else - { - vao[1].bind(); - attrib_buffers(this); - rendering_program.bind(); - glDrawArrays(GL_TRIANGLES, 0, static_cast(pos_facets.size()/3)); - rendering_program.release(); - vao[1].release(); - } + vao[0].bind(); + attrib_buffers(this); + rendering_program.bind(); + glDrawArrays(GL_TRIANGLES, 0, static_cast(pos_facets.size()/3)); + rendering_program.release(); + vao[0].release(); } - if(edges) + else { - vao[2].bind(); - attrib_buffers(this); - color.setRgbF(0.2f, 0.2f, 0.7f); - rendering_program_p_l.bind(); - rendering_program_p_l.setAttributeValue(colorLocation,color); - glDrawArrays(GL_LINES, 0, static_cast(pos_lines.size()/3)); - rendering_program_p_l.release(); - vao[2].release(); - } - if(vertices) - { - ::glPointSize(7.f); - vao[3].bind(); - attrib_buffers(this); - color.setRgbF(.2f,.2f,.6f); - rendering_program_p_l.bind(); - rendering_program_p_l.setAttributeValue(colorLocation,color); - glDrawArrays(GL_POINTS, 0, static_cast(pos_points.size()/3)); - rendering_program_p_l.release(); - vao[3].release(); + vao[1].bind(); + attrib_buffers(this); + rendering_program.bind(); + glDrawArrays(GL_TRIANGLES, 0, static_cast(pos_facets.size()/3)); + rendering_program.release(); + vao[1].release(); } + } + if(edges) + { + vao[2].bind(); + attrib_buffers(this); + color.setRgbF(0.2f, 0.2f, 0.7f); + rendering_program_p_l.bind(); + rendering_program_p_l.setAttributeValue(colorLocation,color); + glDrawArrays(GL_LINES, 0, static_cast(pos_lines.size()/3)); + rendering_program_p_l.release(); + vao[2].release(); + } + if(vertices) + { + ::glPointSize(7.f); + vao[3].bind(); + attrib_buffers(this); + color.setRgbF(.2f,.2f,.6f); + rendering_program_p_l.bind(); + rendering_program_p_l.setAttributeValue(colorLocation,color); + glDrawArrays(GL_POINTS, 0, static_cast(pos_points.size()/3)); + rendering_program_p_l.release(); + vao[3].release(); + } } void Viewer::init() @@ -748,7 +691,6 @@ void Viewer::init() ::glEnable(GL_LIGHTING); ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); - // ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); if (flatShading) { @@ -776,7 +718,6 @@ void Viewer::keyPressEvent(QKeyEvent *e) { const Qt::KeyboardModifiers modifiers = e->modifiers(); - bool handled = false; if ((e->key()==Qt::Key_W) && (modifiers==Qt::NoButton)) { wireframe = !wireframe; @@ -784,7 +725,6 @@ void Viewer::keyPressEvent(QKeyEvent *e) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - handled = true; updateGL(); } else if ((e->key()==Qt::Key_F) && (modifiers==Qt::NoButton)) @@ -801,30 +741,26 @@ void Viewer::keyPressEvent(QKeyEvent *e) } else { - ::glShadeModel(GL_FLAT); - ::glDisable(GL_BLEND); - ::glDisable(GL_LINE_SMOOTH); - ::glDisable(GL_POLYGON_SMOOTH_HINT); - ::glBlendFunc(GL_ONE, GL_ZERO); - ::glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); + ::glShadeModel(GL_FLAT); + ::glDisable(GL_BLEND); + ::glDisable(GL_LINE_SMOOTH); + ::glDisable(GL_POLYGON_SMOOTH_HINT); + ::glBlendFunc(GL_ONE, GL_ZERO); + ::glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); } - handled = true; updateGL(); } else if ((e->key()==Qt::Key_E) && (modifiers==Qt::NoButton)) { edges = !edges; - handled = true; updateGL(); } else if ((e->key()==Qt::Key_V) && (modifiers==Qt::NoButton)) { vertices = !vertices; - handled = true; updateGL(); } - - if (!handled) + else QGLViewer::keyPressEvent(e); } diff --git a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h index c03977f900a..450cea1da1a 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h +++ b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h @@ -22,57 +22,29 @@ #define VIEWER_H #include "typedefs.h" + +#include #include #include - #include #include #include #include -class Viewer : public QGLViewer, QOpenGLFunctions_2_1 + +class Viewer : public QGLViewer, public QOpenGLFunctions_2_1 { Q_OBJECT - CGAL::Timer timer; - Scene* scene; - bool wireframe; - bool flatShading; - bool edges; - bool vertices; - CGAL::Bbox_3 bb; - - GLuint m_dlFaces; - GLuint m_dlFacesFlat; - GLuint m_dlEdges; - GLuint m_dlVertices; - bool m_displayListCreated; - typedef LCC::Dart_handle Dart_handle; typedef LCC::Dart_const_handle Dart_const_handle; - public: Viewer(QWidget* parent); - ~Viewer() - { - buffers[0].destroy(); - buffers[1].destroy(); - buffers[2].destroy(); - buffers[3].destroy(); - buffers[4].destroy(); - buffers[5].destroy(); - buffers[6].destroy(); - buffers[7].destroy(); - vao[0].destroy(); - vao[1].destroy(); - vao[2].destroy(); - vao[3].destroy(); - } + ~Viewer(); + void setScene(Scene* scene_) - { - scene = scene_; - } + { scene = scene_; } public: void draw(); @@ -87,12 +59,27 @@ public Q_SLOTS: void sceneChanged(); +private: + void initialize_buffers(); + void attrib_buffers(QGLViewer*); + void compile_shaders(); + + void compute_elements(); + void compute_faces(Dart_handle dh); + void compute_edges(Dart_handle dh); + void compute_vertices(Dart_handle dh, bool empty); private: - + Scene* scene; + bool wireframe; + bool flatShading; + bool edges; + bool vertices; + CGAL::Bbox_3 bb; + bool m_previous_scene_empty; bool are_buffers_initialized; - //Shaders elements + //Shaders elements int vertexLocation[3]; int normalsLocation; int mvpLocation[2]; @@ -101,24 +88,17 @@ private: int colorsLocation; int lightLocation[5]; - std::vector pos_points; std::vector pos_lines; std::vector pos_facets; std::vector smooth_normals; std::vector flat_normals; - std::vector colors; + std::vector colors; QGLBuffer buffers[10]; QOpenGLVertexArrayObject vao[10]; QOpenGLShaderProgram rendering_program; QOpenGLShaderProgram rendering_program_p_l; - - void initialize_buffers(); - void compute_elements(); - void attrib_buffers(QGLViewer*); - void compile_shaders(); - void triangulate_facet(); - bool is_Triangulated(); }; + #endif diff --git a/Linear_cell_complex/demo/Linear_cell_complex/import_moka.h b/Linear_cell_complex/demo/Linear_cell_complex/import_moka.h new file mode 100644 index 00000000000..f0a62a6609e --- /dev/null +++ b/Linear_cell_complex/demo/Linear_cell_complex/import_moka.h @@ -0,0 +1,192 @@ +// Copyright (c) 2011 CNRS and LIRIS' Establishments (France). +// 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; either version 3 of the License, +// or (at your option) any later version. +// +// 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 +// +#ifndef IMPORT_MOKA_H +#define IMPORT_MOKA_H + +namespace CGAL +{ +struct GDart +{ + unsigned int alpha[4]; + Dart_handle dh; + LCC::Vertex_attribute_handle vh; + + GDart() : dh(NULL), vh(NULL) + {} + + GDart(const GDart& adart) : dh(adart.dh), + vh(adart.vh) + { + for (unsigned int i=0; i<4; ++i) + alpha[i]=adart.alpha[i]; + } +}; + +template +bool import_from_moka(LCC& lcc, const char* filename) +{ + typedef typename LCC::Point Point; + + std::ifstream ifile(filename); + if (!ifile) + { + std::cout<<"Error opening file "< gdarts; + unsigned int nbLoaded = 0; + unsigned int number; + double x,y,z; + + // First load all the gdarts, and create vertex attributes + while(ifile) + { + GDart agdart; + ifile>>agdart.alpha[0]>>agdart.alpha[1] + >>agdart.alpha[2]>>agdart.alpha[3]; // the 4 alpha + ifile>>number>>number>>number>>number; // to skip the 4*8 marks + if ( agdart.alpha[0]==nbLoaded ) + { + std::cout<<"Impossible to load a moka file with 0-free darts.\n"; + return false; + } + if ( ifile ) + { + ifile>>number; // bool to know if dart has a vertex of not. + if (number) + { + ifile>>x>>y>>z; + agdart.vh = lcc.create_vertex_attribute(Point(x, y, z)); + } + + gdarts.push_back(agdart); + ++nbLoaded; + } + } + ifile.close(); + + // Second orient the gmap, and create oriented darts. + std::stack totreat; + for (unsigned int startingdart = 0; startingdartattribute<3>() == NULL ) + { + lcc.template set_attribute<3>(gdarts[i].dh, lcc.template create_attribute<3>()); + } + } + if (gdarts[i].vh!=NULL) + { + lcc.set_vertex_attribute(gdarts[i].dh, gdarts[i].vh); + } + } + + return true; +} + +} + +#endif diff --git a/Linear_cell_complex/demo/Linear_cell_complex/typedefs.h b/Linear_cell_complex/demo/Linear_cell_complex/typedefs.h index d31132c1de3..3609e6665cf 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/typedefs.h +++ b/Linear_cell_complex/demo/Linear_cell_complex/typedefs.h @@ -24,6 +24,13 @@ #include #include #include +#include + +#include +#include +#include +#include +#include #include #include @@ -45,6 +52,11 @@ extern CGAL::Random myrandom; class Volume_info { + friend void CGAL::read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,Volume_info &val); + + friend void CGAL::write_cmap_attribute_node(boost::property_tree::ptree & node, + const Volume_info& arg); public: Volume_info() : m_color(CGAL::Color(myrandom.get_int(0,256), myrandom.get_int(0,256), @@ -91,22 +103,61 @@ public: void negate_filled() { set_filled(!is_filled()); } - private: +private: CGAL::Color m_color; char m_status; }; +namespace CGAL +{ + +template<> +inline void read_cmap_attribute_node +(const boost::property_tree::ptree::value_type &v,Volume_info &val) +{ + try + { + val.m_status = v.second.get("status"); + } + catch(const std::exception & ) + {} + + try + { + char r = v.second.get("color-r"); + char g = v.second.get("color-g"); + char b = v.second.get("color-b"); + val.m_color = CGAL::Color(r,g,b); + } + catch(const std::exception & ) + {} +} + +// Definition of function allowing to save custon information. +template<> +inline void write_cmap_attribute_node(boost::property_tree::ptree & node, + const Volume_info& arg) +{ + boost::property_tree::ptree & nValue = node.add("v",""); + nValue.add("status",(int)arg.m_status); + nValue.add("color-r",(int)arg.m_color.r()); + nValue.add("color-g",(int)arg.m_color.g()); + nValue.add("color-b",(int)arg.m_color.b()); +} + +} + class Myitems { public: template < class Refs > - struct Dart_wrapper + struct Dart_wrapper { typedef CGAL::Dart<3, Refs > Dart; - + typedef CGAL::Cell_attribute_with_point< Refs > Vertex_attrib; typedef CGAL::Cell_attribute< Refs, Volume_info> Volume_attrib; - + typedef CGAL::cpp11::tuple Attributes; }; @@ -124,6 +175,22 @@ typedef LCC::Vector Vector_3; typedef CGAL::Timer Timer; +typedef CGAL::Triangulation_2_filtered_projection_traits_3 P_traits; +typedef CGAL::Triangulation_vertex_base_with_info_2 Vb; + +struct Face_info { + bool exist_edge[3]; + bool is_external; +}; + +typedef CGAL::Triangulation_face_base_with_info_2 Fb1; + +typedef CGAL::Constrained_triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 TDS; +typedef CGAL::No_intersection_tag Itag; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; + struct Scene { LCC* lcc; };