mirror of https://github.com/CGAL/cgal
Merge pull request #127 from gdamiand/Combinatorial_map_save_load-gdamiand
Combinatorial_map: add save/load functionality in the LCC demo
This commit is contained in:
commit
69706c7de9
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#include <CGAL/Compact_container.h>
|
#include <CGAL/Compact_container.h>
|
||||||
#include <CGAL/internal/Combinatorial_map_utility.h>
|
#include <CGAL/internal/Combinatorial_map_utility.h>
|
||||||
#include <CGAL/internal/Combinatorial_map_internal_functors.h>
|
|
||||||
#include <CGAL/internal/Combinatorial_map_group_functors.h>
|
#include <CGAL/internal/Combinatorial_map_group_functors.h>
|
||||||
#include <CGAL/internal/Combinatorial_map_copy_functors.h>
|
#include <CGAL/internal/Combinatorial_map_copy_functors.h>
|
||||||
#include <CGAL/internal/Combinatorial_map_sewable.h>
|
#include <CGAL/internal/Combinatorial_map_sewable.h>
|
||||||
|
|
@ -350,6 +349,18 @@ namespace CGAL {
|
||||||
bool is_empty() const
|
bool is_empty() const
|
||||||
{ return mdarts.empty(); }
|
{ 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.
|
/** Create a new dart and add it to the map.
|
||||||
* The marks of the darts are initialised with mmask_marks, i.e. the dart
|
* The marks of the darts are initialised with mmask_marks, i.e. the dart
|
||||||
* is unmarked for all the marks.
|
* is unmarked for all the marks.
|
||||||
|
|
|
||||||
|
|
@ -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.damiand@liris.cnrs.fr>
|
||||||
|
// Guillaume Castano <guillaume.castano@gmail.com>
|
||||||
|
// Pascal Khieu <pascal.khieu@gmail.com>
|
||||||
|
//
|
||||||
|
#ifndef CGAL_COMBINATORIAL_MAP_SAVE_LOAD_H
|
||||||
|
#define CGAL_COMBINATORIAL_MAP_SAVE_LOAD_H
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/property_tree/xml_parser.hpp>
|
||||||
|
#include <boost/property_tree/ptree.hpp>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#include <CGAL/Combinatorial_map.h>
|
||||||
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
|
#include <CGAL/Cell_attribute_with_point.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
|
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:
|
||||||
|
// <darts>
|
||||||
|
// <d> // new dart
|
||||||
|
// <b i="1"> neighbor dart index for beta1 </b>
|
||||||
|
// ...
|
||||||
|
// <v> value of dart (optional) </v>
|
||||||
|
// </d>
|
||||||
|
// ...
|
||||||
|
// </darts>
|
||||||
|
// For attributes:
|
||||||
|
// <attributes>
|
||||||
|
// <dimension index="1"> // new type of non void attribute
|
||||||
|
// <type>type of the info associated</type>
|
||||||
|
// <a> // new attribute
|
||||||
|
// <d> dart index </d>
|
||||||
|
// <v> value of attribute </v>
|
||||||
|
// </a>
|
||||||
|
// ...
|
||||||
|
// </attributes>
|
||||||
|
|
||||||
|
// Here T is a Dart_const_handle so we don't need &
|
||||||
|
template<typename T>
|
||||||
|
void write_cmap_dart_node(boost::property_tree::ptree & /*node*/, T)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
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<typename CMap, unsigned int i,
|
||||||
|
bool WithInfo=CGAL::Is_attribute_has_non_void_info
|
||||||
|
<typename CMap::template Attribute_type<i>::type>::value,
|
||||||
|
bool WithPoint=CGAL::Is_attribute_has_point
|
||||||
|
<typename CMap::template Attribute_type<i>::type >::value >
|
||||||
|
struct My_functor_cmap_save_one_attrib;
|
||||||
|
|
||||||
|
// An attrib with point and with info
|
||||||
|
template<typename CMap, unsigned int i>
|
||||||
|
struct My_functor_cmap_save_one_attrib<CMap, i, true, true>
|
||||||
|
{
|
||||||
|
static void run(const CMap* amap, boost::property_tree::ptree* ptree,
|
||||||
|
std::map<typename CMap::Dart_const_handle, typename CMap::size_type>* myDarts)
|
||||||
|
{
|
||||||
|
// to check all i-cells of the map
|
||||||
|
typename CMap::template Attribute_range<i>::type::const_iterator
|
||||||
|
it_attrib, itend_attrib;
|
||||||
|
it_attrib=amap->template attributes<i>().begin();
|
||||||
|
itend_attrib=amap->template attributes<i>().end();
|
||||||
|
|
||||||
|
// add dimension & type
|
||||||
|
boost::property_tree::ptree & ndim = ptree->add("dimension", "");
|
||||||
|
ndim.put("<xmlattr>.index", i);
|
||||||
|
ndim.add("type", typeid(typename CMap::template Attribute_type<i>::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<typename CMap, unsigned int i>
|
||||||
|
struct My_functor_cmap_save_one_attrib<CMap, i, false, true>
|
||||||
|
{
|
||||||
|
static void run(const CMap* amap, boost::property_tree::ptree* ptree,
|
||||||
|
std::map<typename CMap::Dart_const_handle, typename CMap::size_type>* myDarts)
|
||||||
|
{
|
||||||
|
// to check all i-cells of the map
|
||||||
|
typename CMap::template Attribute_range<i>::type::const_iterator
|
||||||
|
it_attrib, itend_attrib;
|
||||||
|
it_attrib=amap->template attributes<i>().begin();
|
||||||
|
itend_attrib=amap->template attributes<i>().end();
|
||||||
|
|
||||||
|
// add dimension & type
|
||||||
|
boost::property_tree::ptree & ndim = ptree->add("dimension", "");
|
||||||
|
ndim.put("<xmlattr>.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<typename CMap, unsigned int i>
|
||||||
|
struct My_functor_cmap_save_one_attrib<CMap, i, true, false>
|
||||||
|
{
|
||||||
|
static void run(const CMap* amap, boost::property_tree::ptree* ptree,
|
||||||
|
std::map<typename CMap::Dart_const_handle, typename CMap::size_type>* myDarts)
|
||||||
|
{
|
||||||
|
// to check all i-cells of the map
|
||||||
|
typename CMap::template Attribute_range<i>::type::const_iterator
|
||||||
|
it_attrib, itend_attrib;
|
||||||
|
it_attrib=amap->template attributes<i>().begin();
|
||||||
|
itend_attrib=amap->template attributes<i>().end();
|
||||||
|
|
||||||
|
// add dimension & type
|
||||||
|
boost::property_tree::ptree & ndim = ptree->add("dimension", "");
|
||||||
|
ndim.put("<xmlattr>.index", i);
|
||||||
|
ndim.add("type", typeid(typename CMap::template Attribute_type<i>::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<typename CMap, unsigned int i>
|
||||||
|
struct My_functor_cmap_save_one_attrib<CMap, i, false, false>
|
||||||
|
{
|
||||||
|
static void run(const CMap* amap, boost::property_tree::ptree* ptree,
|
||||||
|
std::map<typename CMap::Dart_const_handle, typename CMap::size_type>* myDarts)
|
||||||
|
{
|
||||||
|
// to check all i-cells of the map
|
||||||
|
typename CMap::template Attribute_range<i>::type::const_iterator
|
||||||
|
it_attrib, itend_attrib;
|
||||||
|
it_attrib=amap->template attributes<i>().begin();
|
||||||
|
itend_attrib=amap->template attributes<i>().end();
|
||||||
|
|
||||||
|
// add dimension & type
|
||||||
|
boost::property_tree::ptree & ndim = ptree->add("dimension", "");
|
||||||
|
ndim.put("<xmlattr>.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<typename CMap>
|
||||||
|
struct My_functor_cmap_save_attrib
|
||||||
|
{
|
||||||
|
template <unsigned int i>
|
||||||
|
static void run(const CMap* amap, boost::property_tree::ptree* ptree,
|
||||||
|
std::map<typename CMap::Dart_const_handle, typename CMap::size_type>* myDarts)
|
||||||
|
{
|
||||||
|
My_functor_cmap_save_one_attrib<CMap, i>::run(amap, ptree, myDarts);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template < class CMap >
|
||||||
|
boost::property_tree::ptree cmap_save_darts
|
||||||
|
(const CMap& amap, std::map<typename CMap::Dart_const_handle, typename CMap::size_type>& 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<amap.number_of_darts(); ++num, ++it)
|
||||||
|
{
|
||||||
|
// make a dart node
|
||||||
|
ptree & ndart = pt.add("d", "");
|
||||||
|
|
||||||
|
// the beta, only for non free sews
|
||||||
|
for(unsigned int dim=1; dim<=amap.dimension; dim++)
|
||||||
|
{
|
||||||
|
if(!amap.is_free(it, dim))
|
||||||
|
{
|
||||||
|
ptree & currentNext = ndart.add("b", myDarts[amap.beta(it, dim)]);
|
||||||
|
currentNext.put("<xmlattr>.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<typename CMap::Dart_const_handle, typename CMap::size_type>& myDarts)
|
||||||
|
{
|
||||||
|
using boost::property_tree::ptree;
|
||||||
|
ptree pt;
|
||||||
|
|
||||||
|
// update pt adding nodes containing attributes informations
|
||||||
|
CMap::Helper::template Foreach_enabled_attributes
|
||||||
|
<My_functor_cmap_save_attrib<CMap> >::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<typename CMap::Dart_const_handle, typename CMap::size_type> 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<typename T>
|
||||||
|
void read_cmap_dart_node
|
||||||
|
(const boost::property_tree::ptree::value_type &/*v*/, T /*val*/)
|
||||||
|
{}
|
||||||
|
template<typename T>
|
||||||
|
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<double>("x");
|
||||||
|
double y=v.second.get<double>("y");
|
||||||
|
double z=v.second.get<double>("z");
|
||||||
|
val = RPoint_3(x,y,z);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CMap, unsigned int i,
|
||||||
|
bool WithInfo=CGAL::Is_attribute_has_non_void_info
|
||||||
|
<typename CMap::template Attribute_type<i>::type>::value,
|
||||||
|
bool WithPoint=CGAL::Is_attribute_has_point
|
||||||
|
<typename CMap::template Attribute_type<i>::type >::value >
|
||||||
|
struct My_functor_cmap_load_one_attrib;
|
||||||
|
|
||||||
|
// An attrib with point and with info
|
||||||
|
template<typename CMap, unsigned int i>
|
||||||
|
struct My_functor_cmap_load_one_attrib<CMap, i, true, true>
|
||||||
|
{
|
||||||
|
static void run(const boost::property_tree::ptree& pt, CMap* amap,
|
||||||
|
const std::vector<typename CMap::Dart_handle>& myDarts)
|
||||||
|
{
|
||||||
|
BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0,
|
||||||
|
pt.get_child("data.attributes") )
|
||||||
|
{
|
||||||
|
// <dimension>
|
||||||
|
if (v0.first == "dimension")
|
||||||
|
{
|
||||||
|
int dimension=v0.second.get("<xmlattr>.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<std::string>("type");
|
||||||
|
std::string type_map=std::string
|
||||||
|
(typeid(typename CMap::template Attribute_type<i>::type::Info).name());
|
||||||
|
|
||||||
|
std::string ptype = v0.second.get<std::string>("type_point");
|
||||||
|
std::string ptype_map= std::string
|
||||||
|
(typeid(typename CMap::template Attribute_type<i>::type::Point).name());
|
||||||
|
|
||||||
|
// std::cout<<"ptype="<<ptype<<" and type_map="<<type_map<<std::endl;
|
||||||
|
/* if(type!=type_map && ptype!=ptype_map)
|
||||||
|
{
|
||||||
|
// std::cout<<"Not loaded."<<std::endl;
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
BOOST_FOREACH(const boost::property_tree::ptree::value_type &v1,
|
||||||
|
v0.second )
|
||||||
|
{
|
||||||
|
if( v1.first == "a" )
|
||||||
|
{
|
||||||
|
id_dart_cellule=v1.second.get<unsigned int>("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<i>()==NULL )
|
||||||
|
amap->template set_attribute<i>
|
||||||
|
(myDarts[id_dart_cellule],
|
||||||
|
amap->template create_attribute<i>());
|
||||||
|
read_cmap_attribute_node
|
||||||
|
(v2,
|
||||||
|
myDarts[id_dart_cellule]->
|
||||||
|
template attribute<i>()->info());
|
||||||
|
}
|
||||||
|
if( ptype==ptype_map && v2.first == "p" )
|
||||||
|
{
|
||||||
|
if (myDarts[id_dart_cellule]->
|
||||||
|
template attribute<i>()==NULL )
|
||||||
|
amap->template set_attribute<i>
|
||||||
|
(myDarts[id_dart_cellule],
|
||||||
|
amap->template create_attribute<i>());
|
||||||
|
read_cmap_attribute_node
|
||||||
|
(v2,
|
||||||
|
myDarts[id_dart_cellule]->
|
||||||
|
template attribute<i>()->point());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// An attribute with point and without info
|
||||||
|
template<typename CMap, unsigned int i>
|
||||||
|
struct My_functor_cmap_load_one_attrib<CMap, i, false, true>
|
||||||
|
{
|
||||||
|
static void run(const boost::property_tree::ptree& pt, CMap* amap,
|
||||||
|
const std::vector<typename CMap::Dart_handle>& myDarts)
|
||||||
|
{
|
||||||
|
BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0,
|
||||||
|
pt.get_child("data.attributes") )
|
||||||
|
{
|
||||||
|
// <dimension>
|
||||||
|
if (v0.first == "dimension")
|
||||||
|
{
|
||||||
|
int dimension=v0.second.get("<xmlattr>.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<std::string>("type_point");
|
||||||
|
std::string type_map= typeid
|
||||||
|
(typename CMap::template Attribute_type<i>::type::Point).name();
|
||||||
|
// std::cout<<"ptype="<<ptype<<" and type_map="<<type_map<<std::endl;
|
||||||
|
/* if(ptype!=type_map)
|
||||||
|
{
|
||||||
|
// std::cout<<"Not loaded."<<std::endl;
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
BOOST_FOREACH(const boost::property_tree::ptree::value_type &v1,
|
||||||
|
v0.second )
|
||||||
|
{
|
||||||
|
if( v1.first == "a" )
|
||||||
|
{
|
||||||
|
id_dart_cellule=v1.second.get<unsigned int>("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<i>()==NULL )
|
||||||
|
amap->template set_attribute<i>
|
||||||
|
(myDarts[id_dart_cellule],
|
||||||
|
amap->template create_attribute<i>());
|
||||||
|
|
||||||
|
read_cmap_attribute_node
|
||||||
|
(v2,
|
||||||
|
myDarts[id_dart_cellule]->
|
||||||
|
template attribute<i>()->point());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// An attribute without point and with info
|
||||||
|
template<typename CMap, unsigned int i>
|
||||||
|
struct My_functor_cmap_load_one_attrib<CMap, i, true, false>
|
||||||
|
{
|
||||||
|
static void run(const boost::property_tree::ptree& pt, CMap* amap,
|
||||||
|
const std::vector<typename CMap::Dart_handle>& myDarts)
|
||||||
|
{
|
||||||
|
BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0,
|
||||||
|
pt.get_child("data.attributes") )
|
||||||
|
{
|
||||||
|
// <dimension>
|
||||||
|
if (v0.first == "dimension")
|
||||||
|
{
|
||||||
|
int dimension=v0.second.get("<xmlattr>.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<std::string>("type");
|
||||||
|
std::string type_map= typeid
|
||||||
|
(typename CMap::template Attribute_type<i>::type::Info).name();
|
||||||
|
// std::cout<<"ptype="<<ptype<<" and type_map="<<type_map<<std::endl;
|
||||||
|
/* if(ptype!=type_map)
|
||||||
|
{
|
||||||
|
// std::cout<<"Not loaded."<<std::endl;
|
||||||
|
return;
|
||||||
|
} */
|
||||||
|
|
||||||
|
BOOST_FOREACH(const boost::property_tree::ptree::value_type &v1,
|
||||||
|
v0.second )
|
||||||
|
{
|
||||||
|
if( v1.first == "a" )
|
||||||
|
{
|
||||||
|
id_dart_cellule=v1.second.get<unsigned int>("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<i>()==NULL )
|
||||||
|
amap->template set_attribute<i>
|
||||||
|
(myDarts[id_dart_cellule],
|
||||||
|
amap->template create_attribute<i>());
|
||||||
|
read_cmap_attribute_node
|
||||||
|
(v2,
|
||||||
|
myDarts[id_dart_cellule]->
|
||||||
|
template attribute<i>()->info());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// An attribute without point and without info
|
||||||
|
template<typename CMap, unsigned int i>
|
||||||
|
struct My_functor_cmap_load_one_attrib<CMap, i, false, false>
|
||||||
|
{
|
||||||
|
static void run(const boost::property_tree::ptree& pt, CMap* amap,
|
||||||
|
const std::vector<typename CMap::Dart_handle>& myDarts)
|
||||||
|
{
|
||||||
|
BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0,
|
||||||
|
pt.get_child("data.attributes") )
|
||||||
|
{
|
||||||
|
// <dimension>
|
||||||
|
if (v0.first == "dimension")
|
||||||
|
{
|
||||||
|
int dimension=v0.second.get("<xmlattr>.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<unsigned int>("d")-1;
|
||||||
|
|
||||||
|
if (myDarts[id_dart_cellule]->
|
||||||
|
template attribute<i>()==NULL )
|
||||||
|
amap->template set_attribute<i>
|
||||||
|
(myDarts[id_dart_cellule],
|
||||||
|
amap->template create_attribute<i>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 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<class CMap>
|
||||||
|
struct My_functor_cmap_load_attrib
|
||||||
|
{
|
||||||
|
template <unsigned int i>
|
||||||
|
static void run(const boost::property_tree::ptree& pt, CMap* amap,
|
||||||
|
const std::vector<typename CMap::Dart_handle>& myDarts)
|
||||||
|
{
|
||||||
|
My_functor_cmap_load_one_attrib<CMap, i>::run(pt, amap, myDarts);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template < class CMap >
|
||||||
|
bool cmap_load_darts(boost::property_tree::ptree &pt, CMap& amap,
|
||||||
|
std::vector<typename CMap::Dart_handle>& 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("<xmlattr>.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<typename CMap::Dart_handle>& myDarts)
|
||||||
|
{
|
||||||
|
CMap::Helper::template Foreach_enabled_attributes
|
||||||
|
<My_functor_cmap_load_attrib<CMap> >::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<typename CMap::Dart_handle> 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 //
|
||||||
|
|
@ -16,6 +16,7 @@ endif()
|
||||||
|
|
||||||
## To add expensive tests
|
## To add expensive tests
|
||||||
# add_definitions("-DCGAL_CHECK_EXPENSIVE")
|
# add_definitions("-DCGAL_CHECK_EXPENSIVE")
|
||||||
|
# add_definitions("-Wall -Wextra")
|
||||||
|
|
||||||
## For profilling with gprof
|
## For profilling with gprof
|
||||||
# add_definitions("-pg")
|
# add_definitions("-pg")
|
||||||
|
|
@ -72,7 +73,6 @@ target_link_libraries(Linear_cell_complex_3_demo ${CGAL_LIBRARIES}
|
||||||
${CGAL_3RD_PARTY_LIBRARIES})
|
${CGAL_3RD_PARTY_LIBRARIES})
|
||||||
target_link_libraries(Linear_cell_complex_3_demo ${QT_LIBRARIES}
|
target_link_libraries(Linear_cell_complex_3_demo ${QT_LIBRARIES}
|
||||||
${QGLVIEWER_LIBRARIES} )
|
${QGLVIEWER_LIBRARIES} )
|
||||||
target_link_libraries(Linear_cell_complex_3_demo ${OPENGL_gl_LIBRARY}
|
target_link_libraries(Linear_cell_complex_3_demo ${OPENGL_gl_LIBRARY} )
|
||||||
${OPENGL_glu_LIBRARY} )
|
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <CGAL/Timer.h>
|
#include <CGAL/Timer.h>
|
||||||
#include <CGAL/ipower.h>
|
#include <CGAL/ipower.h>
|
||||||
|
#include "MainWindow.moc"
|
||||||
|
#include "import_moka.h"
|
||||||
|
|
||||||
// Function defined in Linear_cell_complex_3_subivision.cpp
|
// Function defined in Linear_cell_complex_3_subivision.cpp
|
||||||
void subdivide_lcc_3 (LCC & m);
|
void subdivide_lcc_3 (LCC & m);
|
||||||
|
|
@ -58,7 +60,7 @@ MainWindow::MainWindow (QWidget * parent):CGAL::Qt::DemosMainWindow (parent),
|
||||||
labels.append(QString(tr("Hidden")));
|
labels.append(QString(tr("Hidden")));
|
||||||
volumeList->setHorizontalHeaderLabels(labels);
|
volumeList->setHorizontalHeaderLabels(labels);
|
||||||
//volumeList->resizeColumnsToContents();
|
//volumeList->resizeColumnsToContents();
|
||||||
volumeList->setFixedWidth(200);
|
volumeList->setFixedWidth(220);
|
||||||
/* volumeList->setColumnWidth(0,85);
|
/* volumeList->setColumnWidth(0,85);
|
||||||
volumeList->setColumnWidth(1,35);
|
volumeList->setColumnWidth(1,35);
|
||||||
volumeList->setColumnWidth(2,35);*/
|
volumeList->setColumnWidth(2,35);*/
|
||||||
|
|
@ -82,7 +84,7 @@ MainWindow::MainWindow (QWidget * parent):CGAL::Qt::DemosMainWindow (parent),
|
||||||
|
|
||||||
this->addRecentFiles (this->menuFile, this->actionQuit);
|
this->addRecentFiles (this->menuFile, this->actionQuit);
|
||||||
connect (this, SIGNAL (openRecentFile (QString)),
|
connect (this, SIGNAL (openRecentFile (QString)),
|
||||||
this, SLOT (load_off (QString)));
|
this, SLOT (load_depend_on_extension(QString)));
|
||||||
|
|
||||||
statusMessage = new QLabel
|
statusMessage = new QLabel
|
||||||
("Darts: 0, Vertices: 0 (Points: 0), Edges: 0, Facets: 0,"
|
("Darts: 0, Vertices: 0 (Points: 0), Edges: 0, Facets: 0,"
|
||||||
|
|
@ -223,6 +225,32 @@ void MainWindow::init_all_new_volumes()
|
||||||
{ on_new_volume(it); }
|
{ 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 ()
|
void MainWindow::on_actionImportOFF_triggered ()
|
||||||
{
|
{
|
||||||
QString fileName = QFileDialog::getOpenFileName (this,
|
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 ()
|
void MainWindow::on_actionImport3DTDS_triggered ()
|
||||||
{
|
{
|
||||||
QString fileName = QFileDialog::getOpenFileName (this,
|
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."<<std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::load(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
|
||||||
|
|
||||||
|
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 "<<qPrintable(fileName)<<": "
|
||||||
|
<<timer.time()<<" seconds."<<std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
recreate_whole_volume_list();
|
||||||
|
|
||||||
|
this->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 "<<qPrintable(fileName)<<": "
|
||||||
|
<<timer.time()<<" seconds."<<std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::load_off (const QString & fileName, bool clear)
|
void MainWindow::load_off (const QString & fileName, bool clear)
|
||||||
{
|
{
|
||||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||||
|
|
@ -333,6 +452,40 @@ void MainWindow::load_3DTDS (const QString & fileName, bool clear)
|
||||||
Q_EMIT (sceneChanged ());
|
Q_EMIT (sceneChanged ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::load_moka(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
|
||||||
|
|
||||||
|
CGAL::import_from_moka < LCC > (*scene.lcc, qPrintable (fileName));
|
||||||
|
|
||||||
|
#ifdef CGAL_PROFILE_LCC_DEMO
|
||||||
|
timer.stop();
|
||||||
|
std::cout<<"Time to load off "<<qPrintable(fileName)<<": "
|
||||||
|
<<timer.time()<<" seconds."<<std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
init_all_new_volumes();
|
||||||
|
recreate_whole_volume_list();
|
||||||
|
|
||||||
|
this->addToRecentFiles (fileName);
|
||||||
|
QApplication::restoreOverrideCursor ();
|
||||||
|
|
||||||
|
if (clear)
|
||||||
|
statusBar ()->showMessage (QString ("Load off file") + fileName,
|
||||||
|
DELAY_STATUSMSG);
|
||||||
|
else
|
||||||
|
statusBar ()->showMessage (QString ("Add off file") + fileName,
|
||||||
|
DELAY_STATUSMSG);
|
||||||
|
Q_EMIT (sceneChanged ());
|
||||||
|
}
|
||||||
|
|
||||||
Dart_handle MainWindow::make_iso_cuboid(const Point_3 basepoint, LCC::FT lg)
|
Dart_handle MainWindow::make_iso_cuboid(const Point_3 basepoint, LCC::FT lg)
|
||||||
{
|
{
|
||||||
return scene.lcc->make_hexahedron(basepoint,
|
return scene.lcc->make_hexahedron(basepoint,
|
||||||
|
|
@ -783,7 +936,7 @@ void MainWindow::on_actionRemove_filled_volumes_triggered()
|
||||||
DELAY_STATUSMSG);
|
DELAY_STATUSMSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionTriangulate_all_facets_triggered()
|
void MainWindow::on_actionInsert_center_vertices_triggered()
|
||||||
{
|
{
|
||||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||||
|
|
||||||
|
|
@ -805,17 +958,113 @@ void MainWindow::on_actionTriangulate_all_facets_triggered()
|
||||||
|
|
||||||
#ifdef CGAL_PROFILE_LCC_DEMO
|
#ifdef CGAL_PROFILE_LCC_DEMO
|
||||||
timer.stop();
|
timer.stop();
|
||||||
std::cout<<"Time to triangulate all filled faces: "
|
std::cout<<"Time to insert center vertices in all filled faces: "
|
||||||
<<timer.time()<<" seconds."<<std::endl;
|
<<timer.time()<<" seconds."<<std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QApplication::restoreOverrideCursor ();
|
QApplication::restoreOverrideCursor ();
|
||||||
Q_EMIT (sceneChanged ());
|
Q_EMIT (sceneChanged ());
|
||||||
statusBar()->showMessage
|
statusBar()->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);
|
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<Dart_handle> 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<LCC, 1>(*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<LCC, 1>(*scene.lcc, it, treated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (std::vector<Dart_handle>::iterator it=edges.begin(),
|
||||||
|
itend=edges.end(); it!=itend; ++it)
|
||||||
|
{
|
||||||
|
CGAL::mark_cell<LCC, 1>(*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<LCC, 1>(*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<LCC, 2>(*scene.lcc, *it,
|
||||||
|
scene.lcc->beta<2>(*it)) )
|
||||||
|
CGAL::remove_cell<LCC, 1>(*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: "
|
||||||
|
<<timer.time()<<" seconds."<<std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
recreate_whole_volume_list();
|
||||||
|
|
||||||
|
QApplication::restoreOverrideCursor ();
|
||||||
|
Q_EMIT (sceneChanged ());
|
||||||
|
statusBar()->showMessage
|
||||||
|
(QString ("Coplanar face(s) merged"), DELAY_STATUSMSG);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionMerge_all_volumes_triggered()
|
void MainWindow::on_actionMerge_all_volumes_triggered()
|
||||||
{
|
{
|
||||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||||
|
|
@ -861,6 +1110,179 @@ void MainWindow::on_actionMerge_all_volumes_triggered()
|
||||||
(QString ("Visible and filled volume(s) merged"), DELAY_STATUSMSG);
|
(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<CDT::Face_handle> 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<LCC::Dart_handle> 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<LCC::Dart_handle>::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: "
|
||||||
|
<<timer.time()<<" seconds."<<std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
recreate_whole_volume_list();
|
||||||
|
|
||||||
|
QApplication::restoreOverrideCursor ();
|
||||||
|
Q_EMIT (sceneChanged ());
|
||||||
|
statusBar()->showMessage
|
||||||
|
(QString ("All visible and filled faces were triangulated"), DELAY_STATUSMSG);
|
||||||
|
}
|
||||||
|
|
||||||
bool MainWindow::is_volume_in_list(LCC::Attribute_handle<3>::type ah)
|
bool MainWindow::is_volume_in_list(LCC::Attribute_handle<3>::type ah)
|
||||||
{
|
{
|
||||||
for(int row=0; row < volumeList->rowCount(); ++row)
|
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)
|
void MainWindow::onCellChanged(int row, int col)
|
||||||
{
|
{
|
||||||
|
volumeList->disconnect(this);
|
||||||
|
|
||||||
LCC::Attribute_type<3>::type* ptr=
|
LCC::Attribute_type<3>::type* ptr=
|
||||||
reinterpret_cast<LCC::Attribute_type<3>::type*>
|
reinterpret_cast<LCC::Attribute_type<3>::type*>
|
||||||
( volumeList->item(row,3)->data(Qt::UserRole).value<quintptr>() );
|
( volumeList->item(row,3)->data(Qt::UserRole).value<quintptr>() );
|
||||||
|
|
@ -994,6 +1418,7 @@ void MainWindow::onCellChanged(int row, int col)
|
||||||
(volumeList->item(row,1)->flags()|Qt::ItemIsEnabled);
|
(volumeList->item(row,1)->flags()|Qt::ItemIsEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connectVolumeListHandlers();
|
||||||
Q_EMIT( sceneChanged());
|
Q_EMIT( sceneChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1875,64 +2300,6 @@ void MainWindow::onSierpinskiCarpetUpdateAttributes(bool newValue)
|
||||||
sierpinskiCarpetUpdateAttributes = 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()
|
void MainWindow::onSierpinskiCarpetInc()
|
||||||
{
|
{
|
||||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||||
|
|
|
||||||
|
|
@ -110,9 +110,12 @@ public:
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
// File menu
|
// File menu
|
||||||
|
void on_actionSave_triggered();
|
||||||
|
void on_actionLoad_triggered();
|
||||||
void on_actionImportOFF_triggered();
|
void on_actionImportOFF_triggered();
|
||||||
void on_actionAddOFF_triggered();
|
void on_actionAddOFF_triggered();
|
||||||
void on_actionImport3DTDS_triggered();
|
void on_actionImport3DTDS_triggered();
|
||||||
|
void on_actionImportMoka_triggered();
|
||||||
void on_actionCompute_Voronoi_3D_triggered();
|
void on_actionCompute_Voronoi_3D_triggered();
|
||||||
void on_actionClear_triggered();
|
void on_actionClear_triggered();
|
||||||
|
|
||||||
|
|
@ -130,19 +133,25 @@ public Q_SLOTS:
|
||||||
void on_actionSubdivide_pqq_triggered();
|
void on_actionSubdivide_pqq_triggered();
|
||||||
void on_actionDual_3_triggered();
|
void on_actionDual_3_triggered();
|
||||||
void on_actionClose_volume_triggered();
|
void on_actionClose_volume_triggered();
|
||||||
void on_actionTriangulate_all_facets_triggered();
|
|
||||||
void on_actionSew3_same_facets_triggered();
|
void on_actionSew3_same_facets_triggered();
|
||||||
void on_actionUnsew3_all_triggered();
|
void on_actionUnsew3_all_triggered();
|
||||||
|
void on_actionMerge_coplanar_faces_triggered();
|
||||||
void on_actionMerge_all_volumes_triggered();
|
void on_actionMerge_all_volumes_triggered();
|
||||||
void on_actionRemove_filled_volumes_triggered();
|
void on_actionRemove_filled_volumes_triggered();
|
||||||
|
void on_actionInsert_center_vertices_triggered();
|
||||||
|
void on_actionTriangulate_all_facets_triggered();
|
||||||
|
|
||||||
// View menu
|
// View menu
|
||||||
void on_actionExtend_filled_volumes_triggered();
|
void on_actionExtend_filled_volumes_triggered();
|
||||||
void on_actionExtend_hidden_volumes_triggered();
|
void on_actionExtend_hidden_volumes_triggered();
|
||||||
|
|
||||||
// Other slots
|
// 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_off(const QString& fileName, bool clear=true);
|
||||||
void load_3DTDS(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();
|
void onSceneChanged();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,15 +33,19 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>635</width>
|
<width>635</width>
|
||||||
<height>22</height>
|
<height>25</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menuFile">
|
<widget class="QMenu" name="menuFile">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>&File</string>
|
<string>&File</string>
|
||||||
</property>
|
</property>
|
||||||
|
<addaction name="actionLoad"/>
|
||||||
|
<addaction name="actionSave"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="actionImportOFF"/>
|
<addaction name="actionImportOFF"/>
|
||||||
<addaction name="actionAddOFF"/>
|
<addaction name="actionAddOFF"/>
|
||||||
|
<addaction name="actionImportMoka"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionImport3DTDS"/>
|
<addaction name="actionImport3DTDS"/>
|
||||||
<addaction name="actionCompute_Voronoi_3D"/>
|
<addaction name="actionCompute_Voronoi_3D"/>
|
||||||
|
|
@ -54,12 +58,15 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>&Operations</string>
|
<string>&Operations</string>
|
||||||
</property>
|
</property>
|
||||||
|
<addaction name="actionInsert_center_vertices"/>
|
||||||
<addaction name="actionTriangulate_all_facets"/>
|
<addaction name="actionTriangulate_all_facets"/>
|
||||||
<addaction name="actionSew3_same_facets"/>
|
<addaction name="actionMerge_coplanar_faces"/>
|
||||||
<addaction name="actionUnsew3_all"/>
|
|
||||||
<addaction name="actionMerge_all_volumes"/>
|
<addaction name="actionMerge_all_volumes"/>
|
||||||
<addaction name="actionRemove_filled_volumes"/>
|
<addaction name="actionRemove_filled_volumes"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionSew3_same_facets"/>
|
||||||
|
<addaction name="actionUnsew3_all"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="actionSubdivide"/>
|
<addaction name="actionSubdivide"/>
|
||||||
<addaction name="actionSubdivide_pqq"/>
|
<addaction name="actionSubdivide_pqq"/>
|
||||||
<addaction name="actionClose_volume"/>
|
<addaction name="actionClose_volume"/>
|
||||||
|
|
@ -221,6 +228,31 @@
|
||||||
<string>Create Sierpinski Triangle</string>
|
<string>Create Sierpinski Triangle</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionLoad">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Load</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSave">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Save</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionImportMoka">
|
||||||
|
<property name="text">
|
||||||
|
<string>Import Moka</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionMerge_coplanar_faces">
|
||||||
|
<property name="text">
|
||||||
|
<string>Merge coplanar faces</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionInsert_center_vertices">
|
||||||
|
<property name="text">
|
||||||
|
<string>Insert center vertices in faces</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -22,57 +22,29 @@
|
||||||
#define VIEWER_H
|
#define VIEWER_H
|
||||||
|
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include <QGLViewer/qglviewer.h>
|
#include <QGLViewer/qglviewer.h>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
|
||||||
#include <QOpenGLFunctions_2_1>
|
#include <QOpenGLFunctions_2_1>
|
||||||
#include <QOpenGLVertexArrayObject>
|
#include <QOpenGLVertexArrayObject>
|
||||||
#include <QGLBuffer>
|
#include <QGLBuffer>
|
||||||
#include <QOpenGLShaderProgram>
|
#include <QOpenGLShaderProgram>
|
||||||
class Viewer : public QGLViewer, QOpenGLFunctions_2_1
|
|
||||||
|
class Viewer : public QGLViewer, public QOpenGLFunctions_2_1
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
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_handle Dart_handle;
|
||||||
typedef LCC::Dart_const_handle Dart_const_handle;
|
typedef LCC::Dart_const_handle Dart_const_handle;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Viewer(QWidget* parent);
|
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_)
|
void setScene(Scene* scene_)
|
||||||
{
|
{ scene = scene_; }
|
||||||
scene = scene_;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void draw();
|
void draw();
|
||||||
|
|
@ -87,12 +59,27 @@ public Q_SLOTS:
|
||||||
|
|
||||||
void sceneChanged();
|
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:
|
private:
|
||||||
|
Scene* scene;
|
||||||
|
bool wireframe;
|
||||||
|
bool flatShading;
|
||||||
|
bool edges;
|
||||||
|
bool vertices;
|
||||||
|
CGAL::Bbox_3 bb;
|
||||||
|
bool m_previous_scene_empty;
|
||||||
bool are_buffers_initialized;
|
bool are_buffers_initialized;
|
||||||
//Shaders elements
|
|
||||||
|
|
||||||
|
//Shaders elements
|
||||||
int vertexLocation[3];
|
int vertexLocation[3];
|
||||||
int normalsLocation;
|
int normalsLocation;
|
||||||
int mvpLocation[2];
|
int mvpLocation[2];
|
||||||
|
|
@ -101,24 +88,17 @@ private:
|
||||||
int colorsLocation;
|
int colorsLocation;
|
||||||
int lightLocation[5];
|
int lightLocation[5];
|
||||||
|
|
||||||
|
|
||||||
std::vector<float> pos_points;
|
std::vector<float> pos_points;
|
||||||
std::vector<float> pos_lines;
|
std::vector<float> pos_lines;
|
||||||
std::vector<float> pos_facets;
|
std::vector<float> pos_facets;
|
||||||
std::vector<float> smooth_normals;
|
std::vector<float> smooth_normals;
|
||||||
std::vector<float> flat_normals;
|
std::vector<float> flat_normals;
|
||||||
std::vector <float> colors;
|
std::vector<float> colors;
|
||||||
|
|
||||||
QGLBuffer buffers[10];
|
QGLBuffer buffers[10];
|
||||||
QOpenGLVertexArrayObject vao[10];
|
QOpenGLVertexArrayObject vao[10];
|
||||||
QOpenGLShaderProgram rendering_program;
|
QOpenGLShaderProgram rendering_program;
|
||||||
QOpenGLShaderProgram rendering_program_p_l;
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -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 <guillaume.damiand@liris.cnrs.fr>
|
||||||
|
//
|
||||||
|
#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<typename LCC>
|
||||||
|
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 "<<filename<<"."<<std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
std::getline(ifile, line);
|
||||||
|
|
||||||
|
if ( line == "Moka file [binary]" )
|
||||||
|
{
|
||||||
|
std::cout<<"Binary file not (yet) considered.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if ( line != "Moka file [ascii]" )
|
||||||
|
{
|
||||||
|
std::cout<<"File "<<filename<<" is not a moka file.\n";
|
||||||
|
std::cout<< line;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// To skip the masks mark (TODO read the marks ?)
|
||||||
|
std::getline(ifile, line);
|
||||||
|
|
||||||
|
std::vector<GDart> 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<unsigned int> totreat;
|
||||||
|
for (unsigned int startingdart = 0; startingdart<nbLoaded; ++startingdart)
|
||||||
|
{
|
||||||
|
bool orient=(gdarts[startingdart].dh==NULL);
|
||||||
|
for (unsigned int dim=0; orient && dim<4; ++dim)
|
||||||
|
if (gdarts[gdarts[startingdart].alpha[dim]].dh!=NULL) orient=false;
|
||||||
|
|
||||||
|
if ( orient )
|
||||||
|
{
|
||||||
|
totreat.push(startingdart);
|
||||||
|
gdarts[startingdart].dh=lcc.create_dart();
|
||||||
|
|
||||||
|
while ( !totreat.empty() )
|
||||||
|
{
|
||||||
|
unsigned int i=totreat.top();
|
||||||
|
totreat.pop();
|
||||||
|
|
||||||
|
assert(gdarts[i].dh!=NULL);
|
||||||
|
|
||||||
|
for (unsigned int dim=1; dim<4; ++dim)
|
||||||
|
{
|
||||||
|
if (gdarts[i].alpha[dim]!=i &&
|
||||||
|
gdarts[gdarts[i].alpha[dim]].vh!=NULL)
|
||||||
|
{
|
||||||
|
gdarts[i].vh = gdarts[gdarts[i].alpha[dim]].vh;
|
||||||
|
gdarts[gdarts[i].alpha[dim]].vh = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int alpha0 = gdarts[i].alpha[0];
|
||||||
|
assert( alpha0!=i );
|
||||||
|
|
||||||
|
if (gdarts[alpha0].alpha[dim]!=alpha0)
|
||||||
|
{
|
||||||
|
if ( gdarts[gdarts[alpha0].alpha[dim]].dh==NULL )
|
||||||
|
{
|
||||||
|
totreat.push(gdarts[alpha0].alpha[dim]);
|
||||||
|
gdarts[gdarts[alpha0].alpha[dim]].dh = lcc.create_dart();
|
||||||
|
lcc.basic_link_beta(gdarts[i].dh,
|
||||||
|
gdarts[gdarts[alpha0].alpha[dim]].dh,
|
||||||
|
dim);
|
||||||
|
}
|
||||||
|
else if (lcc.is_free(gdarts[i].dh, dim))
|
||||||
|
{
|
||||||
|
lcc.basic_link_beta(gdarts[i].dh,
|
||||||
|
gdarts[gdarts[alpha0].alpha[dim]].dh,
|
||||||
|
dim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the gmap was orientable.
|
||||||
|
bool orientable = true;
|
||||||
|
for (unsigned int i = 0; i<nbLoaded; ++i)
|
||||||
|
{
|
||||||
|
if (gdarts[i].dh!=NULL)
|
||||||
|
{
|
||||||
|
for (unsigned int dim=0; dim<4; ++dim)
|
||||||
|
{
|
||||||
|
if (orientable &&
|
||||||
|
gdarts[i].alpha[dim]!=i &&
|
||||||
|
gdarts[gdarts[i].alpha[dim]].dh!=NULL)
|
||||||
|
{
|
||||||
|
std::cout<<"Pb, the gmap is NOT orientable."<<std::endl;
|
||||||
|
orientable=false;
|
||||||
|
// lcc.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( gdarts[i].dh->attribute<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
|
||||||
|
|
@ -24,6 +24,13 @@
|
||||||
#include <CGAL/Linear_cell_complex_constructors.h>
|
#include <CGAL/Linear_cell_complex_constructors.h>
|
||||||
#include <CGAL/Linear_cell_complex_operations.h>
|
#include <CGAL/Linear_cell_complex_operations.h>
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
#include <CGAL/Combinatorial_map_save_load.h>
|
||||||
|
|
||||||
|
#include <CGAL/Triangulation_2_filtered_projection_traits_3.h>
|
||||||
|
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
|
||||||
|
#include <CGAL/Triangulation_face_base_with_info_2.h>
|
||||||
|
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
|
||||||
|
#include <CGAL/Constrained_triangulation_plus_2.h>
|
||||||
|
|
||||||
#include <CGAL/IO/Color.h>
|
#include <CGAL/IO/Color.h>
|
||||||
#include <CGAL/Timer.h>
|
#include <CGAL/Timer.h>
|
||||||
|
|
@ -45,6 +52,11 @@ extern CGAL::Random myrandom;
|
||||||
|
|
||||||
class Volume_info
|
class Volume_info
|
||||||
{
|
{
|
||||||
|
friend void CGAL::read_cmap_attribute_node<Volume_info>
|
||||||
|
(const boost::property_tree::ptree::value_type &v,Volume_info &val);
|
||||||
|
|
||||||
|
friend void CGAL::write_cmap_attribute_node<Volume_info>(boost::property_tree::ptree & node,
|
||||||
|
const Volume_info& arg);
|
||||||
public:
|
public:
|
||||||
Volume_info() : m_color(CGAL::Color(myrandom.get_int(0,256),
|
Volume_info() : m_color(CGAL::Color(myrandom.get_int(0,256),
|
||||||
myrandom.get_int(0,256),
|
myrandom.get_int(0,256),
|
||||||
|
|
@ -91,22 +103,61 @@ public:
|
||||||
void negate_filled()
|
void negate_filled()
|
||||||
{ set_filled(!is_filled()); }
|
{ set_filled(!is_filled()); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CGAL::Color m_color;
|
CGAL::Color m_color;
|
||||||
char m_status;
|
char m_status;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace CGAL
|
||||||
|
{
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void read_cmap_attribute_node<Volume_info>
|
||||||
|
(const boost::property_tree::ptree::value_type &v,Volume_info &val)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
val.m_status = v.second.get<int>("status");
|
||||||
|
}
|
||||||
|
catch(const std::exception & )
|
||||||
|
{}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
char r = v.second.get<int>("color-r");
|
||||||
|
char g = v.second.get<int>("color-g");
|
||||||
|
char b = v.second.get<int>("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<Volume_info>(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
|
class Myitems
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template < class Refs >
|
template < class Refs >
|
||||||
struct Dart_wrapper
|
struct Dart_wrapper
|
||||||
{
|
{
|
||||||
typedef CGAL::Dart<3, Refs > Dart;
|
typedef CGAL::Dart<3, Refs > Dart;
|
||||||
|
|
||||||
typedef CGAL::Cell_attribute_with_point< Refs > Vertex_attrib;
|
typedef CGAL::Cell_attribute_with_point< Refs > Vertex_attrib;
|
||||||
typedef CGAL::Cell_attribute< Refs, Volume_info> Volume_attrib;
|
typedef CGAL::Cell_attribute< Refs, Volume_info> Volume_attrib;
|
||||||
|
|
||||||
typedef CGAL::cpp11::tuple<Vertex_attrib,void,void,
|
typedef CGAL::cpp11::tuple<Vertex_attrib,void,void,
|
||||||
Volume_attrib> Attributes;
|
Volume_attrib> Attributes;
|
||||||
};
|
};
|
||||||
|
|
@ -124,6 +175,22 @@ typedef LCC::Vector Vector_3;
|
||||||
|
|
||||||
typedef CGAL::Timer Timer;
|
typedef CGAL::Timer Timer;
|
||||||
|
|
||||||
|
typedef CGAL::Triangulation_2_filtered_projection_traits_3<Mytraits> P_traits;
|
||||||
|
typedef CGAL::Triangulation_vertex_base_with_info_2<Dart_handle,P_traits> Vb;
|
||||||
|
|
||||||
|
struct Face_info {
|
||||||
|
bool exist_edge[3];
|
||||||
|
bool is_external;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef CGAL::Triangulation_face_base_with_info_2<Face_info,P_traits> Fb1;
|
||||||
|
|
||||||
|
typedef CGAL::Constrained_triangulation_face_base_2<P_traits, Fb1> Fb;
|
||||||
|
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
|
||||||
|
typedef CGAL::No_intersection_tag Itag;
|
||||||
|
typedef CGAL::Constrained_Delaunay_triangulation_2<P_traits, TDS,
|
||||||
|
Itag> CDT;
|
||||||
|
|
||||||
struct Scene {
|
struct Scene {
|
||||||
LCC* lcc;
|
LCC* lcc;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue