mirror of https://github.com/CGAL/cgal
Update to master.
This commit is contained in:
commit
4f97ab767b
22
.travis.yml
22
.travis.yml
|
|
@ -1,5 +1,5 @@
|
||||||
language: cpp
|
language: cpp
|
||||||
dist: trusty
|
dist: xenial
|
||||||
sudo: required
|
sudo: required
|
||||||
git:
|
git:
|
||||||
depth: 3
|
depth: 3
|
||||||
|
|
@ -44,26 +44,26 @@ env:
|
||||||
- PACKAGE='Solver_interface Spatial_searching Spatial_sorting '
|
- PACKAGE='Solver_interface Spatial_searching Spatial_sorting '
|
||||||
- PACKAGE='STL_Extension Straight_skeleton_2 Stream_lines_2 '
|
- PACKAGE='STL_Extension Straight_skeleton_2 Stream_lines_2 '
|
||||||
- PACKAGE='Stream_support Subdivision_method_3 Surface_mesh '
|
- PACKAGE='Stream_support Subdivision_method_3 Surface_mesh '
|
||||||
- PACKAGE='Surface_mesh_deformation Surface_mesher Surface_mesh_parameterization '
|
- PACKAGE='Surface_mesh_approximation Surface_mesh_deformation Surface_mesher '
|
||||||
- PACKAGE='Surface_mesh_segmentation Surface_mesh_shortest_path Surface_mesh_simplification '
|
- PACKAGE='Surface_mesh_parameterization Surface_mesh_segmentation Surface_mesh_shortest_path '
|
||||||
- PACKAGE='Surface_mesh_skeletonization Surface_sweep_2 TDS_2 '
|
- PACKAGE='Surface_mesh_simplification Surface_mesh_skeletonization Surface_sweep_2 '
|
||||||
- PACKAGE='TDS_3 Testsuite Three '
|
- PACKAGE='TDS_2 TDS_3 Testsuite '
|
||||||
- PACKAGE='Triangulation Triangulation_2 Triangulation_3 '
|
- PACKAGE='Three Triangulation Triangulation_2 '
|
||||||
- PACKAGE='Union_find Visibility_2 Voronoi_diagram_2 '
|
- PACKAGE='Triangulation_3 Union_find Visibility_2 '
|
||||||
- PACKAGE='wininst '
|
- PACKAGE='Voronoi_diagram_2 wininst '
|
||||||
compiler: clang-3.6
|
compiler: clang
|
||||||
install:
|
install:
|
||||||
- echo "$PWD"
|
- echo "$PWD"
|
||||||
- if [ -n "$TRAVIS_PULL_REQUEST" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi
|
- if [ -n "$TRAVIS_PULL_REQUEST" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi
|
||||||
- bash .travis/install.sh
|
- bash .travis/install.sh
|
||||||
- export CXX=clang++-3.6 CC=clang-3.6;
|
- export CXX=clang++ CC=clang;
|
||||||
before_script:
|
before_script:
|
||||||
- wget -O doxygen_exe https://cgal.geometryfactory.com/~mgimeno/doxygen_exe
|
- wget -O doxygen_exe https://cgal.geometryfactory.com/~mgimeno/doxygen_exe
|
||||||
- sudo mv doxygen_exe /usr/bin/doxygen
|
- sudo mv doxygen_exe /usr/bin/doxygen
|
||||||
- sudo chmod +x /usr/bin/doxygen
|
- sudo chmod +x /usr/bin/doxygen
|
||||||
- mkdir -p build
|
- mkdir -p build
|
||||||
- cd build
|
- cd build
|
||||||
- cmake -DCMAKE_CXX_FLAGS="-std=c++11" -DCGAL_HEADER_ONLY=ON -DQt5_DIR="/opt/qt55/lib/cmake/Qt5" -DQt5Svg_DIR="/opt/qt55/lib/cmake/Qt5Svg" -DQt5OpenGL_DIR="/opt/qt55/lib/cmake/Qt5OpenGL" -DCMAKE_CXX_FLAGS_RELEASE=-DCGAL_NDEBUG -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON ..
|
- cmake -DCMAKE_CXX_FLAGS="-std=c++11" -DCGAL_HEADER_ONLY=ON -DCMAKE_CXX_FLAGS_RELEASE=-DCGAL_NDEBUG -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON ..
|
||||||
- make
|
- make
|
||||||
- sudo make install &>/dev/null
|
- sudo make install &>/dev/null
|
||||||
- cd ..
|
- cd ..
|
||||||
|
|
|
||||||
|
|
@ -18,40 +18,18 @@ function build_tests {
|
||||||
function build_demo {
|
function build_demo {
|
||||||
mkdir -p build-travis
|
mkdir -p build-travis
|
||||||
cd build-travis
|
cd build-travis
|
||||||
if [ $NEED_3D = 1 ]; then
|
|
||||||
#install libqglviewer
|
|
||||||
git clone --depth=4 -b v2.6.3 --single-branch https://github.com/GillesDebunne/libQGLViewer.git ./qglviewer
|
|
||||||
pushd ./qglviewer/QGLViewer
|
|
||||||
#use qt5 instead of qt4
|
|
||||||
# export QT_SELECT=5
|
|
||||||
qmake NO_QT_VERSION_SUFFIX=yes
|
|
||||||
make -j2
|
|
||||||
if [ ! -f libQGLViewer.so ]; then
|
|
||||||
echo "libQGLViewer.so not made"
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo "QGLViewer built successfully"
|
|
||||||
fi
|
|
||||||
#end install qglviewer
|
|
||||||
popd
|
|
||||||
fi
|
|
||||||
EXTRA_CXX_FLAGS=
|
EXTRA_CXX_FLAGS=
|
||||||
case "$CC" in
|
case "$CC" in
|
||||||
clang*)
|
clang*)
|
||||||
EXTRA_CXX_FLAGS="-Werror=inconsistent-missing-override"
|
EXTRA_CXX_FLAGS="-Werror=inconsistent-missing-override"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
if [ $NEED_3D = 1 ]; then
|
cmake -DCGAL_DIR="/usr/local/lib/cmake/CGAL" -DCGAL_DONT_OVERRIDE_CMAKE_FLAGS:BOOL=ON -DCMAKE_CXX_FLAGS="${CXX_FLAGS} ${EXTRA_CXX_FLAGS}" ..
|
||||||
QGLVIEWERROOT=$PWD/qglviewer
|
|
||||||
export QGLVIEWERROOT
|
|
||||||
fi
|
|
||||||
cmake -DCGAL_DIR="/usr/local/lib/cmake/CGAL" -DQt5_DIR="/opt/qt55/lib/cmake/Qt5" -DQt5Svg_DIR="/opt/qt55/lib/cmake/Qt5Svg" -DQt5OpenGL_DIR="/opt/qt55/lib/cmake/Qt5OpenGL" -DCGAL_DONT_OVERRIDE_CMAKE_FLAGS:BOOL=ON -DCMAKE_CXX_FLAGS="${CXX_FLAGS} ${EXTRA_CXX_FLAGS}" ..
|
|
||||||
make -j2
|
make -j2
|
||||||
}
|
}
|
||||||
old_IFS=$IFS
|
old_IFS=$IFS
|
||||||
IFS=$' '
|
IFS=$' '
|
||||||
ROOT="$PWD/.."
|
ROOT="$PWD/.."
|
||||||
NEED_3D=0
|
|
||||||
for ARG in $(echo "$@")
|
for ARG in $(echo "$@")
|
||||||
do
|
do
|
||||||
#skip package maintenance
|
#skip package maintenance
|
||||||
|
|
@ -146,12 +124,6 @@ cd $ROOT
|
||||||
EXAMPLES="$ARG/examples/$ARG"
|
EXAMPLES="$ARG/examples/$ARG"
|
||||||
TEST="$ARG/test/$ARG"
|
TEST="$ARG/test/$ARG"
|
||||||
DEMOS=$ROOT/$ARG/demo/*
|
DEMOS=$ROOT/$ARG/demo/*
|
||||||
if [ "$ARG" = AABB_tree ] || [ "$ARG" = Alpha_shapes_3 ] ||\
|
|
||||||
[ "$ARG" = Circular_kernel_3 ] || [ "$ARG" = Linear_cell_complex ] ||\
|
|
||||||
[ "$ARG" = Periodic_3_triangulation_3 ] || [ "$ARG" = Principal_component_analysis ] ||\
|
|
||||||
[ "$ARG" = Surface_mesher ] || [ "$ARG" = Triangulation_3 ]; then
|
|
||||||
NEED_3D=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -d "$ROOT/$EXAMPLES" ]
|
if [ -d "$ROOT/$EXAMPLES" ]
|
||||||
then
|
then
|
||||||
|
|
@ -206,10 +178,9 @@ cd $ROOT
|
||||||
done
|
done
|
||||||
if [ "$ARG" = Polyhedron_demo ]; then
|
if [ "$ARG" = Polyhedron_demo ]; then
|
||||||
DEMO=Polyhedron/demo/Polyhedron
|
DEMO=Polyhedron/demo/Polyhedron
|
||||||
NEED_3D=1
|
|
||||||
cd "$ROOT/$DEMO"
|
cd "$ROOT/$DEMO"
|
||||||
build_demo
|
build_demo
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
IFS=$old_IFS
|
IFS=$old_IFS
|
||||||
# Local Variables:
|
# Local Variables:
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ done
|
||||||
COPY=0
|
COPY=0
|
||||||
for LINE in $(cat "$PWD/.travis/template.txt")
|
for LINE in $(cat "$PWD/.travis/template.txt")
|
||||||
do
|
do
|
||||||
if [ "$LINE" = "compiler: clang-3.6" ]
|
if [ "$LINE" = "compiler: clang" ]
|
||||||
then
|
then
|
||||||
COPY=1
|
COPY=1
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -2,23 +2,13 @@
|
||||||
|
|
||||||
[ -n "$CGAL_DEBUG_TRAVIS" ] && set -x
|
[ -n "$CGAL_DEBUG_TRAVIS" ] && set -x
|
||||||
DONE=0
|
DONE=0
|
||||||
|
sudo apt-get update
|
||||||
while [ $DONE = 0 ]
|
while [ $DONE = 0 ]
|
||||||
do
|
do
|
||||||
DONE=1 && sudo -E apt-add-repository -y "ppa:ppsspp/cmake" || DONE=0 && sleep 5
|
DONE=1 && sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install clang zsh \
|
||||||
done
|
flex bison cmake graphviz libgmp-dev libmpfr-dev libmpfi-dev zlib1g-dev libeigen3-dev libboost-dev \
|
||||||
DONE=0
|
libboost-system-dev libboost-program-options-dev libboost-thread-dev libboost-iostreams-dev \
|
||||||
while [ $DONE = 0 ]
|
qtbase5-dev libqt5sql5-sqlite libqt5opengl5-dev qtscript5-dev libqt5svg5-dev qttools5-dev qttools5-dev-tools qml-module-qtgraphicaleffects libopencv-dev mesa-common-dev libmetis-dev libglu1-mesa-dev \
|
||||||
do
|
|
||||||
DONE=1 && sudo -E apt-add-repository -y "ppa:hedges/qt5.5" || DONE=0 && sleep 5
|
|
||||||
done
|
|
||||||
|
|
||||||
DONE=0
|
|
||||||
while [ $DONE = 0 ]
|
|
||||||
do
|
|
||||||
DONE=1 && sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install clang-3.6 zsh \
|
|
||||||
flex bison cmake graphviz libgmp-dev libmpfr-dev libmpfi-dev zlib1g-dev libeigen3-dev libboost1.55-dev \
|
|
||||||
libboost-system1.55-dev libboost-program-options1.55-dev libboost-thread1.55-dev libboost-iostreams1.55-dev \
|
|
||||||
qt55base qt55script qt55svg qt55tools qt55graphicaleffects libopencv-dev mesa-common-dev libmetis-dev libglu1-mesa-dev \
|
|
||||||
|| DONE=0 && sudo apt-get update
|
|| DONE=0 && sudo apt-get update
|
||||||
done
|
done
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ Stream_lines_2
|
||||||
Stream_support
|
Stream_support
|
||||||
Subdivision_method_3
|
Subdivision_method_3
|
||||||
Surface_mesh
|
Surface_mesh
|
||||||
|
Surface_mesh_approximation
|
||||||
Surface_mesh_deformation
|
Surface_mesh_deformation
|
||||||
Surface_mesher
|
Surface_mesher
|
||||||
Surface_mesh_parameterization
|
Surface_mesh_parameterization
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
language: cpp
|
language: cpp
|
||||||
dist: trusty
|
dist: xenial
|
||||||
sudo: required
|
sudo: required
|
||||||
git:
|
git:
|
||||||
depth: 3
|
depth: 3
|
||||||
|
|
@ -7,19 +7,19 @@ env:
|
||||||
matrix:
|
matrix:
|
||||||
PACKAGES_MATRIX
|
PACKAGES_MATRIX
|
||||||
|
|
||||||
compiler: clang-3.6
|
compiler: clang
|
||||||
install:
|
install:
|
||||||
- echo "$PWD"
|
- echo "$PWD"
|
||||||
- if [ -n "$TRAVIS_PULL_REQUEST" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi
|
- if [ -n "$TRAVIS_PULL_REQUEST" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi
|
||||||
- bash .travis/install.sh
|
- bash .travis/install.sh
|
||||||
- export CXX=clang++-3.6 CC=clang-3.6;
|
- export CXX=clang++ CC=clang;
|
||||||
before_script:
|
before_script:
|
||||||
- wget -O doxygen_exe https://cgal.geometryfactory.com/~mgimeno/doxygen_exe
|
- wget -O doxygen_exe https://cgal.geometryfactory.com/~mgimeno/doxygen_exe
|
||||||
- sudo mv doxygen_exe /usr/bin/doxygen
|
- sudo mv doxygen_exe /usr/bin/doxygen
|
||||||
- sudo chmod +x /usr/bin/doxygen
|
- sudo chmod +x /usr/bin/doxygen
|
||||||
- mkdir -p build
|
- mkdir -p build
|
||||||
- cd build
|
- cd build
|
||||||
- cmake -DCMAKE_CXX_FLAGS="-std=c++11" -DCGAL_HEADER_ONLY=ON -DQt5_DIR="/opt/qt55/lib/cmake/Qt5" -DQt5Svg_DIR="/opt/qt55/lib/cmake/Qt5Svg" -DQt5OpenGL_DIR="/opt/qt55/lib/cmake/Qt5OpenGL" -DCMAKE_CXX_FLAGS_RELEASE=-DCGAL_NDEBUG -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON ..
|
- cmake -DCMAKE_CXX_FLAGS="-std=c++11" -DCGAL_HEADER_ONLY=ON -DCMAKE_CXX_FLAGS_RELEASE=-DCGAL_NDEBUG -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON ..
|
||||||
- make
|
- make
|
||||||
- sudo make install &>/dev/null
|
- sudo make install &>/dev/null
|
||||||
- cd ..
|
- cd ..
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <boost/iterator.hpp>
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
|
||||||
#include <CGAL/Simple_cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
#include <CGAL/AABB_tree.h>
|
#include <CGAL/AABB_tree.h>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
|
|
||||||
// Author(s) : Camille Wormser, Pierre Alliez
|
// Author(s) : Camille Wormser, Pierre Alliez
|
||||||
// Example of an AABB tree used with a simple list of
|
// Example of an AABB tree used with a simple list of
|
||||||
// triangles (a triangle soup) stored into an array of points.
|
// triangles (a triangle soup) stored into an array of points.
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/iterator.hpp>
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
|
||||||
#include <CGAL/Simple_cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
#include <CGAL/AABB_tree.h>
|
#include <CGAL/AABB_tree.h>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
// Copyright (c) 2017 GeometryFactory (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
|
||||||
|
// 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$
|
||||||
|
// SPDX-License-Identifier: GPL-3.0+
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author : Jane Tournois
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CGAL_AABB_TRIANGULATION_3_CELL_PRIMITIVE_H_
|
||||||
|
#define CGAL_AABB_TRIANGULATION_3_CELL_PRIMITIVE_H_
|
||||||
|
|
||||||
|
#include <CGAL/license/AABB_tree.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <CGAL/AABB_primitive.h>
|
||||||
|
#include <CGAL/result_of.h>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace CGAL
|
||||||
|
{
|
||||||
|
namespace internal
|
||||||
|
{
|
||||||
|
template <class GeomTraits, class Iterator>
|
||||||
|
struct Point_from_cell_iterator_proprety_map
|
||||||
|
{
|
||||||
|
//classical typedefs
|
||||||
|
typedef Iterator key_type;
|
||||||
|
typedef typename GeomTraits::Point_3 value_type;
|
||||||
|
typedef typename cpp11::result_of<
|
||||||
|
typename GeomTraits::Construct_vertex_3(typename GeomTraits::Tetrahedron_3, int)
|
||||||
|
>::type reference;
|
||||||
|
typedef boost::readable_property_map_tag category;
|
||||||
|
|
||||||
|
inline friend
|
||||||
|
typename Point_from_cell_iterator_proprety_map<GeomTraits, Iterator>::reference
|
||||||
|
get(Point_from_cell_iterator_proprety_map<GeomTraits, Iterator>, Iterator it)
|
||||||
|
{
|
||||||
|
typename GeomTraits::Construct_point_3 point;
|
||||||
|
return point(it->vertex(1)->point());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class GeomTraits, class Iterator>
|
||||||
|
struct Tet_from_cell_iterator_proprety_map
|
||||||
|
{
|
||||||
|
//classical typedefs
|
||||||
|
typedef Iterator key_type;
|
||||||
|
typedef typename GeomTraits::Tetrahedron_3 value_type;
|
||||||
|
typedef value_type reference;
|
||||||
|
typedef boost::readable_property_map_tag category;
|
||||||
|
|
||||||
|
inline friend
|
||||||
|
reference
|
||||||
|
get(Tet_from_cell_iterator_proprety_map<GeomTraits, Iterator>, key_type it)
|
||||||
|
{
|
||||||
|
typename GeomTraits::Construct_point_3 point;
|
||||||
|
return value_type(point(it->vertex(0)->point()),
|
||||||
|
point(it->vertex(1)->point()),
|
||||||
|
point(it->vertex(2)->point()),
|
||||||
|
point(it->vertex(3)->point()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}//namespace internal
|
||||||
|
|
||||||
|
|
||||||
|
template < class GeomTraits,
|
||||||
|
class Tr,
|
||||||
|
class CacheDatum = Tag_false,
|
||||||
|
class Handle = typename Tr::Cell_handle>
|
||||||
|
class AABB_triangulation_3_cell_primitive
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
: public AABB_primitive< Handle,
|
||||||
|
internal::Tet_from_cell_iterator_proprety_map<GeomTraits, Handle>,
|
||||||
|
internal::Point_from_cell_iterator_proprety_map<GeomTraits, Handle>,
|
||||||
|
Tag_false,
|
||||||
|
CacheDatum >
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
typedef AABB_primitive< Handle,
|
||||||
|
internal::Tet_from_cell_iterator_proprety_map<GeomTraits, Handle>,
|
||||||
|
internal::Point_from_cell_iterator_proprety_map<GeomTraits, Handle>,
|
||||||
|
Tag_false,
|
||||||
|
CacheDatum > Base;
|
||||||
|
public:
|
||||||
|
AABB_triangulation_3_cell_primitive(Handle h) : Base(h){} };
|
||||||
|
|
||||||
|
} // end namespace CGAL
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CGAL_AABB_TRIANGULATION_3_CELL_PRIMITIVE_H_
|
||||||
|
|
@ -65,6 +65,9 @@ namespace CGAL
|
||||||
m_id = rhs.m_id;
|
m_id = rhs.m_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS
|
||||||
|
Decorated_point& operator=(const Decorated_point&)=default;
|
||||||
|
#endif
|
||||||
private:
|
private:
|
||||||
Id m_id;
|
Id m_id;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,9 +114,6 @@ public:
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
Algebraic_real_d_1() : Base(static_cast<const Base&>(get_default_instance())) {}
|
Algebraic_real_d_1() : Base(static_cast<const Base&>(get_default_instance())) {}
|
||||||
|
|
||||||
//! copy constructor: copy existing Algebraic_real_d_1 (shares rep)
|
|
||||||
Algebraic_real_d_1(const Self& p) : Base(static_cast<const Base&>(p)) {}
|
|
||||||
|
|
||||||
//! creates the algebraic real from \a i.
|
//! creates the algebraic real from \a i.
|
||||||
Algebraic_real_d_1(int i ) : Base(Algebraic_real_rep_d_1(i)) { }
|
Algebraic_real_d_1(int i ) : Base(Algebraic_real_rep_d_1(i)) { }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,9 +108,11 @@ public:
|
||||||
|
|
||||||
Bitstream_coefficient_kernel_at_alpha() : Base(Rep()) {}
|
Bitstream_coefficient_kernel_at_alpha() : Base(Rep()) {}
|
||||||
|
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Bitstream_coefficient_kernel_at_alpha(const Self& traits)
|
Bitstream_coefficient_kernel_at_alpha(const Self& traits)
|
||||||
: Base(static_cast<const Base&>(traits)) {}
|
: Base(static_cast<const Base&>(traits)) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
Bitstream_coefficient_kernel_at_alpha(Algebraic_kernel_d_1* kernel,
|
Bitstream_coefficient_kernel_at_alpha(Algebraic_kernel_d_1* kernel,
|
||||||
Algebraic_real_1 alpha)
|
Algebraic_real_1 alpha)
|
||||||
: Base(kernel,alpha) {}
|
: Base(kernel,alpha) {}
|
||||||
|
|
|
||||||
|
|
@ -476,7 +476,9 @@ private:
|
||||||
log_C_eps_ = n.log_C_eps_;
|
log_C_eps_ = n.log_C_eps_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const Self& operator= (const Self&); // assignment is forbidden
|
#ifndef CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS
|
||||||
|
Self& operator= (const Self&) = delete;
|
||||||
|
#endif
|
||||||
}; // struct Bitstream_descartes_E08_node
|
}; // struct Bitstream_descartes_E08_node
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -575,9 +577,11 @@ public:
|
||||||
Bitstream_descartes_E08_tree() : Base(Rep()) { }
|
Bitstream_descartes_E08_tree() : Base(Rep()) { }
|
||||||
|
|
||||||
//! copy constructor
|
//! copy constructor
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Bitstream_descartes_E08_tree(const Self& p)
|
Bitstream_descartes_E08_tree(const Self& p)
|
||||||
: Base(static_cast<const Base&>(p))
|
: Base(static_cast<const Base&>(p))
|
||||||
{ }
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
/*! \brief construct from initial interval and coefficients
|
/*! \brief construct from initial interval and coefficients
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -566,8 +566,10 @@ private:
|
||||||
log_eps_ = n.log_eps_;
|
log_eps_ = n.log_eps_;
|
||||||
log_C_eps_ = n.log_C_eps_;
|
log_C_eps_ = n.log_C_eps_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const Self& operator= (const Self&); // assignment is forbidden
|
#ifndef CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS
|
||||||
|
Self& operator= (const Self&)=delete;
|
||||||
|
#endif
|
||||||
}; // struct Bitstream_descartes_rndl_node
|
}; // struct Bitstream_descartes_rndl_node
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -931,9 +933,11 @@ public:
|
||||||
Bitstream_descartes_rndl_tree() : Base(Rep()) { }
|
Bitstream_descartes_rndl_tree() : Base(Rep()) { }
|
||||||
|
|
||||||
//! copy constructor
|
//! copy constructor
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Bitstream_descartes_rndl_tree(const Self& p)
|
Bitstream_descartes_rndl_tree(const Self& p)
|
||||||
: Base(static_cast<const Base&>(p))
|
: Base(static_cast<const Base&>(p))
|
||||||
{ }
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
//! Internal function called by constructor. Avoids code duplication
|
//! Internal function called by constructor. Avoids code duplication
|
||||||
void init_tree() {
|
void init_tree() {
|
||||||
|
|
|
||||||
|
|
@ -154,9 +154,10 @@ public:
|
||||||
: Base(static_cast<const Base&>(get_default_instance())){}
|
: Base(static_cast<const Base&>(get_default_instance())){}
|
||||||
|
|
||||||
// explicit copy-constructor, required by VC9
|
// explicit copy-constructor, required by VC9
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Bitstream_descartes_rndl_tree_traits(const Self& traits)
|
Bitstream_descartes_rndl_tree_traits(const Self& traits)
|
||||||
: Base(static_cast<const Base&>(traits)){}
|
: Base(static_cast<const Base&>(traits)){}
|
||||||
|
#endif
|
||||||
//! @}
|
//! @}
|
||||||
|
|
||||||
class Approximator {
|
class Approximator {
|
||||||
|
|
|
||||||
|
|
@ -505,11 +505,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief Copy constructor
|
//! \brief Copy constructor
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Curve_analysis_2(const Self& alg_curve)
|
Curve_analysis_2(const Self& alg_curve)
|
||||||
: Base(static_cast<const Base&>(alg_curve))
|
: Base(static_cast<const Base&>(alg_curve))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//!@}
|
//!@}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -446,11 +446,12 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Copy constructor
|
//! \brief Copy constructor
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Curve_pair_analysis_2(const Self& alg_curve_pair)
|
Curve_pair_analysis_2(const Self& alg_curve_pair)
|
||||||
: Base(static_cast<const Base&>(alg_curve_pair))
|
: Base(static_cast<const Base&>(alg_curve_pair))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// Assignable
|
// Assignable
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -1434,7 +1435,13 @@ compute_event_x_coordinates_with_event_indices() const {
|
||||||
CGAL_ACK_DEBUG_PRINT << " one curve event" << std::endl;
|
CGAL_ACK_DEBUG_PRINT << " one curve event" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
|
#if CGAL_CXX11
|
||||||
|
// Fix a warning by using `emplace_back()` instead of
|
||||||
|
// copying a non-initialized `optional
|
||||||
|
this->ptr()->event_slices.emplace_back();
|
||||||
|
#else
|
||||||
this->ptr()->event_slices.push_back(Lazy_status_line_CPA_1());
|
this->ptr()->event_slices.push_back(Lazy_status_line_CPA_1());
|
||||||
|
#endif
|
||||||
switch(*(one_curve_it++)) {
|
switch(*(one_curve_it++)) {
|
||||||
case(CGAL::internal::ROOT_OF_FIRST_SET): {
|
case(CGAL::internal::ROOT_OF_FIRST_SET): {
|
||||||
event_indices.push_back(Event_indices(-1,f_count,-1));
|
event_indices.push_back(Event_indices(-1,f_count,-1));
|
||||||
|
|
@ -1461,8 +1468,11 @@ compute_event_x_coordinates_with_event_indices() const {
|
||||||
CGAL_ACK_DEBUG_PRINT << " two curve event" << std::endl;
|
CGAL_ACK_DEBUG_PRINT << " two curve event" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
this->ptr()->
|
#if CGAL_CXX11
|
||||||
event_slices.push_back(Lazy_status_line_CPA_1());
|
this->ptr()->event_slices.emplace_back();
|
||||||
|
#else
|
||||||
|
this->ptr()->event_slices.push_back(Lazy_status_line_CPA_1());
|
||||||
|
#endif
|
||||||
|
|
||||||
event_indices.push_back
|
event_indices.push_back
|
||||||
(Event_indices(inter_count,-1,-1));
|
(Event_indices(inter_count,-1,-1));
|
||||||
|
|
@ -1476,7 +1486,11 @@ compute_event_x_coordinates_with_event_indices() const {
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
|
#if CGAL_CXX11
|
||||||
|
this->ptr()->event_slices.emplace_back();
|
||||||
|
#else
|
||||||
this->ptr()->event_slices.push_back(Lazy_status_line_CPA_1());
|
this->ptr()->event_slices.push_back(Lazy_status_line_CPA_1());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
switch(*(one_curve_it++)) {
|
switch(*(one_curve_it++)) {
|
||||||
|
|
|
||||||
|
|
@ -252,9 +252,11 @@ public:
|
||||||
/*!\brief
|
/*!\brief
|
||||||
* copy constructor
|
* copy constructor
|
||||||
*/
|
*/
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Status_line_CA_1(const Self& p) :
|
Status_line_CA_1(const Self& p) :
|
||||||
Base(static_cast<const Base&>(p)) {
|
Base(static_cast<const Base&>(p)) {
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!\brief
|
/*!\brief
|
||||||
* constructs a status line over the \c i-th interval with x-coordinate
|
* constructs a status line over the \c i-th interval with x-coordinate
|
||||||
|
|
|
||||||
|
|
@ -174,10 +174,12 @@ public:
|
||||||
/*!\brief
|
/*!\brief
|
||||||
* copy constructor
|
* copy constructor
|
||||||
*/
|
*/
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Status_line_CPA_1(const Self& p) :
|
Status_line_CPA_1(const Self& p) :
|
||||||
Base(static_cast<const Base&>(p)) {
|
Base(static_cast<const Base&>(p)) {
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!\brief
|
/*!\brief
|
||||||
* constructs undefined status line
|
* constructs undefined status line
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -219,9 +219,11 @@ public:
|
||||||
/*!\brief
|
/*!\brief
|
||||||
* copy constructor
|
* copy constructor
|
||||||
*/
|
*/
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Xy_coordinate_2(const Self& p) :
|
Xy_coordinate_2(const Self& p) :
|
||||||
Base(static_cast<const Base&>(p)) {
|
Base(static_cast<const Base&>(p)) {
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!\brief
|
/*!\brief
|
||||||
* Point at \c x, on \c curve with \c arcno. Finite points on vertical arcs
|
* Point at \c x, on \c curve with \c arcno. Finite points on vertical arcs
|
||||||
|
|
|
||||||
|
|
@ -47,10 +47,6 @@ public:
|
||||||
Apollonius_site_2(const Point_2& p = Point_2(),
|
Apollonius_site_2(const Point_2& p = Point_2(),
|
||||||
const Weight& w = Weight(0))
|
const Weight& w = Weight(0))
|
||||||
: _p(p), _w(w) {}
|
: _p(p), _w(w) {}
|
||||||
|
|
||||||
Apollonius_site_2(const Apollonius_site_2& other)
|
|
||||||
: _p(other._p), _w(other._w) {}
|
|
||||||
|
|
||||||
|
|
||||||
const Point_2& point() const { return _p; }
|
const Point_2& point() const { return _p; }
|
||||||
const Weight& weight() const { return _w; }
|
const Weight& weight() const { return _w; }
|
||||||
|
|
|
||||||
|
|
@ -2881,12 +2881,14 @@ public:
|
||||||
/*! Copy constructor
|
/*! Copy constructor
|
||||||
* \param other the other arc
|
* \param other the other arc
|
||||||
*/
|
*/
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Arr_geodesic_arc_on_sphere_3
|
Arr_geodesic_arc_on_sphere_3
|
||||||
(const Arr_geodesic_arc_on_sphere_3& other) : Base(other)
|
(const Arr_geodesic_arc_on_sphere_3& other) : Base(other)
|
||||||
{
|
{
|
||||||
m_is_x_monotone = other.m_is_x_monotone;
|
m_is_x_monotone = other.m_is_x_monotone;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*! Constructor
|
/*! Constructor
|
||||||
* \param src the source point of the arc
|
* \param src the source point of the arc
|
||||||
* \param trg the target point of the arc
|
* \param trg the target point of the arc
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,10 @@ public:
|
||||||
Point_handle (p)
|
Point_handle (p)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
#ifndef CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS
|
||||||
|
_One_root_point_2& operator=(const _One_root_point_2&)=default;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*! Constructor of a point with one-root coefficients.
|
/*! Constructor of a point with one-root coefficients.
|
||||||
This constructor of a point can also be used with rational coefficients
|
This constructor of a point can also be used with rational coefficients
|
||||||
thanks to convertor of CoordNT. */
|
thanks to convertor of CoordNT. */
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,15 @@ public:
|
||||||
_rational_function(rational_function),
|
_rational_function(rational_function),
|
||||||
_x_coordinate(x_coordinate) {}
|
_x_coordinate(x_coordinate) {}
|
||||||
|
|
||||||
|
Algebraic_point_2_rep(const Algebraic_point_2_rep& other)
|
||||||
|
{
|
||||||
|
if (this != &other) // protect against invalid self-assignment
|
||||||
|
{
|
||||||
|
_rational_function = other._rational_function;
|
||||||
|
_x_coordinate = other._x_coordinate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//assignment oparator
|
//assignment oparator
|
||||||
Algebraic_point_2_rep& operator=(const Algebraic_point_2_rep& other)
|
Algebraic_point_2_rep& operator=(const Algebraic_point_2_rep& other)
|
||||||
{
|
{
|
||||||
|
|
@ -374,10 +383,6 @@ public:
|
||||||
Algebraic_point_2() :
|
Algebraic_point_2() :
|
||||||
Base(static_cast<const Base &> (get_default_instance())) {}
|
Base(static_cast<const Base &> (get_default_instance())) {}
|
||||||
|
|
||||||
// explicit copy-constructor, required by VC9
|
|
||||||
Algebraic_point_2 (const Self & p)
|
|
||||||
: Base(static_cast<const Base &> (p)) {}
|
|
||||||
|
|
||||||
Comparison_result compare_xy_2(const Algebraic_point_2& other,
|
Comparison_result compare_xy_2(const Algebraic_point_2& other,
|
||||||
const Cache& cache) const
|
const Cache& cache) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,10 @@ public:
|
||||||
Rational_function (const Self & r)
|
Rational_function (const Self & r)
|
||||||
: Base(static_cast<const Base &> (r)) {}
|
: Base(static_cast<const Base &> (r)) {}
|
||||||
|
|
||||||
|
#ifndef CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS
|
||||||
|
Self& operator=(const Self&)=default;
|
||||||
|
#endif
|
||||||
|
|
||||||
CGAL::Sign sign_at(const Algebraic_real_1& x,
|
CGAL::Sign sign_at(const Algebraic_real_1& x,
|
||||||
CGAL::Sign epsilon = CGAL::ZERO) const
|
CGAL::Sign epsilon = CGAL::ZERO) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -382,10 +382,11 @@ public:
|
||||||
/*!\brief
|
/*!\brief
|
||||||
* copy constructor
|
* copy constructor
|
||||||
*/
|
*/
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Arc_2(const Self& a) :
|
Arc_2(const Self& a) :
|
||||||
Base(static_cast<const Base&>(a)) {
|
Base(static_cast<const Base&>(a)) {
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
//!@}
|
//!@}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -150,10 +150,12 @@ public:
|
||||||
/*!\brief
|
/*!\brief
|
||||||
* copy constructor
|
* copy constructor
|
||||||
*/
|
*/
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Generic_arc_2(const Self& p) :
|
Generic_arc_2(const Self& p) :
|
||||||
Base(static_cast<const Base&>(p)) {
|
Base(static_cast<const Base&>(p)) {
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!\brief
|
/*!\brief
|
||||||
* constructs an arc from a given represenation
|
* constructs an arc from a given represenation
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -131,10 +131,11 @@ public:
|
||||||
/*!\brief
|
/*!\brief
|
||||||
* copy constructor
|
* copy constructor
|
||||||
*/
|
*/
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Generic_point_2(const Self& p) :
|
Generic_point_2(const Self& p) :
|
||||||
Base(static_cast<const Base&>(p)) {
|
Base(static_cast<const Base&>(p)) {
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/*!\brief
|
/*!\brief
|
||||||
* constructs an arc from a given represenation
|
* constructs an arc from a given represenation
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -146,9 +146,11 @@ public:
|
||||||
/*!\brief
|
/*!\brief
|
||||||
* copy constructor
|
* copy constructor
|
||||||
*/
|
*/
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Non_x_monotone_arc_2(const Self& a) :
|
Non_x_monotone_arc_2(const Self& a) :
|
||||||
Base(static_cast<const Base&>(a)) {
|
Base(static_cast<const Base&>(a)) {
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*! \brief
|
/*! \brief
|
||||||
* constructs an arc from one x-monotone piece
|
* constructs an arc from one x-monotone piece
|
||||||
|
|
|
||||||
|
|
@ -256,10 +256,11 @@ public:
|
||||||
/*!\brief
|
/*!\brief
|
||||||
* copy constructor
|
* copy constructor
|
||||||
*/
|
*/
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Point_2(const Self& p) :
|
Point_2(const Self& p) :
|
||||||
Base(static_cast<const Base&>(p)) {
|
Base(static_cast<const Base&>(p)) {
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
//!@}
|
//!@}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \
|
||||||
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/METIS/partition_graph.h \
|
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/METIS/partition_graph.h \
|
||||||
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/METIS/partition_dual_graph.h
|
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/METIS/partition_dual_graph.h
|
||||||
|
|
||||||
|
|
||||||
EXAMPLE_PATH = ${CGAL_Surface_mesh_skeletonization_EXAMPLE_DIR} \
|
EXAMPLE_PATH = ${CGAL_Surface_mesh_skeletonization_EXAMPLE_DIR} \
|
||||||
${CGAL_Surface_mesh_segmentation_EXAMPLE_DIR} \
|
${CGAL_Surface_mesh_segmentation_EXAMPLE_DIR} \
|
||||||
${CGAL_Polygon_mesh_processing_EXAMPLE_DIR} \
|
${CGAL_Polygon_mesh_processing_EXAMPLE_DIR} \
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,13 @@ being marked or not.\n
|
||||||
<b>Default:</b> a default property map where no edge is constrained
|
<b>Default:</b> a default property map where no edge is constrained
|
||||||
\cgalNPEnd
|
\cgalNPEnd
|
||||||
|
|
||||||
|
\cgalNPBegin{use_binary_mode} \anchor BGL_use_binary_mode
|
||||||
|
is a Boolean indicating whether the binary mode or the ASCII mode should be used
|
||||||
|
when writing data into a stream.\n
|
||||||
|
<b>Type:</b> `bool`\n
|
||||||
|
<b>Default:</b> Function specific.
|
||||||
|
\cgalNPEnd
|
||||||
|
|
||||||
\cgalNPBegin{METIS_options} \anchor BGL_METIS_options
|
\cgalNPBegin{METIS_options} \anchor BGL_METIS_options
|
||||||
is a parameter used in `partition_graph()` and `partition_dual_graph()`
|
is a parameter used in `partition_graph()` and `partition_dual_graph()`
|
||||||
to pass options to the METIS graph partitioner. The many options of METIS
|
to pass options to the METIS graph partitioner. The many options of METIS
|
||||||
|
|
|
||||||
|
|
@ -709,6 +709,7 @@ user might encounter.
|
||||||
- \link PkgBGLIOFct CGAL::read_off() \endlink
|
- \link PkgBGLIOFct CGAL::read_off() \endlink
|
||||||
- \link PkgBGLIOFct CGAL::write_off() \endlink
|
- \link PkgBGLIOFct CGAL::write_off() \endlink
|
||||||
- \link PkgBGLIOFct CGAL::write_wrl() \endlink
|
- \link PkgBGLIOFct CGAL::write_wrl() \endlink
|
||||||
|
- `CGAL::write_vtp()`
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1329,38 +1329,37 @@ flip_edge(typename boost::graph_traits<Graph>::halfedge_descriptor h,
|
||||||
/**
|
/**
|
||||||
* \returns `true` if `e` satisfies the *link condition* \cgalCite{degn-tpec-98}, which guarantees that the surface is also 2-manifold after the edge collapse.
|
* \returns `true` if `e` satisfies the *link condition* \cgalCite{degn-tpec-98}, which guarantees that the surface is also 2-manifold after the edge collapse.
|
||||||
*/
|
*/
|
||||||
template<typename Graph>
|
template<typename Graph>
|
||||||
bool
|
bool
|
||||||
does_satisfy_link_condition(typename boost::graph_traits<Graph>::edge_descriptor e,
|
does_satisfy_link_condition(typename boost::graph_traits<Graph>::edge_descriptor e,
|
||||||
Graph& g)
|
Graph& g)
|
||||||
{
|
{
|
||||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||||
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
|
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
|
||||||
typedef CGAL::Halfedge_around_source_iterator<Graph> out_edge_iterator;
|
typedef CGAL::Halfedge_around_source_iterator<Graph> out_edge_iterator;
|
||||||
|
|
||||||
halfedge_descriptor v0_v1 = halfedge(e,g);
|
halfedge_descriptor v0_v1 = halfedge(e,g);
|
||||||
halfedge_descriptor v1_v0 = opposite(v0_v1,g);
|
halfedge_descriptor v1_v0 = opposite(v0_v1,g);
|
||||||
|
|
||||||
vertex_descriptor v0 = target(v1_v0,g), v1 = target(v0_v1,g);
|
|
||||||
|
|
||||||
vertex_descriptor vL = target(next(v0_v1,g),g);
|
vertex_descriptor v0 = target(v1_v0,g), v1 = target(v0_v1,g);
|
||||||
vertex_descriptor vR = target(next(v1_v0,g),g);
|
|
||||||
|
|
||||||
out_edge_iterator eb1, ee1 ;
|
vertex_descriptor vL = target(next(v0_v1,g),g);
|
||||||
out_edge_iterator eb2, ee2 ;
|
vertex_descriptor vR = target(next(v1_v0,g),g);
|
||||||
|
|
||||||
|
out_edge_iterator eb1, ee1 ;
|
||||||
|
out_edge_iterator eb2, ee2 ;
|
||||||
|
|
||||||
// The following loop checks the link condition for v0_v1.
|
// The following loop checks the link condition for v0_v1.
|
||||||
// Specifically, that for every vertex 'k' adjacent to both 'p and 'q', 'pkq' is a face of the mesh.
|
// Specifically, that for every vertex 'k' adjacent to both 'p and 'q', 'pkq' is a face of the mesh.
|
||||||
//
|
//
|
||||||
for ( boost::tie(eb1,ee1) = halfedges_around_source(v0,g) ; eb1 != ee1 ; ++ eb1 )
|
for ( boost::tie(eb1,ee1) = halfedges_around_source(v0,g) ; eb1 != ee1 ; ++ eb1 )
|
||||||
{
|
{
|
||||||
halfedge_descriptor v0_k = *eb1;
|
halfedge_descriptor v0_k = *eb1;
|
||||||
|
|
||||||
if ( v0_k != v0_v1 )
|
if ( v0_k != v0_v1 )
|
||||||
{
|
{
|
||||||
vertex_descriptor k = target(v0_k,g);
|
vertex_descriptor k = target(v0_k,g);
|
||||||
|
|
||||||
for ( boost::tie(eb2,ee2) = halfedges_around_source(k,g) ; eb2 != ee2 ; ++ eb2 )
|
for ( boost::tie(eb2,ee2) = halfedges_around_source(k,g) ; eb2 != ee2 ; ++ eb2 )
|
||||||
{
|
{
|
||||||
halfedge_descriptor k_v1 = *eb2;
|
halfedge_descriptor k_v1 = *eb2;
|
||||||
|
|
@ -1377,66 +1376,53 @@ bool
|
||||||
// If k is either t or b then p-q-k *might* be a face of the mesh. It won't be if k==t but p->q is border
|
// If k is either t or b then p-q-k *might* be a face of the mesh. It won't be if k==t but p->q is border
|
||||||
// or k==b but q->b is a border (because in that case even though there exists triangles p->q->t (or q->p->b)
|
// or k==b but q->b is a border (because in that case even though there exists triangles p->q->t (or q->p->b)
|
||||||
// they are holes, not faces)
|
// they are holes, not faces)
|
||||||
//
|
//
|
||||||
|
|
||||||
bool lIsFace = ( vL == k && (! is_border(v0_v1,g)) )
|
bool lIsFace = ( vL == k && (! is_border(v0_v1,g)) )
|
||||||
|| ( vR == k && (! is_border(v1_v0,g)) ) ;
|
|| ( vR == k && (! is_border(v1_v0,g)) ) ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( !lIsFace )
|
if ( !lIsFace )
|
||||||
{
|
{
|
||||||
// CGAL_ECMS_TRACE(3," k=V" << get(Vertex_index_map,k) << " IS NOT in a face with p-q. NON-COLLAPSABLE edge." ) ;
|
// CGAL_ECMS_TRACE(3," k=V" << get(Vertex_index_map,k) << " IS NOT in a face with p-q. NON-COLLAPSABLE edge." ) ;
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//CGAL_ECMS_TRACE(4," k=V" << get(Vertex_index_map,k) << " is in a face with p-q") ;
|
//CGAL_ECMS_TRACE(4," k=V" << get(Vertex_index_map,k) << " is in a face with p-q") ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ( is_border(v0_v1,g) )
|
|
||||||
{
|
|
||||||
if ( next(next(next(v0_v1,g),g),g) == v0_v1 )
|
|
||||||
{
|
|
||||||
//CGAL_ECMS_TRACE(3," p-q belongs to an open triangle. NON-COLLAPSABLE edge." ) ;
|
|
||||||
return false ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( is_border(v1_v0,g) )
|
}
|
||||||
|
|
||||||
|
// detect isolated triangle (or triangle attached to a mesh with non-manifold vertices)
|
||||||
|
if (!is_border(v0_v1,g) && is_border(opposite(next(v0_v1,g), g), g)
|
||||||
|
&& is_border(opposite(prev(v0_v1,g), g), g) ) return false;
|
||||||
|
if (!is_border(v1_v0,g) && is_border(opposite(next(v1_v0,g), g), g)
|
||||||
|
&& is_border(opposite(prev(v1_v0,g), g), g) ) return false;
|
||||||
|
|
||||||
|
if ( !is_border(v0_v1,g) && !is_border(v1_v0,g) )
|
||||||
|
{
|
||||||
|
if ( is_border(v0,g) && is_border(v1,g) )
|
||||||
{
|
{
|
||||||
if ( next(next(next(v1_v0,g),g),g) == v1_v0 )
|
//CGAL_ECMS_TRACE(3," both p and q are boundary vertices but p-q is not. NON-COLLAPSABLE edge." ) ;
|
||||||
{
|
return false ;
|
||||||
//CGAL_ECMS_TRACE(3," p-q belongs to an open triangle. NON-COLLAPSABLE edge." ) ;
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( is_border(v0,g) && is_border(v1,g) )
|
if ( is_tetrahedron(v0_v1,g) )
|
||||||
{
|
{
|
||||||
//CGAL_ECMS_TRACE(3," both p and q are boundary vertices but p-q is not. NON-COLLAPSABLE edge." ) ;
|
//CGAL_ECMS_TRACE(3," p-q belongs to a tetrahedron. NON-COLLAPSABLE edge." ) ;
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
else
|
if ( next(v0_v1, g) == opposite(prev(v1_v0, g), g) &&
|
||||||
|
prev(v0_v1, g) == opposite(next(v1_v0, g), g) )
|
||||||
{
|
{
|
||||||
if ( is_tetrahedron(v0_v1,g) )
|
//CGAL_ECMS_TRACE(3," degenerate volume." ) ;
|
||||||
{
|
return false ;
|
||||||
//CGAL_ECMS_TRACE(3," p-q belongs to a tetrahedron. NON-COLLAPSABLE edge." ) ;
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
if ( next(v0_v1, g) == opposite(prev(v1_v0, g), g) &&
|
|
||||||
prev(v0_v1, g) == opposite(next(v1_v0, g), g) )
|
|
||||||
{
|
|
||||||
//CGAL_ECMS_TRACE(3," degenerate volume." ) ;
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,10 +55,6 @@ public:
|
||||||
: tmhd(), seam(false)
|
: tmhd(), seam(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Seam_mesh_halfedge_descriptor(const Seam_mesh_halfedge_descriptor& other)
|
|
||||||
: tmhd(other.tmhd), seam(other.seam)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Seam_mesh_halfedge_descriptor(TM_halfedge_descriptor tmhd, bool seam = false)
|
Seam_mesh_halfedge_descriptor(TM_halfedge_descriptor tmhd, bool seam = false)
|
||||||
: tmhd(tmhd), seam(seam)
|
: tmhd(tmhd), seam(seam)
|
||||||
{ }
|
{ }
|
||||||
|
|
@ -303,10 +299,6 @@ public:
|
||||||
: hd(h)
|
: hd(h)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
vertex_descriptor(const vertex_descriptor& other)
|
|
||||||
: hd(other.hd)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool operator==(const vertex_descriptor& other) const
|
bool operator==(const vertex_descriptor& other) const
|
||||||
{
|
{
|
||||||
return (hd == other.hd);
|
return (hd == other.hd);
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
#include <CGAL/boost/graph/helpers.h>
|
#include <CGAL/boost/graph/helpers.h>
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
#include <CGAL/boost/graph/named_function_params.h>
|
#include <CGAL/boost/graph/named_function_params.h>
|
||||||
|
#include <CGAL/IO/write_vtk.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -401,6 +402,278 @@ bool write_inp(std::ostream& os,
|
||||||
{
|
{
|
||||||
return write_inp(os, g, name, type, parameters::all_default());
|
return write_inp(os, g, name, type, parameters::all_default());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
namespace write_vtp {
|
||||||
|
|
||||||
|
// writes the polys appended data at the end of the .vtp file
|
||||||
|
template <class Mesh,
|
||||||
|
typename NamedParameters>
|
||||||
|
void
|
||||||
|
write_polys(std::ostream& os,
|
||||||
|
const Mesh & mesh,
|
||||||
|
const NamedParameters& np)
|
||||||
|
{
|
||||||
|
typedef typename boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
|
||||||
|
typedef typename boost::graph_traits<Mesh>::face_iterator face_iterator;
|
||||||
|
typedef typename CGAL::Polygon_mesh_processing::GetVertexIndexMap<Mesh, NamedParameters>::type Vimap;
|
||||||
|
Vimap V = choose_param(get_param(np, CGAL::internal_np::vertex_index),
|
||||||
|
get_const_property_map(CGAL::internal_np::vertex_index, mesh));
|
||||||
|
|
||||||
|
std::vector<std::size_t> connectivity_table;
|
||||||
|
std::vector<std::size_t> offsets;
|
||||||
|
std::vector<unsigned char> cell_type(num_faces(mesh),5); // triangle == 5
|
||||||
|
|
||||||
|
std::size_t off = 0;
|
||||||
|
for( face_iterator fit = faces(mesh).begin() ;
|
||||||
|
fit != faces(mesh).end() ;
|
||||||
|
++fit )
|
||||||
|
{
|
||||||
|
off += 3;
|
||||||
|
offsets.push_back(off);
|
||||||
|
BOOST_FOREACH(vertex_descriptor v,
|
||||||
|
vertices_around_face(halfedge(*fit, mesh), mesh))
|
||||||
|
connectivity_table.push_back(V[v]);
|
||||||
|
}
|
||||||
|
write_vector<std::size_t>(os,connectivity_table);
|
||||||
|
write_vector<std::size_t>(os,offsets);
|
||||||
|
write_vector<unsigned char>(os,cell_type);
|
||||||
|
}
|
||||||
|
//todo use named params for maps
|
||||||
|
template <class Mesh,
|
||||||
|
typename NamedParameters>
|
||||||
|
void
|
||||||
|
write_polys_tag(std::ostream& os,
|
||||||
|
const Mesh & mesh,
|
||||||
|
bool binary,
|
||||||
|
std::size_t& offset,
|
||||||
|
const NamedParameters& np)
|
||||||
|
{
|
||||||
|
typedef typename boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
|
||||||
|
typedef typename boost::graph_traits<Mesh>::face_iterator face_iterator;
|
||||||
|
typedef typename CGAL::Polygon_mesh_processing::GetVertexIndexMap<Mesh, NamedParameters>::type Vimap;
|
||||||
|
Vimap V = choose_param(get_param(np, CGAL::internal_np::vertex_index),
|
||||||
|
get_const_property_map(CGAL::internal_np::vertex_index, mesh));
|
||||||
|
|
||||||
|
std::string formatattribute =
|
||||||
|
binary ? " format=\"appended\"" : " format=\"ascii\"";
|
||||||
|
|
||||||
|
std::string typeattribute;
|
||||||
|
switch(sizeof(std::size_t)) {
|
||||||
|
case 8: typeattribute = " type=\"UInt64\""; break;
|
||||||
|
case 4: typeattribute = " type=\"UInt32\""; break;
|
||||||
|
default: CGAL_error_msg("Unknown size of std::size_t");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write connectivity table
|
||||||
|
os << " <Polys>\n"
|
||||||
|
<< " <DataArray Name=\"connectivity\""
|
||||||
|
<< formatattribute << typeattribute;
|
||||||
|
|
||||||
|
if (binary) { // if binary output, just write the xml tag
|
||||||
|
os << " offset=\"" << offset << "\"/>\n";
|
||||||
|
offset += (3 * num_faces(mesh)+ 1) * sizeof(std::size_t);
|
||||||
|
// 3 indices (size_t) per triangle + length of the encoded data (size_t)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
os << "\">\n";
|
||||||
|
for( face_iterator fit = faces(mesh).begin() ;
|
||||||
|
fit != faces(mesh).end() ;
|
||||||
|
++fit )
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(vertex_descriptor v,
|
||||||
|
vertices_around_face(halfedge(*fit, mesh), mesh))
|
||||||
|
os << V[v] << " ";
|
||||||
|
}
|
||||||
|
os << " </DataArray>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write offsets
|
||||||
|
os << " <DataArray Name=\"offsets\""
|
||||||
|
<< formatattribute << typeattribute;
|
||||||
|
|
||||||
|
if (binary) { // if binary output, just write the xml tag
|
||||||
|
os << " offset=\"" << offset << "\"/>\n";
|
||||||
|
offset += (num_faces(mesh) + 1) * sizeof(std::size_t);
|
||||||
|
// 1 offset (size_t) per triangle + length of the encoded data (size_t)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
os << "\">\n";
|
||||||
|
std::size_t polys_offset = 0;
|
||||||
|
for( face_iterator fit = faces(mesh).begin() ;
|
||||||
|
fit != faces(mesh).end() ;
|
||||||
|
++fit )
|
||||||
|
{
|
||||||
|
polys_offset += 3;
|
||||||
|
os << polys_offset << " ";
|
||||||
|
}
|
||||||
|
os << " </DataArray>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write cell type (triangle == 5)
|
||||||
|
os << " <DataArray Name=\"types\""
|
||||||
|
<< formatattribute << " type=\"UInt8\"";
|
||||||
|
|
||||||
|
if (binary) {
|
||||||
|
os << " offset=\"" << offset << "\"/>\n";
|
||||||
|
offset += num_faces(mesh) + sizeof(std::size_t);
|
||||||
|
// 1 unsigned char per cell + length of the encoded data (size_t)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
os << "\">\n";
|
||||||
|
for(std::size_t i = 0; i< num_faces(mesh); ++i)
|
||||||
|
os << "5 ";
|
||||||
|
os << " </DataArray>\n";
|
||||||
|
}
|
||||||
|
os << " </Polys>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo : use namedparams for points and ids
|
||||||
|
//overload for facegraph
|
||||||
|
template <class Mesh,
|
||||||
|
typename NamedParameters>
|
||||||
|
void
|
||||||
|
write_points_tag(std::ostream& os,
|
||||||
|
const Mesh & mesh,
|
||||||
|
bool binary,
|
||||||
|
std::size_t& offset,
|
||||||
|
const NamedParameters& np)
|
||||||
|
{
|
||||||
|
typedef typename boost::graph_traits<Mesh>::vertex_iterator vertex_iterator;
|
||||||
|
typedef typename CGAL::Polygon_mesh_processing::GetVertexPointMap<Mesh, NamedParameters>::const_type Vpmap;
|
||||||
|
Vpmap vpm = choose_param(get_param(np, CGAL::vertex_point),
|
||||||
|
get_const_property_map(CGAL::vertex_point, mesh));
|
||||||
|
typedef typename boost::property_traits<Vpmap>::value_type Point_t;
|
||||||
|
typedef typename CGAL::Kernel_traits<Point_t>::Kernel Gt;
|
||||||
|
typedef typename Gt::FT FT;
|
||||||
|
|
||||||
|
std::string format = binary ? "appended" : "ascii";
|
||||||
|
std::string type = (sizeof(FT) == 8) ? "Float64" : "Float32";
|
||||||
|
|
||||||
|
os << " <Points>\n"
|
||||||
|
<< " <DataArray type =\"" << type << "\" NumberOfComponents=\"3\" format=\""
|
||||||
|
<< format;
|
||||||
|
|
||||||
|
if (binary) {
|
||||||
|
os << "\" offset=\"" << offset << "\"/>\n";
|
||||||
|
offset += 3 * num_vertices(mesh) * sizeof(FT) + sizeof(std::size_t);
|
||||||
|
// 3 coords per points + length of the encoded data (size_t)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
os << "\">\n";
|
||||||
|
for( vertex_iterator vit = vertices(mesh).begin();
|
||||||
|
vit != vertices(mesh).end();
|
||||||
|
++vit)
|
||||||
|
{
|
||||||
|
os << get(vpm, *vit).x() << " " << get(vpm, *vit).y() << " "
|
||||||
|
<< get(vpm, *vit).z() << " ";
|
||||||
|
}
|
||||||
|
os << " </DataArray>\n";
|
||||||
|
}
|
||||||
|
os << " </Points>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// writes the points appended data at the end of the .vtp file
|
||||||
|
template <class Mesh,
|
||||||
|
class NamedParameters>
|
||||||
|
void
|
||||||
|
write_polys_points(std::ostream& os,
|
||||||
|
const Mesh & mesh,
|
||||||
|
const NamedParameters& np)
|
||||||
|
{
|
||||||
|
typedef typename boost::graph_traits<Mesh>::vertex_iterator vertex_iterator;
|
||||||
|
typedef typename CGAL::Polygon_mesh_processing::GetVertexPointMap<Mesh, NamedParameters>::const_type Vpmap;
|
||||||
|
Vpmap vpm = choose_param(get_param(np, CGAL::vertex_point),
|
||||||
|
get_const_property_map(CGAL::vertex_point, mesh));
|
||||||
|
typedef typename boost::property_traits<Vpmap>::value_type Point_t;
|
||||||
|
typedef typename CGAL::Kernel_traits<Point_t>::Kernel Gt;
|
||||||
|
typedef typename Gt::FT FT;
|
||||||
|
std::vector<FT> coordinates;
|
||||||
|
for( vertex_iterator vit = vertices(mesh).begin();
|
||||||
|
vit != vertices(mesh).end();
|
||||||
|
++vit)
|
||||||
|
{
|
||||||
|
coordinates.push_back(get(vpm, *vit).x());
|
||||||
|
coordinates.push_back(get(vpm, *vit).y());
|
||||||
|
coordinates.push_back(get(vpm, *vit).z());
|
||||||
|
}
|
||||||
|
write_vector<FT>(os,coordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace CGAL::internal::write_vtp
|
||||||
|
} // end namespace CGAL::internal
|
||||||
|
|
||||||
|
/*!\ingroup PkgBGLIOFct
|
||||||
|
*
|
||||||
|
* \brief writes a triangulated surface mesh in the `PolyData` XML format.
|
||||||
|
*
|
||||||
|
* \tparam TriangleMesh a model of `FaceListGraph` with only triangle faces.
|
||||||
|
* \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters"
|
||||||
|
*
|
||||||
|
* \param os the stream used for writing.
|
||||||
|
* \param mesh the triangle mesh to be written.
|
||||||
|
* \param np optional sequence of \ref pmp_namedparameters "Named Parameters" among the
|
||||||
|
* ones listed below
|
||||||
|
*
|
||||||
|
* \cgalNamedParamsBegin
|
||||||
|
* \cgalParamBegin{use_binary_mode} a Boolean indicating if the
|
||||||
|
* data should be written in binary (`true`, the default) or in ASCII (`false`).
|
||||||
|
* \cgalParamEnd
|
||||||
|
* \cgalParamBegin{vertex_point_map} the property map with the points associated to
|
||||||
|
* the vertices of `mesh`. If this parameter is omitted, an internal property map for
|
||||||
|
* `CGAL::vertex_point_t` must be available in `TriangleMesh`.
|
||||||
|
* \cgalParamEnd
|
||||||
|
* \cgalParamBegin{vertex_index_map} the property map with the indices associated to
|
||||||
|
* the vertices of `mesh`. If this parameter is omitted, an internal property map for
|
||||||
|
* `CGAL::vertex_index_t` must be available in `TriangleMesh`.
|
||||||
|
* \cgalParamEnd
|
||||||
|
* \cgalNamedParamsEnd
|
||||||
|
*/
|
||||||
|
template<class TriangleMesh,
|
||||||
|
class NamedParameters>
|
||||||
|
void write_vtp(std::ostream& os,
|
||||||
|
const TriangleMesh& mesh,
|
||||||
|
const NamedParameters& np)
|
||||||
|
{
|
||||||
|
os << "<?xml version=\"1.0\"?>\n"
|
||||||
|
<< "<VTKFile type=\"PolyData\" version=\"0.1\"";
|
||||||
|
#ifdef CGAL_LITTLE_ENDIAN
|
||||||
|
os << " byte_order=\"LittleEndian\"";
|
||||||
|
#else // CGAL_BIG_ENDIAN
|
||||||
|
os << " byte_order=\"BigEndian\"";
|
||||||
|
#endif
|
||||||
|
switch(sizeof(std::size_t)) {
|
||||||
|
case 4: os << " header_type=\"UInt32\""; break;
|
||||||
|
case 8: os << " header_type=\"UInt64\""; break;
|
||||||
|
default: CGAL_error_msg("Unknown size of std::size_t");
|
||||||
|
}
|
||||||
|
os << ">\n"
|
||||||
|
<< " <PolyData>" << "\n";
|
||||||
|
|
||||||
|
os << " <Piece NumberOfPoints=\"" << num_vertices(mesh)
|
||||||
|
<< "\" NumberOfPolys=\"" << num_faces(mesh) << "\">\n";
|
||||||
|
std::size_t offset = 0;
|
||||||
|
const bool binary = boost::choose_param(boost::get_param(np, internal_np::use_binary_mode), true);
|
||||||
|
internal::write_vtp::write_points_tag(os,mesh,binary,offset, np);
|
||||||
|
internal::write_vtp::write_polys_tag(os,mesh,binary,offset, np);
|
||||||
|
os << " </Piece>\n"
|
||||||
|
<< " </PolyData>\n";
|
||||||
|
if (binary) {
|
||||||
|
os << "<AppendedData encoding=\"raw\">\n_";
|
||||||
|
internal::write_vtp::write_polys_points(os,mesh, np);
|
||||||
|
internal::write_vtp::write_polys(os,mesh, np);
|
||||||
|
}
|
||||||
|
os << "</VTKFile>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class TriangleMesh>
|
||||||
|
void write_vtp(std::ostream& os,
|
||||||
|
const TriangleMesh& mesh)
|
||||||
|
{
|
||||||
|
write_vtp(os, mesh, CGAL::parameters::all_default());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
#endif // CGAL_BOOST_GRAPH_IO_H
|
#endif // CGAL_BOOST_GRAPH_IO_H
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ CGAL_add_named_parameter(edge_is_constrained_t, edge_is_constrained, edge_is_con
|
||||||
CGAL_add_named_parameter(first_index_t, first_index, first_index)
|
CGAL_add_named_parameter(first_index_t, first_index, first_index)
|
||||||
CGAL_add_named_parameter(number_of_iterations_t, number_of_iterations, number_of_iterations)
|
CGAL_add_named_parameter(number_of_iterations_t, number_of_iterations, number_of_iterations)
|
||||||
CGAL_add_named_parameter(verbosity_level_t, verbosity_level, verbosity_level)
|
CGAL_add_named_parameter(verbosity_level_t, verbosity_level, verbosity_level)
|
||||||
|
CGAL_add_named_parameter(use_binary_mode_t, use_binary_mode, use_binary_mode)
|
||||||
|
|
||||||
CGAL_add_named_parameter(metis_options_t, METIS_options, METIS_options)
|
CGAL_add_named_parameter(metis_options_t, METIS_options, METIS_options)
|
||||||
CGAL_add_named_parameter(vertex_partition_id_t, vertex_partition_id, vertex_partition_id_map)
|
CGAL_add_named_parameter(vertex_partition_id_t, vertex_partition_id, vertex_partition_id_map)
|
||||||
|
|
@ -118,3 +119,24 @@ CGAL_add_named_parameter(plane_index_t, plane_index_map, plane_index_map)
|
||||||
CGAL_add_named_parameter(select_percentage_t, select_percentage, select_percentage)
|
CGAL_add_named_parameter(select_percentage_t, select_percentage, select_percentage)
|
||||||
CGAL_add_named_parameter(require_uniform_sampling_t, require_uniform_sampling, require_uniform_sampling)
|
CGAL_add_named_parameter(require_uniform_sampling_t, require_uniform_sampling, require_uniform_sampling)
|
||||||
CGAL_add_named_parameter(point_is_constrained_t, point_is_constrained, point_is_constrained_map)
|
CGAL_add_named_parameter(point_is_constrained_t, point_is_constrained, point_is_constrained_map)
|
||||||
|
|
||||||
|
// List of named parameters used in Surface_mesh_approximation package
|
||||||
|
CGAL_add_named_parameter(verbose_level_t, verbose_level, verbose_level)
|
||||||
|
CGAL_add_named_parameter(seeding_method_t, seeding_method, seeding_method)
|
||||||
|
CGAL_add_named_parameter(max_number_of_proxies_t, max_number_of_proxies, max_number_of_proxies)
|
||||||
|
CGAL_add_named_parameter(min_error_drop_t, min_error_drop, min_error_drop)
|
||||||
|
CGAL_add_named_parameter(number_of_relaxations_t, number_of_relaxations, number_of_relaxations)
|
||||||
|
|
||||||
|
// meshing parameters
|
||||||
|
CGAL_add_named_parameter(subdivision_ratio_t, subdivision_ratio, subdivision_ratio)
|
||||||
|
CGAL_add_named_parameter(relative_to_chord_t, relative_to_chord, relative_to_chord)
|
||||||
|
CGAL_add_named_parameter(with_dihedral_angle_t, with_dihedral_angle, with_dihedral_angle)
|
||||||
|
CGAL_add_named_parameter(optimize_anchor_location_t, optimize_anchor_location, optimize_anchor_location)
|
||||||
|
CGAL_add_named_parameter(pca_plane_t, pca_plane, pca_plane)
|
||||||
|
|
||||||
|
// output parameters
|
||||||
|
CGAL_add_named_parameter(face_proxy_map_t, face_proxy_map, face_proxy_map)
|
||||||
|
CGAL_add_named_parameter(proxies_t, proxies, proxies)
|
||||||
|
CGAL_add_named_parameter(anchors_t, anchors, anchors)
|
||||||
|
CGAL_add_named_parameter(triangles_t, triangles, triangles)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,7 @@ void test(const NamedParameters& np)
|
||||||
assert(get_param(np, CGAL::internal_np::weight_calculator).v == 39);
|
assert(get_param(np, CGAL::internal_np::weight_calculator).v == 39);
|
||||||
assert(get_param(np, CGAL::internal_np::preserve_genus).v == 40);
|
assert(get_param(np, CGAL::internal_np::preserve_genus).v == 40);
|
||||||
assert(get_param(np, CGAL::internal_np::verbosity_level).v == 41);
|
assert(get_param(np, CGAL::internal_np::verbosity_level).v == 41);
|
||||||
|
assert(get_param(np, CGAL::internal_np::use_binary_mode).v == 51);
|
||||||
assert(get_param(np, CGAL::internal_np::projection_functor).v == 42);
|
assert(get_param(np, CGAL::internal_np::projection_functor).v == 42);
|
||||||
assert(get_param(np, CGAL::internal_np::apply_per_connected_component).v == 46);
|
assert(get_param(np, CGAL::internal_np::apply_per_connected_component).v == 46);
|
||||||
assert(get_param(np, CGAL::internal_np::output_iterator).v == 47);
|
assert(get_param(np, CGAL::internal_np::output_iterator).v == 47);
|
||||||
|
|
@ -182,6 +183,7 @@ void test(const NamedParameters& np)
|
||||||
check_same_type<39>(get_param(np, CGAL::internal_np::weight_calculator));
|
check_same_type<39>(get_param(np, CGAL::internal_np::weight_calculator));
|
||||||
check_same_type<40>(get_param(np, CGAL::internal_np::preserve_genus));
|
check_same_type<40>(get_param(np, CGAL::internal_np::preserve_genus));
|
||||||
check_same_type<41>(get_param(np, CGAL::internal_np::verbosity_level));
|
check_same_type<41>(get_param(np, CGAL::internal_np::verbosity_level));
|
||||||
|
check_same_type<51>(get_param(np, CGAL::internal_np::use_binary_mode));
|
||||||
check_same_type<42>(get_param(np, CGAL::internal_np::projection_functor));
|
check_same_type<42>(get_param(np, CGAL::internal_np::projection_functor));
|
||||||
check_same_type<46>(get_param(np, CGAL::internal_np::apply_per_connected_component));
|
check_same_type<46>(get_param(np, CGAL::internal_np::apply_per_connected_component));
|
||||||
check_same_type<47>(get_param(np, CGAL::internal_np::output_iterator));
|
check_same_type<47>(get_param(np, CGAL::internal_np::output_iterator));
|
||||||
|
|
@ -241,6 +243,7 @@ int main()
|
||||||
.weight_calculator(A<39>(39))
|
.weight_calculator(A<39>(39))
|
||||||
.preserve_genus(A<40>(40))
|
.preserve_genus(A<40>(40))
|
||||||
.verbosity_level(A<41>(41))
|
.verbosity_level(A<41>(41))
|
||||||
|
.use_binary_mode(A<51>(51))
|
||||||
.projection_functor(A<42>(42))
|
.projection_functor(A<42>(42))
|
||||||
.throw_on_self_intersection(A<43>(43))
|
.throw_on_self_intersection(A<43>(43))
|
||||||
.clip_volume(A<44>(44))
|
.clip_volume(A<44>(44))
|
||||||
|
|
|
||||||
|
|
@ -67,9 +67,6 @@ class Min_sphere_annulus_d_traits_2 {
|
||||||
// typedef typename K::Construct_point_2 Construct_point_d;
|
// typedef typename K::Construct_point_2 Construct_point_d;
|
||||||
typedef _Construct_point_2<K> Construct_point_d;
|
typedef _Construct_point_2<K> Construct_point_d;
|
||||||
|
|
||||||
// creation
|
|
||||||
Min_sphere_annulus_d_traits_2( ) { }
|
|
||||||
Min_sphere_annulus_d_traits_2( const Min_sphere_annulus_d_traits_2<K_,ET_,NT_>&) {}
|
|
||||||
|
|
||||||
// operations
|
// operations
|
||||||
Access_dimension_d
|
Access_dimension_d
|
||||||
|
|
|
||||||
|
|
@ -67,10 +67,6 @@ class Min_sphere_annulus_d_traits_3 {
|
||||||
// this does not (yet) work:
|
// this does not (yet) work:
|
||||||
// typedef typename K::Construct_point_3 Construct_point_d;
|
// typedef typename K::Construct_point_3 Construct_point_d;
|
||||||
|
|
||||||
// creation
|
|
||||||
Min_sphere_annulus_d_traits_3( ) { }
|
|
||||||
Min_sphere_annulus_d_traits_3( const Min_sphere_annulus_d_traits_3<K_,ET_,NT_>&) {}
|
|
||||||
|
|
||||||
// operations
|
// operations
|
||||||
Access_dimension_d
|
Access_dimension_d
|
||||||
access_dimension_d_object( ) const
|
access_dimension_d_object( ) const
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,6 @@ class Min_sphere_annulus_d_traits_d {
|
||||||
|
|
||||||
typedef CGAL::_Construct_point_d<K> Construct_point_d;
|
typedef CGAL::_Construct_point_d<K> Construct_point_d;
|
||||||
|
|
||||||
// creation
|
|
||||||
Min_sphere_annulus_d_traits_d( ) { }
|
|
||||||
Min_sphere_annulus_d_traits_d( const Min_sphere_annulus_d_traits_d<K_,ET_,NT_>&) {}
|
|
||||||
|
|
||||||
// operations
|
// operations
|
||||||
Access_dimension_d
|
Access_dimension_d
|
||||||
access_dimension_d_object( ) const
|
access_dimension_d_object( ) const
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,19 @@ struct I_Infinity_distance_2
|
||||||
: public CGAL::cpp98::binary_function<
|
: public CGAL::cpp98::binary_function<
|
||||||
Point_2< R >, Point_2< R >, typename R::FT >
|
Point_2< R >, Point_2< R >, typename R::FT >
|
||||||
{
|
{
|
||||||
|
// Added as workaround for VC2017 with /arch:AVX to fix
|
||||||
|
// https://cgal.geometryfactory.com/CGAL/testsuite/CGAL-4.14-I-95/Rectangular_p_center_2_Examples/TestReport_afabri_x64_Cygwin-Windows10_MSVC2017-Release-64bits.gz
|
||||||
|
I_Infinity_distance_2()
|
||||||
|
{}
|
||||||
|
|
||||||
|
I_Infinity_distance_2(const I_Infinity_distance_2&)
|
||||||
|
{}
|
||||||
|
|
||||||
|
I_Infinity_distance_2& operator=(const I_Infinity_distance_2&)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
typename R::FT
|
typename R::FT
|
||||||
operator()(const Point_2< R >& q1, const Point_2< R >& q2) const {
|
operator()(const Point_2< R >& q1, const Point_2< R >& q2) const {
|
||||||
return (std::max)(CGAL_NTS abs(q1.x() - q2.x()),
|
return (std::max)(CGAL_NTS abs(q1.x() - q2.x()),
|
||||||
|
|
|
||||||
|
|
@ -27,14 +27,18 @@ struct Util {
|
||||||
int numBoxes, numDim;
|
int numBoxes, numDim;
|
||||||
int boxNum, dim;
|
int boxNum, dim;
|
||||||
|
|
||||||
std::fscanf(infile, "%d %d\n", &numBoxes, &numDim);
|
int n = std::fscanf(infile, "%d %d\n", &numBoxes, &numDim);
|
||||||
|
assert(n == 2); CGAL_USE(n);
|
||||||
std::vector< int > minc( numDim ), maxc( numDim );
|
std::vector< int > minc( numDim ), maxc( numDim );
|
||||||
/* Read boxes */
|
/* Read boxes */
|
||||||
for(boxNum = 0; boxNum < numBoxes; boxNum++) {
|
for(boxNum = 0; boxNum < numBoxes; boxNum++) {
|
||||||
for(dim = 0; dim < numDim; dim++)
|
for(dim = 0; dim < numDim; dim++) {
|
||||||
std::fscanf( infile, "[%d, %d) ", &minc[dim], &maxc[dim] );
|
n = std::fscanf( infile, "[%d, %d) ", &minc[dim], &maxc[dim] );
|
||||||
|
assert( n == 2);
|
||||||
|
}
|
||||||
boxes.push_back( Box( &minc[0], &maxc[0] ) );
|
boxes.push_back( Box( &minc[0], &maxc[0] ) );
|
||||||
std::fscanf(infile, "\n");
|
n = std::fscanf(infile, "\n");
|
||||||
|
assert(n == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -322,7 +322,6 @@ inline bool setRationalReduceFlag(bool f) {
|
||||||
inline void CORE_init(long d) {
|
inline void CORE_init(long d) {
|
||||||
get_static_defAbsPrec() = CORE_posInfty;
|
get_static_defAbsPrec() = CORE_posInfty;
|
||||||
get_static_defOutputDigits() = d;
|
get_static_defOutputDigits() = d;
|
||||||
std::setprecision(get_static_defOutputDigits());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// change to scientific output format
|
/// change to scientific output format
|
||||||
|
|
|
||||||
|
|
@ -1079,7 +1079,11 @@ _image *_readImageHeaderAndGetError( const char *name_to_be_read, int *error )
|
||||||
_openReadImage(im, name);
|
_openReadImage(im, name);
|
||||||
|
|
||||||
if(!im->fd) {
|
if(!im->fd) {
|
||||||
fprintf(stderr, "_readImageHeaderAndGetError: error: unable to open file \'%s\'\n", name);
|
if(name == NULL) {
|
||||||
|
fprintf(stderr, "_readImageHeaderAndGetError: error: NULL file name\n");
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "_readImageHeaderAndGetError: error: unable to open file \'%s\'\n", name);
|
||||||
|
}
|
||||||
_freeImage(im);
|
_freeImage(im);
|
||||||
*error = ImageIO_OPENING;
|
*error = ImageIO_OPENING;
|
||||||
if ( name != NULL ) free( name );
|
if ( name != NULL ) free( name );
|
||||||
|
|
|
||||||
|
|
@ -73,14 +73,23 @@ struct Indicator_factory
|
||||||
|
|
||||||
class CGAL_IMAGEIO_EXPORT Image_3
|
class CGAL_IMAGEIO_EXPORT Image_3
|
||||||
{
|
{
|
||||||
|
class Image_deleter {
|
||||||
|
const bool own_the_data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Image_deleter(bool own_the_data) : own_the_data(own_the_data) {}
|
||||||
|
|
||||||
struct Image_deleter {
|
|
||||||
void operator()(_image* image)
|
void operator()(_image* image)
|
||||||
{
|
{
|
||||||
|
if(!own_the_data && image != 0) {
|
||||||
|
image->data = 0;
|
||||||
|
}
|
||||||
::_freeImage(image);
|
::_freeImage(image);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
|
enum Own { OWN_THE_DATA, DO_NOT_OWN_THE_DATA };
|
||||||
|
|
||||||
typedef boost::shared_ptr<_image> Image_shared_ptr;
|
typedef boost::shared_ptr<_image> Image_shared_ptr;
|
||||||
typedef Image_shared_ptr Pointer;
|
typedef Image_shared_ptr Pointer;
|
||||||
|
|
||||||
|
|
@ -88,7 +97,7 @@ protected:
|
||||||
Image_shared_ptr image_ptr;
|
Image_shared_ptr image_ptr;
|
||||||
|
|
||||||
// implementation in src/CGAL_ImageIO/Image_3.cpp
|
// implementation in src/CGAL_ImageIO/Image_3.cpp
|
||||||
bool private_read(_image* im);
|
bool private_read(_image* im, Own own_the_data = OWN_THE_DATA);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Image_3()
|
Image_3()
|
||||||
|
|
@ -102,9 +111,9 @@ public:
|
||||||
// std::cerr << "Image_3::copy_constructor\n";
|
// std::cerr << "Image_3::copy_constructor\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
Image_3(_image* im)
|
Image_3(_image* im, Own own_the_data = OWN_THE_DATA)
|
||||||
{
|
{
|
||||||
private_read(im);
|
private_read(im, own_the_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Image_3()
|
~Image_3()
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,12 @@
|
||||||
#define CGAL_INLINE_FUNCTION
|
#define CGAL_INLINE_FUNCTION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <CGAL/basic.h>
|
#include <CGAL/assertions.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
CGAL_INLINE_FUNCTION
|
CGAL_INLINE_FUNCTION
|
||||||
bool Image_3::private_read(_image* im)
|
bool Image_3::private_read(_image* im, Own own)
|
||||||
{
|
{
|
||||||
if(im != 0)
|
if(im != 0)
|
||||||
{
|
{
|
||||||
|
|
@ -38,7 +38,7 @@ bool Image_3::private_read(_image* im)
|
||||||
{
|
{
|
||||||
::_freeImage(image());
|
::_freeImage(image());
|
||||||
}
|
}
|
||||||
image_ptr = Image_shared_ptr(im, Image_deleter());
|
image_ptr = Image_shared_ptr(im, Image_deleter(own == OWN_THE_DATA));
|
||||||
|
|
||||||
// std::cerr <<
|
// std::cerr <<
|
||||||
// boost::format("image=%1% (xdim=%2%, ydim=%3%, zdim=%4%)\n")
|
// boost::format("image=%1% (xdim=%2%, ydim=%3%, zdim=%4%)\n")
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ static const VTK_to_ImageIO_type_mapper VTK_to_ImageIO_type[VTK_ID_TYPE] =
|
||||||
|
|
||||||
inline
|
inline
|
||||||
Image_3
|
Image_3
|
||||||
read_vtk_image_data(vtkImageData* vtk_image)
|
read_vtk_image_data(vtkImageData* vtk_image, Image_3::Own owning = Image_3::OWN_THE_DATA)
|
||||||
{
|
{
|
||||||
if(!vtk_image)
|
if(!vtk_image)
|
||||||
return Image_3();
|
return Image_3();
|
||||||
|
|
@ -85,16 +85,21 @@ read_vtk_image_data(vtkImageData* vtk_image)
|
||||||
image->wdim = imageio_type.wdim;
|
image->wdim = imageio_type.wdim;
|
||||||
image->wordKind = imageio_type.wordKind;
|
image->wordKind = imageio_type.wordKind;
|
||||||
image->sign = imageio_type.sign;
|
image->sign = imageio_type.sign;
|
||||||
image->data = ::ImageIO_alloc(dims[0]*dims[1]*dims[2]*image->wdim);
|
|
||||||
std::cerr << "GetNumberOfTuples()=" << vtk_image->GetPointData()->GetScalars()->GetNumberOfTuples()
|
|
||||||
<< "\nimage->size()=" << dims[0]*dims[1]*dims[2]
|
|
||||||
<< "\nwdim=" << image->wdim << '\n';
|
|
||||||
CGAL_assertion(vtk_image->GetPointData()->GetScalars()->GetNumberOfTuples() == dims[0]*dims[1]*dims[2]);
|
CGAL_assertion(vtk_image->GetPointData()->GetScalars()->GetNumberOfTuples() == dims[0]*dims[1]*dims[2]);
|
||||||
vtk_image->GetPointData()->GetScalars()->ExportToVoidPointer(image->data);
|
if(owning == Image_3::OWN_THE_DATA) {
|
||||||
|
image->data = ::ImageIO_alloc(dims[0]*dims[1]*dims[2]*image->wdim);
|
||||||
|
// std::cerr << "GetNumberOfTuples()=" << vtk_image->GetPointData()->GetScalars()->GetNumberOfTuples()
|
||||||
|
// << "\nimage->size()=" << dims[0]*dims[1]*dims[2]
|
||||||
|
// << "\nwdim=" << image->wdim << '\n';
|
||||||
|
vtk_image->GetPointData()->GetScalars()->ExportToVoidPointer(image->data);
|
||||||
|
} else {
|
||||||
|
image->data = vtk_image->GetPointData()->GetScalars()->GetVoidPointer(0);
|
||||||
|
}
|
||||||
|
|
||||||
return Image_3(image);
|
return Image_3(image, owning);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
|
|
||||||
#endif // CGAL_READ_VTK_IMAGE_DATA_H
|
#endif // CGAL_READ_VTK_IMAGE_DATA_H
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,13 @@ message( "== CMake setup (DONE) ==\n" )
|
||||||
|
|
||||||
# Enable testing with BUILD_TESTING
|
# Enable testing with BUILD_TESTING
|
||||||
option(BUILD_TESTING "Build the testing tree." OFF)
|
option(BUILD_TESTING "Build the testing tree." OFF)
|
||||||
include(CTest)
|
|
||||||
if(BUILD_TESTING AND NOT POLICY CMP0064)
|
if(BUILD_TESTING AND NOT POLICY CMP0064)
|
||||||
message(FATAL_ERROR "CGAL support of CTest requires CMake version 3.4 or later.
|
message(FATAL_ERROR "CGAL support of CTest requires CMake version 3.4 or later.
|
||||||
The variable BUILD_TESTING must be set of OFF.")
|
The variable BUILD_TESTING must be set of OFF.")
|
||||||
endif()
|
endif()
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
enable_testing()
|
||||||
|
endif()
|
||||||
|
|
||||||
# and finally start actual build
|
# and finally start actual build
|
||||||
add_subdirectory( Installation )
|
add_subdirectory( Installation )
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,6 @@ namespace CGAL {
|
||||||
}
|
}
|
||||||
|
|
||||||
Circular_arc_3()
|
Circular_arc_3()
|
||||||
: RCircular_arc_3(typename R::Construct_circular_arc_3()())
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Circular_arc_3(const Circle_3& c,
|
Circular_arc_3(const Circle_3& c,
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ namespace CGAL {
|
||||||
typedef typename SK::template Handle<Rep>::type Base;
|
typedef typename SK::template Handle<Rep>::type Base;
|
||||||
|
|
||||||
Base base;
|
Base base;
|
||||||
mutable bool _full;
|
bool _full;
|
||||||
// It is the sign of the cross product
|
// It is the sign of the cross product
|
||||||
// of the vector (Center -> S) x (Center -> T)
|
// of the vector (Center -> S) x (Center -> T)
|
||||||
// it saves execution time for the has_on functor
|
// it saves execution time for the has_on functor
|
||||||
|
|
@ -141,7 +141,7 @@ namespace CGAL {
|
||||||
// This is the one of the two cases we want that s == t
|
// This is the one of the two cases we want that s == t
|
||||||
// that makes the is_full() correct and complete
|
// that makes the is_full() correct and complete
|
||||||
Circular_arc_3(const Circle_3 &c)
|
Circular_arc_3(const Circle_3 &c)
|
||||||
: _full(true)
|
: _full(true), _sign_cross_product(CGAL::ZERO)
|
||||||
{
|
{
|
||||||
const Plane_3 &p = c.supporting_plane();
|
const Plane_3 &p = c.supporting_plane();
|
||||||
if(is_zero(p.b()) && is_zero(p.c())) {
|
if(is_zero(p.b()) && is_zero(p.c())) {
|
||||||
|
|
@ -153,9 +153,6 @@ namespace CGAL {
|
||||||
SphericalFunctors::x_extremal_point<SK>(c,true);
|
SphericalFunctors::x_extremal_point<SK>(c,true);
|
||||||
base = Rep(c,v,v);
|
base = Rep(c,v,v);
|
||||||
}
|
}
|
||||||
/* don't matter
|
|
||||||
_sign_cross_product = 0;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the second case where we want that s == t
|
// This is the second case where we want that s == t
|
||||||
|
|
@ -221,6 +218,7 @@ namespace CGAL {
|
||||||
Circular_arc_3(const Point_3 &begin,
|
Circular_arc_3(const Point_3 &begin,
|
||||||
const Point_3 &middle,
|
const Point_3 &middle,
|
||||||
const Point_3 &end)
|
const Point_3 &end)
|
||||||
|
: _full(false)
|
||||||
{
|
{
|
||||||
CGAL_kernel_precondition(!typename SK::Collinear_3()(begin, middle, end));
|
CGAL_kernel_precondition(!typename SK::Collinear_3()(begin, middle, end));
|
||||||
const Circle_3 c = Circle_3(begin, middle, end);
|
const Circle_3 c = Circle_3(begin, middle, end);
|
||||||
|
|
|
||||||
|
|
@ -733,13 +733,6 @@ public:
|
||||||
Circulator_from_container( Container* c) : ctnr(c), i(c->begin()) {}
|
Circulator_from_container( Container* c) : ctnr(c), i(c->begin()) {}
|
||||||
Circulator_from_container( Container* c, iterator j) : ctnr(c), i(j) {}
|
Circulator_from_container( Container* c, iterator j) : ctnr(c), i(j) {}
|
||||||
|
|
||||||
// Gnu-bug workaround: define operator= explicitly.
|
|
||||||
Self& operator=( const Self& c) {
|
|
||||||
ctnr = c.ctnr;
|
|
||||||
i = c.i;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// OPERATIONS
|
// OPERATIONS
|
||||||
|
|
||||||
bool operator==( Nullptr_t p) const {
|
bool operator==( Nullptr_t p) const {
|
||||||
|
|
@ -867,13 +860,6 @@ public:
|
||||||
Const_circulator_from_container( const Mutable& c)
|
Const_circulator_from_container( const Mutable& c)
|
||||||
: ctnr( c.container()), i( c.current_iterator()) {}
|
: ctnr( c.container()), i( c.current_iterator()) {}
|
||||||
|
|
||||||
// Gnu-bug workaround: define operator= explicitly.
|
|
||||||
Self& operator=( const Self& c) {
|
|
||||||
ctnr = c.ctnr;
|
|
||||||
i = c.i;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// OPERATIONS
|
// OPERATIONS
|
||||||
|
|
||||||
bool operator==( Nullptr_t p) const {
|
bool operator==( Nullptr_t p) const {
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,10 @@ The following code snippet shows how to instantiate such data structures from an
|
||||||
- [Distance_to_plane](@ref CGAL::Classification::Feature::Distance_to_plane) measures how far away a point is from a locally estimated plane;
|
- [Distance_to_plane](@ref CGAL::Classification::Feature::Distance_to_plane) measures how far away a point is from a locally estimated plane;
|
||||||
- [Eigenvalue](@ref CGAL::Classification::Feature::Eigenvalue) measures one of the three local eigenvalues;
|
- [Eigenvalue](@ref CGAL::Classification::Feature::Eigenvalue) measures one of the three local eigenvalues;
|
||||||
- [Elevation](@ref CGAL::Classification::Feature::Elevation) computes the local distance to an estimation of the ground;
|
- [Elevation](@ref CGAL::Classification::Feature::Elevation) computes the local distance to an estimation of the ground;
|
||||||
|
- [Height_above](@ref CGAL::Classification::Feature::Elevation) computes the distance between the local highest point and the point;
|
||||||
|
- [Height_below](@ref CGAL::Classification::Feature::Elevation) computes the distance between the point and the local lowest point;
|
||||||
- [Vertical_dispersion](@ref CGAL::Classification::Feature::Vertical_dispersion) computes how noisy the point set is on a local Z-cylinder;
|
- [Vertical_dispersion](@ref CGAL::Classification::Feature::Vertical_dispersion) computes how noisy the point set is on a local Z-cylinder;
|
||||||
|
- [Vertical_range](@ref CGAL::Classification::Feature::Elevation) computes the distance between the local highest and lowest points;
|
||||||
- [Verticality](@ref CGAL::Classification::Feature::Verticality) compares the local normal vector to the vertical vector.
|
- [Verticality](@ref CGAL::Classification::Feature::Verticality) compares the local normal vector to the vertical vector.
|
||||||
|
|
||||||
These features are designed for point sets but can easily be used with surface meshes as well (see \ref Classification_meshes). For more details about how these different features can help to identify one label or the other, please refer to their associated reference manual pages.
|
These features are designed for point sets but can easily be used with surface meshes as well (see \ref Classification_meshes). For more details about how these different features can help to identify one label or the other, please refer to their associated reference manual pages.
|
||||||
|
|
@ -108,6 +111,8 @@ Multiple scales that are sequentially larger can be used to increase the quality
|
||||||
|
|
||||||
Note that using this class in order to generate features is not mandatory, as features and data structures can all be handled by hand. It is mainly provided to make the specific case of point sets simpler to handle. Users can still add their own features within their feature set.
|
Note that using this class in order to generate features is not mandatory, as features and data structures can all be handled by hand. It is mainly provided to make the specific case of point sets simpler to handle. Users can still add their own features within their feature set.
|
||||||
|
|
||||||
|
Some data structure instantiated by the generator will be used by feature: for this reason, the generator should be instantiated _within the same scope_ as the feature set and should not be deleted before the feature set.
|
||||||
|
|
||||||
The following snippet shows how to use the point set feature generator:
|
The following snippet shows how to use the point set feature generator:
|
||||||
|
|
||||||
\snippet Classification/example_generation_and_training.cpp Generator
|
\snippet Classification/example_generation_and_training.cpp Generator
|
||||||
|
|
@ -196,13 +201,17 @@ Example of cluster classification mesh (left: input, middle: clusters computed f
|
||||||
|
|
||||||
%Classification relies on a classifier: this classifier is an object that, from the set of values taken by the features at an input item, computes the probability that an input item belongs to one label or another. A model of the concept `CGAL::Classification::Classifier` must take the index of an input item and store the probability associated to each label in a vector. If a classifier returns the value 1 for a pair of label and input item, it means that this item belongs to this label with certainty; values close to 0 mean that this item is not likely to belong to this label.
|
%Classification relies on a classifier: this classifier is an object that, from the set of values taken by the features at an input item, computes the probability that an input item belongs to one label or another. A model of the concept `CGAL::Classification::Classifier` must take the index of an input item and store the probability associated to each label in a vector. If a classifier returns the value 1 for a pair of label and input item, it means that this item belongs to this label with certainty; values close to 0 mean that this item is not likely to belong to this label.
|
||||||
|
|
||||||
\cgal provides three models for this concept, [ETHZ_random_forest_classifier](@ref CGAL::Classification::ETHZ_random_forest_classifier), [OpenCV_random_forest_classifier](@ref CGAL::Classification::OpenCV_random_forest_classifier) and [Sum_of_weighted_features_classifier](@ref CGAL::Classification::Sum_of_weighted_features_classifier).
|
\cgal provides four models for this concept, [ETHZ::Random_forest_classifier](@ref CGAL::Classification::ETHZ::Random_forest_classifier), [OpenCV::Random_forest_classifier](@ref CGAL::Classification::OpenCV::Random_forest_classifier), [TensorFlow::Neural_network_classifier](@ref CGAL::Classification::TensorFlow::Neural_network_classifier) and [Sum_of_weighted_features_classifier](@ref CGAL::Classification::Sum_of_weighted_features_classifier).
|
||||||
|
|
||||||
To perform classification based on these classifiers, please refer to \ref Classification_classification_functions.
|
\note Currently, [ETHZ::Random_forest_classifier](@ref CGAL::Classification::ETHZ::Random_forest_classifier)
|
||||||
|
is the best classifier available in \cgal and we strongly advise users
|
||||||
|
to use it.
|
||||||
|
|
||||||
|
To perform classification based on four classifiers, please refer to \ref Classification_classification_functions.
|
||||||
|
|
||||||
\subsection Classification_ETHZ_random_forest ETHZ Random Forest
|
\subsection Classification_ETHZ_random_forest ETHZ Random Forest
|
||||||
|
|
||||||
\cgal provides [ETHZ_random_forest_classifier](@ref CGAL::Classification::ETHZ_random_forest_classifier),
|
\cgal provides [ETHZ::Random_forest_classifier](@ref CGAL::Classification::ETHZ::Random_forest_classifier),
|
||||||
a classifier based on the Random Forest Template Library developed by
|
a classifier based on the Random Forest Template Library developed by
|
||||||
Stefan Walk at ETH Zurich \cgalCite{cgal:w-erftl-14} (the library is
|
Stefan Walk at ETH Zurich \cgalCite{cgal:w-erftl-14} (the library is
|
||||||
distributed under the MIT license and is included with the \cgal release,
|
distributed under the MIT license and is included with the \cgal release,
|
||||||
|
|
@ -210,9 +219,6 @@ the user does not have to install anything more). This classifier uses
|
||||||
a ground truth training set to construct several decision trees that
|
a ground truth training set to construct several decision trees that
|
||||||
are then used to assign a label to each input item.
|
are then used to assign a label to each input item.
|
||||||
|
|
||||||
__This classifier is currently the best available in \cgal and we
|
|
||||||
strongly advise users to use it.__
|
|
||||||
|
|
||||||
This classifier cannot be set up by hand and requires a ground truth
|
This classifier cannot be set up by hand and requires a ground truth
|
||||||
training set. The training algorithm is fast but usually requires a
|
training set. The training algorithm is fast but usually requires a
|
||||||
high number of inliers. The training algorithm uses more memory at
|
high number of inliers. The training algorithm uses more memory at
|
||||||
|
|
@ -227,14 +233,13 @@ to README provided in the [ETH Zurich's code archive](https://www.ethz.ch/conten
|
||||||
|
|
||||||
\subsection Classification_OpenCV_random_forest OpenCV Random Forest
|
\subsection Classification_OpenCV_random_forest OpenCV Random Forest
|
||||||
|
|
||||||
The second classifier is [OpenCV_random_forest_classifier](@ref CGAL::Classification::OpenCV_random_forest_classifier).
|
The second classifier is [OpenCV::Random_forest_classifier](@ref CGAL::Classification::OpenCV::Random_forest_classifier).
|
||||||
It uses the \ref thirdpartyOpenCV library, more specifically the
|
It uses the \ref thirdpartyOpenCV library, more specifically the
|
||||||
[Random Trees](http://docs.opencv.org/2.4/modules/ml/doc/random_trees.html)
|
[Random Trees](http://docs.opencv.org/2.4/modules/ml/doc/random_trees.html)
|
||||||
package.
|
package.
|
||||||
|
|
||||||
Note that this classifier usually produces results with a lower
|
Note that this classifier usually produces results with a lower
|
||||||
quality than [ETHZ_random_forest_classifier](@ref CGAL::Classification::ETHZ_random_forest_classifier).
|
quality than [ETHZ::Random_forest_classifier](@ref CGAL::Classification::ETHZ::Random_forest_classifier).
|
||||||
|
|
||||||
It is provided for the sake of completeness and for testing purposes,
|
It is provided for the sake of completeness and for testing purposes,
|
||||||
but if you are not sure what to use, we advise using the ETHZ Random
|
but if you are not sure what to use, we advise using the ETHZ Random
|
||||||
Forest instead.
|
Forest instead.
|
||||||
|
|
@ -244,6 +249,31 @@ use this classifier. For more details about the algorithm, please refer
|
||||||
to [the official documentation](http://docs.opencv.org/2.4/modules/ml/doc/random_trees.html)
|
to [the official documentation](http://docs.opencv.org/2.4/modules/ml/doc/random_trees.html)
|
||||||
of OpenCV.
|
of OpenCV.
|
||||||
|
|
||||||
|
\subsection Classification_TensorFlow_neural_network TensorFlow Neural Network
|
||||||
|
|
||||||
|
\cgal provides [TensorFlow::Neural_network_classifier](@ref CGAL::Classification::TensorFlow::Neural_network_classifier).
|
||||||
|
|
||||||
|
It uses the C++ API of the \ref thirdpartyTensorFlow library.
|
||||||
|
|
||||||
|
\warning This feature is still experimental: it may not be stable
|
||||||
|
and is likely to undergo substantial changes in future releases of
|
||||||
|
\cgal. The API changes will be announced in the release notes.
|
||||||
|
|
||||||
|
The provided interface is a feature-based neural network: a set of
|
||||||
|
features is used as an input layer followed by a user-specified number
|
||||||
|
of hidden layers with a user-specified activation function. The output
|
||||||
|
layer is a softmax layer providing, for each label, the probability
|
||||||
|
that an input item belongs to it.
|
||||||
|
|
||||||
|
This classifier cannot be set up by hand and requires a ground truth
|
||||||
|
training set. The training algorithm usually requires a higher number
|
||||||
|
of inliers than random forest. The quality of the results, so far, is
|
||||||
|
comparable to random forest.
|
||||||
|
|
||||||
|
An [example](\ref Classification_example_tensorflow_neural_network) shows how to
|
||||||
|
use this classifier. For more details about the algorithm, please refer
|
||||||
|
to [the TensorFlow tutorials](https://www.tensorflow.org/tutorials/).
|
||||||
|
|
||||||
\subsection Classification_sowf Sum of Weighted Features
|
\subsection Classification_sowf Sum of Weighted Features
|
||||||
|
|
||||||
This latest classifier defines the following attributes:
|
This latest classifier defines the following attributes:
|
||||||
|
|
@ -334,7 +364,7 @@ Top-Left: input point set. Top-Right: raw output classification represented by a
|
||||||
|
|
||||||
Mathematical details are provided hereafter.
|
Mathematical details are provided hereafter.
|
||||||
|
|
||||||
\subsection Classification_classify Raw classification
|
\subsection Classification_classify Raw Classification
|
||||||
|
|
||||||
- `CGAL::Classification::classify()`: this is the fastest method
|
- `CGAL::Classification::classify()`: this is the fastest method
|
||||||
that provides acceptable but usually noisy results (see Figure
|
that provides acceptable but usually noisy results (see Figure
|
||||||
|
|
@ -478,23 +508,31 @@ The following example:
|
||||||
|
|
||||||
\subsection Classification_example_ethz_random_forest ETHZ Random Forest
|
\subsection Classification_example_ethz_random_forest ETHZ Random Forest
|
||||||
|
|
||||||
The following example shows how to use the classifier [ETHZ_random_forest_classifier](@ref CGAL::Classification::ETHZ_random_forest_classifier) using an input training set.
|
The following example shows how to use the classifier [ETHZ::Random_forest_classifier](@ref CGAL::Classification::ETHZ::Random_forest_classifier) using an input training set.
|
||||||
|
|
||||||
\cgalExample{Classification/example_ethz_random_forest.cpp}
|
\cgalExample{Classification/example_ethz_random_forest.cpp}
|
||||||
|
|
||||||
\subsection Classification_example_opencv_random_forest OpenCV Random Forest
|
\subsection Classification_example_opencv_random_forest OpenCV Random Forest
|
||||||
|
|
||||||
The following example shows how to use the classifier [OpenCV_random_forest_classifier](@ref CGAL::Classification::OpenCV_random_forest_classifier) using an input training set.
|
The following example shows how to use the classifier [OpenCV::Random_forest_classifier](@ref CGAL::Classification::OpenCV::Random_forest_classifier) using an input training set.
|
||||||
|
|
||||||
\cgalExample{Classification/example_opencv_random_forest.cpp}
|
\cgalExample{Classification/example_opencv_random_forest.cpp}
|
||||||
|
|
||||||
|
\subsection Classification_example_tensorflow_neural_network TensorFlow Neural Network
|
||||||
|
|
||||||
|
The following example shows how to use the classifier
|
||||||
|
[TensorFlow::Neural_network_classifier](@ref CGAL::Classification::TensorFlow::Neural_network_classifier)
|
||||||
|
using an input training set.
|
||||||
|
|
||||||
|
\cgalExample{Classification/example_tensorflow_neural_network.cpp}
|
||||||
|
|
||||||
\subsection Classification_example_mesh Mesh Classification
|
\subsection Classification_example_mesh Mesh Classification
|
||||||
|
|
||||||
The following example:
|
The following example:
|
||||||
|
|
||||||
- reads a mesh in OFF format;
|
- reads a mesh in OFF format;
|
||||||
- automatically generates features on 5 scales;
|
- automatically generates features on 5 scales;
|
||||||
- loads a configuration file for classifier [ETHZ_random_forest_classifier](@ref CGAL::Classification::ETHZ_random_forest_classifier);
|
- loads a configuration file for classifier [ETHZ::Random_forest_classifier](@ref CGAL::Classification::ETHZ::Random_forest_classifier);
|
||||||
- runs the algorithm using the graphcut regularization.
|
- runs the algorithm using the graphcut regularization.
|
||||||
|
|
||||||
\cgalExample{Classification/example_mesh_classification.cpp}
|
\cgalExample{Classification/example_mesh_classification.cpp}
|
||||||
|
|
@ -509,7 +547,7 @@ The following example:
|
||||||
- detects plane using the algorithm `CGAL::Shape_detection_3::Region_growing`;
|
- detects plane using the algorithm `CGAL::Shape_detection_3::Region_growing`;
|
||||||
- creates [Cluster](@ref CGAL::Classification::Cluster) objects from these detected planes;
|
- creates [Cluster](@ref CGAL::Classification::Cluster) objects from these detected planes;
|
||||||
- computes cluster features from the pointwise features;
|
- computes cluster features from the pointwise features;
|
||||||
- loads a configuration file for classifier [ETHZ_random_forest_classifier](@ref CGAL::Classification::ETHZ_random_forest_classifier);
|
- loads a configuration file for classifier [ETHZ::Random_forest_classifier](@ref CGAL::Classification::ETHZ::Random_forest_classifier);
|
||||||
- runs the algorithm using the raw algorithm.
|
- runs the algorithm using the raw algorithm.
|
||||||
|
|
||||||
\cgalExample{Classification/example_cluster_classification.cpp}
|
\cgalExample{Classification/example_cluster_classification.cpp}
|
||||||
|
|
@ -517,7 +555,7 @@ The following example:
|
||||||
|
|
||||||
\section Classification_history History
|
\section Classification_history History
|
||||||
|
|
||||||
This package is based on a research code by [Florent Lafarge](https://www-sop.inria.fr/members/Florent.Lafarge/) that was generalized, extended and packaged by [Simon Giraudot](http://geometryfactory.com/who-we-are/) in \cgal 4.12. %Classification of surface meshes and of clusters were introduced in \cgal 4.13.
|
This package is based on a research code by [Florent Lafarge](https://www-sop.inria.fr/members/Florent.Lafarge/) that was generalized, extended and packaged by [Simon Giraudot](http://geometryfactory.com/who-we-are/) in \cgal 4.12. %Classification of surface meshes and of clusters were introduced in \cgal 4.13. The Neural Network classifier was introduced in \cgal 4.14.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,9 @@ Concept describing a classifier used by classification functions (see
|
||||||
`CGAL::Classification::classify_with_graphcut()`).
|
`CGAL::Classification::classify_with_graphcut()`).
|
||||||
|
|
||||||
\cgalHasModel `CGAL::Classification::Sum_of_weighted_features_classifier`
|
\cgalHasModel `CGAL::Classification::Sum_of_weighted_features_classifier`
|
||||||
\cgalHasModel `CGAL::Classification::ETHZ_random_forest_classifier`
|
\cgalHasModel `CGAL::Classification::ETHZ::Random_forest_classifier`
|
||||||
\cgalHasModel `CGAL::Classification::OpenCV_random_forest_classifier`
|
\cgalHasModel `CGAL::Classification::OpenCV::Random_forest_classifier`
|
||||||
|
\cgalHasModel `CGAL::Classification::TensorFlow::Neural_network_classifier`
|
||||||
|
|
||||||
*/
|
*/
|
||||||
class Classifier
|
class Classifier
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,21 @@ Functions that perform classification based on a set of labels and a classifier,
|
||||||
|
|
||||||
Classifiers are functors that, given a label set and an input item, associate this input item with an energy for each label. This energy measures the likelihood of the item to belong to this label.
|
Classifiers are functors that, given a label set and an input item, associate this input item with an energy for each label. This energy measures the likelihood of the item to belong to this label.
|
||||||
|
|
||||||
|
\defgroup PkgClassificationClassifiersETHZ ETHZ
|
||||||
|
\ingroup PkgClassificationClassifiers
|
||||||
|
|
||||||
|
Classifiers that use the ETHZ library.
|
||||||
|
|
||||||
|
\defgroup PkgClassificationClassifiersOpenCV OpenCV
|
||||||
|
\ingroup PkgClassificationClassifiers
|
||||||
|
|
||||||
|
Classifiers that use the \ref thirdpartyOpenCV library.
|
||||||
|
|
||||||
|
\defgroup PkgClassificationClassifiersTensorFlow TensorFlow
|
||||||
|
\ingroup PkgClassificationClassifiers
|
||||||
|
|
||||||
|
Classifiers that use the \ref thirdpartyTensorFlow library.
|
||||||
|
|
||||||
\defgroup PkgClassificationDataStructures Common Data Structures
|
\defgroup PkgClassificationDataStructures Common Data Structures
|
||||||
\ingroup PkgClassificationRef
|
\ingroup PkgClassificationRef
|
||||||
|
|
||||||
|
|
@ -86,9 +101,10 @@ Data structures specialized to classify clusters.
|
||||||
|
|
||||||
## Classifiers ##
|
## Classifiers ##
|
||||||
|
|
||||||
|
- `CGAL::Classification::ETHZ::Random_forest_classifier`
|
||||||
|
- `CGAL::Classification::OpenCV::Random_forest_classifier`
|
||||||
|
- `CGAL::Classification::TensorFlow::Neural_network_classifier<ActivationFunction>`
|
||||||
- `CGAL::Classification::Sum_of_weighted_features_classifier`
|
- `CGAL::Classification::Sum_of_weighted_features_classifier`
|
||||||
- `CGAL::Classification::ETHZ_random_forest_classifier`
|
|
||||||
- `CGAL::Classification::OpenCV_random_forest_classifier`
|
|
||||||
|
|
||||||
## Common Data Structures ##
|
## Common Data Structures ##
|
||||||
|
|
||||||
|
|
@ -115,8 +131,11 @@ Data structures specialized to classify clusters.
|
||||||
- `CGAL::Classification::Feature::Echo_scatter<GeomTraits, PointRange, PointMap, EchoMap>`
|
- `CGAL::Classification::Feature::Echo_scatter<GeomTraits, PointRange, PointMap, EchoMap>`
|
||||||
- `CGAL::Classification::Feature::Eigenvalue`
|
- `CGAL::Classification::Feature::Eigenvalue`
|
||||||
- `CGAL::Classification::Feature::Elevation<GeomTraits, PointRange, PointMap>`
|
- `CGAL::Classification::Feature::Elevation<GeomTraits, PointRange, PointMap>`
|
||||||
|
- `CGAL::Classification::Feature::Height_above<GeomTraits, PointRange, PointMap>`
|
||||||
|
- `CGAL::Classification::Feature::Height_below<GeomTraits, PointRange, PointMap>`
|
||||||
- `CGAL::Classification::Feature::Simple_feature<InputRange, PropertyMap>`
|
- `CGAL::Classification::Feature::Simple_feature<InputRange, PropertyMap>`
|
||||||
- `CGAL::Classification::Feature::Vertical_dispersion<GeomTraits, PointRange, PointMap>`
|
- `CGAL::Classification::Feature::Vertical_dispersion<GeomTraits, PointRange, PointMap>`
|
||||||
|
- `CGAL::Classification::Feature::Vertical_range<GeomTraits, PointRange, PointMap>`
|
||||||
- `CGAL::Classification::Feature::Verticality<GeomTraits>`
|
- `CGAL::Classification::Feature::Verticality<GeomTraits>`
|
||||||
|
|
||||||
## Point Set Classification ##
|
## Point Set Classification ##
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
\example Classification/example_generation_and_training.cpp
|
\example Classification/example_generation_and_training.cpp
|
||||||
\example Classification/example_ethz_random_forest.cpp
|
\example Classification/example_ethz_random_forest.cpp
|
||||||
\example Classification/example_opencv_random_forest.cpp
|
\example Classification/example_opencv_random_forest.cpp
|
||||||
|
\example Classification/example_tensorflow_neural_network.cpp
|
||||||
\example Classification/example_mesh_classification.cpp
|
\example Classification/example_mesh_classification.cpp
|
||||||
\example Classification/example_cluster_classification.cpp
|
\example Classification/example_cluster_classification.cpp
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,6 @@ if( WIN32 )
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(OpenCV QUIET)
|
|
||||||
if (OpenCV_FOUND)
|
if (OpenCV_FOUND)
|
||||||
message(STATUS "Found OpenCV ${OpenCV_VERSION}")
|
message(STATUS "Found OpenCV ${OpenCV_VERSION}")
|
||||||
include_directories(${OpenCV_INCLUDE_DIRS})
|
include_directories(${OpenCV_INCLUDE_DIRS})
|
||||||
|
|
@ -108,6 +107,21 @@ else()
|
||||||
message(STATUS "NOTICE: OpenCV was not found. OpenCV random forest predicate for classification won't be available.")
|
message(STATUS "NOTICE: OpenCV was not found. OpenCV random forest predicate for classification won't be available.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
find_package(TensorFlow QUIET)
|
||||||
|
if (TensorFlow_FOUND)
|
||||||
|
message(STATUS "Found TensorFlow")
|
||||||
|
include_directories( ${TensorFlow_INCLUDE_DIR} )
|
||||||
|
set(classification_linked_libraries ${classification_linked_libraries}
|
||||||
|
${TensorFlow_LIBRARY})
|
||||||
|
set(classification_compile_definitions ${classification_compile_definitions}
|
||||||
|
"-DCGAL_LINKED_WITH_TENSORFLOW")
|
||||||
|
|
||||||
|
set(targets ${targets} example_tensorflow_neural_network)
|
||||||
|
else()
|
||||||
|
message(STATUS "NOTICE: TensorFlow not found, Neural Network predicate for classification won't be available.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# Creating targets with correct libraries and flags
|
# Creating targets with correct libraries and flags
|
||||||
foreach(target ${targets})
|
foreach(target ${targets})
|
||||||
create_single_source_cgal_program( "${target}.cpp" CXX_FEATURES ${needed_cxx_features} )
|
create_single_source_cgal_program( "${target}.cpp" CXX_FEATURES ${needed_cxx_features} )
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ int main (int argc, char** argv)
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
//! [Classify]
|
//! [Classify]
|
||||||
std::vector<std::size_t> label_indices;
|
std::vector<int> label_indices (pts.size(), -1);
|
||||||
|
|
||||||
CGAL::Real_timer t;
|
CGAL::Real_timer t;
|
||||||
t.start();
|
t.start();
|
||||||
|
|
@ -200,7 +200,7 @@ int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
f << pts[i] << " ";
|
f << pts[i] << " ";
|
||||||
|
|
||||||
Label_handle label = labels[label_indices[i]];
|
Label_handle label = labels[std::size_t(label_indices[i])];
|
||||||
if (label == ground)
|
if (label == ground)
|
||||||
f << "245 180 0" << std::endl;
|
f << "245 180 0" << std::endl;
|
||||||
else if (label == vegetation)
|
else if (label == vegetation)
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ int main (int argc, char** argv)
|
||||||
std::vector<int> label_indices(clusters.size(), -1);
|
std::vector<int> label_indices(clusters.size(), -1);
|
||||||
|
|
||||||
std::cerr << "Using ETHZ Random Forest Classifier" << std::endl;
|
std::cerr << "Using ETHZ Random Forest Classifier" << std::endl;
|
||||||
Classification::ETHZ_random_forest_classifier classifier (labels, features);
|
Classification::ETHZ::Random_forest_classifier classifier (labels, features);
|
||||||
|
|
||||||
std::cerr << "Loading configuration" << std::endl;
|
std::cerr << "Loading configuration" << std::endl;
|
||||||
std::ifstream in_config (filename_config, std::ios_base::in | std::ios_base::binary);
|
std::ifstream in_config (filename_config, std::ios_base::in | std::ios_base::binary);
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ int main (int argc, char** argv)
|
||||||
std::vector<int> label_indices(pts.size(), -1);
|
std::vector<int> label_indices(pts.size(), -1);
|
||||||
|
|
||||||
std::cerr << "Using ETHZ Random Forest Classifier" << std::endl;
|
std::cerr << "Using ETHZ Random Forest Classifier" << std::endl;
|
||||||
Classification::ETHZ_random_forest_classifier classifier (labels, features);
|
Classification::ETHZ::Random_forest_classifier classifier (labels, features);
|
||||||
|
|
||||||
std::cerr << "Training" << std::endl;
|
std::cerr << "Training" << std::endl;
|
||||||
t.reset();
|
t.reset();
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ int main (int argc, char** argv)
|
||||||
classifier.set_effect (b, my_feature, Classifier::PENALIZING);
|
classifier.set_effect (b, my_feature, Classifier::PENALIZING);
|
||||||
|
|
||||||
std::cerr << "Classifying" << std::endl;
|
std::cerr << "Classifying" << std::endl;
|
||||||
std::vector<std::size_t> label_indices(pts.size(), -1);
|
std::vector<int> label_indices(pts.size(), -1);
|
||||||
Classification::classify_with_graphcut<CGAL::Sequential_tag>
|
Classification::classify_with_graphcut<CGAL::Sequential_tag>
|
||||||
(pts, Pmap(), labels, classifier,
|
(pts, Pmap(), labels, classifier,
|
||||||
neighborhood.k_neighbor_query(12),
|
neighborhood.k_neighbor_query(12),
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ int main (int argc, char** argv)
|
||||||
std::vector<int> label_indices(mesh.number_of_faces(), -1);
|
std::vector<int> label_indices(mesh.number_of_faces(), -1);
|
||||||
|
|
||||||
std::cerr << "Using ETHZ Random Forest Classifier" << std::endl;
|
std::cerr << "Using ETHZ Random Forest Classifier" << std::endl;
|
||||||
Classification::ETHZ_random_forest_classifier classifier (labels, features);
|
Classification::ETHZ::Random_forest_classifier classifier (labels, features);
|
||||||
|
|
||||||
std::cerr << "Loading configuration" << std::endl;
|
std::cerr << "Loading configuration" << std::endl;
|
||||||
std::ifstream in_config (filename_config, std::ios_base::in | std::ios_base::binary);
|
std::ifstream in_config (filename_config, std::ios_base::in | std::ios_base::binary);
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ int main (int argc, char** argv)
|
||||||
std::vector<int> label_indices(pts.size(), -1);
|
std::vector<int> label_indices(pts.size(), -1);
|
||||||
|
|
||||||
std::cerr << "Using OpenCV Random Forest Classifier" << std::endl;
|
std::cerr << "Using OpenCV Random Forest Classifier" << std::endl;
|
||||||
Classification::OpenCV_random_forest_classifier classifier (labels, features);
|
Classification::OpenCV::Random_forest_classifier classifier (labels, features);
|
||||||
|
|
||||||
std::cerr << "Training" << std::endl;
|
std::cerr << "Training" << std::endl;
|
||||||
t.reset();
|
t.reset();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,164 @@
|
||||||
|
#if defined (_MSC_VER) && !defined (_WIN64)
|
||||||
|
#pragma warning(disable:4244) // boost::number_distance::distance()
|
||||||
|
// converts 64 to 32 bits integers
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <CGAL/Simple_cartesian.h>
|
||||||
|
#include <CGAL/Classification.h>
|
||||||
|
#include <CGAL/Point_set_3.h>
|
||||||
|
#include <CGAL/Point_set_3/IO.h>
|
||||||
|
|
||||||
|
#include <CGAL/Real_timer.h>
|
||||||
|
|
||||||
|
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||||
|
typedef Kernel::Point_3 Point;
|
||||||
|
typedef CGAL::Point_set_3<Point> Point_set;
|
||||||
|
typedef Kernel::Iso_cuboid_3 Iso_cuboid_3;
|
||||||
|
|
||||||
|
typedef Point_set::Point_map Pmap;
|
||||||
|
typedef Point_set::Property_map<int> Imap;
|
||||||
|
typedef Point_set::Property_map<unsigned char> UCmap;
|
||||||
|
|
||||||
|
namespace Classification = CGAL::Classification;
|
||||||
|
|
||||||
|
typedef Classification::Label_handle Label_handle;
|
||||||
|
typedef Classification::Feature_handle Feature_handle;
|
||||||
|
typedef Classification::Label_set Label_set;
|
||||||
|
typedef Classification::Feature_set Feature_set;
|
||||||
|
|
||||||
|
typedef Classification::Point_set_feature_generator<Kernel, Point_set, Pmap> Feature_generator;
|
||||||
|
|
||||||
|
|
||||||
|
int main (int argc, char** argv)
|
||||||
|
{
|
||||||
|
std::string filename = "data/b9_training.ply";
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
filename = argv[1];
|
||||||
|
|
||||||
|
std::ifstream in (filename.c_str(), std::ios::binary);
|
||||||
|
Point_set pts;
|
||||||
|
|
||||||
|
std::cerr << "Reading input" << std::endl;
|
||||||
|
in >> pts;
|
||||||
|
|
||||||
|
Imap label_map;
|
||||||
|
bool lm_found = false;
|
||||||
|
boost::tie (label_map, lm_found) = pts.property_map<int> ("label");
|
||||||
|
if (!lm_found)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: \"label\" property not found in input file." << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> ground_truth;
|
||||||
|
ground_truth.reserve (pts.size());
|
||||||
|
std::copy (pts.range(label_map).begin(), pts.range(label_map).end(),
|
||||||
|
std::back_inserter (ground_truth));
|
||||||
|
|
||||||
|
Feature_set features;
|
||||||
|
|
||||||
|
std::cerr << "Generating features" << std::endl;
|
||||||
|
CGAL::Real_timer t;
|
||||||
|
t.start();
|
||||||
|
Feature_generator generator (pts, pts.point_map(),
|
||||||
|
5); // using 5 scales
|
||||||
|
|
||||||
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
features.begin_parallel_additions();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
generator.generate_point_based_features (features);
|
||||||
|
|
||||||
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
features.end_parallel_additions();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
t.stop();
|
||||||
|
std::cerr << "Done in " << t.time() << " second(s)" << std::endl;
|
||||||
|
|
||||||
|
// Add types
|
||||||
|
Label_set labels;
|
||||||
|
Label_handle ground = labels.add ("ground");
|
||||||
|
Label_handle vegetation = labels.add ("vegetation");
|
||||||
|
Label_handle roof = labels.add ("roof");
|
||||||
|
|
||||||
|
std::vector<int> label_indices(pts.size(), -1);
|
||||||
|
|
||||||
|
std::cerr << "Using TensorFlow neural network Classifier" << std::endl;
|
||||||
|
Classification::TensorFlow::Neural_network_classifier<> classifier (labels, features);
|
||||||
|
|
||||||
|
std::cerr << "Training" << std::endl;
|
||||||
|
t.reset();
|
||||||
|
t.start();
|
||||||
|
classifier.train (ground_truth,
|
||||||
|
true, // restart from scratch
|
||||||
|
100); // 100 iterations
|
||||||
|
t.stop();
|
||||||
|
std::cerr << "Done in " << t.time() << " second(s)" << std::endl;
|
||||||
|
|
||||||
|
t.reset();
|
||||||
|
t.start();
|
||||||
|
Classification::classify_with_graphcut<CGAL::Sequential_tag>
|
||||||
|
(pts, pts.point_map(), labels, classifier,
|
||||||
|
generator.neighborhood().k_neighbor_query(12),
|
||||||
|
0.2f, 1, label_indices);
|
||||||
|
t.stop();
|
||||||
|
|
||||||
|
std::cerr << "Classification with graphcut done in " << t.time() << " second(s)" << std::endl;
|
||||||
|
|
||||||
|
std::cerr << "Precision, recall, F1 scores and IoU:" << std::endl;
|
||||||
|
Classification::Evaluation evaluation (labels, ground_truth, label_indices);
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < labels.size(); ++ i)
|
||||||
|
{
|
||||||
|
std::cerr << " * " << labels[i]->name() << ": "
|
||||||
|
<< evaluation.precision(labels[i]) << " ; "
|
||||||
|
<< evaluation.recall(labels[i]) << " ; "
|
||||||
|
<< evaluation.f1_score(labels[i]) << " ; "
|
||||||
|
<< evaluation.intersection_over_union(labels[i]) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "Accuracy = " << evaluation.accuracy() << std::endl
|
||||||
|
<< "Mean F1 score = " << evaluation.mean_f1_score() << std::endl
|
||||||
|
<< "Mean IoU = " << evaluation.mean_intersection_over_union() << std::endl;
|
||||||
|
|
||||||
|
// Color point set according to class
|
||||||
|
UCmap red = pts.add_property_map<unsigned char>("red", 0).first;
|
||||||
|
UCmap green = pts.add_property_map<unsigned char>("green", 0).first;
|
||||||
|
UCmap blue = pts.add_property_map<unsigned char>("blue", 0).first;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < label_indices.size(); ++ i)
|
||||||
|
{
|
||||||
|
label_map[i] = label_indices[i]; // update label map with computed classification
|
||||||
|
|
||||||
|
Label_handle label = labels[label_indices[i]];
|
||||||
|
|
||||||
|
if (label == ground)
|
||||||
|
{
|
||||||
|
red[i] = 245; green[i] = 180; blue[i] = 0;
|
||||||
|
}
|
||||||
|
else if (label == vegetation)
|
||||||
|
{
|
||||||
|
red[i] = 0; green[i] = 255; blue[i] = 27;
|
||||||
|
}
|
||||||
|
else if (label == roof)
|
||||||
|
{
|
||||||
|
red[i] = 255; green[i] = 0; blue[i] = 170;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write result
|
||||||
|
std::ofstream f ("classification.ply");
|
||||||
|
f.precision(18);
|
||||||
|
f << pts;
|
||||||
|
|
||||||
|
std::cerr << "All done" << std::endl;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
@ -25,10 +25,14 @@
|
||||||
|
|
||||||
#include <CGAL/Classification/classify.h>
|
#include <CGAL/Classification/classify.h>
|
||||||
#include <CGAL/Classification/Sum_of_weighted_features_classifier.h>
|
#include <CGAL/Classification/Sum_of_weighted_features_classifier.h>
|
||||||
#include <CGAL/Classification/ETHZ_random_forest_classifier.h>
|
#include <CGAL/Classification/ETHZ/Random_forest_classifier.h>
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_OPENCV
|
#ifdef CGAL_LINKED_WITH_OPENCV
|
||||||
#include <CGAL/Classification/OpenCV_random_forest_classifier.h>
|
#include <CGAL/Classification/OpenCV/Random_forest_classifier.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CGAL_LINKED_WITH_TENSORFLOW
|
||||||
|
#include <CGAL/Classification/TensorFlow/Neural_network_classifier.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <CGAL/Classification/Cluster.h>
|
#include <CGAL/Classification/Cluster.h>
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include <CGAL/Classification/Feature_set.h>
|
#include <CGAL/Classification/Feature_set.h>
|
||||||
#include <CGAL/Classification/Label_set.h>
|
#include <CGAL/Classification/Label_set.h>
|
||||||
|
#include <CGAL/Classification/internal/verbosity.h>
|
||||||
|
|
||||||
#ifdef CGAL_CLASSIFICATION_VERBOSE
|
#ifdef CGAL_CLASSIFICATION_VERBOSE
|
||||||
#define VERBOSE_TREE_PROGRESS 1
|
#define VERBOSE_TREE_PROGRESS 1
|
||||||
|
|
@ -41,8 +42,10 @@
|
||||||
# pragma warning(disable:4996)
|
# pragma warning(disable:4996)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <CGAL/Classification/internal/auxiliary/random-forest/node-gini.hpp>
|
#include <CGAL/Classification/ETHZ/internal/random-forest/node-gini.hpp>
|
||||||
#include <CGAL/Classification/internal/auxiliary/random-forest/forest.hpp>
|
#include <CGAL/Classification/ETHZ/internal/random-forest/forest.hpp>
|
||||||
|
|
||||||
|
#include <CGAL/tags.h>
|
||||||
|
|
||||||
#include <boost/archive/text_iarchive.hpp>
|
#include <boost/archive/text_iarchive.hpp>
|
||||||
#include <boost/archive/text_oarchive.hpp>
|
#include <boost/archive/text_oarchive.hpp>
|
||||||
|
|
@ -58,16 +61,18 @@ namespace CGAL {
|
||||||
|
|
||||||
namespace Classification {
|
namespace Classification {
|
||||||
|
|
||||||
/*!
|
namespace ETHZ {
|
||||||
\ingroup PkgClassificationClassifiers
|
|
||||||
|
|
||||||
\brief %Classifier based on the ETH Zurich version of random forest algorithm \cgalCite{cgal:w-erftl-14}.
|
/*!
|
||||||
|
\ingroup PkgClassificationClassifiersETHZ
|
||||||
|
|
||||||
|
\brief %Classifier based on the ETH Zurich version of the random forest algorithm \cgalCite{cgal:w-erftl-14}.
|
||||||
|
|
||||||
\note This classifier is distributed under the MIT license.
|
\note This classifier is distributed under the MIT license.
|
||||||
|
|
||||||
\cgalModels `CGAL::Classification::Classifier`
|
\cgalModels `CGAL::Classification::Classifier`
|
||||||
*/
|
*/
|
||||||
class ETHZ_random_forest_classifier
|
class Random_forest_classifier
|
||||||
{
|
{
|
||||||
typedef CGAL::internal::liblearning::RandomForest::RandomForest
|
typedef CGAL::internal::liblearning::RandomForest::RandomForest
|
||||||
< CGAL::internal::liblearning::RandomForest::NodeGini
|
< CGAL::internal::liblearning::RandomForest::NodeGini
|
||||||
|
|
@ -83,16 +88,36 @@ public:
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Instantiate the classifier using the sets of `labels` and `features`.
|
\brief Instantiates the classifier using the sets of `labels` and `features`.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
ETHZ_random_forest_classifier (const Label_set& labels,
|
Random_forest_classifier (const Label_set& labels,
|
||||||
const Feature_set& features)
|
const Feature_set& features)
|
||||||
: m_labels (labels), m_features (features), m_rfc (NULL)
|
: m_labels (labels), m_features (features), m_rfc (NULL)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Copies the `other` classifier's configuration using another
|
||||||
|
set of `features`.
|
||||||
|
|
||||||
|
This constructor can be used to apply a trained random forest to
|
||||||
|
another data set.
|
||||||
|
|
||||||
|
\warning The feature set should be composed of the same features
|
||||||
|
than the ones used by `other`, and in the same order.
|
||||||
|
|
||||||
|
*/
|
||||||
|
Random_forest_classifier (const Random_forest_classifier& other,
|
||||||
|
const Feature_set& features)
|
||||||
|
: m_labels (other.m_labels), m_features (features), m_rfc (NULL)
|
||||||
|
{
|
||||||
|
std::stringstream stream;
|
||||||
|
other.save_configuration(stream);
|
||||||
|
this->load_configuration(stream);
|
||||||
|
}
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
/// \cond SKIP_IN_MANUAL
|
||||||
~ETHZ_random_forest_classifier ()
|
~Random_forest_classifier ()
|
||||||
{
|
{
|
||||||
if (m_rfc != NULL)
|
if (m_rfc != NULL)
|
||||||
delete m_rfc;
|
delete m_rfc;
|
||||||
|
|
@ -102,8 +127,23 @@ public:
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Training
|
/// \name Training
|
||||||
|
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
template <typename LabelIndexRange>
|
||||||
|
void train (const LabelIndexRange& ground_truth,
|
||||||
|
bool reset_trees = true,
|
||||||
|
std::size_t num_trees = 25,
|
||||||
|
std::size_t max_depth = 20)
|
||||||
|
{
|
||||||
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
train<CGAL::Parallel_tag>(ground_truth, reset_trees, num_trees, max_depth);
|
||||||
|
#else
|
||||||
|
train<CGAL::Sequential_tag>(ground_truth, reset_trees, num_trees, max_depth);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Runs the training algorithm.
|
\brief Runs the training algorithm.
|
||||||
|
|
||||||
|
|
@ -114,6 +154,11 @@ public:
|
||||||
\pre At least one ground truth item should be assigned to each
|
\pre At least one ground truth item should be assigned to each
|
||||||
label.
|
label.
|
||||||
|
|
||||||
|
\tparam ConcurrencyTag enables sequential versus parallel
|
||||||
|
algorithm. Possible values are `Parallel_tag` (default value is
|
||||||
|
%CGAL is linked with TBB) or `Sequential_tag` (default value
|
||||||
|
otherwise).
|
||||||
|
|
||||||
\param ground_truth vector of label indices. It should contain for
|
\param ground_truth vector of label indices. It should contain for
|
||||||
each input item, in the same order as the input set, the index of
|
each input item, in the same order as the input set, the index of
|
||||||
the corresponding label in the `Label_set` provided in the
|
the corresponding label in the `Label_set` provided in the
|
||||||
|
|
@ -135,7 +180,7 @@ public:
|
||||||
will underfit the test data and conversely an overly high value
|
will underfit the test data and conversely an overly high value
|
||||||
will likely overfit.
|
will likely overfit.
|
||||||
*/
|
*/
|
||||||
template <typename LabelIndexRange>
|
template <typename ConcurrencyTag, typename LabelIndexRange>
|
||||||
void train (const LabelIndexRange& ground_truth,
|
void train (const LabelIndexRange& ground_truth,
|
||||||
bool reset_trees = true,
|
bool reset_trees = true,
|
||||||
std::size_t num_trees = 25,
|
std::size_t num_trees = 25,
|
||||||
|
|
@ -159,7 +204,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "Using " << gt.size() << " inliers" << std::endl;
|
CGAL_CLASSIFICATION_CERR << "Using " << gt.size() << " inliers" << std::endl;
|
||||||
|
|
||||||
CGAL::internal::liblearning::DataView2D<int> label_vector (&(gt[0]), gt.size(), 1);
|
CGAL::internal::liblearning::DataView2D<int> label_vector (&(gt[0]), gt.size(), 1);
|
||||||
CGAL::internal::liblearning::DataView2D<float> feature_vector(&(ft[0]), gt.size(), ft.size() / gt.size());
|
CGAL::internal::liblearning::DataView2D<float> feature_vector(&(ft[0]), gt.size(), ft.size() / gt.size());
|
||||||
|
|
@ -175,7 +220,8 @@ public:
|
||||||
|
|
||||||
CGAL::internal::liblearning::RandomForest::AxisAlignedRandomSplitGenerator generator;
|
CGAL::internal::liblearning::RandomForest::AxisAlignedRandomSplitGenerator generator;
|
||||||
|
|
||||||
m_rfc->train(feature_vector, label_vector, CGAL::internal::liblearning::DataView2D<int>(), generator, 0, false, reset_trees);
|
m_rfc->train<ConcurrencyTag>
|
||||||
|
(feature_vector, label_vector, CGAL::internal::liblearning::DataView2D<int>(), generator, 0, reset_trees, m_labels.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
|
@ -195,10 +241,46 @@ public:
|
||||||
for (std::size_t i = 0; i < out.size(); ++ i)
|
for (std::size_t i = 0; i < out.size(); ++ i)
|
||||||
out[i] = (std::min) (1.f, (std::max) (0.f, prob[i]));
|
out[i] = (std::min) (1.f, (std::max) (0.f, prob[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \endcond
|
/// \endcond
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
/// \name Miscellaneous
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Computes, for each feature, how many nodes in the forest
|
||||||
|
uses it as a split criterion.
|
||||||
|
|
||||||
|
Each tree of the random forest recursively splits the training
|
||||||
|
data set using at each node one of the input features. This method
|
||||||
|
counts, for each feature, how many times it was selected by the
|
||||||
|
training algorithm as a split criterion.
|
||||||
|
|
||||||
|
This method allows to evaluate how useful a feature was with
|
||||||
|
respect to a training set: if a feature is used a lot, that means
|
||||||
|
that it has a strong discriminative power with respect to how the
|
||||||
|
labels are represented by the feature set; on the contrary, if a
|
||||||
|
feature is not used very often, its discriminative power is
|
||||||
|
probably low; if a feature is _never_ used, it likely has no
|
||||||
|
interest at all and is completely uncorrelated to the label
|
||||||
|
segmentation of the training set.
|
||||||
|
|
||||||
|
\param count vector where the result is stored. After running the
|
||||||
|
method, it contains, for each feature, the number of nodes in the
|
||||||
|
forest that use it as a split criterion, in the same order as the
|
||||||
|
feature set order.
|
||||||
|
*/
|
||||||
|
void get_feature_usage (std::vector<std::size_t>& count) const
|
||||||
|
{
|
||||||
|
count.clear();
|
||||||
|
count.resize(m_features.size(), 0);
|
||||||
|
return m_rfc->get_feature_usage(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
/// \name Input/Output
|
/// \name Input/Output
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
|
@ -211,7 +293,7 @@ public:
|
||||||
The output file is written in an GZIP container that is readable
|
The output file is written in an GZIP container that is readable
|
||||||
by the `load_configuration()` method.
|
by the `load_configuration()` method.
|
||||||
*/
|
*/
|
||||||
void save_configuration (std::ostream& output)
|
void save_configuration (std::ostream& output) const
|
||||||
{
|
{
|
||||||
boost::iostreams::filtering_ostream outs;
|
boost::iostreams::filtering_ostream outs;
|
||||||
outs.push(boost::iostreams::gzip_compressor());
|
outs.push(boost::iostreams::gzip_compressor());
|
||||||
|
|
@ -247,6 +329,13 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
// Backward compatibility
|
||||||
|
typedef ETHZ::Random_forest_classifier ETHZ_random_forest_classifier;
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CGAL_CLASSIFICATION_ETHZ_RANDOM_FOREST_CLASSIFIER_H
|
#endif // CGAL_CLASSIFICATION_ETHZ_RANDOM_FOREST_CLASSIFIER_H
|
||||||
|
|
@ -27,6 +27,16 @@
|
||||||
// Modifications from original library:
|
// Modifications from original library:
|
||||||
// * changed inclusion protection tag
|
// * changed inclusion protection tag
|
||||||
// * moved to namespace CGAL::internal::
|
// * moved to namespace CGAL::internal::
|
||||||
|
// * init_feature_class_data() does not resize anymore (it's done
|
||||||
|
// later directly in the splitter). WARNING: all splitters other
|
||||||
|
// than the default won't be working correctly (but experimentally
|
||||||
|
// they are less good and we don't use them - we keep them just in
|
||||||
|
// case)
|
||||||
|
// * sample reduction is now 36.8% (to account for the correction of
|
||||||
|
// the randomization of the input which used to implicitly ignore
|
||||||
|
// this proportion of items)
|
||||||
|
// * map_points() in axis aligned splitter now only uses a subset of
|
||||||
|
// the points for evaluation (for timing optimization=
|
||||||
|
|
||||||
#ifndef CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_COMMON_LIBRARIES_H
|
#ifndef CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_COMMON_LIBRARIES_H
|
||||||
#define CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_COMMON_LIBRARIES_H
|
#define CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_COMMON_LIBRARIES_H
|
||||||
|
|
@ -62,9 +72,9 @@ namespace liblearning {
|
||||||
namespace RandomForest {
|
namespace RandomForest {
|
||||||
|
|
||||||
typedef std::vector< std::pair<float, int> > FeatureClassDataFloat;
|
typedef std::vector< std::pair<float, int> > FeatureClassDataFloat;
|
||||||
inline void init_feature_class_data(FeatureClassDataFloat& data, int /*n_classes*/, int n_samples)
|
inline void init_feature_class_data(FeatureClassDataFloat& /*data*/, int /*n_classes*/, int /* n_samples */)
|
||||||
{
|
{
|
||||||
data.resize(n_samples);
|
// data.resize(n_samples);
|
||||||
}
|
}
|
||||||
typedef boost::unordered_set<int> FeatureSet;
|
typedef boost::unordered_set<int> FeatureSet;
|
||||||
|
|
||||||
|
|
@ -97,7 +107,7 @@ struct ForestParams {
|
||||||
max_depth(42),
|
max_depth(42),
|
||||||
n_trees(100),
|
n_trees(100),
|
||||||
min_samples_per_node(5),
|
min_samples_per_node(5),
|
||||||
sample_reduction(0)
|
sample_reduction(0.368f)
|
||||||
{}
|
{}
|
||||||
template <typename Archive>
|
template <typename Archive>
|
||||||
void serialize(Archive& ar, unsigned /*version*/)
|
void serialize(Archive& ar, unsigned /*version*/)
|
||||||
|
|
@ -222,15 +232,21 @@ struct AxisAlignedSplitter {
|
||||||
int n_samples,
|
int n_samples,
|
||||||
FeatureClassData& data_points) const
|
FeatureClassData& data_points) const
|
||||||
{
|
{
|
||||||
for (int i_sample = 0; i_sample < n_samples; ++i_sample) {
|
std::size_t size = (std::min)(std::size_t(5000), std::size_t(n_samples));
|
||||||
// determine index of this sample ...
|
data_points.clear();
|
||||||
int sample_idx = sample_idxes[i_sample];
|
data_points.reserve(size);
|
||||||
// determine class ...
|
|
||||||
int sample_class = labels(sample_idx, 0);
|
std::size_t step = n_samples / size;
|
||||||
// determine value of the selected feature for this sample
|
|
||||||
FeatureType sample_fval = samples(sample_idx, feature);
|
for (int i_sample = 0; i_sample < n_samples; i_sample += step) {
|
||||||
data_points[i_sample] = std::make_pair(sample_fval, sample_class);
|
// determine index of this sample ...
|
||||||
}
|
int sample_idx = sample_idxes[i_sample];
|
||||||
|
// determine class ...
|
||||||
|
int sample_class = labels(sample_idx, 0);
|
||||||
|
// determine value of the selected feature for this sample
|
||||||
|
FeatureType sample_fval = samples(sample_idx, feature);
|
||||||
|
data_points.push_back(std::make_pair(sample_fval, sample_class));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
template <typename Archive>
|
template <typename Archive>
|
||||||
void serialize(Archive& ar, unsigned /*version*/)
|
void serialize(Archive& ar, unsigned /*version*/)
|
||||||
|
|
@ -29,6 +29,12 @@
|
||||||
// * moved to namespace CGAL::internal::
|
// * moved to namespace CGAL::internal::
|
||||||
// * add parameter "reset_trees" to train() to be able to construct
|
// * add parameter "reset_trees" to train() to be able to construct
|
||||||
// forest with several iterations
|
// forest with several iterations
|
||||||
|
// * training algorithm has been parallelized with Intel TBB
|
||||||
|
// * remove the unused feature "register_obb"
|
||||||
|
// * add option to not count labels (if it's know before)
|
||||||
|
// * fix the randomization of input (which was implicitly losing
|
||||||
|
// samples)
|
||||||
|
// * add method to get feature usage
|
||||||
|
|
||||||
#ifndef CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_FOREST_H
|
#ifndef CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_FOREST_H
|
||||||
#define CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_FOREST_H
|
#define CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_FOREST_H
|
||||||
|
|
@ -39,11 +45,80 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <CGAL/tags.h>
|
||||||
|
|
||||||
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
#include <tbb/parallel_for.h>
|
||||||
|
#include <tbb/blocked_range.h>
|
||||||
|
#include <tbb/scalable_allocator.h>
|
||||||
|
#include <tbb/mutex.h>
|
||||||
|
#endif // CGAL_LINKED_WITH_TBB
|
||||||
|
|
||||||
|
|
||||||
namespace CGAL { namespace internal {
|
namespace CGAL { namespace internal {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace liblearning {
|
namespace liblearning {
|
||||||
namespace RandomForest {
|
namespace RandomForest {
|
||||||
|
|
||||||
|
template <typename NodeT, typename SplitGenerator>
|
||||||
|
class Tree_training_functor
|
||||||
|
{
|
||||||
|
typedef typename NodeT::ParamType ParamType;
|
||||||
|
typedef typename NodeT::FeatureType FeatureType;
|
||||||
|
typedef Tree<NodeT> TreeType;
|
||||||
|
|
||||||
|
std::size_t seed_start;
|
||||||
|
const std::vector<int>& sample_idxes;
|
||||||
|
boost::ptr_vector<Tree<NodeT> >& trees;
|
||||||
|
DataView2D<FeatureType> samples;
|
||||||
|
DataView2D<int> labels;
|
||||||
|
std::size_t n_in_bag_samples;
|
||||||
|
const SplitGenerator& split_generator;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Tree_training_functor(std::size_t seed_start,
|
||||||
|
const std::vector<int>& sample_idxes,
|
||||||
|
boost::ptr_vector<Tree<NodeT> >& trees,
|
||||||
|
DataView2D<FeatureType> samples,
|
||||||
|
DataView2D<int> labels,
|
||||||
|
std::size_t n_in_bag_samples,
|
||||||
|
const SplitGenerator& split_generator)
|
||||||
|
: seed_start (seed_start)
|
||||||
|
, sample_idxes (sample_idxes)
|
||||||
|
, trees (trees)
|
||||||
|
, samples (samples)
|
||||||
|
, labels (labels)
|
||||||
|
, n_in_bag_samples(n_in_bag_samples)
|
||||||
|
, split_generator(split_generator)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
void operator()(const tbb::blocked_range<std::size_t>& r) const
|
||||||
|
{
|
||||||
|
for (std::size_t s = r.begin(); s != r.end(); ++ s)
|
||||||
|
apply(s);
|
||||||
|
}
|
||||||
|
#endif // CGAL_LINKED_WITH_TBB
|
||||||
|
|
||||||
|
inline void apply (std::size_t i_tree) const
|
||||||
|
{
|
||||||
|
// initialize random generator with sequential seeds (one for each
|
||||||
|
// tree)
|
||||||
|
RandomGen gen(seed_start + i_tree);
|
||||||
|
std::vector<int> in_bag_samples = sample_idxes;
|
||||||
|
|
||||||
|
// Bagging: draw random sample indexes used for this tree
|
||||||
|
std::random_shuffle (in_bag_samples.begin(),in_bag_samples.end());
|
||||||
|
|
||||||
|
// Train the tree
|
||||||
|
trees[i_tree].train(samples, labels, &in_bag_samples[0], n_in_bag_samples, split_generator, gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
template <typename NodeT>
|
template <typename NodeT>
|
||||||
class RandomForest {
|
class RandomForest {
|
||||||
public:
|
public:
|
||||||
|
|
@ -52,28 +127,29 @@ public:
|
||||||
typedef Tree<NodeT> TreeType;
|
typedef Tree<NodeT> TreeType;
|
||||||
ParamType params;
|
ParamType params;
|
||||||
|
|
||||||
std::vector<uint8_t> was_oob_data;
|
|
||||||
DataView2D<uint8_t> was_oob;
|
|
||||||
|
|
||||||
boost::ptr_vector< Tree<NodeT> > trees;
|
boost::ptr_vector< Tree<NodeT> > trees;
|
||||||
|
|
||||||
RandomForest() {}
|
RandomForest() {}
|
||||||
RandomForest(ParamType const& params) : params(params) {}
|
RandomForest(ParamType const& params) : params(params) {}
|
||||||
|
|
||||||
template<typename SplitGenerator>
|
template<typename ConcurrencyTag, typename SplitGenerator>
|
||||||
void train(DataView2D<FeatureType> samples,
|
void train(DataView2D<FeatureType> samples,
|
||||||
DataView2D<int> labels,
|
DataView2D<int> labels,
|
||||||
DataView2D<int> train_sample_idxes,
|
DataView2D<int> train_sample_idxes,
|
||||||
SplitGenerator const& split_generator,
|
SplitGenerator const& split_generator,
|
||||||
size_t seed_start = 1,
|
size_t seed_start = 1,
|
||||||
bool register_oob = true,
|
bool reset_trees = true,
|
||||||
bool reset_trees = true
|
std::size_t n_classes = std::size_t(-1)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (reset_trees)
|
if (reset_trees)
|
||||||
trees.clear();
|
trees.clear();
|
||||||
|
|
||||||
params.n_classes = *std::max_element(&labels(0,0), &labels(0,0)+labels.num_elements()) + 1;
|
if (n_classes == std::size_t(-1))
|
||||||
|
params.n_classes = *std::max_element(&labels(0,0), &labels(0,0)+labels.num_elements()) + 1;
|
||||||
|
else
|
||||||
|
params.n_classes = n_classes;
|
||||||
|
|
||||||
params.n_features = samples.cols;
|
params.n_features = samples.cols;
|
||||||
params.n_samples = samples.rows;
|
params.n_samples = samples.rows;
|
||||||
|
|
||||||
|
|
@ -93,42 +169,31 @@ public:
|
||||||
size_t n_idxes = sample_idxes.size();
|
size_t n_idxes = sample_idxes.size();
|
||||||
params.n_in_bag_samples = n_idxes * (1 - params.sample_reduction);
|
params.n_in_bag_samples = n_idxes * (1 - params.sample_reduction);
|
||||||
|
|
||||||
// Random distribution over indexes
|
|
||||||
UniformIntDist dist(0, n_idxes - 1);
|
|
||||||
|
|
||||||
// Store for each sample and each tree if sample was used for tree
|
|
||||||
if (register_oob) {
|
|
||||||
was_oob_data.assign(n_idxes*params.n_trees, 1);
|
|
||||||
was_oob = DataView2D<uint8_t>(&was_oob_data[0], n_idxes, params.n_trees);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t nb_trees = trees.size();
|
std::size_t nb_trees = trees.size();
|
||||||
for (size_t i_tree = nb_trees; i_tree < nb_trees + params.n_trees; ++i_tree) {
|
for (std::size_t i_tree = nb_trees; i_tree < nb_trees + params.n_trees; ++ i_tree)
|
||||||
|
trees.push_back (new TreeType(¶ms));
|
||||||
|
|
||||||
|
Tree_training_functor<NodeT, SplitGenerator>
|
||||||
|
f (seed_start, sample_idxes, trees, samples, labels, params.n_in_bag_samples, split_generator);
|
||||||
|
|
||||||
|
#ifndef CGAL_LINKED_WITH_TBB
|
||||||
|
CGAL_static_assertion_msg (!(boost::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
||||||
|
"Parallel_tag is enabled but TBB is unavailable.");
|
||||||
|
#else
|
||||||
|
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
||||||
|
{
|
||||||
|
tbb::parallel_for(tbb::blocked_range<size_t>(nb_trees, nb_trees + params.n_trees), f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
for (size_t i_tree = nb_trees; i_tree < nb_trees + params.n_trees; ++i_tree)
|
||||||
|
{
|
||||||
#if VERBOSE_TREE_PROGRESS
|
#if VERBOSE_TREE_PROGRESS
|
||||||
std::printf("Training tree %zu/%zu, max depth %zu\n", i_tree+1, nb_trees + params.n_trees, params.max_depth);
|
std::printf("Training tree %zu/%zu, max depth %zu\n", i_tree+1, nb_trees + params.n_trees, params.max_depth);
|
||||||
#endif
|
#endif
|
||||||
// new tree
|
f.apply(i_tree);
|
||||||
trees.push_back(new TreeType(¶ms));
|
}
|
||||||
// initialize random generator with sequential seeds (one for each
|
|
||||||
// tree)
|
|
||||||
RandomGen gen(seed_start + i_tree);
|
|
||||||
// Bagging: draw random sample indexes used for this tree
|
|
||||||
std::vector<int> in_bag_samples(params.n_in_bag_samples);
|
|
||||||
for (size_t i_sample = 0; i_sample < in_bag_samples.size(); ++i_sample) {
|
|
||||||
int random_idx = dist(gen);
|
|
||||||
in_bag_samples[i_sample] = sample_idxes[random_idx];
|
|
||||||
if (register_oob && was_oob(random_idx, i_tree)) {
|
|
||||||
was_oob(random_idx, i_tree) = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef TREE_GRAPHVIZ_STREAM
|
|
||||||
TREE_GRAPHVIZ_STREAM << "digraph Tree {" << std::endl;
|
|
||||||
#endif
|
|
||||||
// Train the tree
|
|
||||||
trees.back().train(samples, labels, &in_bag_samples[0], in_bag_samples.size(), split_generator, gen);
|
|
||||||
#ifdef TREE_GRAPHVIZ_STREAM
|
|
||||||
TREE_GRAPHVIZ_STREAM << "}" << std::endl << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int evaluate(FeatureType const* sample, float* results) {
|
int evaluate(FeatureType const* sample, float* results) {
|
||||||
|
|
@ -177,6 +242,12 @@ public:
|
||||||
ar & BOOST_SERIALIZATION_NVP(params);
|
ar & BOOST_SERIALIZATION_NVP(params);
|
||||||
ar & BOOST_SERIALIZATION_NVP(trees);
|
ar & BOOST_SERIALIZATION_NVP(trees);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_feature_usage (std::vector<std::size_t>& count) const
|
||||||
|
{
|
||||||
|
for (std::size_t i_tree = 0; i_tree < trees.size(); ++i_tree)
|
||||||
|
trees[i_tree].get_feature_usage(count);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -28,6 +28,11 @@
|
||||||
// * changed inclusion protection tag
|
// * changed inclusion protection tag
|
||||||
// * moved to namespace CGAL::internal::
|
// * moved to namespace CGAL::internal::
|
||||||
|
|
||||||
|
// * improve sorting algorithm by only comparing the first of pair
|
||||||
|
// (second is useless)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_NODE_GINI_H
|
#ifndef CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_NODE_GINI_H
|
||||||
#define CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_NODE_GINI_H
|
#define CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_NODE_GINI_H
|
||||||
#include "node.hpp"
|
#include "node.hpp"
|
||||||
|
|
@ -79,7 +84,13 @@ public:
|
||||||
n_r += 1;
|
n_r += 1;
|
||||||
}
|
}
|
||||||
// sort data so thresholding is easy based on position in array
|
// sort data so thresholding is easy based on position in array
|
||||||
std::sort(data_points.begin(), data_points.end());
|
std::sort(data_points.begin(), data_points.end(),
|
||||||
|
[&](const std::pair<float, int>& a,
|
||||||
|
const std::pair<float, int>& b) -> bool
|
||||||
|
{
|
||||||
|
return a.first < b.first;
|
||||||
|
});
|
||||||
|
|
||||||
// loop over data, update class distributions left&right
|
// loop over data, update class distributions left&right
|
||||||
for (size_t i_point = 1; i_point < data_points.size(); ++i_point) {
|
for (size_t i_point = 1; i_point < data_points.size(); ++i_point) {
|
||||||
int cls = data_points[i_point-1].second;
|
int cls = data_points[i_point-1].second;
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
// * fix computation of node_dist[label] so that results are always <= 1.0
|
// * fix computation of node_dist[label] so that results are always <= 1.0
|
||||||
// * change serialization functions to avoid a bug with boost and some
|
// * change serialization functions to avoid a bug with boost and some
|
||||||
// compilers (that leads to dereferencing a null pointer)
|
// compilers (that leads to dereferencing a null pointer)
|
||||||
|
// * add a method to get feature usage
|
||||||
|
|
||||||
#ifndef CGAL_INTERNAL_LIBLEARNING_RANDOMFORESTS_NODE_H
|
#ifndef CGAL_INTERNAL_LIBLEARNING_RANDOMFORESTS_NODE_H
|
||||||
#define CGAL_INTERNAL_LIBLEARNING_RANDOMFORESTS_NODE_H
|
#define CGAL_INTERNAL_LIBLEARNING_RANDOMFORESTS_NODE_H
|
||||||
|
|
@ -257,6 +258,16 @@ public:
|
||||||
ar & BOOST_SERIALIZATION_NVP(right);
|
ar & BOOST_SERIALIZATION_NVP(right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_feature_usage (std::vector<std::size_t>& count) const
|
||||||
|
{
|
||||||
|
if (!is_leaf)
|
||||||
|
{
|
||||||
|
count[std::size_t(splitter.feature)] ++;
|
||||||
|
left->get_feature_usage(count);
|
||||||
|
right->get_feature_usage(count);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
// Modifications from original library:
|
// Modifications from original library:
|
||||||
// * changed inclusion protection tag
|
// * changed inclusion protection tag
|
||||||
// * moved to namespace CGAL::internal::
|
// * moved to namespace CGAL::internal::
|
||||||
|
// * add a method to get feature usage
|
||||||
|
|
||||||
#ifndef CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_TREE_H
|
#ifndef CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_TREE_H
|
||||||
#define CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_TREE_H
|
#define CGAL_INTERNAL_LIBLEARNING_RANDOMFOREST_TREE_H
|
||||||
|
|
@ -135,6 +136,10 @@ public:
|
||||||
ar & BOOST_SERIALIZATION_NVP(params);
|
ar & BOOST_SERIALIZATION_NVP(params);
|
||||||
ar & BOOST_SERIALIZATION_NVP(root_node);
|
ar & BOOST_SERIALIZATION_NVP(root_node);
|
||||||
}
|
}
|
||||||
|
void get_feature_usage (std::vector<std::size_t>& count) const
|
||||||
|
{
|
||||||
|
root_node->get_feature_usage(count);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -85,6 +85,8 @@ public:
|
||||||
: grid (grid)
|
: grid (grid)
|
||||||
{
|
{
|
||||||
this->set_name ("echo_scatter");
|
this->set_name ("echo_scatter");
|
||||||
|
if (radius_neighbors < 0.)
|
||||||
|
radius_neighbors = 3.f * grid.resolution();
|
||||||
|
|
||||||
if (grid.width() * grid.height() > input.size())
|
if (grid.width() * grid.height() > input.size())
|
||||||
echo_scatter.resize(input.size(), compressed_float(0));
|
echo_scatter.resize(input.size(), compressed_float(0));
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ public:
|
||||||
{
|
{
|
||||||
this->set_name ("elevation");
|
this->set_name ("elevation");
|
||||||
if (radius_dtm < 0.)
|
if (radius_dtm < 0.)
|
||||||
radius_dtm = 100.f * grid.resolution();
|
radius_dtm = 10.f * grid.resolution();
|
||||||
|
|
||||||
//DEM
|
//DEM
|
||||||
Image_float dem(grid.width(),grid.height());
|
Image_float dem(grid.width(),grid.height());
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
// Copyright (c) 2012 INRIA Sophia-Antipolis (France).
|
||||||
|
// Copyright (c) 2017 GeometryFactory Sarl (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
|
||||||
|
// 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$
|
||||||
|
// SPDX-License-Identifier: GPL-3.0+
|
||||||
|
//
|
||||||
|
// Author(s) : Florent Lafarge, Simon Giraudot
|
||||||
|
|
||||||
|
#ifndef CGAL_CLASSIFICATION_FEATURE_HEIGHT_ABOVE_H
|
||||||
|
#define CGAL_CLASSIFICATION_FEATURE_HEIGHT_ABOVE_H
|
||||||
|
|
||||||
|
#include <CGAL/license/Classification.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <CGAL/Classification/Feature_base.h>
|
||||||
|
#include <CGAL/Classification/compressed_float.h>
|
||||||
|
#include <CGAL/Classification/Image.h>
|
||||||
|
#include <CGAL/Classification/Planimetric_grid.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
namespace Classification {
|
||||||
|
|
||||||
|
namespace Feature {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgClassificationFeatures
|
||||||
|
|
||||||
|
%Feature based on local height distribution This feature computes
|
||||||
|
the distance between the maximum height on the local cell of the
|
||||||
|
planimetric grid and a point's height.
|
||||||
|
|
||||||
|
Its default name is "height_above".
|
||||||
|
|
||||||
|
\tparam GeomTraits model of \cgal Kernel.
|
||||||
|
\tparam PointRange model of `ConstRange`. Its iterator type
|
||||||
|
is `RandomAccessIterator` and its value type is the key type of
|
||||||
|
`PointMap`.
|
||||||
|
\tparam PointMap model of `ReadablePropertyMap` whose key
|
||||||
|
type is the value type of the iterator of `PointRange` and value type
|
||||||
|
is `GeomTraits::Point_3`.
|
||||||
|
|
||||||
|
*/
|
||||||
|
template <typename GeomTraits, typename PointRange, typename PointMap>
|
||||||
|
class Height_above : public Feature_base
|
||||||
|
{
|
||||||
|
typedef typename GeomTraits::Iso_cuboid_3 Iso_cuboid_3;
|
||||||
|
|
||||||
|
typedef Image<float> Image_float;
|
||||||
|
typedef Planimetric_grid<GeomTraits, PointRange, PointMap> Grid;
|
||||||
|
|
||||||
|
const PointRange& input;
|
||||||
|
PointMap point_map;
|
||||||
|
const Grid& grid;
|
||||||
|
Image_float dtm;
|
||||||
|
std::vector<float> values;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
\brief Constructs the feature.
|
||||||
|
|
||||||
|
\param input point range.
|
||||||
|
\param point_map property map to access the input points.
|
||||||
|
\param grid precomputed `Planimetric_grid`.
|
||||||
|
*/
|
||||||
|
Height_above (const PointRange& input,
|
||||||
|
PointMap point_map,
|
||||||
|
const Grid& grid)
|
||||||
|
: input(input), point_map(point_map), grid(grid)
|
||||||
|
{
|
||||||
|
this->set_name ("height_above");
|
||||||
|
|
||||||
|
dtm = Image_float(grid.width(),grid.height());
|
||||||
|
|
||||||
|
for (std::size_t j = 0; j < grid.height(); ++ j)
|
||||||
|
for (std::size_t i = 0; i < grid.width(); ++ i)
|
||||||
|
if (grid.has_points(i,j))
|
||||||
|
{
|
||||||
|
float z_max = -std::numeric_limits<float>::max();
|
||||||
|
|
||||||
|
typename Grid::iterator end = grid.indices_end(i,j);
|
||||||
|
for (typename Grid::iterator it = grid.indices_begin(i,j); it != end; ++ it)
|
||||||
|
{
|
||||||
|
float z = float(get(point_map, *(input.begin()+(*it))).z());
|
||||||
|
z_max = (std::max(z_max, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
dtm(i,j) = z_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grid.width() * grid.height() > input.size())
|
||||||
|
{
|
||||||
|
values.resize (input.size(), 0.f);
|
||||||
|
for (std::size_t i = 0; i < input.size(); ++ i)
|
||||||
|
{
|
||||||
|
std::size_t I = grid.x(i);
|
||||||
|
std::size_t J = grid.y(i);
|
||||||
|
values[i] = float(dtm(I,J) - get (point_map, *(input.begin() + i)).z());
|
||||||
|
}
|
||||||
|
dtm.free();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
virtual float value (std::size_t pt_index)
|
||||||
|
{
|
||||||
|
if (values.empty())
|
||||||
|
{
|
||||||
|
std::size_t I = grid.x(pt_index);
|
||||||
|
std::size_t J = grid.y(pt_index);
|
||||||
|
return dtm(I,J) - float(get (point_map, *(input.begin() + pt_index)).z());
|
||||||
|
}
|
||||||
|
|
||||||
|
return values[pt_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \endcond
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Feature
|
||||||
|
|
||||||
|
} // namespace Classification
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_CLASSIFICATION_FEATURE_HEIGHT_ABOVE_H
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
// Copyright (c) 2012 INRIA Sophia-Antipolis (France).
|
||||||
|
// Copyright (c) 2017 GeometryFactory Sarl (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
|
||||||
|
// 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$
|
||||||
|
// SPDX-License-Identifier: GPL-3.0+
|
||||||
|
//
|
||||||
|
// Author(s) : Florent Lafarge, Simon Giraudot
|
||||||
|
|
||||||
|
#ifndef CGAL_CLASSIFICATION_FEATURE_HEIGHT_BELOW_H
|
||||||
|
#define CGAL_CLASSIFICATION_FEATURE_HEIGHT_BELOW_H
|
||||||
|
|
||||||
|
#include <CGAL/license/Classification.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <CGAL/Classification/Feature_base.h>
|
||||||
|
#include <CGAL/Classification/compressed_float.h>
|
||||||
|
#include <CGAL/Classification/Image.h>
|
||||||
|
#include <CGAL/Classification/Planimetric_grid.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
namespace Classification {
|
||||||
|
|
||||||
|
namespace Feature {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgClassificationFeatures
|
||||||
|
|
||||||
|
%Feature based on local height distribution This feature computes
|
||||||
|
the distance between a point's height and the minimum height on
|
||||||
|
the local cell of the planimetric grid.
|
||||||
|
|
||||||
|
Its default name is "height_below".
|
||||||
|
|
||||||
|
\tparam GeomTraits model of \cgal Kernel.
|
||||||
|
\tparam PointRange model of `ConstRange`. Its iterator type
|
||||||
|
is `RandomAccessIterator` and its value type is the key type of
|
||||||
|
`PointMap`.
|
||||||
|
\tparam PointMap model of `ReadablePropertyMap` whose key
|
||||||
|
type is the value type of the iterator of `PointRange` and value type
|
||||||
|
is `GeomTraits::Point_3`.
|
||||||
|
|
||||||
|
*/
|
||||||
|
template <typename GeomTraits, typename PointRange, typename PointMap>
|
||||||
|
class Height_below : public Feature_base
|
||||||
|
{
|
||||||
|
typedef typename GeomTraits::Iso_cuboid_3 Iso_cuboid_3;
|
||||||
|
|
||||||
|
typedef Image<float> Image_float;
|
||||||
|
typedef Planimetric_grid<GeomTraits, PointRange, PointMap> Grid;
|
||||||
|
|
||||||
|
const PointRange& input;
|
||||||
|
PointMap point_map;
|
||||||
|
const Grid& grid;
|
||||||
|
Image_float dtm;
|
||||||
|
std::vector<float> values;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
\brief Constructs the feature.
|
||||||
|
|
||||||
|
\param input point range.
|
||||||
|
\param point_map property map to access the input points.
|
||||||
|
\param grid precomputed `Planimetric_grid`.
|
||||||
|
*/
|
||||||
|
Height_below (const PointRange& input,
|
||||||
|
PointMap point_map,
|
||||||
|
const Grid& grid)
|
||||||
|
: input(input), point_map(point_map), grid(grid)
|
||||||
|
{
|
||||||
|
this->set_name ("height_below");
|
||||||
|
|
||||||
|
dtm = Image_float(grid.width(),grid.height());
|
||||||
|
|
||||||
|
for (std::size_t j = 0; j < grid.height(); ++ j)
|
||||||
|
for (std::size_t i = 0; i < grid.width(); ++ i)
|
||||||
|
if (grid.has_points(i,j))
|
||||||
|
{
|
||||||
|
float z_min = std::numeric_limits<float>::max();
|
||||||
|
|
||||||
|
typename Grid::iterator end = grid.indices_end(i,j);
|
||||||
|
for (typename Grid::iterator it = grid.indices_begin(i,j); it != end; ++ it)
|
||||||
|
{
|
||||||
|
float z = float(get(point_map, *(input.begin()+(*it))).z());
|
||||||
|
z_min = (std::min(z_min, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
dtm(i,j) = z_min;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grid.width() * grid.height() > input.size())
|
||||||
|
{
|
||||||
|
values.resize (input.size(), 0.f);
|
||||||
|
for (std::size_t i = 0; i < input.size(); ++ i)
|
||||||
|
{
|
||||||
|
std::size_t I = grid.x(i);
|
||||||
|
std::size_t J = grid.y(i);
|
||||||
|
values[i] = float(get (point_map, *(input.begin() + i)).z() - dtm(I,J));
|
||||||
|
}
|
||||||
|
dtm.free();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
virtual float value (std::size_t pt_index)
|
||||||
|
{
|
||||||
|
if (values.empty())
|
||||||
|
{
|
||||||
|
std::size_t I = grid.x(pt_index);
|
||||||
|
std::size_t J = grid.y(pt_index);
|
||||||
|
return float(get (point_map, *(input.begin() + pt_index)).z() - dtm(I,J));
|
||||||
|
}
|
||||||
|
|
||||||
|
return values[pt_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \endcond
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Feature
|
||||||
|
|
||||||
|
} // namespace Classification
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_CLASSIFICATION_FEATURE_HEIGHT_BELOW_H
|
||||||
|
|
@ -0,0 +1,144 @@
|
||||||
|
// Copyright (c) 2012 INRIA Sophia-Antipolis (France).
|
||||||
|
// Copyright (c) 2017 GeometryFactory Sarl (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
|
||||||
|
// 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$
|
||||||
|
// SPDX-License-Identifier: GPL-3.0+
|
||||||
|
//
|
||||||
|
// Author(s) : Florent Lafarge, Simon Giraudot
|
||||||
|
|
||||||
|
#ifndef CGAL_CLASSIFICATION_FEATURE_VERTICAL_RANGE_H
|
||||||
|
#define CGAL_CLASSIFICATION_FEATURE_VERTICAL_RANGE_H
|
||||||
|
|
||||||
|
#include <CGAL/license/Classification.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <CGAL/Classification/Feature_base.h>
|
||||||
|
#include <CGAL/Classification/compressed_float.h>
|
||||||
|
#include <CGAL/Classification/Image.h>
|
||||||
|
#include <CGAL/Classification/Planimetric_grid.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
namespace Classification {
|
||||||
|
|
||||||
|
namespace Feature {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgClassificationFeatures
|
||||||
|
|
||||||
|
%Feature based on local height distribution. This feature computes
|
||||||
|
the distance between the maximum and the minimum height on the
|
||||||
|
local cell of the planimetric grid.
|
||||||
|
|
||||||
|
Its default name is "vertical_range".
|
||||||
|
|
||||||
|
\tparam GeomTraits model of \cgal Kernel.
|
||||||
|
\tparam PointRange model of `ConstRange`. Its iterator type
|
||||||
|
is `RandomAccessIterator` and its value type is the key type of
|
||||||
|
`PointMap`.
|
||||||
|
\tparam PointMap model of `ReadablePropertyMap` whose key
|
||||||
|
type is the value type of the iterator of `PointRange` and value type
|
||||||
|
is `GeomTraits::Point_3`.
|
||||||
|
|
||||||
|
*/
|
||||||
|
template <typename GeomTraits, typename PointRange, typename PointMap>
|
||||||
|
class Vertical_range : public Feature_base
|
||||||
|
{
|
||||||
|
typedef typename GeomTraits::Iso_cuboid_3 Iso_cuboid_3;
|
||||||
|
|
||||||
|
typedef Image<float> Image_float;
|
||||||
|
typedef Planimetric_grid<GeomTraits, PointRange, PointMap> Grid;
|
||||||
|
|
||||||
|
const PointRange& input;
|
||||||
|
PointMap point_map;
|
||||||
|
const Grid& grid;
|
||||||
|
Image_float dtm;
|
||||||
|
std::vector<float> values;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
\brief Constructs the feature.
|
||||||
|
|
||||||
|
\param input point range.
|
||||||
|
\param point_map property map to access the input points.
|
||||||
|
\param grid precomputed `Planimetric_grid`.
|
||||||
|
*/
|
||||||
|
Vertical_range (const PointRange& input,
|
||||||
|
PointMap point_map,
|
||||||
|
const Grid& grid)
|
||||||
|
: input(input), point_map(point_map), grid(grid)
|
||||||
|
{
|
||||||
|
this->set_name ("vertical_range");
|
||||||
|
|
||||||
|
dtm = Image_float(grid.width(),grid.height());
|
||||||
|
|
||||||
|
for (std::size_t j = 0; j < grid.height(); ++ j)
|
||||||
|
for (std::size_t i = 0; i < grid.width(); ++ i)
|
||||||
|
if (grid.has_points(i,j))
|
||||||
|
{
|
||||||
|
float z_max = -std::numeric_limits<float>::max();
|
||||||
|
float z_min = std::numeric_limits<float>::max();
|
||||||
|
|
||||||
|
typename Grid::iterator end = grid.indices_end(i,j);
|
||||||
|
for (typename Grid::iterator it = grid.indices_begin(i,j); it != end; ++ it)
|
||||||
|
{
|
||||||
|
float z = float(get(point_map, *(input.begin()+(*it))).z());
|
||||||
|
z_max = (std::max(z_max, z));
|
||||||
|
z_min = (std::min(z_min, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
dtm(i,j) = z_max - z_min;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grid.width() * grid.height() > input.size())
|
||||||
|
{
|
||||||
|
values.resize (input.size(), 0.f);
|
||||||
|
for (std::size_t i = 0; i < input.size(); ++ i)
|
||||||
|
{
|
||||||
|
std::size_t I = grid.x(i);
|
||||||
|
std::size_t J = grid.y(i);
|
||||||
|
values[i] = dtm(I,J);
|
||||||
|
}
|
||||||
|
dtm.free();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
virtual float value (std::size_t pt_index)
|
||||||
|
{
|
||||||
|
if (values.empty())
|
||||||
|
{
|
||||||
|
std::size_t I = grid.x(pt_index);
|
||||||
|
std::size_t J = grid.y(pt_index);
|
||||||
|
return dtm(I,J);
|
||||||
|
}
|
||||||
|
|
||||||
|
return values[pt_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \endcond
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Feature
|
||||||
|
|
||||||
|
} // namespace Classification
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_CLASSIFICATION_FEATURE_VERTICAL_RANGE_H
|
||||||
|
|
@ -41,6 +41,8 @@ class Image
|
||||||
|
|
||||||
std::size_t m_width;
|
std::size_t m_width;
|
||||||
std::size_t m_height;
|
std::size_t m_height;
|
||||||
|
std::size_t m_depth;
|
||||||
|
|
||||||
boost::shared_ptr<Vector> m_raw;
|
boost::shared_ptr<Vector> m_raw;
|
||||||
boost::shared_ptr<Map> m_sparse;
|
boost::shared_ptr<Map> m_sparse;
|
||||||
Type m_default;
|
Type m_default;
|
||||||
|
|
@ -52,18 +54,19 @@ class Image
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Image () : m_width(0), m_height(0), m_raw (NULL)
|
Image () : m_width(0), m_height(0), m_depth(0), m_raw (NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Image (std::size_t width, std::size_t height)
|
Image (std::size_t width, std::size_t height, std::size_t depth = 1)
|
||||||
: m_width (width),
|
: m_width (width)
|
||||||
m_height (height)
|
, m_height (height)
|
||||||
|
, m_depth (depth)
|
||||||
{
|
{
|
||||||
if (m_width * m_height > 0)
|
if (m_width * m_height * m_depth > 0)
|
||||||
{
|
{
|
||||||
if (m_width * m_height < CGAL_CLASSIFICATION_IMAGE_SIZE_LIMIT)
|
if (m_width * m_height * m_depth < CGAL_CLASSIFICATION_IMAGE_SIZE_LIMIT)
|
||||||
m_raw = boost::shared_ptr<Vector> (new Vector(m_width * m_height));
|
m_raw = boost::shared_ptr<Vector> (new Vector(m_width * m_height * m_depth));
|
||||||
else
|
else
|
||||||
m_sparse = boost::shared_ptr<Map> (new Map());
|
m_sparse = boost::shared_ptr<Map> (new Map());
|
||||||
}
|
}
|
||||||
|
|
@ -85,33 +88,41 @@ public:
|
||||||
m_sparse = other.m_sparse;
|
m_sparse = other.m_sparse;
|
||||||
m_width = other.width();
|
m_width = other.width();
|
||||||
m_height = other.height();
|
m_height = other.height();
|
||||||
|
m_depth = other.depth();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t width() const { return m_width; }
|
std::size_t width() const { return m_width; }
|
||||||
std::size_t height() const { return m_height; }
|
std::size_t height() const { return m_height; }
|
||||||
|
std::size_t depth() const { return m_depth; }
|
||||||
|
|
||||||
Type& operator() (const std::size_t& x, const std::size_t& y)
|
inline std::size_t coord (const std::size_t& x, const std::size_t& y, const std::size_t& z) const
|
||||||
|
{
|
||||||
|
return z + (m_depth * y) + (m_depth * m_height * x);
|
||||||
|
}
|
||||||
|
|
||||||
|
Type& operator() (const std::size_t& x, const std::size_t& y, const std::size_t& z = 0)
|
||||||
{
|
{
|
||||||
if (m_raw == boost::shared_ptr<Vector>()) // sparse case
|
if (m_raw == boost::shared_ptr<Vector>()) // sparse case
|
||||||
{
|
{
|
||||||
typename Map::iterator inserted = m_sparse->insert (std::make_pair (x * m_height + y, Type())).first;
|
typename Map::iterator inserted = m_sparse->insert
|
||||||
|
(std::make_pair (coord(x,y,z), Type())).first;
|
||||||
return inserted->second;
|
return inserted->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*m_raw)[x * m_height + y];
|
return (*m_raw)[coord(x,y,z)];
|
||||||
}
|
}
|
||||||
const Type& operator() (const std::size_t& x, const std::size_t& y) const
|
const Type& operator() (const std::size_t& x, const std::size_t& y, const std::size_t& z = 0) const
|
||||||
{
|
{
|
||||||
if (m_raw == boost::shared_ptr<Vector>()) // sparse case
|
if (m_raw == boost::shared_ptr<Vector>()) // sparse case
|
||||||
{
|
{
|
||||||
typename Map::iterator found = m_sparse->find (x * m_height + y);
|
typename Map::iterator found = m_sparse->find (coord(x,y,z));
|
||||||
if (found != m_sparse->end())
|
if (found != m_sparse->end())
|
||||||
return found->second;
|
return found->second;
|
||||||
return m_default;
|
return m_default;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*m_raw)[x * m_height + y];
|
return (*m_raw)[coord(x,y,z)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,10 @@ public:
|
||||||
Label (std::string name) : m_name (name) { }
|
Label (std::string name) : m_name (name) { }
|
||||||
|
|
||||||
const std::string& name() const { return m_name; }
|
const std::string& name() const { return m_name; }
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
void set_name (const std::string& name) { m_name = name; }
|
||||||
|
/// \endcond
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef DOXYGEN_RUNNING
|
#ifdef DOXYGEN_RUNNING
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,9 @@
|
||||||
#include <CGAL/Classification/Feature/Verticality.h>
|
#include <CGAL/Classification/Feature/Verticality.h>
|
||||||
#include <CGAL/Classification/Feature/Eigenvalue.h>
|
#include <CGAL/Classification/Feature/Eigenvalue.h>
|
||||||
#include <CGAL/Classification/Feature/Color_channel.h>
|
#include <CGAL/Classification/Feature/Color_channel.h>
|
||||||
|
#include <CGAL/Classification/Feature/Height_below.h>
|
||||||
|
#include <CGAL/Classification/Feature/Height_above.h>
|
||||||
|
#include <CGAL/Classification/Feature/Vertical_range.h>
|
||||||
#include <CGAL/Classification/internal/verbosity.h>
|
#include <CGAL/Classification/internal/verbosity.h>
|
||||||
|
|
||||||
#include <CGAL/bounding_box.h>
|
#include <CGAL/bounding_box.h>
|
||||||
|
|
@ -65,15 +68,20 @@ namespace Classification {
|
||||||
\brief Generates a set of generic features for surface mesh
|
\brief Generates a set of generic features for surface mesh
|
||||||
classification.
|
classification.
|
||||||
|
|
||||||
This class takes care of computing all necessary data structures and
|
This class takes care of computing and storing all necessary data
|
||||||
of generating a set of generic features at multiple scales to
|
structures and of generating a set of generic features at multiple
|
||||||
increase the reliability of the classification.
|
scales to increase the reliability of the classification.
|
||||||
|
|
||||||
A `PointMap` is required: this map should associate each face of the
|
A `PointMap` is required: this map should associate each face of the
|
||||||
mesh to a representative point (for example, the center of mass of
|
mesh to a representative point (for example, the center of mass of
|
||||||
the face). It is used to generate point set features by considering
|
the face). It is used to generate point set features by considering
|
||||||
the mesh as a point set.
|
the mesh as a point set.
|
||||||
|
|
||||||
|
\warning The generated features use data structures that are stored
|
||||||
|
inside the generator. For this reason, the generator should be
|
||||||
|
instantiated _within the same scope_ as the feature set and should
|
||||||
|
not be deleted before the feature set.
|
||||||
|
|
||||||
\tparam GeomTraits model of \cgal Kernel.
|
\tparam GeomTraits model of \cgal Kernel.
|
||||||
\tparam FaceListGraph model of `FaceListGraph`.
|
\tparam FaceListGraph model of `FaceListGraph`.
|
||||||
\tparam PointMap model of `ReadablePropertyMap` whose key type is
|
\tparam PointMap model of `ReadablePropertyMap` whose key type is
|
||||||
|
|
@ -134,6 +142,12 @@ public:
|
||||||
<Face_range, PointMap> Distance_to_plane;
|
<Face_range, PointMap> Distance_to_plane;
|
||||||
typedef Classification::Feature::Elevation
|
typedef Classification::Feature::Elevation
|
||||||
<GeomTraits, Face_range, PointMap> Elevation;
|
<GeomTraits, Face_range, PointMap> Elevation;
|
||||||
|
typedef Classification::Feature::Height_below
|
||||||
|
<GeomTraits, Face_range, PointMap> Height_below;
|
||||||
|
typedef Classification::Feature::Height_above
|
||||||
|
<GeomTraits, Face_range, PointMap> Height_above;
|
||||||
|
typedef Classification::Feature::Vertical_range
|
||||||
|
<GeomTraits, Face_range, PointMap> Vertical_range;
|
||||||
typedef Classification::Feature::Vertical_dispersion
|
typedef Classification::Feature::Vertical_dispersion
|
||||||
<GeomTraits, Face_range, PointMap> Dispersion;
|
<GeomTraits, Face_range, PointMap> Dispersion;
|
||||||
typedef Classification::Feature::Verticality
|
typedef Classification::Feature::Verticality
|
||||||
|
|
@ -212,8 +226,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
float grid_resolution() const { return voxel_size; }
|
float grid_resolution() const { return voxel_size; }
|
||||||
float radius_neighbors() const { return voxel_size * 5; }
|
float radius_neighbors() const { return voxel_size * 3; }
|
||||||
float radius_dtm() const { return voxel_size * 100; }
|
float radius_dtm() const { return voxel_size * 10; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -327,7 +341,10 @@ public:
|
||||||
|
|
||||||
- `CGAL::Classification::Feature::Distance_to_plane`
|
- `CGAL::Classification::Feature::Distance_to_plane`
|
||||||
- `CGAL::Classification::Feature::Elevation`
|
- `CGAL::Classification::Feature::Elevation`
|
||||||
|
- `CGAL::Classification::Feature::Height_above`
|
||||||
|
- `CGAL::Classification::Feature::Height_below`
|
||||||
- `CGAL::Classification::Feature::Vertical_dispersion`
|
- `CGAL::Classification::Feature::Vertical_dispersion`
|
||||||
|
- `CGAL::Classification::Feature::Vertical_range`
|
||||||
|
|
||||||
\param features the feature set where the features are instantiated.
|
\param features the feature set where the features are instantiated.
|
||||||
*/
|
*/
|
||||||
|
|
@ -339,6 +356,12 @@ public:
|
||||||
features.add_with_scale_id<Dispersion> (i, m_range, m_point_map, grid(i), radius_neighbors(i));
|
features.add_with_scale_id<Dispersion> (i, m_range, m_point_map, grid(i), radius_neighbors(i));
|
||||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||||
features.add_with_scale_id<Elevation> (i, m_range, m_point_map, grid(i), radius_dtm(i));
|
features.add_with_scale_id<Elevation> (i, m_range, m_point_map, grid(i), radius_dtm(i));
|
||||||
|
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||||
|
features.add_with_scale_id<Height_below> (i, m_range, m_point_map, grid(i));
|
||||||
|
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||||
|
features.add_with_scale_id<Height_above> (i, m_range, m_point_map, grid(i));
|
||||||
|
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||||
|
features.add_with_scale_id<Vertical_range> (i, m_range, m_point_map, grid(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
||||||
|
|
@ -37,16 +37,18 @@ namespace CGAL {
|
||||||
|
|
||||||
namespace Classification {
|
namespace Classification {
|
||||||
|
|
||||||
/*!
|
namespace OpenCV {
|
||||||
\ingroup PkgClassificationClassifiers
|
|
||||||
|
|
||||||
\brief %Classifier based on the OpenCV version of random forest algorithm.
|
/*!
|
||||||
|
\ingroup PkgClassificationClassifiersOpenCV
|
||||||
|
|
||||||
|
\brief %Classifier based on the OpenCV version of the random forest algorithm.
|
||||||
|
|
||||||
\note This class requires the \ref thirdpartyOpenCV library.
|
\note This class requires the \ref thirdpartyOpenCV library.
|
||||||
|
|
||||||
\cgalModels `CGAL::Classification::Classifier`
|
\cgalModels `CGAL::Classification::Classifier`
|
||||||
*/
|
*/
|
||||||
class OpenCV_random_forest_classifier
|
class Random_forest_classifier
|
||||||
{
|
{
|
||||||
const Label_set& m_labels;
|
const Label_set& m_labels;
|
||||||
const Feature_set& m_features;
|
const Feature_set& m_features;
|
||||||
|
|
@ -68,7 +70,7 @@ public:
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Instantiate the classifier using the sets of `labels` and `features`.
|
\brief Instantiates the classifier using the sets of `labels` and `features`.
|
||||||
|
|
||||||
Parameters documentation is copy-pasted from [the official documentation of OpenCV](http://docs.opencv.org/2.4/modules/ml/doc/random_trees.html). For more details on this method, please refer to it.
|
Parameters documentation is copy-pasted from [the official documentation of OpenCV](http://docs.opencv.org/2.4/modules/ml/doc/random_trees.html). For more details on this method, please refer to it.
|
||||||
|
|
||||||
|
|
@ -80,13 +82,13 @@ public:
|
||||||
\param max_number_of_trees_in_the_forest The maximum number of trees in the forest (surprise, surprise). Typically the more trees you have the better the accuracy. However, the improvement in accuracy generally diminishes and asymptotes pass a certain number of trees. Also to keep in mind, the number of tree increases the prediction time linearly.
|
\param max_number_of_trees_in_the_forest The maximum number of trees in the forest (surprise, surprise). Typically the more trees you have the better the accuracy. However, the improvement in accuracy generally diminishes and asymptotes pass a certain number of trees. Also to keep in mind, the number of tree increases the prediction time linearly.
|
||||||
\param forest_accuracy Sufficient accuracy (OOB error).
|
\param forest_accuracy Sufficient accuracy (OOB error).
|
||||||
*/
|
*/
|
||||||
OpenCV_random_forest_classifier (const Label_set& labels,
|
Random_forest_classifier (const Label_set& labels,
|
||||||
const Feature_set& features,
|
const Feature_set& features,
|
||||||
int max_depth = 20,
|
int max_depth = 20,
|
||||||
int min_sample_count = 5,
|
int min_sample_count = 5,
|
||||||
int max_categories = 15,
|
int max_categories = 15,
|
||||||
int max_number_of_trees_in_the_forest = 100,
|
int max_number_of_trees_in_the_forest = 100,
|
||||||
float forest_accuracy = 0.01f)
|
float forest_accuracy = 0.01f)
|
||||||
: m_labels (labels), m_features (features),
|
: m_labels (labels), m_features (features),
|
||||||
m_max_depth (max_depth), m_min_sample_count (min_sample_count),
|
m_max_depth (max_depth), m_min_sample_count (min_sample_count),
|
||||||
m_max_categories (max_categories),
|
m_max_categories (max_categories),
|
||||||
|
|
@ -98,7 +100,7 @@ public:
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
/// \cond SKIP_IN_MANUAL
|
||||||
~OpenCV_random_forest_classifier ()
|
~Random_forest_classifier ()
|
||||||
{
|
{
|
||||||
#if (CV_MAJOR_VERSION < 3)
|
#if (CV_MAJOR_VERSION < 3)
|
||||||
if (rtree != NULL)
|
if (rtree != NULL)
|
||||||
|
|
@ -298,6 +300,13 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
// Backward compatibility
|
||||||
|
typedef OpenCV::Random_forest_classifier OpenCV_random_forest_classifier;
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CGAL_CLASSIFICATION_OPENCV_RANDOM_FOREST_CLASSIFIER_H
|
#endif // CGAL_CLASSIFICATION_OPENCV_RANDOM_FOREST_CLASSIFIER_H
|
||||||
|
|
@ -35,6 +35,9 @@
|
||||||
#include <CGAL/Classification/Feature/Verticality.h>
|
#include <CGAL/Classification/Feature/Verticality.h>
|
||||||
#include <CGAL/Classification/Feature/Eigenvalue.h>
|
#include <CGAL/Classification/Feature/Eigenvalue.h>
|
||||||
#include <CGAL/Classification/Feature/Color_channel.h>
|
#include <CGAL/Classification/Feature/Color_channel.h>
|
||||||
|
#include <CGAL/Classification/Feature/Height_below.h>
|
||||||
|
#include <CGAL/Classification/Feature/Height_above.h>
|
||||||
|
#include <CGAL/Classification/Feature/Vertical_range.h>
|
||||||
|
|
||||||
// Experimental feature, not used officially
|
// Experimental feature, not used officially
|
||||||
#ifdef CGAL_CLASSIFICATION_USE_GRADIENT_OF_FEATURE
|
#ifdef CGAL_CLASSIFICATION_USE_GRADIENT_OF_FEATURE
|
||||||
|
|
@ -67,9 +70,14 @@ namespace Classification {
|
||||||
\brief Generates a set of generic features for point set
|
\brief Generates a set of generic features for point set
|
||||||
classification.
|
classification.
|
||||||
|
|
||||||
This class takes care of computing all necessary data structures and
|
This class takes care of computing and storing all necessary data
|
||||||
of generating a set of generic features at multiple scales to
|
structures and of generating a set of generic features at multiple
|
||||||
increase the reliability of the classification.
|
scales to increase the reliability of the classification.
|
||||||
|
|
||||||
|
\warning The generated features use data structures that are stored
|
||||||
|
inside the generator. For this reason, the generator should be
|
||||||
|
instantiated _within the same scope_ as the feature set and should
|
||||||
|
not be deleted before the feature set.
|
||||||
|
|
||||||
\tparam GeomTraits model of \cgal Kernel.
|
\tparam GeomTraits model of \cgal Kernel.
|
||||||
\tparam PointRange model of `ConstRange`. Its iterator type is
|
\tparam PointRange model of `ConstRange`. Its iterator type is
|
||||||
|
|
@ -128,6 +136,12 @@ public:
|
||||||
<PointRange, PointMap> Distance_to_plane;
|
<PointRange, PointMap> Distance_to_plane;
|
||||||
typedef Classification::Feature::Elevation
|
typedef Classification::Feature::Elevation
|
||||||
<GeomTraits, PointRange, PointMap> Elevation;
|
<GeomTraits, PointRange, PointMap> Elevation;
|
||||||
|
typedef Classification::Feature::Height_below
|
||||||
|
<GeomTraits, PointRange, PointMap> Height_below;
|
||||||
|
typedef Classification::Feature::Height_above
|
||||||
|
<GeomTraits, PointRange, PointMap> Height_above;
|
||||||
|
typedef Classification::Feature::Vertical_range
|
||||||
|
<GeomTraits, PointRange, PointMap> Vertical_range;
|
||||||
typedef Classification::Feature::Vertical_dispersion
|
typedef Classification::Feature::Vertical_dispersion
|
||||||
<GeomTraits, PointRange, PointMap> Dispersion;
|
<GeomTraits, PointRange, PointMap> Dispersion;
|
||||||
typedef Classification::Feature::Verticality
|
typedef Classification::Feature::Verticality
|
||||||
|
|
@ -166,7 +180,7 @@ private:
|
||||||
neighborhood = new Neighborhood (input, point_map, voxel_size);
|
neighborhood = new Neighborhood (input, point_map, voxel_size);
|
||||||
t.stop();
|
t.stop();
|
||||||
|
|
||||||
if (voxel_size < 0.)
|
if (lower_grid == NULL)
|
||||||
CGAL_CLASSIFICATION_CERR << "Neighborhood computed in " << t.time() << " second(s)" << std::endl;
|
CGAL_CLASSIFICATION_CERR << "Neighborhood computed in " << t.time() << " second(s)" << std::endl;
|
||||||
else
|
else
|
||||||
CGAL_CLASSIFICATION_CERR << "Neighborhood with voxel size " << voxel_size
|
CGAL_CLASSIFICATION_CERR << "Neighborhood with voxel size " << voxel_size
|
||||||
|
|
@ -216,8 +230,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
float grid_resolution() const { return voxel_size; }
|
float grid_resolution() const { return voxel_size; }
|
||||||
float radius_neighbors() const { return voxel_size * 5; }
|
float radius_neighbors() const { return voxel_size * 3; }
|
||||||
float radius_dtm() const { return voxel_size * 100; }
|
float radius_dtm() const { return voxel_size * 10; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -365,7 +379,10 @@ public:
|
||||||
- `CGAL::Classification::Feature::Eigenvalue` with indices 0, 1 and 2
|
- `CGAL::Classification::Feature::Eigenvalue` with indices 0, 1 and 2
|
||||||
- `CGAL::Classification::Feature::Distance_to_plane`
|
- `CGAL::Classification::Feature::Distance_to_plane`
|
||||||
- `CGAL::Classification::Feature::Elevation`
|
- `CGAL::Classification::Feature::Elevation`
|
||||||
|
- `CGAL::Classification::Feature::Height_above`
|
||||||
|
- `CGAL::Classification::Feature::Height_below`
|
||||||
- `CGAL::Classification::Feature::Vertical_dispersion`
|
- `CGAL::Classification::Feature::Vertical_dispersion`
|
||||||
|
- `CGAL::Classification::Feature::Vertical_range`
|
||||||
- The version of `CGAL::Classification::Feature::Verticality` based on eigenvalues
|
- The version of `CGAL::Classification::Feature::Verticality` based on eigenvalues
|
||||||
|
|
||||||
\param features the feature set where the features are instantiated.
|
\param features the feature set where the features are instantiated.
|
||||||
|
|
@ -381,6 +398,12 @@ public:
|
||||||
features.add_with_scale_id<Dispersion> (i, m_input, m_point_map, grid(i), radius_neighbors(i));
|
features.add_with_scale_id<Dispersion> (i, m_input, m_point_map, grid(i), radius_neighbors(i));
|
||||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||||
features.add_with_scale_id<Elevation> (i, m_input, m_point_map, grid(i), radius_dtm(i));
|
features.add_with_scale_id<Elevation> (i, m_input, m_point_map, grid(i), radius_dtm(i));
|
||||||
|
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||||
|
features.add_with_scale_id<Height_below> (i, m_input, m_point_map, grid(i));
|
||||||
|
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||||
|
features.add_with_scale_id<Height_above> (i, m_input, m_point_map, grid(i));
|
||||||
|
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||||
|
features.add_with_scale_id<Vertical_range> (i, m_input, m_point_map, grid(i));
|
||||||
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
for (std::size_t i = 0; i < m_scales.size(); ++ i)
|
||||||
features.add_with_scale_id<Verticality> (i, m_input, eigen(i));
|
features.add_with_scale_id<Verticality> (i, m_input, eigen(i));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief Instantiate the classifier using the sets of `labels` and `features`.
|
\brief Instantiates the classifier using the sets of `labels` and `features`.
|
||||||
|
|
||||||
\note If the label set of the feature set are modified after
|
\note If the label set of the feature set are modified after
|
||||||
instantiating this object (addition of removal of a label and/or of
|
instantiating this object (addition of removal of a label and/or of
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -87,6 +87,53 @@ namespace internal {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Classifier, typename LabelIndexRange, typename ProbabilitiesRanges>
|
||||||
|
class Classify_detailed_output_functor
|
||||||
|
{
|
||||||
|
const Label_set& m_labels;
|
||||||
|
const Classifier& m_classifier;
|
||||||
|
LabelIndexRange& m_out;
|
||||||
|
ProbabilitiesRanges& m_prob;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Classify_detailed_output_functor (const Label_set& labels,
|
||||||
|
const Classifier& classifier,
|
||||||
|
LabelIndexRange& out,
|
||||||
|
ProbabilitiesRanges& prob)
|
||||||
|
: m_labels (labels), m_classifier (classifier), m_out (out), m_prob (prob)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
|
void operator()(const tbb::blocked_range<std::size_t>& r) const
|
||||||
|
{
|
||||||
|
for (std::size_t s = r.begin(); s != r.end(); ++ s)
|
||||||
|
apply(s);
|
||||||
|
}
|
||||||
|
#endif // CGAL_LINKED_WITH_TBB
|
||||||
|
|
||||||
|
inline void apply (std::size_t s) const
|
||||||
|
{
|
||||||
|
std::size_t nb_class_best=0;
|
||||||
|
std::vector<float> values;
|
||||||
|
m_classifier (s, values);
|
||||||
|
|
||||||
|
float val_class_best = 0.f;
|
||||||
|
for(std::size_t k = 0; k < m_labels.size(); ++ k)
|
||||||
|
{
|
||||||
|
m_prob[k][s] = values[k];
|
||||||
|
if(val_class_best < values[k])
|
||||||
|
{
|
||||||
|
val_class_best = values[k];
|
||||||
|
nb_class_best = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_out[s] = static_cast<typename LabelIndexRange::iterator::value_type>(nb_class_best);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Classifier>
|
template <typename Classifier>
|
||||||
class Classify_functor_local_smoothing_preprocessing
|
class Classify_functor_local_smoothing_preprocessing
|
||||||
{
|
{
|
||||||
|
|
@ -323,8 +370,6 @@ namespace internal {
|
||||||
const Classifier& classifier,
|
const Classifier& classifier,
|
||||||
LabelIndexRange& output)
|
LabelIndexRange& output)
|
||||||
{
|
{
|
||||||
output.resize(input.size());
|
|
||||||
|
|
||||||
internal::Classify_functor<Classifier, LabelIndexRange>
|
internal::Classify_functor<Classifier, LabelIndexRange>
|
||||||
f (labels, classifier, output);
|
f (labels, classifier, output);
|
||||||
|
|
||||||
|
|
@ -344,6 +389,39 @@ namespace internal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
// variant to get a detailed output (not documented yet)
|
||||||
|
template <typename ConcurrencyTag,
|
||||||
|
typename ItemRange,
|
||||||
|
typename Classifier,
|
||||||
|
typename LabelIndexRange,
|
||||||
|
typename ProbabilitiesRanges>
|
||||||
|
void classify (const ItemRange& input,
|
||||||
|
const Label_set& labels,
|
||||||
|
const Classifier& classifier,
|
||||||
|
LabelIndexRange& output,
|
||||||
|
ProbabilitiesRanges& probabilities)
|
||||||
|
{
|
||||||
|
internal::Classify_detailed_output_functor<Classifier, LabelIndexRange, ProbabilitiesRanges>
|
||||||
|
f (labels, classifier, output, probabilities);
|
||||||
|
|
||||||
|
#ifndef CGAL_LINKED_WITH_TBB
|
||||||
|
CGAL_static_assertion_msg (!(boost::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
||||||
|
"Parallel_tag is enabled but TBB is unavailable.");
|
||||||
|
#else
|
||||||
|
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
||||||
|
{
|
||||||
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, input.size ()), f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < input.size(); ++ i)
|
||||||
|
f.apply(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgClassificationMain
|
\ingroup PkgClassificationMain
|
||||||
|
|
||||||
|
|
@ -388,8 +466,6 @@ namespace internal {
|
||||||
const NeighborQuery& neighbor_query,
|
const NeighborQuery& neighbor_query,
|
||||||
LabelIndexRange& output)
|
LabelIndexRange& output)
|
||||||
{
|
{
|
||||||
output.resize(input.size());
|
|
||||||
|
|
||||||
std::vector<std::vector<float> > values
|
std::vector<std::vector<float> > values
|
||||||
(labels.size(), std::vector<float> (input.size(), -1.));
|
(labels.size(), std::vector<float> (input.size(), -1.));
|
||||||
internal::Classify_functor_local_smoothing_preprocessing<Classifier>
|
internal::Classify_functor_local_smoothing_preprocessing<Classifier>
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ int main (int, char**)
|
||||||
color_map, echo_map);
|
color_map, echo_map);
|
||||||
|
|
||||||
assert (generator.number_of_scales() == 5);
|
assert (generator.number_of_scales() == 5);
|
||||||
assert (features.size() == 44);
|
assert (features.size() == 59);
|
||||||
|
|
||||||
Label_set labels;
|
Label_set labels;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ typedef Classification::Feature_handle
|
||||||
typedef Classification::Label_set Label_set;
|
typedef Classification::Label_set Label_set;
|
||||||
typedef Classification::Feature_set Feature_set;
|
typedef Classification::Feature_set Feature_set;
|
||||||
|
|
||||||
typedef Classification::ETHZ_random_forest_classifier Classifier;
|
typedef Classification::ETHZ::Random_forest_classifier Classifier;
|
||||||
|
|
||||||
typedef Classification::Planimetric_grid<Kernel, Point_set, Point_map> Planimetric_grid;
|
typedef Classification::Planimetric_grid<Kernel, Point_set, Point_map> Planimetric_grid;
|
||||||
typedef Classification::Point_set_neighborhood<Kernel, Point_set, Point_map> Neighborhood;
|
typedef Classification::Point_set_neighborhood<Kernel, Point_set, Point_map> Neighborhood;
|
||||||
|
|
@ -87,13 +87,18 @@ int main (int, char**)
|
||||||
std::ifstream inf ("output_config.gz", std::ios::binary);
|
std::ifstream inf ("output_config.gz", std::ios::binary);
|
||||||
classifier2.load_configuration(inf);
|
classifier2.load_configuration(inf);
|
||||||
|
|
||||||
std::vector<std::size_t> label_indices;
|
Classifier classifier3 (classifier, features);
|
||||||
std::vector<std::size_t> label_indices_2;
|
|
||||||
|
std::vector<std::size_t> label_indices (points.size());
|
||||||
|
std::vector<std::size_t> label_indices_2 (points.size());
|
||||||
|
std::vector<std::size_t> label_indices_3 (points.size());
|
||||||
|
|
||||||
Classification::classify<CGAL::Sequential_tag> (points, labels, classifier, label_indices);
|
Classification::classify<CGAL::Sequential_tag> (points, labels, classifier, label_indices);
|
||||||
Classification::classify<CGAL::Sequential_tag> (points, labels, classifier2, label_indices_2);
|
Classification::classify<CGAL::Sequential_tag> (points, labels, classifier2, label_indices_2);
|
||||||
|
Classification::classify<CGAL::Sequential_tag> (points, labels, classifier3, label_indices_3);
|
||||||
|
|
||||||
assert (label_indices == label_indices_2);
|
assert (label_indices == label_indices_2);
|
||||||
|
assert (label_indices == label_indices_3);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ int main (int, char**)
|
||||||
Size_t_map echo_map;
|
Size_t_map echo_map;
|
||||||
Color_map color_map;
|
Color_map color_map;
|
||||||
|
|
||||||
map_added = pts.add_normal_map();
|
map_added = pts.add_normal_map().second;
|
||||||
assert (map_added);
|
assert (map_added);
|
||||||
normal_map = pts.normal_map();
|
normal_map = pts.normal_map();
|
||||||
boost::tie (echo_map, map_added) = pts.add_property_map<std::size_t> ("echo");
|
boost::tie (echo_map, map_added) = pts.add_property_map<std::size_t> ("echo");
|
||||||
|
|
@ -91,7 +91,7 @@ int main (int, char**)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert (generator.number_of_scales() == 5);
|
assert (generator.number_of_scales() == 5);
|
||||||
assert (features.size() == 44);
|
assert (features.size() == 59);
|
||||||
|
|
||||||
Label_set labels;
|
Label_set labels;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -228,7 +228,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Simplex_iterator(const Simplex_iterator& it) : Base_iterator(it) {}
|
|
||||||
|
|
||||||
Simplex_iterator& operator++()
|
Simplex_iterator& operator++()
|
||||||
/* here we get a new candidate from the stack
|
/* here we get a new candidate from the stack
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ public:
|
||||||
RC_vertex_d(Simplex_handle s, int i, const Point_d& p) :
|
RC_vertex_d(Simplex_handle s, int i, const Point_d& p) :
|
||||||
s_(s), index_(i), point_(p) {}
|
s_(s), index_(i), point_(p) {}
|
||||||
RC_vertex_d(const Point_d& p) : point_(p), pp(NULL) {}
|
RC_vertex_d(const Point_d& p) : point_(p), pp(NULL) {}
|
||||||
RC_vertex_d() : s_(), index_(-42), pp(NULL) {}
|
RC_vertex_d() : s_(), pp(NULL) {}
|
||||||
// beware that ass_point was initialized here by nil_point
|
// beware that ass_point was initialized here by nil_point
|
||||||
~RC_vertex_d() {}
|
~RC_vertex_d() {}
|
||||||
|
|
||||||
|
|
@ -514,9 +514,7 @@ Vertex_handle new_vertex()
|
||||||
is the point |Regular_complex_d::nil_point| which is a static
|
is the point |Regular_complex_d::nil_point| which is a static
|
||||||
member of class |Regular_complex_d.|}*/
|
member of class |Regular_complex_d.|}*/
|
||||||
{
|
{
|
||||||
Vertex v(nil_point);
|
return vertices_.emplace(nil_point);
|
||||||
Vertex_handle h = vertices_.insert(v);
|
|
||||||
return h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vertex_handle new_vertex(const Point_d& p)
|
Vertex_handle new_vertex(const Point_d& p)
|
||||||
|
|
@ -524,9 +522,7 @@ Vertex_handle new_vertex(const Point_d& p)
|
||||||
has |p| as the associated point, but is has no associated
|
has |p| as the associated point, but is has no associated
|
||||||
simplex nor index yet.}*/
|
simplex nor index yet.}*/
|
||||||
{
|
{
|
||||||
Vertex v(p);
|
return vertices_.emplace(p);
|
||||||
Vertex_handle h = vertices_.insert(v);
|
|
||||||
return h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void associate_vertex_with_simplex(Simplex_handle s, int i, Vertex_handle v)
|
void associate_vertex_with_simplex(Simplex_handle s, int i, Vertex_handle v)
|
||||||
|
|
|
||||||
|
|
@ -593,6 +593,22 @@ In \cgal, \sc{OpenCV} is used by the \ref PkgClassificationRef package.
|
||||||
|
|
||||||
The \sc{OpenCV} web site is <A HREF="http://opencv.org/">`http://opencv.org/`</A>.
|
The \sc{OpenCV} web site is <A HREF="http://opencv.org/">`http://opencv.org/`</A>.
|
||||||
|
|
||||||
|
\subsection thirdpartyTensorFlow TensorFlow
|
||||||
|
|
||||||
|
\sc{TensorFlow} is a library designed for machine learning and deep learning.
|
||||||
|
|
||||||
|
In \cgal, the C++ API of \sc{TensorFlow} is used by the \ref
|
||||||
|
PkgClassificationRef package for neural network. The C++ API can be
|
||||||
|
compiled using CMake: it is distributed as part of the official
|
||||||
|
package and is located in `tensorflow/contrib/cmake`. Be sure to
|
||||||
|
enable and compile the following targets:
|
||||||
|
|
||||||
|
- `tensorflow_BUILD_ALL_KERNELS`
|
||||||
|
- `tensorflow_BUILD_PYTHON_BINDINGS`
|
||||||
|
- `tensorflow_BUILD_SHARED_LIB`.
|
||||||
|
|
||||||
|
The \sc{TensorFlow} web site is <A HREF="https://www.tensorflow.org/">`https://www.tensorflow.org/`</A>.
|
||||||
|
|
||||||
\subsection thirdpartyMETIS METIS
|
\subsection thirdpartyMETIS METIS
|
||||||
|
|
||||||
\sc{METIS} is a library developed by the <A HREF="http://glaros.dtc.umn.edu/gkhome/">Karypis Lab</A>
|
\sc{METIS} is a library developed by the <A HREF="http://glaros.dtc.umn.edu/gkhome/">Karypis Lab</A>
|
||||||
|
|
|
||||||
|
|
@ -98,3 +98,4 @@ Surface_mesh_shortest_path
|
||||||
Polygon_mesh_processing
|
Polygon_mesh_processing
|
||||||
Set_movable_separability_2
|
Set_movable_separability_2
|
||||||
Classification
|
Classification
|
||||||
|
Surface_mesh_approximation
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,7 @@ h1 {
|
||||||
\package_listing{Surface_mesh_parameterization}
|
\package_listing{Surface_mesh_parameterization}
|
||||||
\package_listing{Surface_mesh_shortest_path}
|
\package_listing{Surface_mesh_shortest_path}
|
||||||
\package_listing{Surface_mesh_skeletonization}
|
\package_listing{Surface_mesh_skeletonization}
|
||||||
|
\package_listing{Surface_mesh_approximation}
|
||||||
\package_listing{Ridges_3}
|
\package_listing{Ridges_3}
|
||||||
\package_listing{Jet_fitting_3}
|
\package_listing{Jet_fitting_3}
|
||||||
\package_listing{Point_set_3}
|
\package_listing{Point_set_3}
|
||||||
|
|
|
||||||
|
|
@ -299,6 +299,17 @@ Boissonnat}
|
||||||
,update = "98.01 schirra"
|
,update = "98.01 schirra"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@inproceedings{cgal:cad-vsa-04,
|
||||||
|
title={Variational shape approximation},
|
||||||
|
author={Cohen-Steiner, David and Alliez, Pierre and Desbrun, Mathieu},
|
||||||
|
booktitle={ACM Transactions on Graphics (TOG)},
|
||||||
|
volume={23},
|
||||||
|
number={3},
|
||||||
|
pages={905--914},
|
||||||
|
year={2004},
|
||||||
|
organization={ACM}
|
||||||
|
}
|
||||||
|
|
||||||
@inproceedings{cgal::c-mssbo-04,
|
@inproceedings{cgal::c-mssbo-04,
|
||||||
author={Chen, L.},
|
author={Chen, L.},
|
||||||
title={{Mesh Smoothing Schemes based on Optimal Delaunay Triangulations}},
|
title={{Mesh Smoothing Schemes based on Optimal Delaunay Triangulations}},
|
||||||
|
|
@ -1130,6 +1141,17 @@ Teillaud"
|
||||||
,pages = "307--320"
|
,pages = "307--320"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@article{ cgal:l-lsqp-82,
|
||||||
|
title={Least squares quantization in PCM},
|
||||||
|
author={Lloyd, Stuart},
|
||||||
|
journal={IEEE transactions on information theory},
|
||||||
|
volume={28},
|
||||||
|
number={2},
|
||||||
|
pages={129--137},
|
||||||
|
year={1982},
|
||||||
|
publisher={IEEE}
|
||||||
|
}
|
||||||
|
|
||||||
@book{ cgal:l-mrfmi-09,
|
@book{ cgal:l-mrfmi-09,
|
||||||
author = {Li, Stan Z.},
|
author = {Li, Stan Z.},
|
||||||
title = {Markov Random %Field Modeling in Image Analysis},
|
title = {Markov Random %Field Modeling in Image Analysis},
|
||||||
|
|
@ -1361,6 +1383,17 @@ Voronoi diagram"
|
||||||
,update = "97.04 kettner"
|
,update = "97.04 kettner"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@article{cgal:l-lsqp-82,
|
||||||
|
title={Least squares quantization in PCM},
|
||||||
|
author={Lloyd, Stuart},
|
||||||
|
journal={IEEE transactions on information theory},
|
||||||
|
volume={28},
|
||||||
|
number={2},
|
||||||
|
pages={129--137},
|
||||||
|
year={1982},
|
||||||
|
publisher={IEEE}
|
||||||
|
}
|
||||||
|
|
||||||
@InProceedings{ cgal:lprm-lscm-02,
|
@InProceedings{ cgal:lprm-lscm-02,
|
||||||
author = {Bruno L{\'e}vy and Sylvain Petitjean and Nicolas Ray
|
author = {Bruno L{\'e}vy and Sylvain Petitjean and Nicolas Ray
|
||||||
and J{\'e}rome Maillot},
|
and J{\'e}rome Maillot},
|
||||||
|
|
@ -2181,6 +2214,16 @@ location = {Salt Lake City, Utah, USA}
|
||||||
Geodesy and Photogrammetry)},
|
Geodesy and Photogrammetry)},
|
||||||
url = {https://www.prs.igp.ethz.ch/research/Source_code_and_datasets.html},
|
url = {https://www.prs.igp.ethz.ch/research/Source_code_and_datasets.html},
|
||||||
year = 2014
|
year = 2014
|
||||||
|
|
||||||
|
@inproceedings{ cgal:wk-srhvs-05,
|
||||||
|
title={Structure recovery via hybrid variational surface approximation},
|
||||||
|
author={Wu, Jianhua and Kobbelt, Leif},
|
||||||
|
booktitle={Computer Graphics Forum},
|
||||||
|
volume={24},
|
||||||
|
number={3},
|
||||||
|
pages={277--284},
|
||||||
|
year={2005},
|
||||||
|
organization={Wiley Online Library}
|
||||||
}
|
}
|
||||||
|
|
||||||
@book{cgal:ww-smgd-02
|
@book{cgal:ww-smgd-02
|
||||||
|
|
@ -2218,6 +2261,17 @@ location = {Salt Lake City, Utah, USA}
|
||||||
address = {New York, NY, USA},
|
address = {New York, NY, USA},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@article{cgal:ywly-vmsqs-12,
|
||||||
|
title={Variational mesh segmentation via quadric surface fitting},
|
||||||
|
author={Yan, Dong-Ming and Wang, Wenping and Liu, Yang and Yang, Zhouwang},
|
||||||
|
journal={Computer-Aided Design},
|
||||||
|
volume={44},
|
||||||
|
number={11},
|
||||||
|
pages={1072--1082},
|
||||||
|
year={2012},
|
||||||
|
publisher={Elsevier}
|
||||||
|
}
|
||||||
|
|
||||||
@article{ cgal:ze-fsbi-02
|
@article{ cgal:ze-fsbi-02
|
||||||
,author = "Afra Zomorodian and Herbert Edelsbrunner"
|
,author = "Afra Zomorodian and Herbert Edelsbrunner"
|
||||||
,title = "Fast Software for Box Intersection"
|
,title = "Fast Software for Box Intersection"
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,10 @@ $(document).ready(function() {
|
||||||
// override gotoNode from navtree.js
|
// override gotoNode from navtree.js
|
||||||
gotoNode = function (o,subIndex,root,hash,relpath) {
|
gotoNode = function (o,subIndex,root,hash,relpath) {
|
||||||
var nti = navTreeSubIndices[subIndex][root+hash];
|
var nti = navTreeSubIndices[subIndex][root+hash];
|
||||||
|
if (!nti)
|
||||||
|
{
|
||||||
|
nti = navTreeSubIndices[subIndex][root];
|
||||||
|
}
|
||||||
if(nti && (nti[0] === 1 && nti[0])) {
|
if(nti && (nti[0] === 1 && nti[0])) {
|
||||||
nti.splice(1, 1);
|
nti.splice(1, 1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,10 @@ $(document).ready(function() {
|
||||||
// override gotoNode from navtree.js
|
// override gotoNode from navtree.js
|
||||||
gotoNode = function (o,subIndex,root,hash,relpath) {
|
gotoNode = function (o,subIndex,root,hash,relpath) {
|
||||||
var nti = navTreeSubIndices[subIndex][root+hash];
|
var nti = navTreeSubIndices[subIndex][root+hash];
|
||||||
|
if (!nti)
|
||||||
|
{
|
||||||
|
nti = navTreeSubIndices[subIndex][root];
|
||||||
|
}
|
||||||
if(nti && (nti[0] === 1 && nti[0])) {
|
if(nti && (nti[0] === 1 && nti[0])) {
|
||||||
nti.splice(1, 1);
|
nti.splice(1, 1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include <CGAL/Random.h>
|
#include <CGAL/Random.h>
|
||||||
#include <CGAL/point_generators_2.h>
|
#include <CGAL/point_generators_2.h>
|
||||||
#include <CGAL/Timer.h>
|
#include <CGAL/Timer.h>
|
||||||
|
#include <CGAL/IO/write_vtu.h>
|
||||||
|
|
||||||
// Qt headers
|
// Qt headers
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
|
@ -84,12 +85,12 @@ discoverInfiniteComponent(const CDT & ct)
|
||||||
Face_handle fh = queue.front();
|
Face_handle fh = queue.front();
|
||||||
queue.pop_front();
|
queue.pop_front();
|
||||||
fh->set_in_domain(false);
|
fh->set_in_domain(false);
|
||||||
|
|
||||||
for(int i = 0; i < 3; i++)
|
for(int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
Face_handle fi = fh->neighbor(i);
|
Face_handle fi = fh->neighbor(i);
|
||||||
if(fi->is_in_domain()
|
if(fi->is_in_domain()
|
||||||
&& !ct.is_constrained(CDT::Edge(fh,i)))
|
&& !ct.is_constrained(CDT::Edge(fh,i)))
|
||||||
queue.push_back(fi);
|
queue.push_back(fi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -269,7 +270,7 @@ MainWindow::MainWindow()
|
||||||
dgi->setFacesInDomainBrush(facesColor);
|
dgi->setFacesInDomainBrush(facesColor);
|
||||||
|
|
||||||
QObject::connect(this, SIGNAL(changed()),
|
QObject::connect(this, SIGNAL(changed()),
|
||||||
dgi, SLOT(modelChanged()));
|
dgi, SLOT(modelChanged()));
|
||||||
dgi->setVerticesPen(
|
dgi->setVerticesPen(
|
||||||
QPen(Qt::red, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
QPen(Qt::red, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||||
dgi->setVoronoiPen(
|
dgi->setVoronoiPen(
|
||||||
|
|
@ -285,8 +286,8 @@ MainWindow::MainWindow()
|
||||||
// the signal/slot mechanism
|
// the signal/slot mechanism
|
||||||
pi = new CGAL::Qt::GraphicsViewPolylineInput<K>(this, &scene, 0, true); // inputs polylines which are not closed
|
pi = new CGAL::Qt::GraphicsViewPolylineInput<K>(this, &scene, 0, true); // inputs polylines which are not closed
|
||||||
QObject::connect(pi, SIGNAL(generate(CGAL::Object)),
|
QObject::connect(pi, SIGNAL(generate(CGAL::Object)),
|
||||||
this, SLOT(processInput(CGAL::Object)));
|
this, SLOT(processInput(CGAL::Object)));
|
||||||
|
|
||||||
tcc = new CGAL::Qt::TriangulationCircumcircle<CDT>(&scene, &cdt, this);
|
tcc = new CGAL::Qt::TriangulationCircumcircle<CDT>(&scene, &cdt, this);
|
||||||
tcc->setPen(QPen(Qt::red, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
tcc->setPen(QPen(Qt::red, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||||
|
|
||||||
|
|
@ -298,8 +299,8 @@ MainWindow::MainWindow()
|
||||||
// Manual handling of actions
|
// Manual handling of actions
|
||||||
//
|
//
|
||||||
QObject::connect(this->actionQuit, SIGNAL(triggered()),
|
QObject::connect(this->actionQuit, SIGNAL(triggered()),
|
||||||
this, SLOT(close()));
|
this, SLOT(close()));
|
||||||
|
|
||||||
// We put mutually exclusive actions in an QActionGroup
|
// We put mutually exclusive actions in an QActionGroup
|
||||||
QActionGroup* ag = new QActionGroup(this);
|
QActionGroup* ag = new QActionGroup(this);
|
||||||
ag->addAction(this->actionInsertPolyline);
|
ag->addAction(this->actionInsertPolyline);
|
||||||
|
|
@ -338,7 +339,7 @@ MainWindow::MainWindow()
|
||||||
|
|
||||||
this->addRecentFiles(this->menuFile, this->actionQuit);
|
this->addRecentFiles(this->menuFile, this->actionQuit);
|
||||||
connect(this, SIGNAL(openRecentFile(QString)),
|
connect(this, SIGNAL(openRecentFile(QString)),
|
||||||
this, SLOT(open(QString)));
|
this, SLOT(open(QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -534,11 +535,11 @@ void
|
||||||
MainWindow::on_actionLoadConstraints_triggered()
|
MainWindow::on_actionLoadConstraints_triggered()
|
||||||
{
|
{
|
||||||
QString fileName = QFileDialog::getOpenFileName(this,
|
QString fileName = QFileDialog::getOpenFileName(this,
|
||||||
tr("Open Constraint File"),
|
tr("Open Constraint File"),
|
||||||
".",
|
".",
|
||||||
tr("Edge files (*.edg);;"
|
tr("Edge files (*.edg);;"
|
||||||
"Plg files (*.plg);;"
|
"Plg files (*.plg);;"
|
||||||
"Poly files (*.poly)"));
|
"Poly files (*.poly)"));
|
||||||
open(fileName);
|
open(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -655,12 +656,13 @@ void
|
||||||
MainWindow::on_actionSaveConstraints_triggered()
|
MainWindow::on_actionSaveConstraints_triggered()
|
||||||
{
|
{
|
||||||
QString fileName = QFileDialog::getSaveFileName(this,
|
QString fileName = QFileDialog::getSaveFileName(this,
|
||||||
tr("Save Constraints"),
|
tr("Save Constraints"),
|
||||||
".",
|
".",
|
||||||
tr("Poly files (*.poly)\n"
|
tr("Poly files (*.poly)\n"
|
||||||
"Edge files (*.edg)"));
|
"Edge files (*.edg)\n"
|
||||||
|
"VTU files (*.vtu)"));
|
||||||
if(! fileName.isEmpty()){
|
if(! fileName.isEmpty()){
|
||||||
saveConstraints(fileName);
|
saveConstraints(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -669,7 +671,13 @@ void
|
||||||
MainWindow::saveConstraints(QString fileName)
|
MainWindow::saveConstraints(QString fileName)
|
||||||
{
|
{
|
||||||
std::ofstream output(qPrintable(fileName));
|
std::ofstream output(qPrintable(fileName));
|
||||||
if (output) output << cdt;
|
|
||||||
|
if(!fileName.endsWith("vtu") && output)
|
||||||
|
output << cdt;
|
||||||
|
else if (output)
|
||||||
|
{
|
||||||
|
CGAL::write_vtu(output, cdt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -796,15 +804,15 @@ MainWindow::on_actionInsertRandomPoints_triggered()
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
|
||||||
const int number_of_points =
|
const int number_of_points =
|
||||||
QInputDialog::getInt(this,
|
QInputDialog::getInt(this,
|
||||||
tr("Number of random points"),
|
tr("Number of random points"),
|
||||||
tr("Enter number of random points"),
|
tr("Enter number of random points"),
|
||||||
100,
|
100,
|
||||||
0,
|
0,
|
||||||
(std::numeric_limits<int>::max)(),
|
(std::numeric_limits<int>::max)(),
|
||||||
1,
|
1,
|
||||||
&ok);
|
&ok);
|
||||||
|
|
||||||
if(!ok) {
|
if(!ok) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,13 @@
|
||||||
|
|
||||||
#ifdef CGAL_USE_BASIC_VIEWER
|
#ifdef CGAL_USE_BASIC_VIEWER
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#if __GNUC__ >= 9
|
||||||
|
# pragma GCC diagnostic push
|
||||||
|
# pragma GCC diagnostic ignored "-Wdeprecated-copy"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
|
||||||
|
|
@ -37,6 +44,12 @@
|
||||||
#include <QGLBuffer>
|
#include <QGLBuffer>
|
||||||
#include <QOpenGLShaderProgram>
|
#include <QOpenGLShaderProgram>
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#if __GNUC__ >= 9
|
||||||
|
# pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,13 +115,14 @@ and can hence be used in place of Vec. See also operator const qreal*() .*/
|
||||||
// Vec(const Vec& v) : x(v.x), y(v.y), z(v.z) {}
|
// Vec(const Vec& v) : x(v.x), y(v.y), z(v.z) {}
|
||||||
|
|
||||||
/*! Equal operator. */
|
/*! Equal operator. */
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
Vec &operator=(const Vec &v) {
|
Vec &operator=(const Vec &v) {
|
||||||
x = v.x;
|
x = v.x;
|
||||||
y = v.y;
|
y = v.y;
|
||||||
z = v.z;
|
z = v.z;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/*! Set the current value. May be faster than using operator=() with a
|
/*! Set the current value. May be faster than using operator=() with a
|
||||||
* temporary Vec(x,y,z). */
|
* temporary Vec(x,y,z). */
|
||||||
void setValue(qreal X, qreal Y, qreal Z) {
|
void setValue(qreal X, qreal Y, qreal Z) {
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,11 @@ public:
|
||||||
HalfedgeDS_in_place_list_vertex() {}
|
HalfedgeDS_in_place_list_vertex() {}
|
||||||
HalfedgeDS_in_place_list_vertex( const VertexBase& v) // down cast
|
HalfedgeDS_in_place_list_vertex( const VertexBase& v) // down cast
|
||||||
: VertexBase(v) {}
|
: VertexBase(v) {}
|
||||||
|
|
||||||
|
#ifndef CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS
|
||||||
|
HalfedgeDS_in_place_list_vertex(const HalfedgeDS_in_place_list_vertex&)=default;
|
||||||
|
#endif
|
||||||
|
|
||||||
Self& operator=( const Self& v) {
|
Self& operator=( const Self& v) {
|
||||||
// This self written assignment avoids that assigning vertices will
|
// This self written assignment avoids that assigning vertices will
|
||||||
// overwrite the list linking of the target vertex.
|
// overwrite the list linking of the target vertex.
|
||||||
|
|
@ -66,6 +71,11 @@ public:
|
||||||
HalfedgeDS_in_place_list_halfedge() {} // down cast
|
HalfedgeDS_in_place_list_halfedge() {} // down cast
|
||||||
HalfedgeDS_in_place_list_halfedge( const HalfedgeBase& h)
|
HalfedgeDS_in_place_list_halfedge( const HalfedgeBase& h)
|
||||||
: HalfedgeBase(h) {}
|
: HalfedgeBase(h) {}
|
||||||
|
|
||||||
|
#ifndef CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS
|
||||||
|
HalfedgeDS_in_place_list_halfedge(const HalfedgeDS_in_place_list_halfedge&)=default;
|
||||||
|
#endif
|
||||||
|
|
||||||
Self& operator=( const Self& h) {
|
Self& operator=( const Self& h) {
|
||||||
// This self written assignment avoids that assigning halfedges will
|
// This self written assignment avoids that assigning halfedges will
|
||||||
// overwrite the list linking of the target halfedge.
|
// overwrite the list linking of the target halfedge.
|
||||||
|
|
@ -84,6 +94,11 @@ public:
|
||||||
typedef typename FaceBase::Face_const_handle Face_const_handle;
|
typedef typename FaceBase::Face_const_handle Face_const_handle;
|
||||||
HalfedgeDS_in_place_list_face() {} // down cast
|
HalfedgeDS_in_place_list_face() {} // down cast
|
||||||
HalfedgeDS_in_place_list_face( const FaceBase& f) : FaceBase(f) {}
|
HalfedgeDS_in_place_list_face( const FaceBase& f) : FaceBase(f) {}
|
||||||
|
|
||||||
|
#ifndef CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS
|
||||||
|
HalfedgeDS_in_place_list_face(const HalfedgeDS_in_place_list_face&)=default;
|
||||||
|
#endif
|
||||||
|
|
||||||
Self& operator=( const Self& f) {
|
Self& operator=( const Self& f) {
|
||||||
// This self written assignment avoids that assigning faces will
|
// This self written assignment avoids that assigning faces will
|
||||||
// overwrite the list linking of the target face.
|
// overwrite the list linking of the target face.
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue