diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp index 16b21fed4c9..12bc56e9fdc 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp @@ -1,201 +1,201 @@ -#include "config.h" -#include "Scene_points_with_normal_item.h" -#include "Polyhedron_demo_plugin_helper.h" -#include "Polyhedron_demo_plugin_interface.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "ui_Polyhedron_demo_normal_estimation_plugin.h" - -class Polyhedron_demo_normal_estimation_plugin : - public QObject, - public Polyhedron_demo_plugin_helper -{ - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_plugin_interface) - QAction* actionNormalEstimation; - QAction* actionNormalInversion; - -public: - void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { - - actionNormalEstimation = new QAction(tr("Normal estimation of point set"), mainWindow); - actionNormalEstimation->setObjectName("actionNormalEstimation"); - - actionNormalInversion = new QAction(tr("Inverse normal orientation"), mainWindow); - actionNormalInversion->setObjectName("actionNormalInversion"); - - Polyhedron_demo_plugin_helper::init(mainWindow, scene_interface); - } - - QList actions() const { - return QList() << actionNormalEstimation << actionNormalInversion; - } - - bool applicable() const { - return qobject_cast(scene->item(scene->mainSelectionIndex())); - } - -public slots: - void on_actionNormalEstimation_triggered(); - void on_actionNormalInversion_triggered(); - -}; // end PS_demo_smoothing_plugin - -class Point_set_demo_normal_estimation_dialog : public QDialog, private Ui::NormalEstimationDialog -{ - Q_OBJECT - public: - Point_set_demo_normal_estimation_dialog(QWidget* /*parent*/ = 0) - { - setupUi(this); - } - - QString directionMethod() const { return m_inputDirection->currentText(); } - int directionNbNeighbors() const { return m_inputNbNeighborsDirection->value(); } - - QString orientationMethod() const { return m_inputOrientation->currentText(); } - int orientationNbNeighbors() const { return m_inputNbNeighborsOrientation->value(); } -}; - - -void Polyhedron_demo_normal_estimation_plugin::on_actionNormalInversion_triggered() -{ - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Scene_points_with_normal_item* item = - qobject_cast(scene->item(index)); - - if(item) - { - // Gets point set - Point_set* points = item->point_set(); - if(points == NULL) - return; - - for(Point_set::iterator it = points->begin(); it != points->end(); ++it){ - it->normal() = -1 * it->normal(); - } - } -} - -void Polyhedron_demo_normal_estimation_plugin::on_actionNormalEstimation_triggered() -{ - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Scene_points_with_normal_item* item = - qobject_cast(scene->item(index)); - - if(item) - { - // Gets point set - Point_set* points = item->point_set(); - if(points == NULL) - return; - - // Gets options - Point_set_demo_normal_estimation_dialog dialog; - if(!dialog.exec()) - return; - - QApplication::setOverrideCursor(Qt::WaitCursor); - - // First point to delete - Point_set::iterator first_unoriented_point = points->end(); - - //*************************************** - // normal estimation - //*************************************** - - if (dialog.directionMethod() == "plane") - { - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Estimates normal direction by PCA (k=" << dialog.directionNbNeighbors() <<")...\n"; - - // Estimates normals direction. - CGAL::pca_estimate_normals(points->begin(), points->end(), - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), - dialog.directionNbNeighbors()); - - // Mark all normals as unoriented - first_unoriented_point = points->begin(); - - std::size_t memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "Estimates normal direction: " << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated" - << std::endl; - } - else if (dialog.directionMethod() == "quadric") - { - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Estimates normal direction by Jet Fitting (k=" << dialog.directionNbNeighbors() <<")...\n"; - - // Estimates normals direction. - CGAL::jet_estimate_normals(points->begin(), points->end(), - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), - dialog.directionNbNeighbors()); - - // Mark all normals as unoriented - first_unoriented_point = points->begin(); - - std::size_t memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "Estimates normal direction: " << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated" - << std::endl; - } - - //*************************************** - // normal orientation - //*************************************** - - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Orient normals with a Minimum Spanning Tree (k=" << dialog.orientationNbNeighbors() << ")...\n"; - - // Tries to orient normals - first_unoriented_point = - CGAL::mst_orient_normals(points->begin(), points->end(), - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), - dialog.orientationNbNeighbors()); - - std::size_t nb_unoriented_normals = std::distance(first_unoriented_point, points->end()); - std::size_t memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "Orient normals: " << nb_unoriented_normals << " point(s) with an unoriented normal are selected (" - << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated)" - << std::endl; - - // Selects points with an unoriented normal - points->select(points->begin(), points->end(), false); - points->select(first_unoriented_point, points->end(), true); - - // Updates scene - scene->itemChanged(index); - - QApplication::restoreOverrideCursor(); - - // Warns user - if (nb_unoriented_normals > 0) - { - QMessageBox::information(NULL, - tr("Points with an unoriented normal"), - tr("%1 point(s) with an unoriented normal are selected.\nPlease orient them or remove them before running Poisson reconstruction.") - .arg(nb_unoriented_normals)); - } - } -} - -Q_EXPORT_PLUGIN2(Polyhedron_demo_normal_estimation_plugin, Polyhedron_demo_normal_estimation_plugin) - -#include "Polyhedron_demo_normal_estimation_plugin.moc" +#include "config.h" +#include "Scene_points_with_normal_item.h" +#include "Polyhedron_demo_plugin_helper.h" +#include "Polyhedron_demo_plugin_interface.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ui_Polyhedron_demo_normal_estimation_plugin.h" + +class Polyhedron_demo_normal_estimation_plugin : + public QObject, + public Polyhedron_demo_plugin_helper +{ + Q_OBJECT + Q_INTERFACES(Polyhedron_demo_plugin_interface) + QAction* actionNormalEstimation; + QAction* actionNormalInversion; + +public: + void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { + + actionNormalEstimation = new QAction(tr("Normal estimation of point set"), mainWindow); + actionNormalEstimation->setObjectName("actionNormalEstimation"); + + actionNormalInversion = new QAction(tr("Inverse normal orientation"), mainWindow); + actionNormalInversion->setObjectName("actionNormalInversion"); + + Polyhedron_demo_plugin_helper::init(mainWindow, scene_interface); + } + + QList actions() const { + return QList() << actionNormalEstimation << actionNormalInversion; + } + + bool applicable() const { + return qobject_cast(scene->item(scene->mainSelectionIndex())); + } + +public slots: + void on_actionNormalEstimation_triggered(); + void on_actionNormalInversion_triggered(); + +}; // end PS_demo_smoothing_plugin + +class Point_set_demo_normal_estimation_dialog : public QDialog, private Ui::NormalEstimationDialog +{ + Q_OBJECT + public: + Point_set_demo_normal_estimation_dialog(QWidget* /*parent*/ = 0) + { + setupUi(this); + } + + QString directionMethod() const { return m_inputDirection->currentText(); } + int directionNbNeighbors() const { return m_inputNbNeighborsDirection->value(); } + + QString orientationMethod() const { return m_inputOrientation->currentText(); } + int orientationNbNeighbors() const { return m_inputNbNeighborsOrientation->value(); } +}; + + +void Polyhedron_demo_normal_estimation_plugin::on_actionNormalInversion_triggered() +{ + const Scene_interface::Item_id index = scene->mainSelectionIndex(); + + Scene_points_with_normal_item* item = + qobject_cast(scene->item(index)); + + if(item) + { + // Gets point set + Point_set* points = item->point_set(); + if(points == NULL) + return; + + for(Point_set::iterator it = points->begin(); it != points->end(); ++it){ + it->normal() = -1 * it->normal(); + } + } +} + +void Polyhedron_demo_normal_estimation_plugin::on_actionNormalEstimation_triggered() +{ + const Scene_interface::Item_id index = scene->mainSelectionIndex(); + + Scene_points_with_normal_item* item = + qobject_cast(scene->item(index)); + + if(item) + { + // Gets point set + Point_set* points = item->point_set(); + if(points == NULL) + return; + + // Gets options + Point_set_demo_normal_estimation_dialog dialog; + if(!dialog.exec()) + return; + + QApplication::setOverrideCursor(Qt::WaitCursor); + + // First point to delete + Point_set::iterator first_unoriented_point = points->end(); + + //*************************************** + // normal estimation + //*************************************** + + if (dialog.directionMethod() == "plane") + { + CGAL::Timer task_timer; task_timer.start(); + std::cerr << "Estimates normal direction by PCA (k=" << dialog.directionNbNeighbors() <<")...\n"; + + // Estimates normals direction. + CGAL::pca_estimate_normals(points->begin(), points->end(), + CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), + dialog.directionNbNeighbors()); + + // Mark all normals as unoriented + first_unoriented_point = points->begin(); + + std::size_t memory = CGAL::Memory_sizer().virtual_size(); + std::cerr << "Estimates normal direction: " << task_timer.time() << " seconds, " + << (memory>>20) << " Mb allocated" + << std::endl; + } + else if (dialog.directionMethod() == "quadric") + { + CGAL::Timer task_timer; task_timer.start(); + std::cerr << "Estimates normal direction by Jet Fitting (k=" << dialog.directionNbNeighbors() <<")...\n"; + + // Estimates normals direction. + CGAL::jet_estimate_normals(points->begin(), points->end(), + CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), + dialog.directionNbNeighbors()); + + // Mark all normals as unoriented + first_unoriented_point = points->begin(); + + std::size_t memory = CGAL::Memory_sizer().virtual_size(); + std::cerr << "Estimates normal direction: " << task_timer.time() << " seconds, " + << (memory>>20) << " Mb allocated" + << std::endl; + } + + //*************************************** + // normal orientation + //*************************************** + + CGAL::Timer task_timer; task_timer.start(); + std::cerr << "Orient normals with a Minimum Spanning Tree (k=" << dialog.orientationNbNeighbors() << ")...\n"; + + // Tries to orient normals + first_unoriented_point = + CGAL::mst_orient_normals(points->begin(), points->end(), + CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), + dialog.orientationNbNeighbors()); + + std::size_t nb_unoriented_normals = std::distance(first_unoriented_point, points->end()); + std::size_t memory = CGAL::Memory_sizer().virtual_size(); + std::cerr << "Orient normals: " << nb_unoriented_normals << " point(s) with an unoriented normal are selected (" + << task_timer.time() << " seconds, " + << (memory>>20) << " Mb allocated)" + << std::endl; + + // Selects points with an unoriented normal + points->select(points->begin(), points->end(), false); + points->select(first_unoriented_point, points->end(), true); + + // Updates scene + scene->itemChanged(index); + + QApplication::restoreOverrideCursor(); + + // Warns user + if (nb_unoriented_normals > 0) + { + QMessageBox::information(NULL, + tr("Points with an unoriented normal"), + tr("%1 point(s) with an unoriented normal are selected.\nPlease orient them or remove them before running Poisson reconstruction.") + .arg(nb_unoriented_normals)); + } + } +} + +Q_EXPORT_PLUGIN2(Polyhedron_demo_normal_estimation_plugin, Polyhedron_demo_normal_estimation_plugin) + +#include "Polyhedron_demo_normal_estimation_plugin.moc" diff --git a/Scripts/developer_scripts/create_cgal_test b/Scripts/developer_scripts/create_cgal_test index d3fa453f1dc..09e6b951bec 100755 --- a/Scripts/developer_scripts/create_cgal_test +++ b/Scripts/developer_scripts/create_cgal_test @@ -1,188 +1,188 @@ -#! /bin/sh -# -# ============================================================================= -# $URL: svn+ssh://fcacciola@scm.gforge.inria.fr/svn/cgal/trunk/Scripts/developer_scripts/create_cgal_test $ -# $Id: create_cgal_test 36975 2007-03-09 22:52:40Z spion $ -# -# author(s) : Wieger Wesselink, Geert-Jan Giezeman -# -# coordinator : Utrecht University -# ============================================================================= -# -# This script creates a cgal_test_with_cmake script with entries for all .C and .cpp -# files in the current test directory. - -VERSION=1.1 - -DO_RUN="y" - -usage() -{ - echo 'Usage : create_cgal_test [--no-run]' - echo - echo ' --help : prints this usage help' - echo ' --no-run : produces a cgal_test_with_cmake script that only does compilation, no execution' - exit -} - -while [ $1 ]; do - case "$1" in - -h|-help|--h|--help) - usage; - ;; - --no-run) - DO_RUN="" - shift; continue - ;; - *) - echo "Unknown option: $1" - usage - ;; - esac -done - - -header() -{ - echo "#---------------------------------------------------------------------#" - echo "# $1" - echo "#---------------------------------------------------------------------#" -} - -create_script() -{ - echo "#! /bin/sh" - echo - echo "# This is a script for the CGAL test suite. Such a script must obey" - echo "# the following rules:" - echo "#" - echo "# - the name of the script is cgal_test_with_cmake" - echo "# - for every target two one line messages are written to the file 'error.txt'" - echo "# the first one indicates if the compilation was successful" - echo "# the second one indicates if the execution was successful" - echo "# if one of the two was not successful, the line should start with 'ERROR:'" - echo "# - running the script should not require any user interaction" - echo "# - the script should clean up object files and executables" - echo -cat << EOF - ERRORFILE=error.txt - DO_RUN=${DO_RUN} - if [ -z "\${MAKE_CMD}" ]; then - MAKE_CMD=make - fi - NEED_CLEAN= - -EOF - header "configure" -cat << EOF - -configure() -{ - echo "Configuring... " - - if eval 'cmake "\$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \\ - -DCGAL_DIR="\$CGAL_DIR" \\ - .' ; then - - echo " successful configuration" >> \$ERRORFILE - else - echo " ERROR: configuration" >> \$ERRORFILE - fi -} - -EOF - header "compile_and_run " -cat << EOF - -compile_and_run() -{ - echo "Compiling \$1 ... " - SUCCESS="y" - - if eval '\${MAKE_CMD} VERBOSE=ON -fMakefile \$1' ; then - echo " successful compilation of \$1" >> \$ERRORFILE - else - echo " ERROR: compilation of \$1" >> \$ERRORFILE - SUCCESS="" - fi - - if [ -n "\$DO_RUN" ] ; then - if [ -n "\${SUCCESS}" ] ; then - OUTPUTFILE=ProgramOutput.\$1.\$PLATFORM - rm -f \$OUTPUTFILE - COMMAND="./\$1" - if [ -f \$1.cmd ] ; then - COMMAND="\$COMMAND \`cat \$1.cmd\`" - fi - if [ -f \$1.cin ] ; then - COMMAND="cat \$1.cin | \$COMMAND" - fi - echo "Executing \$1 ... " - echo - ulimit -t 3600 2> /dev/null - if eval \$COMMAND > \$OUTPUTFILE 2>&1 ; then - echo " successful execution of \$1" >> \$ERRORFILE - else - echo " ERROR: execution of \$1" >> \$ERRORFILE - fi - else - echo " ERROR: not executed \$1" >> \$ERRORFILE - fi - fi -} - -EOF - header "remove the previous error file" -cat << EOF - -rm -f \$ERRORFILE -touch \$ERRORFILE - -EOF - header "configure, compile and run the tests" -cat << EOF - -configure - -if [ \$# -ne 0 ] ; then - for file in \$* ; do - compile_and_run \$file - done -else - echo "Run all tests." -EOF - for file in `ls *.C *.cpp 2>/dev/null | sort` ; do - if [ -n "`grep '\' $file`" ] ; then - tmp=`basename $file .C` - tmp=`basename $tmp .cpp` - cat < cgal_test_with_cmake -chmod 755 cgal_test_with_cmake -echo "created cgal_test_with_cmake, version $VERSION, in $PWD ..." +#! /bin/sh +# +# ============================================================================= +# $URL: svn+ssh://fcacciola@scm.gforge.inria.fr/svn/cgal/trunk/Scripts/developer_scripts/create_cgal_test $ +# $Id: create_cgal_test 36975 2007-03-09 22:52:40Z spion $ +# +# author(s) : Wieger Wesselink, Geert-Jan Giezeman +# +# coordinator : Utrecht University +# ============================================================================= +# +# This script creates a cgal_test_with_cmake script with entries for all .C and .cpp +# files in the current test directory. + +VERSION=1.1 + +DO_RUN="y" + +usage() +{ + echo 'Usage : create_cgal_test [--no-run]' + echo + echo ' --help : prints this usage help' + echo ' --no-run : produces a cgal_test_with_cmake script that only does compilation, no execution' + exit +} + +while [ $1 ]; do + case "$1" in + -h|-help|--h|--help) + usage; + ;; + --no-run) + DO_RUN="" + shift; continue + ;; + *) + echo "Unknown option: $1" + usage + ;; + esac +done + + +header() +{ + echo "#---------------------------------------------------------------------#" + echo "# $1" + echo "#---------------------------------------------------------------------#" +} + +create_script() +{ + echo "#! /bin/sh" + echo + echo "# This is a script for the CGAL test suite. Such a script must obey" + echo "# the following rules:" + echo "#" + echo "# - the name of the script is cgal_test_with_cmake" + echo "# - for every target two one line messages are written to the file 'error.txt'" + echo "# the first one indicates if the compilation was successful" + echo "# the second one indicates if the execution was successful" + echo "# if one of the two was not successful, the line should start with 'ERROR:'" + echo "# - running the script should not require any user interaction" + echo "# - the script should clean up object files and executables" + echo +cat << EOF + ERRORFILE=error.txt + DO_RUN=${DO_RUN} + if [ -z "\${MAKE_CMD}" ]; then + MAKE_CMD=make + fi + NEED_CLEAN= + +EOF + header "configure" +cat << EOF + +configure() +{ + echo "Configuring... " + + if eval 'cmake "\$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \\ + -DCGAL_DIR="\$CGAL_DIR" \\ + .' ; then + + echo " successful configuration" >> \$ERRORFILE + else + echo " ERROR: configuration" >> \$ERRORFILE + fi +} + +EOF + header "compile_and_run " +cat << EOF + +compile_and_run() +{ + echo "Compiling \$1 ... " + SUCCESS="y" + + if eval '\${MAKE_CMD} VERBOSE=ON -fMakefile \$1' ; then + echo " successful compilation of \$1" >> \$ERRORFILE + else + echo " ERROR: compilation of \$1" >> \$ERRORFILE + SUCCESS="" + fi + + if [ -n "\$DO_RUN" ] ; then + if [ -n "\${SUCCESS}" ] ; then + OUTPUTFILE=ProgramOutput.\$1.\$PLATFORM + rm -f \$OUTPUTFILE + COMMAND="./\$1" + if [ -f \$1.cmd ] ; then + COMMAND="\$COMMAND \`cat \$1.cmd\`" + fi + if [ -f \$1.cin ] ; then + COMMAND="cat \$1.cin | \$COMMAND" + fi + echo "Executing \$1 ... " + echo + ulimit -t 3600 2> /dev/null + if eval \$COMMAND > \$OUTPUTFILE 2>&1 ; then + echo " successful execution of \$1" >> \$ERRORFILE + else + echo " ERROR: execution of \$1" >> \$ERRORFILE + fi + else + echo " ERROR: not executed \$1" >> \$ERRORFILE + fi + fi +} + +EOF + header "remove the previous error file" +cat << EOF + +rm -f \$ERRORFILE +touch \$ERRORFILE + +EOF + header "configure, compile and run the tests" +cat << EOF + +configure + +if [ \$# -ne 0 ] ; then + for file in \$* ; do + compile_and_run \$file + done +else + echo "Run all tests." +EOF + for file in `ls *.C *.cpp 2>/dev/null | sort` ; do + if [ -n "`grep '\' $file`" ] ; then + tmp=`basename $file .C` + tmp=`basename $tmp .cpp` + cat < cgal_test_with_cmake +chmod 755 cgal_test_with_cmake +echo "created cgal_test_with_cmake, version $VERSION, in $PWD ..." diff --git a/Solver_interface/include/CGAL/Eigen_matrix.h b/Solver_interface/include/CGAL/Eigen_matrix.h index 0b6d10784ee..48d05f09d3d 100644 --- a/Solver_interface/include/CGAL/Eigen_matrix.h +++ b/Solver_interface/include/CGAL/Eigen_matrix.h @@ -1,252 +1,252 @@ -// Copyright (c) 2012 INRIA Bordeaux Sud-Ouest (France), All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// Author(s) : Gael Guennebaud - -#ifndef CGAL_EIGEN_MATRIX_H -#define CGAL_EIGEN_MATRIX_H - -#include // include basic.h before testing #defines - -#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET -#include - -namespace CGAL { - - -/// The class Eigen_sparse_matrix -/// is a C++ wrapper around Eigen' matrix type SparseMatrix<>. -/// -/// This kind of matrix can be either symmetric or not. Symmetric -/// matrices store only the lower triangle. -/// -/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d::Matrix concept. -/// -/// @heading Parameters: -/// @param T Number type. - -template -struct Eigen_sparse_matrix -{ -// Public types -public: - - typedef Eigen::SparseMatrix EigenType; - typedef T NT; - -// Public operations -public: - - /// Create a square matrix initialized with zeros. - Eigen_sparse_matrix(int dim, ///< Matrix dimension. - bool is_symmetric = false) ///< Symmetric/hermitian? - : m_is_already_built(false), m_matrix(dim,dim) - { - CGAL_precondition(dim > 0); - - m_is_symmetric = is_symmetric; - // reserve memory for a regular 3D grid - m_triplets.reserve(dim); - } - - /// Create a rectangular matrix initialized with zeros. - /// - /// @commentheading Precondition: rows == columns if is_symmetric is true. - Eigen_sparse_matrix(int rows, ///< Number of rows. - int columns, ///< Number of columns. - bool is_symmetric = false) ///< Symmetric/hermitian? - : m_is_already_built(false), m_matrix(rows,columns) - { - CGAL_precondition(rows > 0); - CGAL_precondition(columns > 0); - if (m_is_symmetric) { - CGAL_precondition(rows == columns); - } - - m_is_symmetric = is_symmetric; - // reserve memory for a regular 3D grid - m_triplets.reserve(rows); - } - - /// Delete this object and the wrapped TAUCS matrix. - ~Eigen_sparse_matrix() - { - } - - /// Return the matrix number of rows - int row_dimension() const { return m_matrix.rows(); } - /// Return the matrix number of columns - int column_dimension() const { return m_matrix.cols(); } - - - /// Write access to a matrix coefficient: a_ij <- val. - /// - /// Optimizations: - /// - For symmetric matrices, Eigen_sparse_matrix stores only the lower triangle - /// set_coef() does nothing if (i, j) belongs to the upper triangle. - /// - Caller can optimize this call by setting 'new_coef' to true - /// if the coefficient does not already exist in the matrix. - /// - /// @commentheading Preconditions: - /// - 0 <= i < row_dimension(). - /// - 0 <= j < column_dimension(). - void set_coef(int i, int j, T val, bool new_coef = false) - { - CGAL_precondition(i < row_dimension()); - CGAL_precondition(j < column_dimension()); - - if (m_is_symmetric && (j > i)) - return; - - if (m_is_already_built) - m_matrix.coeffRef(i,j)=val; - else - { - if ( new_coef == false ) - { - assemble_matrix(); - m_matrix.coeffRef(i,j)=val; - } - else - m_triplets.push_back(Triplet(i,j,val)); - } - } - - /// Write access to a matrix coefficient: a_ij <- a_ij+val. - /// - /// Optimizations: - /// - For symmetric matrices, Eigen_sparse_matrix stores only the lower triangle - /// add_coef() does nothing if (i, j) belongs to the upper triangle. - /// - /// @commentheading Preconditions: - /// - 0 <= i < row_dimension(). - /// - 0 <= j < column_dimension(). - void add_coef(int i, int j, T val) - { - CGAL_precondition(i < row_dimension()); - CGAL_precondition(j < column_dimension()); - - if (m_is_symmetric && (j > i)) - return; - - if (m_is_already_built) - m_matrix.coeffRef(i,j)+=val; - else - m_triplets.push_back(Triplet(i,j,val)); - } - - void assemble_matrix() const - { - m_matrix.setFromTriplets(m_triplets.begin(), m_triplets.end()); - m_is_already_built = true; - m_triplets.clear(); //the matrix is built and will not be rebuilt - } - - const EigenType& eigen_object() const - { - if(!m_is_already_built) assemble_matrix(); - - // turns the matrix into compressed mode: - // -> release some memory - // -> required for some external solvers - m_matrix.makeCompressed(); - return m_matrix; - } - -private: - - - /// Eigen_sparse_matrix cannot be copied (yet) - Eigen_sparse_matrix(const Eigen_sparse_matrix& rhs); - Eigen_sparse_matrix& operator=(const Eigen_sparse_matrix& rhs); - -// Fields -private: - - mutable bool m_is_already_built; - typedef Eigen::Triplet Triplet; - mutable std::vector m_triplets; - - mutable EigenType m_matrix; - - // Symmetric/hermitian? - bool m_is_symmetric; - -}; // Eigen_sparse_matrix - - - -/// The class Eigen_sparse_symmetric_matrix is a C++ wrapper -/// around a Eigen sparse matrix (type Eigen::SparseMatrix). -/// -/// Symmetric matrices store only the lower triangle. -/// -/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d::Matrix concept. -/// -/// @heading Parameters: -/// @param T Number type. - -template -struct Eigen_sparse_symmetric_matrix - : public Eigen_sparse_matrix -{ -// Public types - typedef T NT; - -// Public operations - - /// Create a square *symmetric* matrix initialized with zeros. - Eigen_sparse_symmetric_matrix(int dim) ///< Matrix dimension. - : Eigen_sparse_matrix(dim, true /* symmetric */) - { - } - - /// Create a square *symmetric* matrix initialized with zeros. - /// - /// @commentheading Precondition: rows == columns. - Eigen_sparse_symmetric_matrix(int rows, ///< Number of rows. - int columns) ///< Number of columns. - : Eigen_sparse_matrix(rows, columns, true /* symmetric */) - { - } -}; - -template -struct Eigen_matrix : public ::Eigen::Matrix -{ - typedef ::Eigen::Matrix EigenType; - - Eigen_matrix( std::size_t n1, std::size_t n2):EigenType(n1,n2){} - - std::size_t number_of_rows () const {return this->rows();} - - std::size_t number_of_columns () const {return this->cols();} - - FT operator()( std::size_t i , std::size_t j ) const {return this->operator()(i,j);} - - void set( std::size_t i, std::size_t j,FT value){ - this->coeffRef(i,j)=value; - } - - const EigenType& eigen_object() const{ - return static_cast(*this); - } - -}; - -} //namespace CGAL - -#endif // CGAL_EIGEN_MATRIX_H +// Copyright (c) 2012 INRIA Bordeaux Sud-Ouest (France), All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Gael Guennebaud + +#ifndef CGAL_EIGEN_MATRIX_H +#define CGAL_EIGEN_MATRIX_H + +#include // include basic.h before testing #defines + +#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET +#include + +namespace CGAL { + + +/// The class Eigen_sparse_matrix +/// is a C++ wrapper around Eigen' matrix type SparseMatrix<>. +/// +/// This kind of matrix can be either symmetric or not. Symmetric +/// matrices store only the lower triangle. +/// +/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d::Matrix concept. +/// +/// @heading Parameters: +/// @param T Number type. + +template +struct Eigen_sparse_matrix +{ +// Public types +public: + + typedef Eigen::SparseMatrix EigenType; + typedef T NT; + +// Public operations +public: + + /// Create a square matrix initialized with zeros. + Eigen_sparse_matrix(int dim, ///< Matrix dimension. + bool is_symmetric = false) ///< Symmetric/hermitian? + : m_is_already_built(false), m_matrix(dim,dim) + { + CGAL_precondition(dim > 0); + + m_is_symmetric = is_symmetric; + // reserve memory for a regular 3D grid + m_triplets.reserve(dim); + } + + /// Create a rectangular matrix initialized with zeros. + /// + /// @commentheading Precondition: rows == columns if is_symmetric is true. + Eigen_sparse_matrix(int rows, ///< Number of rows. + int columns, ///< Number of columns. + bool is_symmetric = false) ///< Symmetric/hermitian? + : m_is_already_built(false), m_matrix(rows,columns) + { + CGAL_precondition(rows > 0); + CGAL_precondition(columns > 0); + if (m_is_symmetric) { + CGAL_precondition(rows == columns); + } + + m_is_symmetric = is_symmetric; + // reserve memory for a regular 3D grid + m_triplets.reserve(rows); + } + + /// Delete this object and the wrapped TAUCS matrix. + ~Eigen_sparse_matrix() + { + } + + /// Return the matrix number of rows + int row_dimension() const { return m_matrix.rows(); } + /// Return the matrix number of columns + int column_dimension() const { return m_matrix.cols(); } + + + /// Write access to a matrix coefficient: a_ij <- val. + /// + /// Optimizations: + /// - For symmetric matrices, Eigen_sparse_matrix stores only the lower triangle + /// set_coef() does nothing if (i, j) belongs to the upper triangle. + /// - Caller can optimize this call by setting 'new_coef' to true + /// if the coefficient does not already exist in the matrix. + /// + /// @commentheading Preconditions: + /// - 0 <= i < row_dimension(). + /// - 0 <= j < column_dimension(). + void set_coef(int i, int j, T val, bool new_coef = false) + { + CGAL_precondition(i < row_dimension()); + CGAL_precondition(j < column_dimension()); + + if (m_is_symmetric && (j > i)) + return; + + if (m_is_already_built) + m_matrix.coeffRef(i,j)=val; + else + { + if ( new_coef == false ) + { + assemble_matrix(); + m_matrix.coeffRef(i,j)=val; + } + else + m_triplets.push_back(Triplet(i,j,val)); + } + } + + /// Write access to a matrix coefficient: a_ij <- a_ij+val. + /// + /// Optimizations: + /// - For symmetric matrices, Eigen_sparse_matrix stores only the lower triangle + /// add_coef() does nothing if (i, j) belongs to the upper triangle. + /// + /// @commentheading Preconditions: + /// - 0 <= i < row_dimension(). + /// - 0 <= j < column_dimension(). + void add_coef(int i, int j, T val) + { + CGAL_precondition(i < row_dimension()); + CGAL_precondition(j < column_dimension()); + + if (m_is_symmetric && (j > i)) + return; + + if (m_is_already_built) + m_matrix.coeffRef(i,j)+=val; + else + m_triplets.push_back(Triplet(i,j,val)); + } + + void assemble_matrix() const + { + m_matrix.setFromTriplets(m_triplets.begin(), m_triplets.end()); + m_is_already_built = true; + m_triplets.clear(); //the matrix is built and will not be rebuilt + } + + const EigenType& eigen_object() const + { + if(!m_is_already_built) assemble_matrix(); + + // turns the matrix into compressed mode: + // -> release some memory + // -> required for some external solvers + m_matrix.makeCompressed(); + return m_matrix; + } + +private: + + + /// Eigen_sparse_matrix cannot be copied (yet) + Eigen_sparse_matrix(const Eigen_sparse_matrix& rhs); + Eigen_sparse_matrix& operator=(const Eigen_sparse_matrix& rhs); + +// Fields +private: + + mutable bool m_is_already_built; + typedef Eigen::Triplet Triplet; + mutable std::vector m_triplets; + + mutable EigenType m_matrix; + + // Symmetric/hermitian? + bool m_is_symmetric; + +}; // Eigen_sparse_matrix + + + +/// The class Eigen_sparse_symmetric_matrix is a C++ wrapper +/// around a Eigen sparse matrix (type Eigen::SparseMatrix). +/// +/// Symmetric matrices store only the lower triangle. +/// +/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d::Matrix concept. +/// +/// @heading Parameters: +/// @param T Number type. + +template +struct Eigen_sparse_symmetric_matrix + : public Eigen_sparse_matrix +{ +// Public types + typedef T NT; + +// Public operations + + /// Create a square *symmetric* matrix initialized with zeros. + Eigen_sparse_symmetric_matrix(int dim) ///< Matrix dimension. + : Eigen_sparse_matrix(dim, true /* symmetric */) + { + } + + /// Create a square *symmetric* matrix initialized with zeros. + /// + /// @commentheading Precondition: rows == columns. + Eigen_sparse_symmetric_matrix(int rows, ///< Number of rows. + int columns) ///< Number of columns. + : Eigen_sparse_matrix(rows, columns, true /* symmetric */) + { + } +}; + +template +struct Eigen_matrix : public ::Eigen::Matrix +{ + typedef ::Eigen::Matrix EigenType; + + Eigen_matrix( std::size_t n1, std::size_t n2):EigenType(n1,n2){} + + std::size_t number_of_rows () const {return this->rows();} + + std::size_t number_of_columns () const {return this->cols();} + + FT operator()( std::size_t i , std::size_t j ) const {return this->operator()(i,j);} + + void set( std::size_t i, std::size_t j,FT value){ + this->coeffRef(i,j)=value; + } + + const EigenType& eigen_object() const{ + return static_cast(*this); + } + +}; + +} //namespace CGAL + +#endif // CGAL_EIGEN_MATRIX_H diff --git a/Spatial_searching/examples/Spatial_searching/searching_with_point_with_info.cpp b/Spatial_searching/examples/Spatial_searching/searching_with_point_with_info.cpp index bd5317c4521..40925cd6beb 100644 --- a/Spatial_searching/examples/Spatial_searching/searching_with_point_with_info.cpp +++ b/Spatial_searching/examples/Spatial_searching/searching_with_point_with_info.cpp @@ -1,64 +1,64 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef Kernel::Point_3 Point_3; -typedef boost::tuple Point_and_int; - -typedef CGAL::Random_points_in_cube_3 Random_points_iterator; -typedef CGAL::Search_traits_3 Traits_base; -typedef CGAL::Search_traits_adapter, - Traits_base> Traits; - - -typedef CGAL::Orthogonal_k_neighbor_search K_neighbor_search; -typedef K_neighbor_search::Tree Tree; -typedef K_neighbor_search::Distance Distance; - -int main() { - const unsigned int K = 5; - // generator for random data points in the cube ( (-1,-1,-1), (1,1,1) ) - Random_points_iterator rpit( 1.0); - std::vector points; - std::vector indices; - - points.push_back(Point_3(*rpit++)); - points.push_back(Point_3(*rpit++)); - points.push_back(Point_3(*rpit++)); - points.push_back(Point_3(*rpit++)); - points.push_back(Point_3(*rpit++)); - points.push_back(Point_3(*rpit++)); - points.push_back(Point_3(*rpit++)); - - indices.push_back(0); - indices.push_back(1); - indices.push_back(2); - indices.push_back(3); - indices.push_back(4); - indices.push_back(5); - indices.push_back(6); - - // Insert number_of_data_points in the tree - Tree tree( - boost::make_zip_iterator(boost::make_tuple( points.begin(),indices.begin() )), - boost::make_zip_iterator(boost::make_tuple( points.end(),indices.end() ) ) - ); - Point_3 query(0.0, 0.0, 0.0); - Distance tr_dist; - - // search K nearest neighbours - K_neighbor_search search(tree, query, K); - for(K_neighbor_search::iterator it = search.begin(); it != search.end(); it++){ - std::cout << " d(q, nearest neighbor)= " - << tr_dist.inverse_of_transformed_distance(it->second) << " " << boost::get<0>(it->first)<< " " << boost::get<1>(it->first) << std::endl; - } - return 0; -} +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point_3; +typedef boost::tuple Point_and_int; + +typedef CGAL::Random_points_in_cube_3 Random_points_iterator; +typedef CGAL::Search_traits_3 Traits_base; +typedef CGAL::Search_traits_adapter, + Traits_base> Traits; + + +typedef CGAL::Orthogonal_k_neighbor_search K_neighbor_search; +typedef K_neighbor_search::Tree Tree; +typedef K_neighbor_search::Distance Distance; + +int main() { + const unsigned int K = 5; + // generator for random data points in the cube ( (-1,-1,-1), (1,1,1) ) + Random_points_iterator rpit( 1.0); + std::vector points; + std::vector indices; + + points.push_back(Point_3(*rpit++)); + points.push_back(Point_3(*rpit++)); + points.push_back(Point_3(*rpit++)); + points.push_back(Point_3(*rpit++)); + points.push_back(Point_3(*rpit++)); + points.push_back(Point_3(*rpit++)); + points.push_back(Point_3(*rpit++)); + + indices.push_back(0); + indices.push_back(1); + indices.push_back(2); + indices.push_back(3); + indices.push_back(4); + indices.push_back(5); + indices.push_back(6); + + // Insert number_of_data_points in the tree + Tree tree( + boost::make_zip_iterator(boost::make_tuple( points.begin(),indices.begin() )), + boost::make_zip_iterator(boost::make_tuple( points.end(),indices.end() ) ) + ); + Point_3 query(0.0, 0.0, 0.0); + Distance tr_dist; + + // search K nearest neighbours + K_neighbor_search search(tree, query, K); + for(K_neighbor_search::iterator it = search.begin(); it != search.end(); it++){ + std::cout << " d(q, nearest neighbor)= " + << tr_dist.inverse_of_transformed_distance(it->second) << " " << boost::get<0>(it->first)<< " " << boost::get<1>(it->first) << std::endl; + } + return 0; +} diff --git a/Spatial_sorting/examples/Spatial_sorting/sp_sort_using_property_map_2.cpp b/Spatial_sorting/examples/Spatial_sorting/sp_sort_using_property_map_2.cpp index a0ffa67499c..ebc176f3df5 100644 --- a/Spatial_sorting/examples/Spatial_sorting/sp_sort_using_property_map_2.cpp +++ b/Spatial_sorting/examples/Spatial_sorting/sp_sort_using_property_map_2.cpp @@ -1,35 +1,35 @@ -#include -#include -#include -#include -#include - -typedef CGAL::Simple_cartesian Kernel; -typedef Kernel::Point_2 Point_2; -typedef std::pair Point_with_info; -typedef std::vector< Point_with_info > Data_vector; - -typedef CGAL::Spatial_sort_traits_adapter_2 -> Search_traits_2; - -int main() -{ - Data_vector points; - points.push_back(std::make_pair(Point_2(14,12) , 3)); - points.push_back(std::make_pair(Point_2(1,2) , 0)); - points.push_back(std::make_pair(Point_2(414,2) , 5)); - points.push_back(std::make_pair(Point_2(4,21) , 1)); - points.push_back(std::make_pair(Point_2(7,74) , 2)); - points.push_back(std::make_pair(Point_2(74,4) , 4)); - - Search_traits_2 traits; - CGAL::spatial_sort(points.begin(), points.end(), traits); - for (Data_vector::iterator it=points.begin();it!=points.end();++it) - std::cout << it->second << " "; - std::cout << "\n"; - - std::cout << "done" << std::endl; - - return 0; -} +#include +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_2 Point_2; +typedef std::pair Point_with_info; +typedef std::vector< Point_with_info > Data_vector; + +typedef CGAL::Spatial_sort_traits_adapter_2 +> Search_traits_2; + +int main() +{ + Data_vector points; + points.push_back(std::make_pair(Point_2(14,12) , 3)); + points.push_back(std::make_pair(Point_2(1,2) , 0)); + points.push_back(std::make_pair(Point_2(414,2) , 5)); + points.push_back(std::make_pair(Point_2(4,21) , 1)); + points.push_back(std::make_pair(Point_2(7,74) , 2)); + points.push_back(std::make_pair(Point_2(74,4) , 4)); + + Search_traits_2 traits; + CGAL::spatial_sort(points.begin(), points.end(), traits); + for (Data_vector::iterator it=points.begin();it!=points.end();++it) + std::cout << it->second << " "; + std::cout << "\n"; + + std::cout << "done" << std::endl; + + return 0; +} diff --git a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/PS_demo_normal_estimation_plugin.cpp b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/PS_demo_normal_estimation_plugin.cpp index 2819e6ef787..178fa439a36 100644 --- a/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/PS_demo_normal_estimation_plugin.cpp +++ b/Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/PS_demo_normal_estimation_plugin.cpp @@ -1,215 +1,215 @@ -#include "config.h" -#include "Point_set_scene_item.h" -#include "Polyhedron_demo_plugin_helper.h" -#include "Polyhedron_demo_plugin_interface.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "ui_PS_demo_normal_estimation_plugin.h" - -class PS_demo_normal_estimation_plugin : - public QObject, - public Polyhedron_demo_plugin_helper -{ - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_plugin_interface) - QAction* actionNormalEstimation; - QAction* actionNormalInversion; - -public: - void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { - this->scene = scene_interface; - this->mw = mainWindow; - actionNormalEstimation = this->getActionFromMainWindow(mw, "actionNormalEstimation"); - if(actionNormalEstimation) { - connect(actionNormalEstimation, SIGNAL(triggered()), - this, SLOT(on_actionNormalEstimation_triggered())); - } - - actionNormalInversion = this->getActionFromMainWindow(mw, "actionNormalInversion"); - if(actionNormalInversion) { - connect(actionNormalInversion, SIGNAL(triggered()), - this, SLOT(on_actionNormalInversion_triggered())); - } - } - - QList actions() const { - return QList() << actionNormalEstimation << actionNormalInversion; - } - -public slots: - void on_actionNormalEstimation_triggered(); - void on_actionNormalInversion_triggered(); - -}; // end PS_demo_smoothing_plugin - -class Point_set_demo_normal_estimation_dialog : public QDialog, private Ui::NormalEstimationDialog -{ - Q_OBJECT - public: - Point_set_demo_normal_estimation_dialog(QWidget* = 0) - { - setupUi(this); - } - - QString directionMethod() const { return m_inputDirection->currentText(); } - int directionNbNeighbors() const { return m_inputNbNeighborsDirection->value(); } - - QString orientationMethod() const { return m_inputOrientation->currentText(); } - int orientationNbNeighbors() const { return m_inputNbNeighborsOrientation->value(); } -}; - - -void PS_demo_normal_estimation_plugin::on_actionNormalInversion_triggered() -{ - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Point_set_scene_item* item = - qobject_cast(scene->item(index)); - - if(item) - { - // Gets point set - Point_set* points = item->point_set(); - if(points == NULL) - return; - - for(Point_set::iterator it = points->begin(); it != points->end(); ++it){ - it->normal() = -1 * it->normal(); - } - } -} - -void PS_demo_normal_estimation_plugin::on_actionNormalEstimation_triggered() -{ - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Point_set_scene_item* item = - qobject_cast(scene->item(index)); - - if(item) - { - // Gets point set - Point_set* points = item->point_set(); - if(points == NULL) - return; - - // Gets options - Point_set_demo_normal_estimation_dialog dialog; - if(!dialog.exec()) - return; - - QApplication::setOverrideCursor(Qt::WaitCursor); - - // First point to delete - Point_set::iterator first_unoriented_point = points->end(); - - //*************************************** - // normal estimation - //*************************************** - - if (dialog.directionMethod() == "plane") - { - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Estimates normal direction by PCA (k=" << dialog.directionNbNeighbors() <<")...\n"; - - // Estimates normals direction. - CGAL::pca_estimate_normals(points->begin(), points->end(), -#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 - CGAL::make_normal_of_point_with_normal_pmap(points->begin()), -#else - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), -#endif - - dialog.directionNbNeighbors()); - - // Mark all normals as unoriented - first_unoriented_point = points->begin(); - - long memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "Estimates normal direction: " << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated" - << std::endl; - } - else if (dialog.directionMethod() == "quadric") - { - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Estimates normal direction by Jet Fitting (k=" << dialog.directionNbNeighbors() <<")...\n"; - - // Estimates normals direction. - CGAL::jet_estimate_normals(points->begin(), points->end(), -#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 - CGAL::make_normal_of_point_with_normal_pmap(points->begin()), -#else - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), -#endif - dialog.directionNbNeighbors()); - - // Mark all normals as unoriented - first_unoriented_point = points->begin(); - - long memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "Estimates normal direction: " << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated" - << std::endl; - } - - //*************************************** - // normal orientation - //*************************************** - - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Orient normals with a Minimum Spanning Tree (k=" << dialog.orientationNbNeighbors() << ")...\n"; - - // Tries to orient normals - first_unoriented_point = - CGAL::mst_orient_normals(points->begin(), points->end(), -#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 - CGAL::make_normal_of_point_with_normal_pmap(points->begin()), -#else - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), -#endif - dialog.orientationNbNeighbors()); - - int nb_unoriented_normals = std::distance(first_unoriented_point, points->end()); - long memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "Orient normals: " << nb_unoriented_normals << " point(s) with an unoriented normal are selected (" - << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated)" - << std::endl; - - // Selects points with an unoriented normal - points->select(points->begin(), points->end(), false); - points->select(first_unoriented_point, points->end(), true); - - // Updates scene - scene->itemChanged(index); - - QApplication::restoreOverrideCursor(); - - // Warns user - if (nb_unoriented_normals > 0) - { - QMessageBox::information(NULL, - tr("Points with an unoriented normal"), - tr("%1 point(s) with an unoriented normal are selected.\nPlease orient them or remove them before running Poisson reconstruction.") - .arg(nb_unoriented_normals)); - } - } -} - -Q_EXPORT_PLUGIN2(PS_demo_normal_estimation_plugin, PS_demo_normal_estimation_plugin) - -#include "PS_demo_normal_estimation_plugin.moc" +#include "config.h" +#include "Point_set_scene_item.h" +#include "Polyhedron_demo_plugin_helper.h" +#include "Polyhedron_demo_plugin_interface.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ui_PS_demo_normal_estimation_plugin.h" + +class PS_demo_normal_estimation_plugin : + public QObject, + public Polyhedron_demo_plugin_helper +{ + Q_OBJECT + Q_INTERFACES(Polyhedron_demo_plugin_interface) + QAction* actionNormalEstimation; + QAction* actionNormalInversion; + +public: + void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { + this->scene = scene_interface; + this->mw = mainWindow; + actionNormalEstimation = this->getActionFromMainWindow(mw, "actionNormalEstimation"); + if(actionNormalEstimation) { + connect(actionNormalEstimation, SIGNAL(triggered()), + this, SLOT(on_actionNormalEstimation_triggered())); + } + + actionNormalInversion = this->getActionFromMainWindow(mw, "actionNormalInversion"); + if(actionNormalInversion) { + connect(actionNormalInversion, SIGNAL(triggered()), + this, SLOT(on_actionNormalInversion_triggered())); + } + } + + QList actions() const { + return QList() << actionNormalEstimation << actionNormalInversion; + } + +public slots: + void on_actionNormalEstimation_triggered(); + void on_actionNormalInversion_triggered(); + +}; // end PS_demo_smoothing_plugin + +class Point_set_demo_normal_estimation_dialog : public QDialog, private Ui::NormalEstimationDialog +{ + Q_OBJECT + public: + Point_set_demo_normal_estimation_dialog(QWidget* = 0) + { + setupUi(this); + } + + QString directionMethod() const { return m_inputDirection->currentText(); } + int directionNbNeighbors() const { return m_inputNbNeighborsDirection->value(); } + + QString orientationMethod() const { return m_inputOrientation->currentText(); } + int orientationNbNeighbors() const { return m_inputNbNeighborsOrientation->value(); } +}; + + +void PS_demo_normal_estimation_plugin::on_actionNormalInversion_triggered() +{ + const Scene_interface::Item_id index = scene->mainSelectionIndex(); + + Point_set_scene_item* item = + qobject_cast(scene->item(index)); + + if(item) + { + // Gets point set + Point_set* points = item->point_set(); + if(points == NULL) + return; + + for(Point_set::iterator it = points->begin(); it != points->end(); ++it){ + it->normal() = -1 * it->normal(); + } + } +} + +void PS_demo_normal_estimation_plugin::on_actionNormalEstimation_triggered() +{ + const Scene_interface::Item_id index = scene->mainSelectionIndex(); + + Point_set_scene_item* item = + qobject_cast(scene->item(index)); + + if(item) + { + // Gets point set + Point_set* points = item->point_set(); + if(points == NULL) + return; + + // Gets options + Point_set_demo_normal_estimation_dialog dialog; + if(!dialog.exec()) + return; + + QApplication::setOverrideCursor(Qt::WaitCursor); + + // First point to delete + Point_set::iterator first_unoriented_point = points->end(); + + //*************************************** + // normal estimation + //*************************************** + + if (dialog.directionMethod() == "plane") + { + CGAL::Timer task_timer; task_timer.start(); + std::cerr << "Estimates normal direction by PCA (k=" << dialog.directionNbNeighbors() <<")...\n"; + + // Estimates normals direction. + CGAL::pca_estimate_normals(points->begin(), points->end(), +#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 + CGAL::make_normal_of_point_with_normal_pmap(points->begin()), +#else + CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), +#endif + + dialog.directionNbNeighbors()); + + // Mark all normals as unoriented + first_unoriented_point = points->begin(); + + long memory = CGAL::Memory_sizer().virtual_size(); + std::cerr << "Estimates normal direction: " << task_timer.time() << " seconds, " + << (memory>>20) << " Mb allocated" + << std::endl; + } + else if (dialog.directionMethod() == "quadric") + { + CGAL::Timer task_timer; task_timer.start(); + std::cerr << "Estimates normal direction by Jet Fitting (k=" << dialog.directionNbNeighbors() <<")...\n"; + + // Estimates normals direction. + CGAL::jet_estimate_normals(points->begin(), points->end(), +#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 + CGAL::make_normal_of_point_with_normal_pmap(points->begin()), +#else + CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), +#endif + dialog.directionNbNeighbors()); + + // Mark all normals as unoriented + first_unoriented_point = points->begin(); + + long memory = CGAL::Memory_sizer().virtual_size(); + std::cerr << "Estimates normal direction: " << task_timer.time() << " seconds, " + << (memory>>20) << " Mb allocated" + << std::endl; + } + + //*************************************** + // normal orientation + //*************************************** + + CGAL::Timer task_timer; task_timer.start(); + std::cerr << "Orient normals with a Minimum Spanning Tree (k=" << dialog.orientationNbNeighbors() << ")...\n"; + + // Tries to orient normals + first_unoriented_point = + CGAL::mst_orient_normals(points->begin(), points->end(), +#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 + CGAL::make_normal_of_point_with_normal_pmap(points->begin()), +#else + CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), +#endif + dialog.orientationNbNeighbors()); + + int nb_unoriented_normals = std::distance(first_unoriented_point, points->end()); + long memory = CGAL::Memory_sizer().virtual_size(); + std::cerr << "Orient normals: " << nb_unoriented_normals << " point(s) with an unoriented normal are selected (" + << task_timer.time() << " seconds, " + << (memory>>20) << " Mb allocated)" + << std::endl; + + // Selects points with an unoriented normal + points->select(points->begin(), points->end(), false); + points->select(first_unoriented_point, points->end(), true); + + // Updates scene + scene->itemChanged(index); + + QApplication::restoreOverrideCursor(); + + // Warns user + if (nb_unoriented_normals > 0) + { + QMessageBox::information(NULL, + tr("Points with an unoriented normal"), + tr("%1 point(s) with an unoriented normal are selected.\nPlease orient them or remove them before running Poisson reconstruction.") + .arg(nb_unoriented_normals)); + } + } +} + +Q_EXPORT_PLUGIN2(PS_demo_normal_estimation_plugin, PS_demo_normal_estimation_plugin) + +#include "PS_demo_normal_estimation_plugin.moc" diff --git a/Triangulation_3/examples/Triangulation_3/info_insert_with_pair_iterator.cpp b/Triangulation_3/examples/Triangulation_3/info_insert_with_pair_iterator.cpp index bca627727f3..e72cfefa1d4 100644 --- a/Triangulation_3/examples/Triangulation_3/info_insert_with_pair_iterator.cpp +++ b/Triangulation_3/examples/Triangulation_3/info_insert_with_pair_iterator.cpp @@ -1,38 +1,38 @@ -#include -#include -#include -#include - -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Triangulation_vertex_base_with_info_3 Vb; -typedef CGAL::Triangulation_data_structure_3 Tds; -//Use the Fast_location tag. Default or Compact_location works too. -typedef CGAL::Delaunay_triangulation_3 Delaunay; -typedef Delaunay::Point Point; - -int main() -{ - std::vector< std::pair > points; - points.push_back( std::make_pair(Point(0,0,0),0) ); - points.push_back( std::make_pair(Point(1,0,0),1) ); - points.push_back( std::make_pair(Point(0,1,0),2) ); - points.push_back( std::make_pair(Point(0,0,1),3) ); - points.push_back( std::make_pair(Point(2,2,2),4) ); - points.push_back( std::make_pair(Point(-1,0,1),5) ); - - - Delaunay T( points.begin(),points.end() ); - - CGAL_assertion( T.number_of_vertices() == 6 ); - - // check that the info was correctly set. - Delaunay::Finite_vertices_iterator vit; - for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit) - if( points[ vit->info() ].first != vit->point() ){ - std::cerr << "Error different info" << std::endl; - exit(EXIT_FAILURE); - } - std::cout << "OK" << std::endl; - - return 0; -} +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Triangulation_vertex_base_with_info_3 Vb; +typedef CGAL::Triangulation_data_structure_3 Tds; +//Use the Fast_location tag. Default or Compact_location works too. +typedef CGAL::Delaunay_triangulation_3 Delaunay; +typedef Delaunay::Point Point; + +int main() +{ + std::vector< std::pair > points; + points.push_back( std::make_pair(Point(0,0,0),0) ); + points.push_back( std::make_pair(Point(1,0,0),1) ); + points.push_back( std::make_pair(Point(0,1,0),2) ); + points.push_back( std::make_pair(Point(0,0,1),3) ); + points.push_back( std::make_pair(Point(2,2,2),4) ); + points.push_back( std::make_pair(Point(-1,0,1),5) ); + + + Delaunay T( points.begin(),points.end() ); + + CGAL_assertion( T.number_of_vertices() == 6 ); + + // check that the info was correctly set. + Delaunay::Finite_vertices_iterator vit; + for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit) + if( points[ vit->info() ].first != vit->point() ){ + std::cerr << "Error different info" << std::endl; + exit(EXIT_FAILURE); + } + std::cout << "OK" << std::endl; + + return 0; +}