#include <iostream>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/HDVF/Hdvf_traits_3.h>
#include <CGAL/HDVF/Simplex.h>
#include <CGAL/HDVF/Simplicial_chain_complex.h>
#include <CGAL/HDVF/Cubical_chain_complex.h>
#include <CGAL/HDVF/Geometric_chain_complex_tools.h>
#include <CGAL/HDVF/hdvf_tools.h>
#include <CGAL/HDVF/Hdvf_duality.h>
#include <CGAL/OSM/OSM.h>
#include <CGAL/HDVF/Sub_sparse_matrix.h>
#include <CGAL/HDVF/hdvf_tools.h>
#include <CGAL/HDVF/Mesh_object_io.h>
#include <CGAL/HDVF/Cub_object_io.h>
#include <CGAL/HDVF/Icosphere_object_io.h>
#include <CGAL/HDVF/Tet_object_io.h>
#include "arguments.h"
using Traits = HDVF::Hdvf_traits_3<Kernel>;
template <typename MeshType, typename Complex>
void mesh_complex_output(
const MeshType& mesh,
const Complex& L,
const HDVF::Sub_chain_complex_mask<Complex>& K,
const Options& options)
{
if (options.with_output)
{
std::cout << "----> mesh informations" << std::endl ;
mesh.print_infos() ;
std::cout << "----> complex informations" << std::endl ;
std::cout << "------> complex L" << std::endl ;
std::cout << L;
std::cout << "------> subcomplex K" << std::endl ;
std::cout << K << std::endl ;
}
}
inline std::ostream& dual_pairs_output(const std::vector<HDVF::Cell_pair>& pairs, std::ostream& out=std::cout)
{
out << "Pairs found by compute_perfect_hdvf:" << std::endl;
for (const auto& pair : pairs) {
out << "Sigma: " << pair.sigma << ", Tau: " << pair.tau << ", Dim: " << pair.dim << std::endl;
}
return out ;
}
template <typename Complex>
void dual_HDVF_pair (HDVF::Hdvf_duality<Complex>& dual_hdvf, const Options &options)
{
std::vector<HDVF::Cell_pair> pairs = dual_hdvf.compute_pairing_hdvf() ;
if (options.with_output)
{
dual_pairs_output(pairs) ;
}
if (options.with_export)
{
std::string file(options.outfile_root+"_pairs.txt") ;
std::ofstream out ( file, std::ios::out | std::ios::trunc);
if ( ! out . good () ) {
std::cerr << "hdvf: with_export. Fatal Error:\n " << file << " not found.\n";
throw std::runtime_error("File Parsing Error: File not found");
}
dual_pairs_output(pairs, out) ;
out.close() ;
}
}
template <typename Complex>
HDVF::Hdvf_duality<Complex>& dual_HDVF_comput (
const Complex& L, HDVF::Sub_chain_complex_mask<Complex>& K,
const Options &options)
{
using HDVF_type = HDVF::Hdvf_duality<Complex> ;
using SubCCType = HDVF::Sub_chain_complex_mask<Complex> ;
HDVF_type& hdvf(*(new HDVF_type(L, K, options.HDVF_opt)));
std::cout << "----> START computing dual HDVF" << std::endl ;
if (options.random)
hdvf.compute_rand_perfect_hdvf() ;
else
hdvf.compute_perfect_hdvf() ;
std::cout << "------> END computing dual HDVF" << std::endl ;
if (options.with_output)
{
std::cout << "----> reduction" << std::endl ;
hdvf.write_reduction() ;
}
if (options.with_export)
{
std::cout << "----> exporting..." << std::endl ;
std::string file(options.outfile_root+"_reduction.txt") ;
std::ofstream out ( file, std::ios::out | std::ios::trunc);
if ( ! out . good () ) {
std::cerr << "hdvf: with_export. Fatal Error:\n " << file << " not found.\n";
throw std::runtime_error("File Parsing Error: File not found");
}
out << "----> reduction" << std::endl ;
hdvf.write_reduction(out) ;
out.close() ;
}
return hdvf ;
}
template <typename Coefficient_ring>
void main_code (const Options &options)
{
#ifndef CUST_FILTRATION
using Degree = double ;
#else
#endif
if (options.in_format == InputFormat::SIMP)
{
std::cout << "not yet..." << std::endl ;
throw("not yet") ;
}
else if (options.in_format == InputFormat::OFF)
{
using Complex = HDVF::Simplicial_chain_complex<Coefficient_ring,Traits> ;
using HDVF_type = HDVF::Hdvf_duality<Complex> ;
using ToolsType = HDVF::Duality_simplicial_complex_tools<Coefficient_ring, Traits> ;
using SubCCType = HDVF::Sub_chain_complex_mask<Complex> ;
HDVF::Mesh_object_io<Traits> mesh ;
mesh.read_off(options.in_file) ;
typename ToolsType::Complex_duality_data t = ToolsType::dualize_complex(mesh) ;
std::shared_ptr<Complex> L(t.L_complex) ;
std::shared_ptr<SubCCType> K(t.K_complex) ;
mesh_complex_output<HDVF::Mesh_object_io<Traits>,
Complex>(mesh, *L, *K, options) ;
HDVF_type& hdvf(dual_HDVF_comput<Complex>(*L, *K, options)) ;
if (options.with_vtk_export)
{
std::cout << "----> exporting to vtk" << std::endl ;
{
hdvf.set_mask_K() ;
CGAL::IO::write_VTK(hdvf, *L, options.outfile_root+"_complex_K", options.co_faces) ;
}
{
hdvf.set_mask_L_K() ;
CGAL::IO::write_VTK(hdvf, *L, options.outfile_root+"_cocomplex_L_K", options.co_faces) ;
}
}
dual_HDVF_pair<Complex>(hdvf, options) ;
}
else if ((options.in_format == InputFormat::PGM) || (options.in_format == InputFormat::CUB))
{
using Complex = HDVF::Cubical_chain_complex<Coefficient_ring, Traits> ;
using HDVF_type = HDVF::Hdvf_duality<Complex> ;
using SubCCType = HDVF::Sub_chain_complex_mask<Complex> ;
using ToolsType = HDVF::Duality_cubical_complex_tools<Coefficient_ring, Traits> ;
HDVF::Cub_object_io<Traits> mesh ;
typename Complex::Cubical_complex_primal_dual primal_dual(Complex::PRIMAL) ;
if (options.primal)
{
if (options.in_format == InputFormat::PGM)
mesh.read_pgm(options.in_file, true) ;
else
mesh.read_cub(options.in_file, true) ;
}
else
{
if (options.in_format == InputFormat::PGM)
mesh.read_pgm(options.in_file, false) ;
else
mesh.read_cub(options.in_file, false) ;
primal_dual = Complex::DUAL ;
}
if (options.with_frame)
{
mesh.frame() ;
}
typename ToolsType::Complex_duality_data p = ToolsType::dualize_complex(mesh, primal_dual) ;
std::shared_ptr<Complex> L(p.L_complex) ;
std::shared_ptr<SubCCType> K(p.K_complex) ;
mesh_complex_output<HDVF::Cub_object_io<Traits>,
Complex>(mesh, *L, *K, options) ;
HDVF_type& hdvf(dual_HDVF_comput<Complex>(*L, *K, options)) ;
if (options.with_vtk_export)
{
std::cout << "----> exporting to vtk" << std::endl ;
{
hdvf.set_mask_K() ;
CGAL::IO::write_VTK(hdvf, *L, options.outfile_root+"_complex_K", options.co_faces) ;
}
{
hdvf.set_mask_L_K() ;
CGAL::IO::write_VTK(hdvf, *L, options.outfile_root+"_cocomplex_L_K", options.co_faces) ;
}
}
dual_HDVF_pair<Complex>(hdvf, options) ;
}
}
int main(int argc, char **argv)
{
if (argc <= 2)
usage() ;
else
{
for (int i=0;i<argc; ++i)
std::cout << "arg " << i << " : " << argv[i] << std::endl ;
Options options(read_arguments_hdvf(argc, argv)) ;
std::cout << "options:" << std::endl << options ;
#ifndef SCALAR
if (options.scalar == 0)
{
main_code<Coefficient_ring>(options) ;
}
else if (options.scalar == 2)
{
main_code<Coefficient_ring>(options) ;
}
else
{
std::cerr << "Z" << options.scalar << " not instantiated, use the #define at line 27" << std::endl ;
}
#else
#endif
}
return 0 ;
}
The concept HDVF describes the requirements for Homological Discrete Vector Fields (HDVF for short) ,...
Definition: HDVF.h:128
Complex::Coefficient_ring Coefficient_ring
Type of coefficients used to compute homology.
Definition: HDVF.h:139
unspecified_type Complex
Type of underlying chain complex (a model of AbstractChainComplex).
Definition: HDVF.h:136
Definition: Abstract_simplicial_chain_complex.h:25