246 lines
6.6 KiB
C
246 lines
6.6 KiB
C
|
// Copyright (c) 2005 Max-Planck-Institute Saarbruecken (Germany).
|
||
|
// All rights reserved.
|
||
|
//
|
||
|
// This file is part of CGAL (www.cgal.org).
|
||
|
//
|
||
|
// $URL: https://github.com/CGAL/cgal/blob/v5.1/Nef_3/include/CGAL/OFF_to_nef_3.h $
|
||
|
// $Id: OFF_to_nef_3.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
|
||
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||
|
//
|
||
|
//
|
||
|
// Author(s) : Ralf Osbild <osbild@mpi-sb.mpg.de>
|
||
|
|
||
|
#ifndef CGAL_OFF_TO_NEF_3_H
|
||
|
#define CGAL_OFF_TO_NEF_3_H
|
||
|
|
||
|
#include <CGAL/license/Nef_3.h>
|
||
|
|
||
|
#include <CGAL/disable_warnings.h>
|
||
|
|
||
|
#include <CGAL/Nef_polyhedron_3.h>
|
||
|
|
||
|
|
||
|
|
||
|
// --- begin preliminary number type converter -----------------
|
||
|
|
||
|
#ifndef CGAL_NUMBER_TYPE_CONVERTER_NEF_3_H
|
||
|
#define CGAL_NUMBER_TYPE_CONVERTER_NEF_3_H
|
||
|
|
||
|
#include<sstream>
|
||
|
#include <CGAL/Exact_rational.h>
|
||
|
#include <CGAL/Exact_integer.h>
|
||
|
#include <CGAL/Fraction_traits.h>
|
||
|
#include<CGAL/Cartesian.h>
|
||
|
#include<CGAL/Homogeneous.h>
|
||
|
#include<CGAL/Nef_S2/Normalizing.h>
|
||
|
#include<CGAL/Nef_nary_union_3.h>
|
||
|
|
||
|
namespace CGAL {
|
||
|
|
||
|
|
||
|
typedef CGAL::Exact_integer Integer;
|
||
|
typedef CGAL::Exact_rational Rational;
|
||
|
|
||
|
class Homogeneous_tag;
|
||
|
class Cartesian_tag;
|
||
|
template<typename Tag, typename Kernel> class number_type_converter_nef_3;
|
||
|
|
||
|
template<class Kernel>
|
||
|
class number_type_converter_nef_3<Homogeneous_tag, Kernel> {
|
||
|
public:
|
||
|
static typename Kernel::Point_3
|
||
|
convert (const CGAL::Cartesian<double>::Point_3 &d)
|
||
|
{
|
||
|
typedef typename Kernel::Point_3 Point_3;
|
||
|
typedef typename Kernel::RT RT;
|
||
|
|
||
|
typedef Fraction_traits<Rational> F_traits;
|
||
|
|
||
|
Rational x(d.x()), y(d.y()), z(d.z());
|
||
|
Integer xn, xd, yn, yd, zn, zd;
|
||
|
typename F_traits::Decompose decompose;
|
||
|
decompose(x, xn, xd);
|
||
|
decompose(y, yn, yd);
|
||
|
decompose(z, zn, zd);
|
||
|
CGAL::Homogeneous<Integer>::Point_3 b =
|
||
|
normalized ( CGAL::Homogeneous<Integer>::Point_3 (
|
||
|
xn * yd * zd,
|
||
|
xd * yn * zd,
|
||
|
xd * yd * zn,
|
||
|
xd * yd * zd ) );
|
||
|
|
||
|
std::ostringstream outx, outy, outz, outw;
|
||
|
outx << b.hx();
|
||
|
outy << b.hy();
|
||
|
outz << b.hz();
|
||
|
outw << b.hw();
|
||
|
RT rx (outx.str().c_str());
|
||
|
RT ry (outy.str().c_str());
|
||
|
RT rz (outz.str().c_str());
|
||
|
RT rw (outw.str().c_str());
|
||
|
|
||
|
return Point_3 (rx, ry, rz, rw);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template<class Kernel>
|
||
|
class number_type_converter_nef_3<Cartesian_tag, Kernel> {
|
||
|
public:
|
||
|
static typename Kernel::Point_3
|
||
|
convert (const CGAL::Cartesian<double>::Point_3 &d)
|
||
|
{ return typename Kernel::Point_3(d.x(), d.y(), d.z());
|
||
|
}
|
||
|
};
|
||
|
|
||
|
} //namespace CGAL
|
||
|
#endif // NUMBER_TYPE_CONVERTER_NEF_3_H
|
||
|
|
||
|
// --- end preliminary number type converter -------------------
|
||
|
|
||
|
#include <iostream>
|
||
|
#include <map>
|
||
|
#include <vector>
|
||
|
|
||
|
#include <CGAL/Cartesian.h>
|
||
|
#include <CGAL/Nef_3/Mark_bounded_volumes.h>
|
||
|
#include <CGAL/IO/Scanner_OFF.h>
|
||
|
#include <CGAL/normal_vector_newell_3.h>
|
||
|
|
||
|
#ifdef CGAL_NEF_OFF_TO_NEF_TIMER
|
||
|
#include <CGAL/Timer.h>
|
||
|
#endif
|
||
|
|
||
|
namespace CGAL {
|
||
|
|
||
|
template <class Nef_3>
|
||
|
std::size_t
|
||
|
OFF_to_nef_3 (std::istream &i_st, Nef_3 &nef_union, bool verb=false)
|
||
|
{
|
||
|
// Nef
|
||
|
typedef typename Nef_3::Kernel Kernel;
|
||
|
typedef typename Nef_3::Point_3 Point_3;
|
||
|
typedef typename std::vector<Point_3> Point_set;
|
||
|
CGAL::Nef_nary_union_3<Nef_3> nary_union;
|
||
|
// input data structure
|
||
|
typedef double Scan_NT;
|
||
|
typedef CGAL::Cartesian<Scan_NT> Scan_kernel;
|
||
|
typedef Scan_kernel::Point_3 Scan_point;
|
||
|
typedef std::vector<Scan_point> Scan_point_set;
|
||
|
typedef Scan_kernel::Vector_3 Scan_vector;
|
||
|
|
||
|
typedef CGAL::Scanner_OFF<Scan_kernel> Scan_OFF;
|
||
|
typedef Scan_OFF::Vertex_iterator Scan_vertex_it;
|
||
|
typedef Scan_OFF::Facet_iterator Scan_facet_it;
|
||
|
typedef Scan_OFF::Index_iterator Scan_index_it;
|
||
|
|
||
|
typedef typename Kernel::Kernel_tag Kernel_tag;
|
||
|
typedef typename CGAL::number_type_converter_nef_3<Kernel_tag,Kernel> ntc;
|
||
|
|
||
|
// declarations and defaults
|
||
|
std::size_t discarded_facets=0;
|
||
|
std::size_t idx;
|
||
|
|
||
|
#ifdef CGAL_NEF_OFF_TO_NEF_TIMER
|
||
|
CGAL::Timer t_convert, t_union;
|
||
|
#endif
|
||
|
|
||
|
// input: description of polyhedron in object file format (OFF)
|
||
|
// with cartesian double coordinates
|
||
|
Scan_OFF scan (i_st);
|
||
|
std::size_t NOV = scan.size_of_vertices();
|
||
|
|
||
|
// read and store vertices
|
||
|
Scan_point_set V_scan;
|
||
|
V_scan.reserve (NOV);
|
||
|
Point_set V;
|
||
|
V.reserve (NOV);
|
||
|
|
||
|
#ifdef CGAL_NEF_OFF_TO_NEF_TIMER
|
||
|
t_convert.start();
|
||
|
#endif
|
||
|
|
||
|
Scan_vertex_it v_it = scan.vertices_begin();
|
||
|
for (idx=0; v_it != scan.vertices_end(); ++v_it, ++idx)
|
||
|
{ V_scan.push_back (*v_it);
|
||
|
V.push_back (ntc::convert(*v_it));
|
||
|
}
|
||
|
CGAL_warning ( idx==NOV );
|
||
|
NOV = idx;
|
||
|
|
||
|
// for each facet
|
||
|
Scan_facet_it f_it = scan.facets_begin();
|
||
|
for (idx=0; f_it != scan.facets_end(); ++f_it, ++idx)
|
||
|
{ // read facet
|
||
|
Scan_facet_it::indices_size_type NOI=f_it.size_of_indices(), jdx;
|
||
|
Scan_point_set V_f_scan;
|
||
|
V_f_scan.reserve(NOI);
|
||
|
Point_set V_f;
|
||
|
V_f.reserve(NOI);
|
||
|
|
||
|
Scan_index_it ind_it = f_it->begin();
|
||
|
for (jdx=0; ind_it != f_it->end(); ++ind_it, ++jdx)
|
||
|
{ // assertion: index out of range?
|
||
|
CGAL_assertion (*ind_it < NOV );
|
||
|
V_f_scan.push_back (V_scan[*ind_it]);
|
||
|
V_f.push_back (V[*ind_it]);
|
||
|
}
|
||
|
CGAL_warning ( jdx==NOI );
|
||
|
NOI = jdx;
|
||
|
|
||
|
bool is_nef = false;
|
||
|
CGAL_assertion_msg( V_f.size() >= 1 || !verb, "empty vertex cycle");
|
||
|
if ( V_f.size() >= 1 )
|
||
|
{ // compute Newell vector <double>
|
||
|
Scan_vector normal;
|
||
|
normal_vector_newell_3(V_f_scan.begin(),V_f_scan.end(),normal);
|
||
|
|
||
|
// construct and enqueue Nef_polyhedron_3 <Kernel>
|
||
|
Nef_3 nef (V_f.begin(), V_f.end(), normal, verb);
|
||
|
if ( !nef.is_empty() )
|
||
|
{nary_union.add_polyhedron(nef);
|
||
|
is_nef = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !is_nef )
|
||
|
{ ++discarded_facets;
|
||
|
if (verb)
|
||
|
{ std::cerr << "Hence, discard input facet " << (idx+1)
|
||
|
<< " (enumerated beginning with 1)."
|
||
|
<< " Check semantics!\n" << std::endl;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#ifdef CGAL_NEF_OFF_TO_NEF_TIMER
|
||
|
t_convert.stop();
|
||
|
std::cout << "time (conversion): " << t_convert.time()<< std::endl;
|
||
|
#endif
|
||
|
|
||
|
// union of queue entries
|
||
|
|
||
|
#ifdef CGAL_NEF_OFF_TO_NEF_TIMER
|
||
|
t_union.start();
|
||
|
#endif
|
||
|
|
||
|
#ifdef CGAL_NEF_OFF_TO_NEF_TIMER
|
||
|
t_union.stop();
|
||
|
std::cout << "time (union): " << t_union.time() << "\n" << std::endl;
|
||
|
#endif
|
||
|
|
||
|
// return values
|
||
|
// if ( nef_map.size() == 0 ) nef_union = Nef_3 ();
|
||
|
// else
|
||
|
nef_union = nary_union.get_union();
|
||
|
CGAL::Mark_bounded_volumes<Nef_3> mbv (true);
|
||
|
nef_union.delegate (mbv);
|
||
|
|
||
|
return discarded_facets;
|
||
|
}
|
||
|
|
||
|
} //namespace CGAL
|
||
|
|
||
|
#include <CGAL/enable_warnings.h>
|
||
|
|
||
|
#endif // CGAL_OFF_TO_NEF_3_H
|