Merge branch 'Polyhedron_demo-import_splatting-GF'

Tested in CGAL-4.5-Ic-100
Approved by the release manager

Conflicts:
	Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/CMakeLists.txt
	Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin.cpp
	Surface_reconstruction_points_3/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin_cgal_code.cpp
This commit is contained in:
Sébastien Loriot 2014-07-21 08:23:36 +02:00
commit 45f7298ce7
109 changed files with 176 additions and 17470 deletions

View File

@ -230,6 +230,10 @@ and <code>src/</code> directories).
<li> Clean up the documentation of the concepts</li>
</ul>
<h3>Point Set Processing and Surface Reconstruction from Point Sets</h3>
<ul>
<li>The former demo has been removed and is fully merge in the Polyhedron demo.</li>
</ul>
</div>
<h2 id="release4.4">Release 4.4 </h2>

View File

@ -29,7 +29,6 @@ pushd Triangulation_2_Demo;
popd
# CGAL<3.8 but was forgot
pushd Surface_reconstruction_points_3_Demo; zip ../surface_reconstruction_points_3.zip *; popd
pushd Principal_component_analysis_Demo; zip ../pca.zip *; popd
# CGAL-3.8

View File

@ -15,7 +15,7 @@
\cgalPkgDependsOn{\ref thirdpartyEigen "Eigen"}
\cgalPkgBib{cgal:ass-psp}
\cgalPkgLicense{\ref licensesGPL "GPL"}
\cgalPkgDemo{Surface Reconstruction,surface_reconstruction_points_3.zip}
\cgalPkgDemo{See Polyhedral Surface,polyhedron_3.zip}
\cgalPkgShortInfoEnd
\cgalPkgDescriptionEnd

View File

@ -12,6 +12,7 @@ class Scene_item;
// OpenGL rendering mode
enum RenderingMode { Points = 0,
PointsPlusNormals,
Splatting,
Wireframe,
Flat,
FlatPlusEdges,

View File

@ -49,6 +49,10 @@ if( POLYHEDRON_QTSCRIPT_DEBUGGER)
endif()
find_package(Qt4)
# Find Glew (optional), for splatting
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/GlSplat/cmake)
find_package(GLEW)
# Find OpenGL
find_package(OpenGL)
@ -59,7 +63,12 @@ if(QT4_FOUND)
find_package(QGLViewer )
endif(QT4_FOUND)
if(GLEW_FOUND)
include_directories ( ${GLEW_INCLUDE_DIR} )
add_definitions(-DCGAL_GLEW_ENABLED)
else(GLEW_FOUND)
message(STATUS "NOTICE: GLEW library is not found. Splat rendering will not be available.")
endif(GLEW_FOUND)
find_package(Eigen3 3.1.0) #(requires 3.1.0 or greater)
if (EIGEN3_FOUND)
@ -168,6 +177,13 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
# special
target_link_libraries(scene_polyhedron_transform_item scene_polyhedron_item)
if(GLEW_FOUND)
qt4_add_resources(gl_splat_rc GlSplat/glsplat.qrc)
add_library(gl_splat SHARED
GlSplat/GlSplat.cpp GlSplat/Shader.cpp ${gl_splat_rc})
target_link_libraries(gl_splat ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${GLEW_LIBRARIES})
endif(GLEW_FOUND)
add_item(scene_combinatorial_map_item Scene_combinatorial_map_item.cpp Scene_combinatorial_map_item.moc)
# special
target_link_libraries(scene_combinatorial_map_item scene_polyhedron_item)
@ -195,6 +211,9 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
Scene_nef_rendering.cpp)
target_link_libraries(scene_nef_polyhedron_item scene_polyhedron_item)
add_item(scene_points_with_normal_item Scene_points_with_normal_item.cpp Scene_points_with_normal_item.moc)
if(GLEW_FOUND)
target_link_libraries( scene_points_with_normal_item gl_splat ${GLEW_LIBRARIES} )
endif(GLEW_FOUND)
foreach( lib
demo_framework
@ -239,6 +258,10 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
target_link_libraries( Polyhedron_3 demo_framework )
target_link_libraries( Polyhedron_3 point_dialog )
if(GLEW_FOUND)
target_link_libraries( Polyhedron_3 gl_splat ${GLEW_LIBRARIES} )
endif(GLEW_FOUND)
# Link with CGAL
target_link_libraries( Polyhedron_3 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} )

View File

@ -3,6 +3,7 @@
#include <QAction>
#include <QStringList>
#include "opengl_tools.h"
#include "Scene_polyhedron_item.h"
#include "Scene_points_with_normal_item.h"
#include "Scene_polylines_item.h"

View File

@ -134,7 +134,7 @@ public:
// Indicate if rendering mode is supported
bool supportsRenderingMode(RenderingMode m) const {
return (m != Gouraud && m!=PointsPlusNormals); // CHECK THIS!
return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting); // CHECK THIS!
}
void draw() const {

View File

@ -1,4 +1,5 @@
#include <QtCore/qglobal.h>
#include "opengl_tools.h"
#include "Messages_interface.h"
#include "Scene_polyhedron_item.h"

View File

@ -1,4 +1,5 @@
#include <QtCore/qglobal.h>
#include "opengl_tools.h"
#include "Messages_interface.h"
#include "Scene_polyhedron_item.h"

View File

@ -1,3 +1,9 @@
#ifdef CGAL_GLEW_ENABLED
# include "GlSplat/GlSplat.h"
#endif
#include <CGAL/check_gl_error.h>
#include "config.h"
#include "Scene.h"
@ -22,6 +28,16 @@ namespace {
}
}
#ifdef CGAL_GLEW_ENABLED
GlSplat::SplatRenderer* Scene::ms_splatting = 0;
int Scene::ms_splattingCounter = 0;
GlSplat::SplatRenderer* Scene::splatting()
{
assert(ms_splatting!=0 && "A Scene object must be created before requesting the splatting object");
return ms_splatting;
}
#endif
Scene::Scene(QObject* parent)
: QAbstractListModel(parent),
selected_item(-1),
@ -32,6 +48,11 @@ Scene::Scene(QObject* parent)
double, double, double)),
this, SLOT(setSelectionRay(double, double, double,
double, double, double)));
#ifdef CGAL_GLEW_ENABLED
if(ms_splatting==0)
ms_splatting = new GlSplat::SplatRenderer();
ms_splattingCounter++;
#endif
}
Scene::Item_id
@ -140,6 +161,11 @@ Scene::~Scene()
delete item_ptr;
}
m_entries.clear();
#ifdef CGAL_GLEW_ENABLED
if((--ms_splattingCounter)==0)
delete ms_splatting;
#endif
}
Scene_item*
@ -183,6 +209,9 @@ Scene::duplicate(Item_id index)
void Scene::initializeGL()
{
#ifdef CGAL_GLEW_ENABLED
ms_splatting->init();
#endif
}
// workaround for Qt-4.2.
@ -335,10 +364,7 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer)
::glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
::glPointSize(2.f);
::glLineWidth(1.0f);
if(index == selected_item)
CGALglcolor(Qt::black);
else
CGALglcolor(item.color().lighter(50));
CGALglcolor(item.color());
if(viewer)
item.draw_points(viewer);
@ -350,6 +376,34 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer)
}
}
}
#ifdef CGAL_GLEW_ENABLED
// Splatting
if(ms_splatting->isSupported())
{
ms_splatting->beginVisibilityPass();
for(int index = 0; index < m_entries.size(); ++index)
{
Scene_item& item = *m_entries[index];
if(item.visible() && item.renderingMode() == Splatting)
{
item.draw_splats();
}
}
ms_splatting->beginAttributePass();
for(int index = 0; index < m_entries.size(); ++index)
{
Scene_item& item = *m_entries[index];
if(item.visible() && item.renderingMode() == Splatting)
{
CGALglcolor(item.color());
item.draw_splats();
}
}
ms_splatting->finalize();
}
#endif
}
// workaround for Qt-4.2 (see above)
@ -512,7 +566,12 @@ Scene::setData(const QModelIndex &index,
{
RenderingMode rendering_mode = static_cast<RenderingMode>(value.toInt());
// Find next supported rendering mode
while ( ! item->supportsRenderingMode(rendering_mode) ) {
while ( ! item->supportsRenderingMode(rendering_mode)
#ifdef CGAL_GLEW_ENABLED
|| (rendering_mode==Splatting && !Scene::splatting()->isSupported())
#endif
)
{
rendering_mode = static_cast<RenderingMode>( (rendering_mode+1) % NumberOfRenderingMode );
}
item->setRenderingMode(rendering_mode);

View File

@ -21,6 +21,7 @@
class QEvent;
class QMouseEvent;
namespace GlSplat { class SplatRenderer; }
class Viewer_interface;
@ -148,7 +149,12 @@ private:
QList<int> selected_items_list;
int item_A;
int item_B;
#ifdef CGAL_GLEW_ENABLED
static GlSplat::SplatRenderer* ms_splatting;
static int ms_splattingCounter;
public:
static GlSplat::SplatRenderer* splatting();
#endif
}; // end class Scene
class SCENE_EXPORT SceneDelegate : public QItemDelegate

View File

@ -74,7 +74,7 @@ public:
// Indicate if rendering mode is supported
bool supportsRenderingMode(RenderingMode m) const {
return (m != Gouraud && m!=PointsPlusNormals); // CHECK THIS!
return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting); // CHECK THIS!
}
void draw() const {

View File

@ -37,7 +37,7 @@ public:
QString toolTip() const;
// Indicate if rendering mode is supported
virtual bool supportsRenderingMode(RenderingMode m) const { return (m != Gouraud && m!=PointsPlusNormals); } // CHECK THIS!
virtual bool supportsRenderingMode(RenderingMode m) const { return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting); } // CHECK THIS!
//Event handling
virtual bool keyPressEvent(QKeyEvent*);
// OpenGL drawing in a display list

View File

@ -1,3 +1,4 @@
#include "opengl_tools.h"
#include "Scene_edit_polyhedron_item.h"
#include <boost/foreach.hpp>
#include <algorithm>

View File

@ -110,6 +110,7 @@ Scene_implicit_function_item::supportsRenderingMode(RenderingMode m) const
{
switch ( m )
{
case Splatting:
case Gouraud:
return false;

View File

@ -29,6 +29,8 @@ QString modeName(RenderingMode mode) {
return QObject::tr("Gouraud");
case PointsPlusNormals:
return QObject::tr("pts+normals");
case Splatting:
return QObject::tr("splats");
default:
Q_ASSERT(false);
return QObject::tr("unknown");
@ -50,6 +52,8 @@ const char* slotName(RenderingMode mode) {
return SLOT(setGouraudMode());
case PointsPlusNormals:
return SLOT(setPointsPlusNormalsMode());
case Splatting:
return SLOT(setSplattingMode());
default:
Q_ASSERT(false);
return "";

View File

@ -50,6 +50,9 @@ public:
// Points OpenGL drawing
virtual void draw_points() const { draw(); }
virtual void draw_points(Viewer_interface*) const { draw_points(); }
// Splats OpenGL drawing
virtual void draw_splats() const {}
virtual void draw_splats(Viewer_interface*) const {draw_splats();}
// Functions for displaying meta-data of the item
virtual QString toolTip() const = 0;
@ -122,6 +125,10 @@ public slots:
setRenderingMode(PointsPlusNormals);
}
void setSplattingMode(){
setRenderingMode(Splatting);
}
virtual void itemAboutToBeDestroyed(Scene_item*);
virtual void select(double orig_x,

View File

@ -28,7 +28,7 @@ public:
QString toolTip() const;
// Indicate if rendering mode is supported
virtual bool supportsRenderingMode(RenderingMode m) const { return m != Gouraud; } // CHECK THIS!
virtual bool supportsRenderingMode(RenderingMode m) const { return m != Gouraud && m!=Splatting; } // CHECK THIS!
// OpenGL drawing in a display list
void direct_draw() const;
// Wireframe OpenGL drawing

View File

@ -173,7 +173,10 @@ Scene_points_with_normal_item::toolTip() const
bool Scene_points_with_normal_item::supportsRenderingMode(RenderingMode m) const
{
return m==Points || m==PointsPlusNormals;
//note that when this function is first called the point set might be empty
bool points_have_normals = (m_points->begin() != m_points->end() &&
m_points->begin()->normal() != CGAL::NULL_VECTOR);
return m==Points || m==PointsPlusNormals || (m==Splatting && points_have_normals);
}
// Points OpenGL drawing in a display list
@ -202,6 +205,21 @@ void Scene_points_with_normal_item::draw_normals() const
}
}
void Scene_points_with_normal_item::draw_splats() const
{
Q_ASSERT(m_points != NULL);
// Draw splats
bool points_have_normals = (m_points->begin() != m_points->end() &&
m_points->begin()->normal() != CGAL::NULL_VECTOR);
bool points_have_radii = (m_points->begin() != m_points->end() &&
m_points->begin()->radius() != 0);
if(points_have_normals && points_have_radii)
{
m_points->gl_draw_splats();
}
}
// Gets wrapped point set
Point_set* Scene_points_with_normal_item::point_set()
{
@ -300,6 +318,10 @@ QMenu* Scene_points_with_normal_item::contextMenu()
void Scene_points_with_normal_item::setRenderingMode(RenderingMode m)
{
Scene_item_with_display_list::setRenderingMode(m);
if (rendering_mode==Splatting && (!m_points->are_radii_uptodate()))
{
computes_local_spacing(6); // default value = small
}
}
#include "Scene_points_with_normal_item.moc"

View File

@ -53,6 +53,9 @@ public:
void draw_normals() const;
virtual void draw_edges() const { draw_normals(); }//to tweak scene
// Splat OpenGL drawing
virtual void draw_splats() const;
// Gets wrapped point set
Point_set* point_set();
const Point_set* point_set() const;

View File

@ -26,7 +26,7 @@ public:
QString toolTip() const;
// Indicate if rendering mode is supported
virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=Gouraud && m!=PointsPlusNormals); } // CHECK THIS!
virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=Gouraud && m!=PointsPlusNormals && m!=Splatting); } // CHECK THIS!
// OpenGL drawing in a display list
void direct_draw() const;
void draw_points() const;

View File

@ -37,7 +37,7 @@ public:
QMenu* contextMenu();
// Indicate if rendering mode is supported
virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals); }
virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals && m!=Splatting); }
// Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list
virtual void direct_draw() const;
virtual void direct_draw_edges() const;

View File

@ -27,7 +27,7 @@ public:
// QMenu* contextMenu();
// Indicate if rendering mode is supported
bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals); }
bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals && m!=Splatting); }
// Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list
// dispatch to poly_item direct_draw and direct_draw_edges
void draw() const;

View File

@ -1,12 +1,12 @@
#ifndef SCENE_POLYHEDRON_SELECTION_ITEM_H
#define SCENE_POLYHEDRON_SELECTION_ITEM_H
#include "opengl_tools.h"
#include "Scene_polyhedron_selection_item_config.h"
#include "Scene_polyhedron_item_k_ring_selection.h"
#include "Travel_isolated_components.h"
#include "Scene_polyhedron_item_decorator.h"
#include "Polyhedron_type.h"
#include "opengl_tools.h"
#include <CGAL/gl_render.h>
#include <CGAL/orient_polygon_soup.h>

View File

@ -28,7 +28,7 @@ public:
virtual QString toolTip() const;
// Indicate if rendering mode is supported
virtual bool supportsRenderingMode(RenderingMode /* m */) const { return true; }
virtual bool supportsRenderingMode(RenderingMode m) const { return m != Splatting; }
// Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list
virtual void direct_draw() const;

View File

@ -281,6 +281,24 @@ public:
}
}
// Draw oriented points with radius using OpenGL calls.
// Preconditions: must be used inbetween calls to GlSplat library
void gl_draw_splats() const
{
// TODO add support for selection
::glBegin(GL_POINTS);
for (const_iterator it = begin(); it != end(); it++)
{
const UI_point& p = *it;
::glNormal3dv(&p.normal().x());
#ifdef CGAL_GLEW_ENABLED
::glMultiTexCoord1d(GL_TEXTURE2, p.radius());
#endif
::glVertex3dv(&p.x());
}
::glEnd();
}
bool are_radii_uptodate() const { return m_radii_are_uptodate; }
void set_radii_uptodate(bool /*on*/) { m_radii_are_uptodate = false; }

View File

@ -25,7 +25,11 @@
#ifndef CGAL_OPENGL_TOOLS_H
#define CGAL_OPENGL_TOOLS_H
#include <CGAL/gl.h>
#ifdef CGAL_GLEW_ENABLED
# include <GL/glew.h>
#else
# include <CGAL/gl.h>
#endif
namespace CGAL {
namespace GL {

View File

@ -1,280 +0,0 @@
# This is the CMake script for compiling the CGAL Point Set demo.
project( Point_set_demo )
cmake_minimum_required(VERSION 2.6.2)
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3)
cmake_policy(VERSION 2.8.4)
else()
cmake_policy(VERSION 2.6)
endif()
#option(POINT_SET_DEMO_ENABLE_FORWARD_DECL "In the Point Set demo, enable " OFF)
#mark_as_advanced(POINT_SET_DEMO_ENABLE_FORWARD_DECL)
# Let plugins be compiled in the same directory as the executable.
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
# Include this package's headers first
include_directories( BEFORE ./ ./include ../../include )
# Find CGAL and CGAL Qt4
find_package(CGAL COMPONENTS Qt4)
include( ${CGAL_USE_FILE} )
# Find Qt4 itself
set( QT_USE_QTXML TRUE )
set( QT_USE_QTMAIN TRUE )
set( QT_USE_QTSCRIPT TRUE )
set( QT_USE_QTOPENGL TRUE )
find_package(Qt4)
# Find OpenGL
find_package(OpenGL)
# Find QGLViewer
if(QT4_FOUND)
include(${QT_USE_FILE})
find_package(QGLViewer )
endif(QT4_FOUND)
# Find Eigen3 (requires 3.1.0 or greater)
find_package(Eigen3 3.1.0)
# Find Glew (optional), for splatting
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/GlSplat/cmake)
find_package(GLEW)
if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
include_directories ( ${QGLVIEWER_INCLUDE_DIR} )
if(GLEW_FOUND)
include_directories ( ${GLEW_INCLUDE_DIR} )
add_definitions(-DCGAL_GLEW_ENABLED)
else(GLEW_FOUND)
message(STATUS "NOTICE: GLEW library is not found. Splat rendering will not be available.")
endif(GLEW_FOUND)
# VisualC++ optimization for applications dealing with large data
if (MSVC)
# Use /FR to turn on IntelliSense
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /FR")
# Allow Windows applications to use up to 3GB of RAM
SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE")
# Turn off stupid VC++ warnings
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4311 /wd4800 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018")
# Prints new compilation options
message( STATUS "USING DEBUG CXXFLAGS = '${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}'" )
message( STATUS "USING DEBUG EXEFLAGS = '${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_DEBUG}'" )
message( STATUS "USING RELEASE CXXFLAGS = '${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}'" )
message( STATUS "USING RELEASE EXEFLAGS = '${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_RELEASE}'" )
endif()
# Temporary debugging stuff
ADD_DEFINITIONS( "-DDEBUG_TRACE" ) # turn on traces
qt4_wrap_ui( UI_FILES MainWindow.ui)
include(AddFileDependencies)
qt4_generate_moc( "MainWindow.h" "${CMAKE_CURRENT_BINARY_DIR}/MainWindow_moc.cpp" )
add_file_dependencies( MainWindow_moc.cpp "${CMAKE_CURRENT_SOURCE_DIR}/MainWindow.h" )
qt4_generate_moc( "Viewer.h" "${CMAKE_CURRENT_BINARY_DIR}/Viewer_moc.cpp" )
add_file_dependencies( Viewer_moc.cpp "${CMAKE_CURRENT_SOURCE_DIR}/Viewer.h" )
qt4_generate_moc( "Scene.h" "${CMAKE_CURRENT_BINARY_DIR}/Scene_moc.cpp" )
add_file_dependencies( Scene_moc.cpp "${CMAKE_CURRENT_SOURCE_DIR}/Scene.h" )
qt4_add_resources ( RESOURCE_FILES Point_set_demo.qrc )
qt4_automoc(Scene_item.cpp
Scene_plane_item.cpp
Point_set_scene_item.cpp
Scene_polyhedron_item.cpp)
# AUXILIARY LIBRARIES
# put plugins (which are shared libraries) at the same location as
# executable files
set(LIBRARY_OUTPUT_PATH ${RUNTIME_OUTPUT_PATH})
add_library(PS_demo_scene_item SHARED
Scene_item.cpp Scene_item.moc
Scene_item_with_display_list.cpp
Polyhedron_demo_plugin_helper.cpp)
target_link_libraries(PS_demo_scene_item ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${GLEW_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY})
add_library(PS_demo_scene_basic_objects SHARED
Scene_plane_item.cpp Scene_plane_item.moc)
target_link_libraries(PS_demo_scene_basic_objects PS_demo_scene_item ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY})
add_library(PS_demo_scene_polyhedron_item SHARED
Scene_polyhedron_item.cpp Scene_polyhedron_item.moc)
target_link_libraries(PS_demo_scene_polyhedron_item PS_demo_scene_item)
if(GLEW_FOUND)
qt4_add_resources(gl_splat_rc GlSplat/glsplat.qrc)
add_library(gl_splat SHARED
GlSplat/GlSplat.cpp GlSplat/Shader.cpp ${gl_splat_rc})
target_link_libraries(gl_splat ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${GLEW_LIBRARIES})
endif(GLEW_FOUND)
add_library(point_set SHARED
Point_set_scene_item.cpp Point_set_scene_item.moc)
target_link_libraries(point_set PS_demo_scene_item)
foreach(lib PS_demo_scene_item PS_demo_scene_basic_objects PS_demo_scene_polyhedron_item point_set)
add_to_cached_list(CGAL_EXECUTABLE_TARGETS ${lib})
endforeach()
if(GLEW_FOUND)
target_link_libraries( point_set gl_splat ${GLEW_LIBRARIES} )
endif(GLEW_FOUND)
add_definitions(-DQT_STATICPLUGIN)
# if(POINT_SET_DEMO_ENABLE_FORWARD_DECL)
add_definitions(-DUSE_FORWARD_DECL)
add_executable ( Point_set_demo
${UI_FILES}
MainWindow.cpp
Point_set_demo.cpp
Viewer.cpp
Scene.cpp
MainWindow_moc.cpp
Scene_moc.cpp
Viewer_moc.cpp
${RESOURCE_FILES} )
add_to_cached_list( CGAL_EXECUTABLE_TARGETS Point_set_demo )
# else(POINT_SET_DEMO_ENABLE_FORWARD_DECL)
# add_file_dependencies( Point_set_demo.cpp "${CMAKE_CURRENT_BINARY_DIR}/MainWindow_moc.cpp"
# "${CMAKE_CURRENT_BINARY_DIR}/Scene_moc.cpp"
# "${CMAKE_CURRENT_BINARY_DIR}/Viewer_moc.cpp" )
# add_executable ( Point_set_demo Point_set_demo.cpp ${UI_FILES} ${RESOURCE_FILES} )
# endif(POINT_SET_DEMO_ENABLE_FORWARD_DECL)
# Link with Qt libraries
target_link_libraries( Point_set_demo ${QT_LIBRARIES} )
# Link with CGAL
target_link_libraries( Point_set_demo ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} )
# Link with libQGLViewer, OpenGL
target_link_libraries( Point_set_demo ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} )
# Link with the scene_item libraries
target_link_libraries( Point_set_demo PS_demo_scene_item PS_demo_scene_polyhedron_item point_set )
if(GLEW_FOUND)
target_link_libraries( Point_set_demo gl_splat ${GLEW_LIBRARIES} )
endif(GLEW_FOUND)
add_to_cached_list( CGAL_EXECUTABLE_TARGETS Point_set_demo )
###########
# PLUGINS #
###########
remove_definitions(-DQT_STATICPLUGIN)
macro(point_set_demo_plugin plugin_name plugin_implementation_base_name)
list_split(option ARGN_TAIL ${ARGN} )
if(NOT ${option} STREQUAL "EXCLUDE_FROM_ALL")
set(other_sources ${ARGN})
set(option "")
else()
set(other_sources ${ARGN_TAIL})
endif()
qt4_generate_moc( "${CMAKE_CURRENT_SOURCE_DIR}/${plugin_implementation_base_name}.cpp" ${plugin_implementation_base_name}.moc )
add_file_dependencies( ${plugin_implementation_base_name}.moc "${CMAKE_CURRENT_SOURCE_DIR}/${plugin_implementation_base_name}.cpp" )
add_library(${plugin_name} MODULE ${option} ${plugin_implementation_base_name}.moc ${plugin_implementation_base_name}.cpp ${other_sources})
add_to_cached_list( CGAL_EXECUTABLE_TARGETS ${plugin_name} )
# Link with Qt
target_link_libraries( ${plugin_name} ${QT_LIBRARIES} )
# Link with scene_item
target_link_libraries( ${plugin_name} PS_demo_scene_item)
# Link with CGAL
target_link_libraries( ${plugin_name} ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} )
endmacro(point_set_demo_plugin)
if(EIGEN3_FOUND)
include( ${EIGEN3_USE_FILE} )
qt4_wrap_ui( POISSON_UI_FILES PS_demo_poisson_plugin.ui)
point_set_demo_plugin(PS_demo_poisson_plugin
PS_demo_poisson_plugin
PS_demo_poisson_plugin_cgal_code.cpp
${POISSON_UI_FILES})
target_link_libraries(PS_demo_poisson_plugin PS_demo_scene_polyhedron_item point_set)
point_set_demo_plugin(PS_demo_smoothing_plugin PS_demo_smoothing_plugin)
target_link_libraries(PS_demo_smoothing_plugin point_set)
qt4_wrap_ui( NORMAL_UI_FILES PS_demo_normal_estimation_plugin.ui)
point_set_demo_plugin(PS_demo_normal_estimation_plugin
PS_demo_normal_estimation_plugin
${NORMAL_UI_FILES})
target_link_libraries(PS_demo_normal_estimation_plugin point_set)
else()
message(STATUS "NOTICE: Eigen 3.1 (or greater) library has not been found. Poisson reconstruction, normal estimation and smoothing will not be available.")
endif()
point_set_demo_plugin(PS_demo_inside_out_plugin PS_demo_inside_out_plugin)
target_link_libraries(PS_demo_inside_out_plugin PS_demo_scene_polyhedron_item point_set)
point_set_demo_plugin(PS_demo_off_plugin PS_demo_off_plugin)
target_link_libraries(PS_demo_off_plugin PS_demo_scene_polyhedron_item point_set)
point_set_demo_plugin(PS_demo_xyz_plugin PS_demo_xyz_plugin)
target_link_libraries(PS_demo_xyz_plugin PS_demo_scene_polyhedron_item point_set)
qt4_wrap_ui(SIMPLIFICATION_UI_FILES PS_demo_simplification_plugin.ui)
point_set_demo_plugin(PS_demo_simplification_plugin
PS_demo_simplification_plugin
${SIMPLIFICATION_UI_FILES})
target_link_libraries(PS_demo_simplification_plugin point_set)
point_set_demo_plugin(PS_demo_local_spacing_plugin PS_demo_local_spacing_plugin)
target_link_libraries(PS_demo_local_spacing_plugin point_set)
point_set_demo_plugin(PS_demo_average_spacing_plugin PS_demo_average_spacing_plugin)
target_link_libraries(PS_demo_average_spacing_plugin point_set)
qt4_wrap_ui( CLEANING_UI_FILES PS_demo_cleaning_plugin.ui)
point_set_demo_plugin(PS_demo_cleaning_plugin
PS_demo_cleaning_plugin
${CLEANING_UI_FILES})
target_link_libraries(PS_demo_cleaning_plugin point_set)
else (CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
set(POINT_SET_DEMO_MISSING_DEPS "")
if(NOT CGAL_Qt4_FOUND)
set(POINT_SET_DEMO_MISSING_DEPS "the CGAL Qt4 library, ${POINT_SET_DEMO_MISSING_DEPS}")
endif()
if(NOT QT4_FOUND)
set(POINT_SET_DEMO_MISSING_DEPS "Qt4, ${POINT_SET_DEMO_MISSING_DEPS}")
endif()
if(NOT OPENGL_FOUND)
set(POINT_SET_DEMO_MISSING_DEPS "OpenGL, ${POINT_SET_DEMO_MISSING_DEPS}")
endif()
if(NOT QGLVIEWER_FOUND)
set(POINT_SET_DEMO_MISSING_DEPS "QGLViewer, ${POINT_SET_DEMO_MISSING_DEPS}")
endif()
message(STATUS "NOTICE: This demo requires ${POINT_SET_DEMO_MISSING_DEPS}and will not be compiled.")
endif (CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)

View File

@ -1,20 +0,0 @@
#ifndef KERNEL_TYPE_H
#define KERNEL_TYPE_H
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
// (Main) CGAL kernel used by this demo
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
// simple geometric types
typedef Kernel::FT FT;
typedef Kernel::Line_3 Line;
typedef Kernel::Point_3 Point;
typedef Kernel::Plane_3 Plane;
typedef Kernel::Sphere_3 Sphere;
typedef Kernel::Vector_3 Vector;
typedef Kernel::Triangle_3 Triangle;
typedef Kernel::Iso_cuboid_3 Iso_cuboid;
typedef Kernel::Plane_3 Plane_3;
#endif // KERNEL_TYPE_H

View File

@ -1,520 +0,0 @@
#include "config.h"
#include "MainWindow.h"
#include "Scene.h"
#include "Scene_item.h"
#include <CGAL/Qt/debug.h>
#include <QtDebug>
#include <QUrl>
#include <QFileDialog>
#include <QFileInfo>
#include <QSettings>
#include <QHeaderView>
#include <QMenu>
#include <QAction>
#include <QLibrary>
#include <QPluginLoader>
#include <QMessageBox>
#include <QScrollBar>
#include <QGLViewer/manipulatedFrame.h>
#include "Polyhedron_demo_plugin_interface.h"
#include "Polyhedron_demo_io_plugin_interface.h"
#include "ui_MainWindow.h"
MainWindow::~MainWindow()
{
delete ui;
}
MainWindow::MainWindow(QWidget* parent)
: CGAL::Qt::DemosMainWindow(parent)
{
ui = new Ui::MainWindow;
ui->setupUi(this);
// Saves some pointers from ui, for latter use.
treeView = ui->treeView;
viewer = ui->viewer;
// Setup the submenu of the View menu that can toggle the dockwidgets
Q_FOREACH(QDockWidget* widget, findChildren<QDockWidget*>()) {
ui->menuDockWindows->addAction(widget->toggleViewAction());
}
ui->menuDockWindows->removeAction(ui->dummyAction);
// do not save the state of the viewer (anoying)
viewer->setStateFileName(QString::null);
// accept drop events
setAcceptDrops(true);
// setup scene
scene = new Scene(this);
viewer->setScene(scene);
treeView->setModel(scene);
// setup the treeview: delegation and columns sizing...
treeView->setItemDelegate(new SceneDelegate(this));
treeView->header()->setStretchLastSection(false);
treeView->header()->setResizeMode(Scene::NameColumn, QHeaderView::Stretch);
treeView->header()->setResizeMode(Scene::NameColumn, QHeaderView::Stretch);
treeView->header()->setResizeMode(Scene::ColorColumn, QHeaderView::ResizeToContents);
treeView->header()->setResizeMode(Scene::RenderingModeColumn, QHeaderView::Fixed);
treeView->header()->setResizeMode(Scene::VisibleColumn, QHeaderView::Fixed);
treeView->resizeColumnToContents(Scene::ColorColumn);
treeView->resizeColumnToContents(Scene::RenderingModeColumn);
treeView->resizeColumnToContents(Scene::VisibleColumn);
// setup connections
connect(scene, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex & )),
this, SLOT(updateInfo()));
connect(scene, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex & )),
viewer, SLOT(updateGL()));
connect(scene, SIGNAL(updated()),
viewer, SLOT(update()));
connect(scene, SIGNAL(itemAboutToBeDestroyed(Scene_item*)),
this, SLOT(removeManipulatedFrame(Scene_item*)));
connect(scene, SIGNAL(updated_bbox()),
this, SLOT(updateViewerBBox()));
connect(treeView->selectionModel(),
SIGNAL(selectionChanged ( const QItemSelection & , const QItemSelection & ) ),
this, SLOT(updateInfo()));
connect(treeView->selectionModel(),
SIGNAL(selectionChanged ( const QItemSelection & , const QItemSelection & ) ),
this, SLOT(selectionChanged()));
connect(viewer, SIGNAL(selected(int)),
this, SLOT(selectSceneItem(int)));
connect(ui->actionAntiAliasing, SIGNAL(toggled(bool)),
viewer, SLOT(setAntiAliasing(bool)));
connect(ui->actionDraw_two_sides, SIGNAL(toggled(bool)),
viewer, SLOT(setTwoSides(bool)));
// enable anti-aliasing by default
ui->actionAntiAliasing->setChecked(true);
// add the "About CGAL..." and "About demo..." entries
this->addAboutCGAL();
this->addAboutDemo(":/cgal/Point_set_demo/about.html");
// Connect the button "addButton" with actionFileOpen
ui->addButton->setDefaultAction(ui->actionFileOpen);
// Same with "removeButton" and "duplicateButton"
ui->removeButton->setDefaultAction(ui->actionFileClose);
ui->duplicateButton->setDefaultAction(ui->actionDuplicate);
// Connect actionQuit (Ctrl+Q) and qApp->quit()
connect(ui->actionQuit, SIGNAL(triggered()),
this, SLOT(quit()));
// Recent files menu
this->addRecentFiles(ui->menuFile, ui->actionQuit);
connect(this, SIGNAL(openRecentFile(QString)),
this, SLOT(open(QString)));
// Empty the menus implemented by plugins:
// "Analysis", "Processing", "Reconstruction".
clearMenu(ui->menuAnalysis);
clearMenu(ui->menuProcessing);
clearMenu(ui->menuReconstruction);
// Loads plugins, and re-enable actions that need it.
loadPlugins();
readSettings(); // Among other things, the column widths are stored.
}
void MainWindow::loadPlugins()
{
Q_FOREACH(QObject *obj, QPluginLoader::staticInstances())
{
initPlugin(obj);
initIOPlugin(obj);
}
QDir pluginsDir(qApp->applicationDirPath());
Q_FOREACH (QString fileName, pluginsDir.entryList(QDir::Files)) {
if(fileName.contains("plugin") && QLibrary::isLibrary(fileName)) {
qDebug("### Loading \"%s\"...", fileName.toUtf8().data());
QPluginLoader loader;
loader.setFileName(pluginsDir.absoluteFilePath(fileName));
QObject *obj = loader.instance();
if(obj) {
initPlugin(obj);
initIOPlugin(obj);
}
else {
qDebug("Error loading \"%s\": %s",
qPrintable(fileName),
qPrintable(loader.errorString()));
}
}
}
}
bool MainWindow::initPlugin(QObject* obj)
{
QObjectList childs = this->children();
Polyhedron_demo_plugin_interface* plugin =
qobject_cast<Polyhedron_demo_plugin_interface*>(obj);
if(plugin) {
// Calls plugin's init() method
plugin->init(this, this->scene, this);
Q_FOREACH(QAction* action, plugin->actions()) {
// If action does not belong to the menus, add it to "Edit" menu.
// TODO: implement something less naive.
if(!childs.contains(action)) {
std::cerr << "Add " << action->text().toStdString() << " menu item to the Edit menu\n";
ui->menuEdit->addAction(action);
}
// Show and enable menu item
addAction(action);
}
return true;
}
else
return false;
}
bool MainWindow::initIOPlugin(QObject* obj)
{
Polyhedron_demo_io_plugin_interface* plugin =
qobject_cast<Polyhedron_demo_io_plugin_interface*>(obj);
if(plugin) {
// std::cerr << "I/O plugin\n";
io_plugins << plugin;
return true;
}
else
return false;
}
void MainWindow::clearMenu(QMenu* menu)
{
Q_FOREACH(QAction* action, menu->actions())
{
QMenu* menu = action->menu();
if(menu) {
clearMenu(menu);
}
action->setVisible(false);
}
menu->menuAction()->setEnabled(false);
}
void MainWindow::addAction(QAction* action)
{
if(!action) return;
action->setVisible(true);
action->setEnabled(true);
Q_FOREACH(QWidget* widget, action->associatedWidgets())
{
// qDebug() << QString("%1 (%2)\n")
// .arg(widget->objectName())
// .arg(widget->metaObject()->className());
QMenu* menu = qobject_cast<QMenu*>(widget);
if(menu)
{
addAction(menu->menuAction());
}
}
}
void MainWindow::message(QString message, QString colorName, QString /*font*/) {
if (message.endsWith('\n')) {
message.remove(message.length()-1, 1);
}
statusBar()->showMessage(message, 5000);
message = "<font color=\"" + colorName + "\" >" + message + "</font><br>";
message = "[" + QTime::currentTime().toString() + "] " + message;
ui->consoleTextEdit->insertHtml(message);
ui->consoleTextEdit->verticalScrollBar()->setValue(ui->consoleTextEdit->verticalScrollBar()->maximum());
}
void MainWindow::information(QString text) {
this->message("INFO: " + text, "");
}
void MainWindow::warning(QString text) {
this->message("WARNING: " + text, "blue");
}
void MainWindow::error(QString text) {
this->message("ERROR: " + text, "red");
}
void MainWindow::updateViewerBBox()
{
const Scene::Bbox bbox = scene->bbox();
const double xmin = bbox.xmin;
const double ymin = bbox.ymin;
const double zmin = bbox.zmin;
const double xmax = bbox.xmax;
const double ymax = bbox.ymax;
const double zmax = bbox.zmax;
// qDebug() << QString("Bounding box: (%1, %2, %3) - (%4, %5, %6)\n")
// .arg(xmin).arg(ymin).arg(zmin).arg(xmax).arg(ymax).arg(zmax);
qglviewer::Vec
vec_min(xmin, ymin, zmin),
vec_max(xmax, ymax, zmax);
viewer->setSceneBoundingBox(vec_min,
vec_max);
viewer->camera()->showEntireScene();
}
void MainWindow::open(QString filename)
{
QFileInfo fileinfo(filename);
Scene_item* item = 0;
if(fileinfo.isFile() && fileinfo.isReadable()) {
Q_FOREACH(Polyhedron_demo_io_plugin_interface* plugin,
io_plugins)
{
if(plugin->canLoad()) {
item = plugin->load(fileinfo);
if(item) break; // go out of the loop
}
}
if(item) {
Scene::Item_id index = scene->addItem(item);
QSettings settings;
settings.setValue("Point set open directory",
fileinfo.absoluteDir().absolutePath());
this->addToRecentFiles(filename);
selectSceneItem(index);
}
else {
QMessageBox::critical(this,
tr("Cannot open file"),
tr("File %1 has not a known file format.")
.arg(filename));
}
}
else {
QMessageBox::critical(this,
tr("Cannot open file"),
tr("File %1 is not a readable file.")
.arg(filename));
}
}
void MainWindow::selectSceneItem(int i)
{
if(i < 0) return;
if((unsigned int)i >= scene->numberOfEntries()) return;
treeView->selectionModel()->select(scene->createSelection(i),
QItemSelectionModel::ClearAndSelect);
}
int MainWindow::getSelectedSceneItemIndex() const
{
QModelIndexList selectedRows = treeView->selectionModel()->selectedRows();
if(selectedRows.empty())
return -1;
else
return selectedRows.first().row();
}
void MainWindow::selectionChanged()
{
scene->setSelectedItem(getSelectedSceneItemIndex());
Scene_item* item = scene->item(getSelectedSceneItemIndex());
if(item != NULL && item->manipulatable()) {
viewer->setManipulatedFrame(item->manipulatedFrame());
connect(viewer->manipulatedFrame(), SIGNAL(modified()),
this, SLOT(updateInfo()));
}
viewer->updateGL();
}
void MainWindow::removeManipulatedFrame(Scene_item* item)
{
if(item->manipulatable() &&
item->manipulatedFrame() == viewer->manipulatedFrame()) {
viewer->setManipulatedFrame(0);
}
}
void MainWindow::updateInfo() {
Scene_item* item = scene->item(getSelectedSceneItemIndex());
if(item)
ui->infoLabel->setText(item->toolTip());
else
ui->infoLabel->clear();
}
void MainWindow::readSettings()
{
this->readState("MainWindow", Size|State);
}
void MainWindow::writeSettings()
{
this->writeState("MainWindow");
std::cerr << "Write setting... done.\n";
}
void MainWindow::quit()
{
close();
}
void MainWindow::closeEvent(QCloseEvent *event)
{
writeSettings();
event->accept();
}
void MainWindow::on_actionFileOpen_triggered()
{
QStringList filters;
Q_FOREACH(Polyhedron_demo_io_plugin_interface* plugin, io_plugins) {
if(plugin->canLoad()) {
filters += plugin->nameFilters();
}
}
filters << tr("All files (*)");
QSettings settings;
QString directory = settings.value("Point set open directory",
QDir::current().dirName()).toString();
QStringList filenames =
QFileDialog::getOpenFileNames(this,
tr("Open File..."),
directory,
filters.join(";;"));
if(!filenames.isEmpty()) {
Q_FOREACH(QString filename, filenames) {
open(filename);
}
}
}
void MainWindow::on_actionSaveAs_triggered()
{
QModelIndexList selectedRows = treeView->selectionModel()->selectedRows();
if(selectedRows.size() != 1)
return;
Scene_item* item = scene->item(getSelectedSceneItemIndex());
if(!item)
return;
QVector<Polyhedron_demo_io_plugin_interface*> canSavePlugins;
QStringList filters;
Q_FOREACH(Polyhedron_demo_io_plugin_interface* plugin, io_plugins) {
if(plugin->canSave(item)) {
canSavePlugins << plugin;
filters += plugin->nameFilters();
}
}
filters << tr("All files (*)");
if(canSavePlugins.isEmpty()) {
QMessageBox::warning(this,
tr("Cannot save"),
tr("The selected object %1 cannot be saved.")
.arg(item->name()));
return;
}
QSettings settings;
QString directory = settings.value("Point set save directory",
QDir::current().dirName()).toString();
QString filename =
QFileDialog::getSaveFileName(this,
tr("Save As..."),
directory,
filters.join(";;"));
if (filename.isEmpty())
return;
QFileInfo fileinfo(filename);
bool saved = false;
Q_FOREACH(Polyhedron_demo_io_plugin_interface* plugin, canSavePlugins) {
if(plugin->save(item, fileinfo)) {
saved = true;
break;
}
}
if (saved) {
settings.setValue("Point set save directory",
fileinfo.absoluteDir().absolutePath());
}
else {
QMessageBox::warning(this,
tr("Cannot save"),
tr("Error while saving object %1 as %2.")
.arg(item->name())
.arg(filename));
}
}
bool MainWindow::on_actionFileClose_triggered()
{
int index = scene->erase(getSelectedSceneItemIndex());
selectSceneItem(index);
return index >= 0;
}
void MainWindow::on_actionFileCloseAll_triggered()
{
while(on_actionFileClose_triggered()) {
}
}
void MainWindow::on_actionDuplicate_triggered()
{
int index = scene->duplicate(getSelectedSceneItemIndex());
selectSceneItem(index);
}
void MainWindow::on_actionConvertToPointSet_triggered()
{
int index = scene->convertToPointSet(getSelectedSceneItemIndex());
selectSceneItem(index);
}
void MainWindow::on_actionDeleteSelection_triggered()
{
scene->deleteSelection(getSelectedSceneItemIndex());
}
void MainWindow::on_actionResetSelection_triggered()
{
scene->resetSelection(getSelectedSceneItemIndex());
}
void MainWindow::on_actionShowHide_triggered()
{
Q_FOREACH(QModelIndex index, treeView->selectionModel()->selectedRows())
{
int i = index.row();
Scene_item* item = scene->item(i);
item->setVisible(!item->visible());
scene->itemChanged(i);
}
}
void MainWindow::setAddKeyFrameKeyboardModifiers(::Qt::KeyboardModifiers m)
{
viewer->setAddKeyFrameKeyboardModifiers(m);
}

View File

@ -1,98 +0,0 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "config.h"
#include <QtOpenGL/qgl.h>
#include <CGAL/Qt/DemosMainWindow.h>
#include <QVector>
class Scene;
class Viewer;
class QTreeView;
class QMenu;
class Polyhedron_demo_io_plugin_interface;
class Scene_item;
namespace Ui {
class MainWindow;
}
#include "Polyhedron_type_fwd.h"
#include "Messages_interface.h"
class MainWindow :
public CGAL::Qt::DemosMainWindow,
public Messages_interface
{
Q_OBJECT
Q_INTERFACES(Messages_interface)
public:
MainWindow(QWidget* parent = 0);
~MainWindow();
public slots:
void updateViewerBBox();
void open(QString filename);
void selectSceneItem(int i);
void setAddKeyFrameKeyboardModifiers(Qt::KeyboardModifiers);
void clearMenu(QMenu*);
void addAction(QAction*);
void information(QString);
void warning(QString);
void error(QString);
protected slots:
void selectionChanged();
void updateInfo();
void removeManipulatedFrame(Scene_item*);
// settings
void quit();
void readSettings();
void writeSettings();
// load, erase, duplicate
void on_actionFileCloseAll_triggered();
void on_actionFileOpen_triggered();
bool on_actionFileClose_triggered();
void on_actionDuplicate_triggered();
void on_actionConvertToPointSet_triggered();
// selection
void on_actionDeleteSelection_triggered();
void on_actionResetSelection_triggered();
// Show/Hide
void on_actionShowHide_triggered();
// save as...
void on_actionSaveAs_triggered();
protected:
void message(QString, QString, QString = QString("normal"));
void loadPlugins();
bool initPlugin(QObject*);
bool initIOPlugin(QObject*);
void closeEvent(QCloseEvent *event);
int getSelectedSceneItemIndex() const;
private:
QString strippedName(const QString &fullFileName);
Scene* scene;
Viewer* viewer;
QTreeView* treeView;
Ui::MainWindow* ui;
QVector<Polyhedron_demo_io_plugin_interface*> io_plugins;
};
#endif // ifndef MAINWINDOW_H

View File

@ -1,429 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>636</width>
<height>578</height>
</rect>
</property>
<property name="windowTitle">
<string>CGAL Point Set demo</string>
</property>
<property name="windowIcon">
<iconset resource="Point_set_demo.qrc">
<normaloff>:/cgal/icons/resources/cgal_logo.xpm</normaloff>:/cgal/icons/resources/cgal_logo.xpm</iconset>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout">
<item>
<widget class="Viewer" name="viewer" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="infoLabel"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>636</width>
<height>26</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="actionFileOpen"/>
<addaction name="actionFileClose"/>
<addaction name="actionFileCloseAll"/>
<addaction name="actionSaveAs"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
</widget>
<widget class="QMenu" name="menuEdit">
<property name="title">
<string>&amp;Edit</string>
</property>
<addaction name="actionShowHide"/>
<addaction name="actionDuplicate"/>
<addaction name="separator"/>
<addaction name="actionDeleteSelection"/>
<addaction name="actionResetSelection"/>
<addaction name="separator"/>
<addaction name="actionConvertToPointSet"/>
</widget>
<widget class="QMenu" name="menuView">
<property name="title">
<string>&amp;View</string>
</property>
<widget class="QMenu" name="menuDockWindows">
<property name="title">
<string>Dock windows</string>
</property>
<addaction name="dummyAction"/>
</widget>
<addaction name="actionAntiAliasing"/>
<addaction name="actionDraw_two_sides"/>
<addaction name="menuDockWindows"/>
</widget>
<widget class="QMenu" name="menuAnalysis">
<property name="title">
<string>Analysis</string>
</property>
<addaction name="actionAverageSpacing"/>
<addaction name="actionRadiusFromDensity"/>
</widget>
<widget class="QMenu" name="menuProcessing">
<property name="title">
<string>Processing</string>
</property>
<addaction name="actionSimplify"/>
<addaction name="actionOutlierRemoval"/>
<addaction name="actionJetSmoothing"/>
<addaction name="actionNormalEstimation"/>
<addaction name="actionNormalInversion"/>
</widget>
<widget class="QMenu" name="menuReconstruction">
<property name="title">
<string>Reconstruction</string>
</property>
<addaction name="actionPoissonReconstruction"/>
<addaction name="actionAPSSReconstruction"/>
<addaction name="actionInsideOut"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
<addaction name="menuAnalysis"/>
<addaction name="menuProcessing"/>
<addaction name="menuReconstruction"/>
<addaction name="menuView"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QDockWidget" name="sceneDockWidget">
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="windowTitle">
<string>Point sets and surfaces</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContent">
<layout class="QGridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout">
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QToolButton" name="addButton">
<property name="text">
<string>+</string>
</property>
<property name="icon">
<iconset resource="Point_set_demo.qrc">
<normaloff>:/cgal/icons/plus</normaloff>:/cgal/icons/plus</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="removeButton">
<property name="text">
<string>-</string>
</property>
<property name="icon">
<iconset resource="Point_set_demo.qrc">
<normaloff>:/cgal/icons/minus</normaloff>:/cgal/icons/minus</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="duplicateButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="Point_set_demo.qrc">
<normaloff>:/cgal/icons/duplicate</normaloff>:/cgal/icons/duplicate</iconset>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="treeView">
<property name="editTriggers">
<set>QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="indentation">
<number>0</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="consoleDockWidget">
<property name="allowedAreas">
<set>Qt::BottomDockWidgetArea|Qt::LeftDockWidgetArea|Qt::TopDockWidgetArea</set>
</property>
<property name="windowTitle">
<string>Console</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout">
<item>
<widget class="QTextEdit" name="consoleTextEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<action name="actionQuit">
<property name="text">
<string>&amp;Quit</string>
</property>
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
<action name="actionSimplify">
<property name="text">
<string>&amp;Simplification</string>
</property>
</action>
<action name="actionFileOpen">
<property name="icon">
<iconset resource="Point_set_demo.qrc">
<normaloff>:/cgal/icons/plus</normaloff>:/cgal/icons/plus</iconset>
</property>
<property name="text">
<string>&amp;Open...</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
</property>
</action>
<action name="actionFileClose">
<property name="icon">
<iconset resource="Point_set_demo.qrc">
<normaloff>:/cgal/icons/minus</normaloff>:/cgal/icons/minus</iconset>
</property>
<property name="text">
<string>&amp;Close</string>
</property>
<property name="shortcut">
<string>Ctrl+W</string>
</property>
</action>
<action name="actionDuplicate">
<property name="icon">
<iconset resource="Point_set_demo.qrc">
<normaloff>:/cgal/icons/duplicate</normaloff>:/cgal/icons/duplicate</iconset>
</property>
<property name="text">
<string>&amp;Duplicate</string>
</property>
<property name="shortcut">
<string>Ctrl+D</string>
</property>
</action>
<action name="actionAntiAliasing">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Antialiasing</string>
</property>
</action>
<action name="dummyAction">
<property name="text">
<string>n/a</string>
</property>
</action>
<action name="actionFileCloseAll">
<property name="text">
<string>&amp;Close All</string>
</property>
</action>
<action name="actionOptions">
<property name="text">
<string>&amp;Options...</string>
</property>
</action>
<action name="actionSaveAs">
<property name="text">
<string>Save &amp;as...</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+S</string>
</property>
</action>
<action name="actionSave">
<property name="text">
<string>&amp;Save</string>
</property>
</action>
<action name="actionSaveAll">
<property name="text">
<string>Save a&amp;ll</string>
</property>
</action>
<action name="actionMergeAll">
<property name="text">
<string>Mer&amp;ge all</string>
</property>
</action>
<action name="actionMerge">
<property name="text">
<string>&amp;Merge</string>
</property>
</action>
<action name="actionSelectAll">
<property name="text">
<string>Select &amp;all</string>
</property>
</action>
<action name="actionSelectNone">
<property name="text">
<string>Select &amp;none</string>
</property>
</action>
<action name="actionSelectInvert">
<property name="text">
<string>&amp;Invert selection</string>
</property>
</action>
<action name="actionShowHide">
<property name="text">
<string>Show/Hide</string>
</property>
<property name="shortcut">
<string>Ctrl+Space</string>
</property>
</action>
<action name="actionInsideOut">
<property name="text">
<string>Inside-out</string>
</property>
</action>
<action name="actionAPSSReconstruction">
<property name="text">
<string>APSS Reconstruction</string>
</property>
</action>
<action name="actionRadiusFromDensity">
<property name="text">
<string>Point radius from density</string>
</property>
</action>
<action name="actionOutlierRemoval">
<property name="text">
<string>Outlier removal</string>
</property>
</action>
<action name="actionJetSmoothing">
<property name="text">
<string>Jet smoothing</string>
</property>
</action>
<action name="actionNormalEstimation">
<property name="text">
<string>Normal estimation</string>
</property>
</action>
<action name="actionDraw_two_sides">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Draw two sides</string>
</property>
</action>
<action name="actionConvertToPointSet">
<property name="text">
<string>Convert to Point Set</string>
</property>
<property name="toolTip">
<string>Convert Mesh to Point Set</string>
</property>
</action>
<action name="actionDeleteSelection">
<property name="text">
<string>Delete Selection</string>
</property>
<property name="shortcut">
<string>Del</string>
</property>
</action>
<action name="actionResetSelection">
<property name="text">
<string>Reset Selection</string>
</property>
</action>
<action name="actionPoissonReconstruction">
<property name="text">
<string>Poisson reconstruction</string>
</property>
</action>
<action name="actionAverageSpacing">
<property name="text">
<string>Average spacing</string>
</property>
</action>
<action name="actionNormalInversion">
<property name="text">
<string>Normal inversion</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>Viewer</class>
<extends>QWidget</extends>
<header>Viewer.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="Point_set_demo.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -1,18 +0,0 @@
#ifndef MESSAGES_INTERFACE_H
#define MESSAGES_INTERFACE_H
#include <QString>
#include <QObject>
class Messages_interface {
public:
virtual ~Messages_interface() {}
virtual void warning(QString) = 0;
virtual void error(QString) = 0;
virtual void information(QString) = 0;
};
Q_DECLARE_INTERFACE(Messages_interface,
"com.geometryfactory.PolyhedronDemo.MessagesInterface/1.0")
#endif // MESSAGES_INTERFACE_H

View File

@ -1,107 +0,0 @@
#include "config.h"
#include "Point_set_scene_item.h"
#include "Polyhedron_demo_plugin_helper.h"
#include "Polyhedron_demo_plugin_interface.h"
#include <CGAL/compute_average_spacing.h>
#include <CGAL/Timer.h>
#include <CGAL/Memory_sizer.h>
#include <QObject>
#include <QAction>
#include <QMainWindow>
#include <QApplication>
#include <QtPlugin>
#include <QInputDialog>
#include <QMessageBox>
class PS_demo_average_spacing_plugin :
public QObject,
public Polyhedron_demo_plugin_helper
{
Q_OBJECT
Q_INTERFACES(Polyhedron_demo_plugin_interface)
private:
QAction* actionAverageSpacing;
public:
void init(QMainWindow* mainWindow, Scene_interface* scene_interface) {
this->scene = scene_interface;
this->mw = mainWindow;
actionAverageSpacing = this->getActionFromMainWindow(mw, "actionAverageSpacing");
if(actionAverageSpacing) {
connect(actionAverageSpacing, SIGNAL(triggered()),
this, SLOT(on_actionAverageSpacing_triggered()));
}
}
QList<QAction*> actions() const {
return QList<QAction*>() << actionAverageSpacing;
}
public slots:
void on_actionAverageSpacing_triggered();
}; // end PS_demo_average_spacing_plugin
void PS_demo_average_spacing_plugin::on_actionAverageSpacing_triggered()
{
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Point_set_scene_item* item =
qobject_cast<Point_set_scene_item*>(scene->item(index));
if(item)
{
// Gets point set
Point_set* points = item->point_set();
if(points == NULL)
return;
// Gets options
bool ok;
const int nb_neighbors =
QInputDialog::getInteger((QWidget*)mw,
tr("Average Spacing"), // dialog title
tr("Number of neighbors:"), // field label
6, // default value = 1 ring
6, // min
1000, // max
1, // step
&ok);
if(!ok)
return;
QApplication::setOverrideCursor(Qt::WaitCursor);
CGAL::Timer task_timer; task_timer.start();
std::cerr << "Average spacing (k=" << nb_neighbors <<")...\n";
// Computes average spacing
double average_spacing = CGAL::compute_average_spacing(
points->begin(), points->end(),
nb_neighbors);
// Print result
Sphere bsphere = points->bounding_sphere();
FT radius = std::sqrt(bsphere.squared_radius());
long memory = CGAL::Memory_sizer().virtual_size();
std::cerr << "Average spacing = " << average_spacing
<< " = " << average_spacing/radius << " * point set radius ("
<< task_timer.time() << " seconds, "
<< (memory>>20) << " Mb allocated)"
<< std::endl;
QApplication::restoreOverrideCursor();
QMessageBox::information(NULL,
tr("Average Spacing"),
tr("Average Spacing = %1 = %2 * point set radius")
.arg(average_spacing)
.arg(average_spacing/radius));
}
}
Q_EXPORT_PLUGIN2(PS_demo_average_spacing_plugin, PS_demo_average_spacing_plugin)
#include "PS_demo_average_spacing_plugin.moc"

View File

@ -1,124 +0,0 @@
#include "config.h"
#include "Point_set_scene_item.h"
#include "Polyhedron_demo_plugin_helper.h"
#include "Polyhedron_demo_plugin_interface.h"
#include <CGAL/remove_outliers.h>
#include <CGAL/Timer.h>
#include <CGAL/Memory_sizer.h>
#include <QObject>
#include <QAction>
#include <QMainWindow>
#include <QApplication>
#include <QtPlugin>
#include <QInputDialog>
#include <QMessageBox>
#include "ui_PS_demo_cleaning_plugin.h"
class PS_demo_cleaning_plugin :
public QObject,
public Polyhedron_demo_plugin_helper
{
Q_OBJECT
Q_INTERFACES(Polyhedron_demo_plugin_interface)
private:
QAction* actionOutlierRemoval;
public:
void init(QMainWindow* mainWindow, Scene_interface* scene_interface) {
this->scene = scene_interface;
this->mw = mainWindow;
actionOutlierRemoval = this->getActionFromMainWindow(mw, "actionOutlierRemoval");
if(actionOutlierRemoval) {
connect(actionOutlierRemoval, SIGNAL(triggered()),
this, SLOT(on_actionOutlierRemoval_triggered()));
}
}
QList<QAction*> actions() const {
return QList<QAction*>() << actionOutlierRemoval;
}
public slots:
void on_actionOutlierRemoval_triggered();
}; // end PS_demo_cleaning_plugin
class Point_set_demo_outlier_removal_dialog : public QDialog, private Ui::OutlierRemovalDialog
{
Q_OBJECT
public:
Point_set_demo_outlier_removal_dialog(QWidget * /*parent*/ = 0)
{
setupUi(this);
}
double percentage() const { return m_inputPercentage->value(); }
int nbNeighbors() const { return m_inputNbNeighbors->value(); }
};
void PS_demo_cleaning_plugin::on_actionOutlierRemoval_triggered()
{
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Point_set_scene_item* item =
qobject_cast<Point_set_scene_item*>(scene->item(index));
if(item)
{
// Gets point set
Point_set* points = item->point_set();
if(points == NULL)
return;
// Gets options
Point_set_demo_outlier_removal_dialog dialog;
if(!dialog.exec())
return;
const double removed_percentage = dialog.percentage(); // percentage of points to remove
const int nb_neighbors = dialog.nbNeighbors();
QApplication::setOverrideCursor(Qt::WaitCursor);
CGAL::Timer task_timer; task_timer.start();
std::cerr << "Remove outliers (" << removed_percentage <<"%)...\n";
// Computes outliers
Point_set::iterator first_point_to_remove =
CGAL::remove_outliers(points->begin(), points->end(),
nb_neighbors,
removed_percentage);
int nb_points_to_remove = std::distance(first_point_to_remove, points->end());
long memory = CGAL::Memory_sizer().virtual_size();
std::cerr << "Simplification: " << nb_points_to_remove << " point(s) are selected for removal ("
<< task_timer.time() << " seconds, "
<< (memory>>20) << " Mb allocated)"
<< std::endl;
// Selects points to delete
points->select(points->begin(), points->end(), false);
points->select(first_point_to_remove, points->end(), true);
// Updates scene
scene->itemChanged(index);
QApplication::restoreOverrideCursor();
// Warns user
if (nb_points_to_remove > 0)
{
QMessageBox::information(NULL,
tr("Points selected from removal"),
tr("%1 point(s) are selected for removal.\nYou may remove them with the \"Delete selection\" menu item.")
.arg(nb_points_to_remove));
}
}
}
Q_EXPORT_PLUGIN2(PS_demo_cleaning_plugin, PS_demo_cleaning_plugin)
#include "PS_demo_cleaning_plugin.moc"

View File

@ -1,109 +0,0 @@
<ui version="4.0" >
<class>OutlierRemovalDialog</class>
<widget class="QDialog" name="OutlierRemovalDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>331</width>
<height>120</height>
</rect>
</property>
<property name="windowTitle" >
<string>Outlier Removal</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>Removed percentage:</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QDoubleSpinBox" name="m_inputPercentage" >
<property name="suffix" >
<string> %</string>
</property>
<property name="minimum" >
<double>0.010000000000000</double>
</property>
<property name="maximum" >
<double>100.000000000000000</double>
</property>
<property name="singleStep" >
<double>0.100000000000000</double>
</property>
<property name="value" >
<double>5.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>Neighbors</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QSpinBox" name="m_inputNbNeighbors" >
<property name="minimum" >
<number>6</number>
</property>
<property name="maximum" >
<number>9999</number>
</property>
<property name="value" >
<number>24</number>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>OutlierRemovalDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>OutlierRemovalDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,55 +0,0 @@
#include <QApplication>
#include <QAction>
#include <QStringList>
#include "Scene_polyhedron_item.h"
#include "Polyhedron_type.h"
#include "Polyhedron_demo_plugin_helper.h"
#include "Polyhedron_demo_plugin_interface.h"
class PS_demo_inside_out_plugin :
public QObject,
public Polyhedron_demo_plugin_helper
{
Q_OBJECT
Q_INTERFACES(Polyhedron_demo_plugin_interface)
public:
// used by Polyhedron_demo_plugin_helper
QStringList actionsNames() const {
return QStringList() << "actionInsideOut";
}
public slots:
void on_actionInsideOut_triggered();
}; // end PS_demo_inside_out_plugin
void PS_demo_inside_out_plugin::on_actionInsideOut_triggered()
{
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Scene_polyhedron_item* poly_item =
qobject_cast<Scene_polyhedron_item*>(scene->item(index));
if(poly_item)
{
QApplication::setOverrideCursor(Qt::WaitCursor);
Polyhedron* pMesh = poly_item->polyhedron();
if(!pMesh) return;
// inside out
pMesh->inside_out();
// update scene
scene->itemChanged(index);
// default cursor
QApplication::restoreOverrideCursor();
}
}
Q_EXPORT_PLUGIN2(PS_demo_inside_out_plugin, PS_demo_inside_out_plugin)
#include "PS_demo_inside_out_plugin.moc"

View File

@ -1,78 +0,0 @@
#include "config.h"
#include "Point_set_scene_item.h"
#include "Polyhedron_demo_plugin_helper.h"
#include "Polyhedron_demo_plugin_interface.h"
#include <QObject>
#include <QAction>
#include <QMainWindow>
#include <QApplication>
#include <QtPlugin>
#include <QInputDialog>
class PS_demo_local_spacing_plugin :
public QObject,
protected Polyhedron_demo_plugin_helper
{
Q_OBJECT
Q_INTERFACES(Polyhedron_demo_plugin_interface)
public:
void init(QMainWindow* mainWindow, Scene_interface* scene_interface) {
this->scene = scene_interface;
this->mw = mainWindow;
actionRadiusFromDensity = this->getActionFromMainWindow(mw, "actionRadiusFromDensity");
if(actionRadiusFromDensity) {
connect(actionRadiusFromDensity, SIGNAL(triggered()),
this, SLOT(on_actionRadiusFromDensity_triggered()));
}
}
QList<QAction*> actions() const {
return QList<QAction*>() << actionRadiusFromDensity;
}
public slots:
void on_actionRadiusFromDensity_triggered();
private:
QAction* actionRadiusFromDensity;
}; // end PS_demo_local_spacing_plugin
void PS_demo_local_spacing_plugin::on_actionRadiusFromDensity_triggered()
{
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Point_set_scene_item* item =
qobject_cast<Point_set_scene_item*>(scene->item(index));
if(item)
{
// Check there is a point set
if(item->point_set() == NULL)
return;
// Gets options
bool ok;
const int k =
QInputDialog::getInteger((QWidget*)mw,
tr("Local spacing"), // dialog title
tr("Number of neighbors:"), // field label
6, // default value = small
1, // min
1000, // max
1, // step
&ok);
if(!ok) return;
QApplication::setOverrideCursor(Qt::WaitCursor);
item->computes_local_spacing(k);
QApplication::restoreOverrideCursor();
}
}
Q_EXPORT_PLUGIN2(PS_demo_local_spacing_plugin, PS_demo_local_spacing_plugin)
#include "PS_demo_local_spacing_plugin.moc"

View File

@ -1,215 +0,0 @@
#include "config.h"
#include "Point_set_scene_item.h"
#include "Polyhedron_demo_plugin_helper.h"
#include "Polyhedron_demo_plugin_interface.h"
#include <CGAL/pca_estimate_normals.h>
#include <CGAL/jet_estimate_normals.h>
#include <CGAL/mst_orient_normals.h>
#include <CGAL/Timer.h>
#include <CGAL/Memory_sizer.h>
#include <QObject>
#include <QAction>
#include <QMainWindow>
#include <QApplication>
#include <QtPlugin>
#include <QInputDialog>
#include <QMessageBox>
#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<QAction*> actions() const {
return QList<QAction*>() << 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<Point_set_scene_item*>(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<Point_set_scene_item*>(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"

View File

@ -1,132 +0,0 @@
<ui version="4.0" >
<class>NormalEstimationDialog</class>
<widget class="QDialog" name="NormalEstimationDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>311</width>
<height>120</height>
</rect>
</property>
<property name="windowTitle" >
<string>Normal estimation</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>Direction:</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QComboBox" name="m_inputDirection" >
<item>
<property name="text" >
<string>quadric</string>
</property>
</item>
<item>
<property name="text" >
<string>plane</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2" >
<widget class="QSpinBox" name="m_inputNbNeighborsDirection" >
<property name="suffix" >
<string> neighbors</string>
</property>
<property name="minimum" >
<number>6</number>
</property>
<property name="maximum" >
<number>9999</number>
</property>
<property name="value" >
<number>18</number>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>Orientation:</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QComboBox" name="m_inputOrientation" >
<item>
<property name="text" >
<string>MST</string>
</property>
</item>
</widget>
</item>
<item row="1" column="2" >
<widget class="QSpinBox" name="m_inputNbNeighborsOrientation" >
<property name="suffix" >
<string> neighbors</string>
</property>
<property name="minimum" >
<number>6</number>
</property>
<property name="maximum" >
<number>9999</number>
</property>
<property name="value" >
<number>18</number>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2" >
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>NormalEstimationDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>NormalEstimationDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,100 +0,0 @@
#include "Point_set_scene_item.h"
#include "Scene_polyhedron_item.h"
#include "Polyhedron_type.h"
#include "Polyhedron_demo_io_plugin_interface.h"
#include <fstream>
class PS_demo_off_plugin :
public QObject,
public Polyhedron_demo_io_plugin_interface
{
Q_OBJECT
Q_INTERFACES(Polyhedron_demo_io_plugin_interface)
public:
QStringList nameFilters() const;
bool canLoad() const;
Scene_item* load(QFileInfo fileinfo);
bool canSave(const Scene_item*);
bool save(const Scene_item*, QFileInfo fileinfo);
};
QStringList PS_demo_off_plugin::nameFilters() const {
return QStringList() << "OFF files (*.off)";
}
bool PS_demo_off_plugin::canLoad() const {
return true;
}
Scene_item*
PS_demo_off_plugin::load(QFileInfo fileinfo) {
// Check extension (quietly)
std::string extension = fileinfo.suffix().toUtf8().data();
if (extension != "off" && extension != "OFF")
return NULL;
// Open file
std::ifstream in(fileinfo.filePath().toUtf8().data());
if(!in) {
std::cerr << "Error! Cannot open file " << fileinfo.filePath().toStdString() << std::endl;
return NULL;
}
// Try to read .off in a polyhedron
Scene_polyhedron_item* item = new Scene_polyhedron_item();
item->setName(fileinfo.completeBaseName());
if(!item->load(in))
{
delete item;
// Try to read .off in a point set
Point_set_scene_item* point_set_item = new Point_set_scene_item;
point_set_item->setName(fileinfo.completeBaseName());
in.close();
std::ifstream in2(fileinfo.filePath().toUtf8().data());
if(!point_set_item->read_off_point_set(in2)) {
delete point_set_item;
return 0;
}
return point_set_item;
}
return item;
}
bool PS_demo_off_plugin::canSave(const Scene_item* item)
{
// This plugin supports polyhedrons and point sets
return qobject_cast<const Scene_polyhedron_item*>(item) ||
qobject_cast<const Point_set_scene_item*>(item);
}
bool PS_demo_off_plugin::save(const Scene_item* item, QFileInfo fileinfo)
{
// Check extension (quietly)
std::string extension = fileinfo.suffix().toUtf8().data();
if (extension != "off" && extension != "OFF")
return false;
// This plugin supports polyhedrons and point sets
const Scene_polyhedron_item* poly_item =
qobject_cast<const Scene_polyhedron_item*>(item);
const Point_set_scene_item* point_set_item =
qobject_cast<const Point_set_scene_item*>(item);
if(!poly_item && !point_set_item)
return false;
// Save polyhedron/point set as .off
std::ofstream out(fileinfo.filePath().toUtf8().data());
return (poly_item && poly_item->save(out)) ||
(point_set_item && point_set_item->write_off_point_set(out));
}
#include <QtPlugin>
Q_EXPORT_PLUGIN2(PS_demo_off_plugin, PS_demo_off_plugin)
#include "PS_demo_off_plugin.moc"

View File

@ -1,124 +0,0 @@
#include "config.h"
#include "Point_set_scene_item.h"
#include "Polyhedron_demo_plugin_helper.h"
#include "Polyhedron_demo_plugin_interface.h"
#include "Scene_polyhedron_item.h"
#include <QObject>
#include <QAction>
#include <QMainWindow>
#include <QApplication>
#include <QtPlugin>
#include <QInputDialog>
#include "ui_PS_demo_poisson_plugin.h"
// Poisson reconstruction method:
// Reconstructs a surface mesh from a point set and returns it as a polyhedron.
Polyhedron* poisson_reconstruct(const Point_set& points,
FT sm_angle, // Min triangle angle (degrees).
FT sm_radius, // Max triangle size w.r.t. point set average spacing.
FT sm_distance, // Approximation error w.r.t. point set average spacing.
const QString& solver); // solver name
class PS_demo_poisson_plugin :
public QObject,
protected Polyhedron_demo_plugin_helper
{
Q_OBJECT
Q_INTERFACES(Polyhedron_demo_plugin_interface)
public:
void init(QMainWindow* mainWindow, Scene_interface* scene_interface) {
this->scene = scene_interface;
this->mw = mainWindow;
actionPoissonReconstruction = this->getActionFromMainWindow(mw, "actionPoissonReconstruction");
if(actionPoissonReconstruction) {
connect(actionPoissonReconstruction, SIGNAL(triggered()),
this, SLOT(reconstruct()));
}
}
QList<QAction*> actions() const {
return QList<QAction*>() << actionPoissonReconstruction;
}
public slots:
void reconstruct();
private:
QAction* actionPoissonReconstruction;
}; // end class PS_demo_poisson_plugin
class PS_demo_poisson_plugin_dialog : public QDialog, private Ui::PoissonDialog
{
Q_OBJECT
public:
PS_demo_poisson_plugin_dialog(QWidget* /*parent*/ = 0)
{
setupUi(this);
#ifdef CGAL_EIGEN3_ENABLED
m_inputSolver->addItem("Eigen - built-in simplicial LDLt");
m_inputSolver->addItem("Eigen - built-in CG");
#endif
}
double triangleAngle() const { return m_inputAngle->value(); }
double triangleRadius() const { return m_inputRadius->value(); }
double triangleError() const { return m_inputDistance->value(); }
QString solver() const { return m_inputSolver->currentText(); }
};
void PS_demo_poisson_plugin::reconstruct()
{
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Point_set_scene_item* point_set_item =
qobject_cast<Point_set_scene_item*>(scene->item(index));
if(point_set_item)
{
// Gets point set
Point_set* points = point_set_item->point_set();
if(!points) return;
// Gets options
PS_demo_poisson_plugin_dialog dialog;
if(!dialog.exec())
return;
const double sm_angle = dialog.triangleAngle();
const double sm_radius = dialog.triangleRadius();
const double sm_distance = dialog.triangleError();
const QString sm_solver = dialog.solver();
QApplication::setOverrideCursor(Qt::WaitCursor);
// Reconstruct point set as a polyhedron
Polyhedron* pRemesh = poisson_reconstruct(*points, sm_angle, sm_radius, sm_distance, sm_solver);
if(pRemesh)
{
// Add polyhedron to scene
Scene_polyhedron_item* new_item = new Scene_polyhedron_item(pRemesh);
new_item->setName(tr("%1 Poisson (%2 %3 %4)")
.arg(point_set_item->name())
.arg(sm_angle)
.arg(sm_radius)
.arg(sm_distance));
new_item->setColor(Qt::lightGray);
scene->addItem(new_item);
// Hide point set
point_set_item->setVisible(false);
scene->itemChanged(index);
}
QApplication::restoreOverrideCursor();
}
}
Q_EXPORT_PLUGIN2(PS_demo_poisson_plugin, PS_demo_poisson_plugin)
#include "PS_demo_poisson_plugin.moc"

View File

@ -1,156 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PoissonDialog</class>
<widget class="QDialog" name="PoissonDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>376</width>
<height>170</height>
</rect>
</property>
<property name="windowTitle">
<string>Poisson reconstruction</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Min triangle angle:</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QDoubleSpinBox" name="m_inputAngle">
<property name="suffix">
<string> °</string>
</property>
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>30.000000000000000</double>
</property>
<property name="value">
<double>20.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Max triangle size:</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QDoubleSpinBox" name="m_inputRadius">
<property name="suffix">
<string> * average spacing</string>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>1000.000000000000000</double>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Approximation error:</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QDoubleSpinBox" name="m_inputDistance">
<property name="suffix">
<string> * average spacing</string>
</property>
<property name="decimals">
<number>6</number>
</property>
<property name="minimum">
<double>0.010000000000000</double>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.250000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Solver:</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QComboBox" name="m_inputSolver">
<property name="toolTip">
<string extracomment="Name of the sparse solver"/>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PoissonDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>177</x>
<y>123</y>
</hint>
<hint type="destinationlabel">
<x>53</x>
<y>125</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PoissonDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>257</x>
<y>119</y>
</hint>
<hint type="destinationlabel">
<x>257</x>
<y>143</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,226 +0,0 @@
//----------------------------------------------------------
// Poisson reconstruction method:
// Reconstructs a surface mesh from a point set and returns it as a polyhedron.
//----------------------------------------------------------
// CGAL
#include <CGAL/AABB_tree.h> // must be included before kernel
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
#include <CGAL/Timer.h>
#include <CGAL/Surface_mesh_default_triangulation_3.h>
#include <CGAL/make_surface_mesh.h>
#include <CGAL/Poisson_implicit_surface_3.h>
#include <CGAL/IO/output_surface_facets_to_polyhedron.h>
#include <CGAL/Poisson_reconstruction_function.h>
#include <CGAL/compute_average_spacing.h>
#ifdef CGAL_EIGEN3_ENABLED
#include <CGAL/Eigen_solver_traits.h>
#endif
#include <math.h>
#include "Kernel_type.h"
#include "Polyhedron_type.h"
#include "Point_set_scene_item.h"
// Poisson implicit function
typedef CGAL::Poisson_reconstruction_function<Kernel> Poisson_reconstruction_function;
// Surface mesher
typedef CGAL::Surface_mesh_default_triangulation_3 STr;
typedef CGAL::Surface_mesh_complex_2_in_triangulation_3<STr> C2t3;
typedef CGAL::Poisson_implicit_surface_3<Kernel, Poisson_reconstruction_function> Surface_3;
// AABB tree
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
typedef CGAL::AABB_traits<Kernel, Primitive> AABB_traits;
typedef CGAL::AABB_tree<AABB_traits> AABB_tree;
// Poisson reconstruction method:
// Reconstructs a surface mesh from a point set and returns it as a polyhedron.
Polyhedron* poisson_reconstruct(const Point_set& points,
FT sm_angle, // Min triangle angle (degrees).
FT sm_radius, // Max triangle size w.r.t. point set average spacing.
FT sm_distance, // Approximation error w.r.t. point set average spacing.
const QString& solver_name) // solver name
{
CGAL::Timer task_timer; task_timer.start();
//***************************************
// Checks requirements
//***************************************
int nb_points = points.size();
if (nb_points == 0)
{
std::cerr << "Error: empty point set" << std::endl;
return NULL;
}
bool points_have_normals = (points.begin()->normal() != CGAL::NULL_VECTOR);
if ( ! points_have_normals )
{
std::cerr << "Input point set not supported: this reconstruction method requires oriented normals" << std::endl;
return NULL;
}
CGAL::Timer reconstruction_timer; reconstruction_timer.start();
//***************************************
// Computes implicit function
//***************************************
std::cerr << "Computes Poisson implicit function "
<< "using " << solver_name.toAscii().data() << " solver...\n";
// Creates implicit function from the point set.
// Note: this method requires an iterator over points
// + property maps to access each point's position and normal.
// The position property map can be omitted here as we use iterators over Point_3 elements.
Poisson_reconstruction_function function(
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
);
bool ok = false;
#ifdef CGAL_EIGEN3_ENABLED
if(solver_name=="Eigen - built-in simplicial LDLt")
{
CGAL::Eigen_solver_traits<Eigen::SimplicialCholesky<CGAL::Eigen_sparse_matrix<double>::EigenType> > solver;
ok = function.compute_implicit_function(solver);
}
if(solver_name=="Eigen - built-in CG")
{
CGAL::Eigen_solver_traits<Eigen::ConjugateGradient<CGAL::Eigen_sparse_matrix<double>::EigenType> > solver;
solver.solver().setTolerance(1e-6);
solver.solver().setMaxIterations(1000);
ok = function.compute_implicit_function(solver);
}
#endif
// Computes the Poisson indicator function f()
// at each vertex of the triangulation.
if ( ! ok )
{
std::cerr << "Error: cannot compute implicit function" << std::endl;
return NULL;
}
// Prints status
std::cerr << "Total implicit function (triangulation+refinement+solver): " << task_timer.time() << " seconds\n";
task_timer.reset();
//***************************************
// Surface mesh generation
//***************************************
std::cerr << "Surface meshing...\n";
// Computes average spacing
FT average_spacing = CGAL::compute_average_spacing(points.begin(), points.end(),
6 /* knn = 1 ring */);
// Gets one point inside the implicit surface
Point inner_point = function.get_inner_point();
FT inner_point_value = function(inner_point);
if(inner_point_value >= 0.0)
{
std::cerr << "Error: unable to seed (" << inner_point_value << " at inner_point)" << std::endl;
return NULL;
}
// Gets implicit function's radius
Sphere bsphere = function.bounding_sphere();
FT radius = std::sqrt(bsphere.squared_radius());
// Defines the implicit surface: requires defining a
// conservative bounding sphere centered at inner point.
FT sm_sphere_radius = 5.0 * radius;
FT sm_dichotomy_error = sm_distance*average_spacing/1000.0; // Dichotomy error must be << sm_distance
Surface_3 surface(function,
Sphere(inner_point,sm_sphere_radius*sm_sphere_radius),
sm_dichotomy_error/sm_sphere_radius);
// Defines surface mesh generation criteria
CGAL::Surface_mesh_default_criteria_3<STr> criteria(sm_angle, // Min triangle angle (degrees)
sm_radius*average_spacing, // Max triangle size
sm_distance*average_spacing); // Approximation error
CGAL_TRACE_STREAM << " make_surface_mesh(sphere center=("<<inner_point << "),\n"
<< " sphere radius="<<sm_sphere_radius<<",\n"
<< " angle="<<sm_angle << " degrees,\n"
<< " triangle size="<<sm_radius<<" * average spacing="<<sm_radius*average_spacing<<",\n"
<< " distance="<<sm_distance<<" * average spacing="<<sm_distance*average_spacing<<",\n"
<< " dichotomy error=distance/"<<sm_distance*average_spacing/sm_dichotomy_error<<",\n"
<< " Manifold_with_boundary_tag)\n";
// Generates surface mesh with manifold option
STr tr; // 3D Delaunay triangulation for surface mesh generation
C2t3 c2t3(tr); // 2D complex in 3D Delaunay triangulation
CGAL::make_surface_mesh(c2t3, // reconstructed mesh
surface, // implicit surface
criteria, // meshing criteria
CGAL::Manifold_with_boundary_tag()); // require manifold mesh
// Prints status
std::cerr << "Surface meshing: " << task_timer.time() << " seconds, "
<< tr.number_of_vertices() << " output vertices"
<< std::endl;
task_timer.reset();
if(tr.number_of_vertices() == 0)
return NULL;
// Converts to polyhedron
Polyhedron* output_mesh = new Polyhedron;
CGAL::output_surface_facets_to_polyhedron(c2t3, *output_mesh);
// Prints total reconstruction duration
std::cerr << "Total reconstruction (implicit function + meshing): " << reconstruction_timer.time() << " seconds\n";
//***************************************
// Computes reconstruction error
//***************************************
// Constructs AABB tree and computes internal KD-tree
// data structure to accelerate distance queries
AABB_tree tree(faces(*output_mesh).first, faces(*output_mesh).second, *output_mesh);
tree.accelerate_distance_queries();
// Computes distance from each input point to reconstructed mesh
double max_distance = DBL_MIN;
double avg_distance = 0;
for (Point_set::const_iterator p=points.begin(); p!=points.end(); p++)
{
double distance = std::sqrt(tree.squared_distance(*p));
max_distance = (std::max)(max_distance, distance);
avg_distance += distance;
}
avg_distance /= double(points.size());
std::cerr << "Reconstruction error:\n"
<< " max = " << max_distance << " = " << max_distance/average_spacing << " * average spacing\n"
<< " avg = " << avg_distance << " = " << avg_distance/average_spacing << " * average spacing\n";
return output_mesh;
}

View File

@ -1,142 +0,0 @@
#include "config.h"
#include "Point_set_scene_item.h"
#include "Polyhedron_demo_plugin_helper.h"
#include "Polyhedron_demo_plugin_interface.h"
#include <CGAL/grid_simplify_point_set.h>
#include <CGAL/random_simplify_point_set.h>
#include <CGAL/compute_average_spacing.h>
#include <CGAL/Timer.h>
#include <CGAL/Memory_sizer.h>
#include <QObject>
#include <QAction>
#include <QMainWindow>
#include <QApplication>
#include <QtPlugin>
#include <QMessageBox>
#include "ui_PS_demo_simplification_plugin.h"
class PS_demo_simplification_plugin :
public QObject,
public Polyhedron_demo_plugin_helper
{
Q_OBJECT
Q_INTERFACES(Polyhedron_demo_plugin_interface)
QAction* actionSimplify;
public:
void init(QMainWindow* mainWindow, Scene_interface* scene_interface) {
this->scene = scene_interface;
this->mw = mainWindow;
actionSimplify = this->getActionFromMainWindow(mw, "actionSimplify");
if(actionSimplify) {
connect(actionSimplify, SIGNAL(triggered()),
this, SLOT(on_actionSimplify_triggered()));
}
}
QList<QAction*> actions() const {
return QList<QAction*>() << actionSimplify;
}
public slots:
void on_actionSimplify_triggered();
}; // end PS_demo_simplification_plugin
class Point_set_demo_point_set_simplification_dialog : public QDialog, private Ui::PointSetSimplificationDialog
{
Q_OBJECT
public:
Point_set_demo_point_set_simplification_dialog(QWidget * /*parent*/ = 0)
{
setupUi(this);
}
QString simplificationMethod() const { return m_simplificationMethod->currentText(); }
float randomSimplificationPercentage() const { return m_randomSimplificationPercentage->value(); }
float gridCellSize() const { return m_gridCellSize->value(); }
};
void PS_demo_simplification_plugin::on_actionSimplify_triggered()
{
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Point_set_scene_item* item =
qobject_cast<Point_set_scene_item*>(scene->item(index));
if(item)
{
// Gets point set
Point_set* points = item->point_set();
if(points == NULL)
return;
// Gets options
Point_set_demo_point_set_simplification_dialog dialog;
if(!dialog.exec())
return;
QApplication::setOverrideCursor(Qt::WaitCursor);
CGAL::Timer task_timer; task_timer.start();
// First point to delete
Point_set::iterator first_point_to_remove = points->end();
if (dialog.simplificationMethod() == "Random")
{
std::cerr << "Random point cloud simplification (" << dialog.randomSimplificationPercentage() <<"%)...\n";
// Computes points to remove by random simplification
first_point_to_remove =
CGAL::random_simplify_point_set(points->begin(), points->end(),
dialog.randomSimplificationPercentage());
}
else if (dialog.simplificationMethod() == "Grid Clustering")
{
std::cerr << "Point cloud simplification by clustering (cell size = " << dialog.gridCellSize() <<" * average spacing)...\n";
// Computes average spacing
double average_spacing = CGAL::compute_average_spacing(
points->begin(), points->end(),
6 /* knn = 1 ring */);
// Computes points to remove by Grid Clustering
first_point_to_remove =
CGAL::grid_simplify_point_set(points->begin(), points->end(),
dialog.gridCellSize()*average_spacing);
}
int nb_points_to_remove = std::distance(first_point_to_remove, points->end());
long memory = CGAL::Memory_sizer().virtual_size();
std::cerr << "Simplification: " << nb_points_to_remove << " point(s) are selected for removal ("
<< task_timer.time() << " seconds, "
<< (memory>>20) << " Mb allocated)"
<< std::endl;
// Selects points to delete
points->select(points->begin(), points->end(), false);
points->select(first_point_to_remove, points->end(), true);
// Updates scene
scene->itemChanged(index);
QApplication::restoreOverrideCursor();
// Warns user
if (nb_points_to_remove > 0)
{
QMessageBox::information(NULL,
tr("Points selected from removal"),
tr("%1 point(s) are selected for removal.\nYou may remove them with the \"Delete selection\" menu item.")
.arg(nb_points_to_remove));
}
}
}
Q_EXPORT_PLUGIN2(PS_demo_simplification_plugin, PS_demo_simplification_plugin)
#include "PS_demo_simplification_plugin.moc"

View File

@ -1,142 +0,0 @@
<ui version="4.0" >
<class>PointSetSimplificationDialog</class>
<widget class="QDialog" name="PointSetSimplificationDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>403</width>
<height>153</height>
</rect>
</property>
<property name="windowTitle" >
<string>Simplification</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>Method:</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QComboBox" name="m_simplificationMethod" >
<item>
<property name="text" >
<string>Random</string>
</property>
</item>
<item>
<property name="text" >
<string>Grid Clustering</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>Points to Remove Randomly</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QDoubleSpinBox" name="m_randomSimplificationPercentage" >
<property name="suffix" >
<string> %</string>
</property>
<property name="decimals" >
<number>2</number>
</property>
<property name="minimum" >
<double>0.100000000000000</double>
</property>
<property name="maximum" >
<double>100.000000000000000</double>
</property>
<property name="singleStep" >
<double>0.100000000000000</double>
</property>
<property name="value" >
<double>50.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>Grid Cell Size</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QDoubleSpinBox" name="m_gridCellSize" >
<property name="suffix" >
<string> * average spacing</string>
</property>
<property name="decimals" >
<number>2</number>
</property>
<property name="minimum" >
<double>0.100000000000000</double>
</property>
<property name="maximum" >
<double>10.000000000000000</double>
</property>
<property name="singleStep" >
<double>0.100000000000000</double>
</property>
<property name="value" >
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2" >
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PointSetSimplificationDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PointSetSimplificationDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,83 +0,0 @@
#include "config.h"
#include "Point_set_scene_item.h"
#include "Polyhedron_demo_plugin_helper.h"
#include "Polyhedron_demo_plugin_interface.h"
#include <QObject>
#include <QAction>
#include <QMainWindow>
#include <QApplication>
#include <QtPlugin>
#include <QInputDialog>
#include <CGAL/jet_smooth_point_set.h>
class PS_demo_smoothing_plugin :
public QObject,
public Polyhedron_demo_plugin_helper
{
Q_OBJECT
Q_INTERFACES(Polyhedron_demo_plugin_interface)
QAction* actionJetSmoothing;
public:
void init(QMainWindow* mainWindow, Scene_interface* scene_interface) {
this->scene = scene_interface;
this->mw = mainWindow;
actionJetSmoothing = this->getActionFromMainWindow(mw, "actionJetSmoothing");
if(actionJetSmoothing) {
connect(actionJetSmoothing, SIGNAL(triggered()),
this, SLOT(on_actionJetSmoothing_triggered()));
}
}
QList<QAction*> actions() const {
return QList<QAction*>() << actionJetSmoothing;
}
public slots:
void on_actionJetSmoothing_triggered();
}; // end PS_demo_smoothing_plugin
void PS_demo_smoothing_plugin::on_actionJetSmoothing_triggered()
{
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Point_set_scene_item* item =
qobject_cast<Point_set_scene_item*>(scene->item(index));
if(item)
{
Point_set* points = item->point_set();
if(!points) return;
// Gets options
bool ok;
const unsigned int nb_neighbors =
QInputDialog::getInteger((QWidget*)mw,
tr("Jet Smoothing"), // dialog title
tr("Number of neighbors:"), // field label
24, // default value = fast
6, // min
1000, // max
1, // step
&ok);
if(!ok) return;
QApplication::setOverrideCursor(Qt::WaitCursor);
CGAL::jet_smooth_point_set(points->begin(), points->end(), nb_neighbors);
points->invalidate_bounds();
// update scene
scene->itemChanged(index);
QApplication::restoreOverrideCursor();
}
}
Q_EXPORT_PLUGIN2(PS_demo_smoothing_plugin, PS_demo_smoothing_plugin)
#include "PS_demo_smoothing_plugin.moc"

View File

@ -1,86 +0,0 @@
#include "Point_set_scene_item.h"
#include "Kernel_type.h"
#include "Polyhedron_demo_io_plugin_interface.h"
#include <fstream>
class PS_demo_xyz_plugin :
public QObject,
public Polyhedron_demo_io_plugin_interface
{
Q_OBJECT
Q_INTERFACES(Polyhedron_demo_io_plugin_interface)
public:
QStringList nameFilters() const;
bool canLoad() const;
Scene_item* load(QFileInfo fileinfo);
bool canSave(const Scene_item*);
bool save(const Scene_item*, QFileInfo fileinfo);
};
QStringList PS_demo_xyz_plugin::nameFilters() const {
return QStringList() << "XYZ files (*.xyz)"
<< "Point Sets with Normal (*.pwn)";
}
bool PS_demo_xyz_plugin::canLoad() const {
return true;
}
Scene_item*
PS_demo_xyz_plugin::load(QFileInfo fileinfo)
{
// Check extension (quietly)
std::string extension = fileinfo.suffix().toUtf8().data();
if (extension != "xyz" && extension != "XYZ" &&
extension != "pwn" && extension != "PWN")
return NULL;
// Open file
std::ifstream in(fileinfo.filePath().toUtf8().data());
if(!in) {
std::cerr << "Error! Cannot open file " << fileinfo.filePath().toStdString() << std::endl;
return NULL;
}
// Read .xyz in a point set
Point_set_scene_item* point_set_item = new Point_set_scene_item;
point_set_item->setName(fileinfo.completeBaseName());
if(!point_set_item->read_xyz_point_set(in)) {
delete point_set_item;
return NULL;
}
return point_set_item;
}
bool PS_demo_xyz_plugin::canSave(const Scene_item* item)
{
// This plugin supports point sets
return qobject_cast<const Point_set_scene_item*>(item);
}
bool PS_demo_xyz_plugin::save(const Scene_item* item, QFileInfo fileinfo)
{
// Check extension (quietly)
std::string extension = fileinfo.suffix().toUtf8().data();
if (extension != "xyz" && extension != "XYZ" &&
extension != "pwn" && extension != "PWN")
return false;
// This plugin supports point sets
const Point_set_scene_item* point_set_item =
qobject_cast<const Point_set_scene_item*>(item);
if(!point_set_item)
return false;
// Save point set as .xyz
std::ofstream out(fileinfo.filePath().toUtf8().data());
return point_set_item->write_xyz_point_set(out);
}
#include <QtPlugin>
Q_EXPORT_PLUGIN2(PS_demo_xyz_plugin, PS_demo_xyz_plugin)
#include "PS_demo_xyz_plugin.moc"

View File

@ -1,41 +0,0 @@
#include "MainWindow.h"
#include <QApplication>
#include <CGAL/Qt/resources.h>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
app.setOrganizationDomain("cgal.org");
app.setOrganizationName("CGAL");
app.setApplicationName("Point Set Demo");
// Import resources from libCGALQt4.
// See http://doc.trolltech.com/4.4/qdir.html#Q_INIT_RESOURCE
CGAL_QT4_INIT_RESOURCES;
MainWindow mainWindow;
mainWindow.show();
QStringList args = app.arguments();
args.removeAt(0);
if(!args.empty() && args[0] == "--use-meta")
{
mainWindow.setAddKeyFrameKeyboardModifiers(::Qt::MetaModifier);
args.removeAt(0);
}
Q_FOREACH(QString filename, args) {
mainWindow.open(filename);
}
return app.exec();
}
#ifndef USE_FORWARD_DECL
# include "Scene.cpp"
# include "Scene_item.cpp"
# include "Scene_moc.cpp"
# include "Viewer.cpp"
# include "Viewer_moc.cpp"
# include "MainWindow.cpp"
# include "MainWindow_moc.cpp"
#endif

View File

@ -1,14 +0,0 @@
<RCC>
<qresource prefix="/cgal/icons" >
<file>resources/cgal_logo.xpm</file>
<file alias="simplification.png" >resources/simplification.png</file>
<file alias="duplicate" >resources/editcopy.png</file>
<file alias="check-on.png" >resources/check-on.png</file>
<file alias="plus" >resources/plus.png</file>
<file alias="check-off.png" >resources/check-off.png</file>
<file alias="minus" >resources/minus.png</file>
</qresource>
<qresource prefix="/cgal/Point_set_demo" >
<file alias="about.html" >resources/about.html</file>
</qresource>
</RCC>

View File

@ -1,292 +0,0 @@
#include "Point_set_scene_item.h"
#include "Polyhedron_type.h"
#include "CGAL/compute_normal.h"
#include <CGAL/IO/read_off_points.h>
#include <CGAL/IO/write_off_points.h>
#include <CGAL/IO/read_xyz_points.h>
#include <CGAL/IO/write_xyz_points.h>
#include <CGAL/Timer.h>
#include <CGAL/Memory_sizer.h>
#include <CGAL/Orthogonal_k_neighbor_search.h>
#include <CGAL/Search_traits_3.h>
#include <QObject>
#include <set>
#include <stack>
#include <algorithm>
#include <boost/array.hpp>
Point_set_scene_item::Point_set_scene_item()
: Scene_item_with_display_list(),
m_points(new Point_set)
{
setRenderingMode(PointsPlusNormals);
}
// Copy constructor
Point_set_scene_item::Point_set_scene_item(const Point_set_scene_item& toCopy)
: Scene_item_with_display_list(), // do not call superclass' copy constructor
m_points(new Point_set(*toCopy.m_points))
{
setRenderingMode(PointsPlusNormals);
}
// Converts polyhedron to point set
Point_set_scene_item::Point_set_scene_item(const Polyhedron& input_mesh)
: Scene_item_with_display_list(),
m_points(new Point_set)
{
// Converts Polyhedron vertices to point set.
// Computes vertices normal from connectivity.
Polyhedron::Vertex_const_iterator v;
for (v = input_mesh.vertices_begin(); v != input_mesh.vertices_end(); v++)
{
const Point& p = v->point();
Vector n = compute_vertex_normal<Polyhedron::Vertex,Kernel>(*v);
m_points->push_back(UI_point(p,n));
}
setRenderingMode(PointsPlusNormals);
}
Point_set_scene_item::~Point_set_scene_item()
{
Q_ASSERT(m_points != NULL);
delete m_points; m_points = NULL;
}
// Duplicates scene item
Point_set_scene_item*
Point_set_scene_item::clone() const
{
return new Point_set_scene_item(*this);
}
// Is selection empty?
bool Point_set_scene_item::isSelectionEmpty() const
{
return (m_points->nb_selected_points() == 0);
}
// Delete selection
void Point_set_scene_item::deleteSelection()
{
CGAL::Timer task_timer; task_timer.start();
std::cerr << "Delete " << m_points->nb_selected_points() << " points...";
// Delete selected points
m_points->delete_selection();
long memory = CGAL::Memory_sizer().virtual_size();
std::cerr << "done: " << task_timer.time() << " seconds, "
<< (memory>>20) << " Mb allocated"
<< std::endl;
}
// Reset selection mark
void Point_set_scene_item::resetSelection()
{
// Un-select all points
m_points->select(m_points->begin(), m_points->end(), false);
}
// Loads point set from .OFF file
bool Point_set_scene_item::read_off_point_set(std::istream& stream)
{
Q_ASSERT(m_points != NULL);
m_points->clear();
bool ok = stream &&
CGAL::read_off_points_and_normals(stream,
std::back_inserter(*m_points),
#ifdef CGAL_USE_PROPERTY_MAPS_API_V1
CGAL::make_normal_of_point_with_normal_pmap(std::back_inserter(*m_points))
#else
CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())
#endif
) &&
!isEmpty();
return ok;
}
// Write point set to .OFF file
bool Point_set_scene_item::write_off_point_set(std::ostream& stream) const
{
Q_ASSERT(m_points != NULL);
return stream &&
CGAL::write_off_points_and_normals(stream,
m_points->begin(), m_points->end(),
#ifdef CGAL_USE_PROPERTY_MAPS_API_V1
CGAL::make_normal_of_point_with_normal_pmap(m_points->begin())
#else
CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())
#endif
);
}
// Loads point set from .XYZ file
bool Point_set_scene_item::read_xyz_point_set(std::istream& stream)
{
Q_ASSERT(m_points != NULL);
m_points->clear();
bool ok = stream &&
CGAL::read_xyz_points_and_normals(stream,
std::back_inserter(*m_points),
#ifdef CGAL_USE_PROPERTY_MAPS_API_V1
CGAL::make_normal_of_point_with_normal_pmap(std::back_inserter(*m_points))
#else
CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())
#endif
) &&
!isEmpty();
return ok;
}
// Write point set to .XYZ file
bool Point_set_scene_item::write_xyz_point_set(std::ostream& stream) const
{
Q_ASSERT(m_points != NULL);
return stream &&
CGAL::write_xyz_points_and_normals(stream,
m_points->begin(), m_points->end(),
#ifdef CGAL_USE_PROPERTY_MAPS_API_V1
CGAL::make_normal_of_point_with_normal_pmap(m_points->begin())
#else
CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())
#endif
);
}
QString
Point_set_scene_item::toolTip() const
{
Q_ASSERT(m_points != NULL);
return QObject::tr("<p><b>%1</b> (color: %4)<br />"
"<i>Point set</i></p>"
"<p>Number of points: %2</p>")
.arg(name())
.arg(m_points->size())
.arg(color().name());
}
bool Point_set_scene_item::supportsRenderingMode(RenderingMode m) const
{
return m==Points || m==PointsPlusNormals || m==Splatting;
}
// Points OpenGL drawing in a display list
void Point_set_scene_item::direct_draw() const
{
Q_ASSERT(m_points != NULL);
// Draw points
m_points->gl_draw_vertices();
}
// Normals OpenGL drawing
void Point_set_scene_item::draw_normals() const
{
Q_ASSERT(m_points != NULL);
// Draw normals
bool points_have_normals = (m_points->begin() != m_points->end() &&
m_points->begin()->normal() != CGAL::NULL_VECTOR);
if(points_have_normals)
{
Sphere region_of_interest = m_points->region_of_interest();
float normal_length = (float)std::sqrt(region_of_interest.squared_radius() / 1000.);
m_points->gl_draw_normals(normal_length);
}
}
void Point_set_scene_item::draw_splats() const
{
Q_ASSERT(m_points != NULL);
// Draw splats
bool points_have_normals = (m_points->begin() != m_points->end() &&
m_points->begin()->normal() != CGAL::NULL_VECTOR);
bool points_have_radii = (m_points->begin() != m_points->end() &&
m_points->begin()->radius() != FT(0));
if(points_have_normals && points_have_radii)
{
m_points->gl_draw_splats();
}
}
// Gets wrapped point set
Point_set* Point_set_scene_item::point_set()
{
Q_ASSERT(m_points != NULL);
return m_points;
}
const Point_set* Point_set_scene_item::point_set() const
{
Q_ASSERT(m_points != NULL);
return m_points;
}
bool
Point_set_scene_item::isEmpty() const
{
Q_ASSERT(m_points != NULL);
return m_points->empty();
}
Point_set_scene_item::Bbox
Point_set_scene_item::bbox() const
{
Q_ASSERT(m_points != NULL);
Iso_cuboid bbox = m_points->bounding_box();
return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(),
bbox.xmax(),bbox.ymax(),bbox.zmax());
}
void Point_set_scene_item::computes_local_spacing(int k)
{
typedef Kernel Geom_traits;
typedef CGAL::Search_traits_3<Geom_traits> TreeTraits;
typedef CGAL::Orthogonal_k_neighbor_search<TreeTraits> Neighbor_search;
typedef Neighbor_search::Tree Tree;
Point_set::iterator end(m_points->end());
// build kdtree
Tree tree(m_points->begin(), end);
// Compute the radius of each point = (distance max to k nearest neighbors)/2.
{
int i=0;
for (Point_set::iterator it=m_points->begin(); it!=end; ++it, ++i)
{
Neighbor_search search(tree, *it, k+1);
double maxdist2 = (--search.end())->second; // squared distance to furthest neighbor
it->radius() = sqrt(maxdist2)/2.;
}
}
m_points->set_radii_uptodate(true);
}
void Point_set_scene_item::setRenderingMode(RenderingMode m)
{
Scene_item_with_display_list::setRenderingMode(m);
if (rendering_mode==Splatting && (!m_points->are_radii_uptodate()))
{
computes_local_spacing(6); // default value = small
}
}
#include "Point_set_scene_item.moc"

View File

@ -1,77 +0,0 @@
#ifndef POINT_SET_ITEM_H
#define POINT_SET_ITEM_H
#include "Point_set_scene_item_config.h"
#include "Polyhedron_type_fwd.h"
#include "Kernel_type.h"
#include "Point_set_3.h"
#include "Scene_item_with_display_list.h"
#include <iostream>
// point set
typedef Point_set_3<Kernel> Point_set;
typedef Point_set::UI_point UI_point; // type of points in Point_set_3
// This class represents a point set in the OpenGL scene
class POINT_SET_ITEM_EXPORT Point_set_scene_item
: public Scene_item_with_display_list
{
Q_OBJECT
public:
Point_set_scene_item();
Point_set_scene_item(const Point_set_scene_item& toCopy);
Point_set_scene_item(const Polyhedron& p);
~Point_set_scene_item();
Point_set_scene_item* clone() const;
// Is selection empty?
virtual bool isSelectionEmpty() const;
// Delete selection
virtual void deleteSelection();
// Reset selection mark
void resetSelection();
// IO
bool read_off_point_set(std::istream& in);
bool write_off_point_set(std::ostream& out) const;
bool read_xyz_point_set(std::istream& in);
bool write_xyz_point_set(std::ostream& out) const;
// Function for displaying meta-data of the item
virtual QString toolTip() const;
// Indicate if rendering mode is supported
virtual bool supportsRenderingMode(RenderingMode m) const;
// Points OpenGL drawing in a display list
virtual void direct_draw() const;
// Normals OpenGL drawing
virtual void draw_normals() const;
// Draws oriented points with radius
virtual void draw_splats() const;
// Gets wrapped point set
Point_set* point_set();
const Point_set* point_set() const;
// Gets dimensions
virtual bool isFinite() const { return true; }
virtual bool isEmpty() const;
virtual Bbox bbox() const;
virtual void setRenderingMode(RenderingMode m);
// computes the local point spacing (aka radius) of each point
void computes_local_spacing(int k);
// Data
private:
Point_set* m_points;
}; // end class Point_set_scene_item
#endif // POINT_SET_ITEM_H

View File

@ -1,10 +0,0 @@
#ifndef POINT_SET_ITEM_CONFIG_H
#define POINT_SET_ITEM_CONFIG_H
#ifdef point_set_EXPORTS
# define POINT_SET_ITEM_EXPORT Q_DECL_EXPORT
#else
# define POINT_SET_ITEM_EXPORT Q_DECL_IMPORT
#endif
#endif // POINT_SET_ITEM_CONFIG_H

View File

@ -1,25 +0,0 @@
#ifndef POLYHEDRON_DEMO_IO_PLUGIN_INTERFACE_H
#define POLYHEDRON_DEMO_IO_PLUGIN_INTERFACE_H
#include <QFileInfo>
#include <QStringList>
class Scene_item;
class Polyhedron_demo_io_plugin_interface
{
public:
virtual ~Polyhedron_demo_io_plugin_interface() {}
virtual QStringList nameFilters() const = 0;
virtual bool canLoad() const = 0;
virtual Scene_item* load(QFileInfo fileinfo) = 0;
virtual bool canSave(const Scene_item*) = 0;
virtual bool save(const Scene_item*, QFileInfo fileinfo) = 0;
};
Q_DECLARE_INTERFACE(Polyhedron_demo_io_plugin_interface,
"com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0")
#endif // POLYHEDRON_DEMO_IO_PLUGIN_INTERFACE_H

View File

@ -1,109 +0,0 @@
#include "Polyhedron_demo_plugin_helper.h"
#include <QMainWindow>
#include <QAction>
#include <QMetaObject>
#include <QMetaMethod>
#include <QtDebug>
#include <QVector>
#include <QSet>
QAction*
Polyhedron_demo_plugin_helper::
getActionFromMainWindow(QMainWindow* mw,
QString action_name)
{
return mw->findChild<QAction*>(action_name);
}
QStringList
Polyhedron_demo_plugin_helper::actionsNames() const
{
return QStringList();
}
void
Polyhedron_demo_plugin_helper::
init(QMainWindow* mainWindow, Scene_interface* scene_interface) {
mw = mainWindow;
scene = scene_interface;
Q_FOREACH(QString actionName, actionsNames())
{
actions_map[actionName] = getActionFromMainWindow(mw, actionName);
}
autoConnectActions();
}
QList<QAction*>
Polyhedron_demo_plugin_helper::actions() const
{
return actions_map.values();
}
// Auto-connect actions to slots
void Polyhedron_demo_plugin_helper::autoConnectActions()
{
QObject* thisObject = dynamic_cast<QObject*>(this);
if(!thisObject)
return;
const QMetaObject* metaObject = thisObject->metaObject();
QVector<QMetaMethod> methods;
QVector<QString> methodsNames;
QSet<QString> connected;
for(int i = metaObject->methodOffset();
i < metaObject->methodCount();
++i)
{
const int pos = QString(metaObject->method(i).signature()).indexOf('(');
methodsNames << QString(metaObject->method(i).signature()).left(pos);
methods << metaObject->method(i);
}
Q_FOREACH(QAction* action, actions())
{
bool success = false;
// qDebug("Autoconnecting action \"%s\"...",
// action->objectName().toUtf8().data());
const QMetaObject* action_metaObject = action->metaObject();
for(int i = action_metaObject->methodOffset();
i < action_metaObject->methodCount(); ++i)
{
QMetaMethod action_method = action_metaObject->method(i);
if(action_method.methodType() == QMetaMethod::Signal)
{
const int pos = QString(action_method.signature()).indexOf('(');
QString methodName = QString(action_method.signature()).left(pos);
QString slotName =
QString("on_%1_%2").arg(action->objectName()).arg(methodName);
// qDebug() << thisObject->tr("Slot %1 (%2)...").arg(slotName).arg(i);
int index = methodsNames.indexOf(slotName);
if(index>=0 && !connected.contains(slotName)) {
const bool ok =
QObject::connect(action,
qPrintable(QString("2%1").arg(action_method.signature())),
thisObject,
qPrintable(QString("1%1").arg(methods[index].signature())));
if(!ok)
{
qDebug() << thisObject->tr("Cannot connect method %1.%2 to slot %3!")
.arg(action->objectName())
.arg(action_method.signature())
.arg(methods[index].signature());
}
else {
// qDebug(" ->Connected!");
success = true;
connected << slotName;
}
}
// else {
// qDebug(" nothing found!\n");
// }
}
} // end for each method of action
if(!success)
qDebug("ERROR: Failed to autoconnect the action \"%s\"!",
action->objectName().toUtf8().data());
} // end foreach action of actions()
}

View File

@ -1,40 +0,0 @@
#ifndef POLYHEDRON_DEMO_OPERATION_HELPER_H
#define POLYHEDRON_DEMO_OPERATION_HELPER_H
#include "Scene_item_config.h" //defines SCENE_ITEM_EXPORT
#include <QString>
#include <QStringList>
#include <QMap>
class QAction;
struct QMetaObject;
class QMainWindow;
class Scene_interface;
#include "Polyhedron_demo_plugin_interface.h"
class SCENE_ITEM_EXPORT Polyhedron_demo_plugin_helper
: public Polyhedron_demo_plugin_interface
{
public:
// Gets action object from its name
static QAction* getActionFromMainWindow(QMainWindow*, QString action_name);
// Init plugin
virtual void init(QMainWindow* mainWindow, Scene_interface* scene_interface);
// Gets list of actions supported by this plugin
virtual QStringList actionsNames() const;
virtual QList<QAction*> actions() const;
// Auto-connect actions to slots. Called by init().
void autoConnectActions();
protected:
QMap<QString, QAction*> actions_map;
Scene_interface* scene;
QMainWindow* mw;
};
#endif // POLYHEDRON_DEMO_OPERATION_HELPER_H

View File

@ -1,27 +0,0 @@
#ifndef POLYHEDRON_DEMO_PLUGIN_INTERFACE_H
#define POLYHEDRON_DEMO_PLUGIN_INTERFACE_H
#include <QString>
#include <QList>
#include <QtPlugin>
class QAction;
class QMainWindow;
class Scene_interface;
class Messages_interface;
class Polyhedron_demo_plugin_interface
{
public:
virtual ~Polyhedron_demo_plugin_interface() {}
virtual void init(QMainWindow*, Scene_interface*) {};
virtual void init(QMainWindow* mw, Scene_interface* sc, Messages_interface*) {
init(mw, sc);
};
virtual QList<QAction*> actions() const = 0;
};
Q_DECLARE_INTERFACE(Polyhedron_demo_plugin_interface,
"com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
#endif // POLYHEDRON_DEMO_PLUGIN_INTERFACE_H

View File

@ -1,14 +0,0 @@
#ifndef POLYHEDRON_TYPE_H
#define POLYHEDRON_TYPE_H
// (Main) CGAL kernel and simple geometric types
#include "Kernel_type.h"
// surface mesh
#include <CGAL/Polyhedron_3.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include "Polyhedron_type_fwd.h"
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
#endif // POLYHEDRON_TYPE_H

View File

@ -1,49 +0,0 @@
#ifndef POLYHEDRON_TYPE_FWD_H
#define POLYHEDRON_TYPE_FWD_H
#include <CGAL/Filtered_kernel_fwd.h>
#include <memory>
#ifdef USE_FORWARD_DECL
#include <CGAL/Filtered_kernel_fwd.h>
namespace CGAL {
template < typename FT_ >
struct Simple_cartesian;
class Polyhedron_items_3;
template < class T, class I, class A>
class HalfedgeDS_default;
template < class PolyhedronTraits_3,
class PolyhedronItems_3,
template < class T, class I, class A>
class T_HDS,
class Alloc
>
class Polyhedron_3;
class Epick;
} // end namespace CGAL
// kernel
typedef CGAL::Epick Kernel;
// surface mesh
typedef CGAL::Polyhedron_3<Kernel,
CGAL::Polyhedron_items_3,
CGAL::HalfedgeDS_default,
std::allocator<int> > Polyhedron;
#else // USE_FORWARD_DECL
#include "Polyhedron_type.h"
#endif // USE_FORWARD_DECL
#endif // POLYHEDRON_TYPE_FWD_H

View File

@ -1,674 +0,0 @@
#ifdef CGAL_GLEW_ENABLED
# include "GlSplat/GlSplat.h"
#endif
#include "config.h"
#include "Scene.h"
#include "Scene_item.h"
#include "Scene_polyhedron_item.h"
#include "Point_set_scene_item.h"
#include <QString>
#include <QGLWidget>
#include <QEvent>
#include <QMouseEvent>
#include <QPainter>
#include <QColorDialog>
#include <QApplication>
#include <QPointer>
namespace {
void CGALglcolor(QColor c)
{
::glColor4f(c.red()/255.0, c.green()/255.0, c.blue()/255.0, c.alpha()/255.0);
}
}
#ifdef CGAL_GLEW_ENABLED
GlSplat::SplatRenderer* Scene::ms_splatting = 0;
int Scene::ms_splattingCounter = 0;
GlSplat::SplatRenderer* Scene::splatting()
{
assert(ms_splatting!=0 && "A Scene object must be created before requesting the splatting object");
return ms_splatting;
}
#endif
Scene::Scene(QObject* parent)
: QAbstractListModel(parent),
selected_item(-1)
{
#ifdef CGAL_GLEW_ENABLED
if(ms_splatting==0)
ms_splatting = new GlSplat::SplatRenderer();
ms_splattingCounter++;
#endif
}
Scene::Item_id
Scene::addItem(Scene_item* item)
{
entries.push_back(item);
emit updated_bbox();
emit updated();
QAbstractListModel::reset();
return entries.size() - 1;
}
// Erases a scene item.
// Returns the index of the polyhedra just before the one that is erased,
// or just after. Returns -1 if the list is empty.
Scene::Item_id Scene::erase(Item_id index)
{
if(index < 0 || index >= entries.size())
return -1;
Scene_item* item = entries[index];
emit itemAboutToBeDestroyed(item);
delete item;
entries.removeAt(index);
selected_item = -1;
emit updated();
QAbstractListModel::reset();
if(--index >= 0)
return index;
if(!entries.isEmpty())
return 0;
return -1;
}
Scene::~Scene()
{
Q_FOREACH(Scene_item* item_ptr, entries)
{
delete item_ptr;
}
entries.clear();
#ifdef CGAL_GLEW_ENABLED
if((--ms_splattingCounter)==0)
delete ms_splatting;
#endif
}
Scene_item*
Scene::item(Item_id index) const
{
return entries.value(index); // QList::value checks bounds
}
size_t
Scene::numberOfEntries() const
{
return entries.size();
}
// Duplicates a scene item.
// Returns the ID of the new item (-1 on error).
Scene::Item_id
Scene::duplicate(Item_id index)
{
if(index < 0 || index >= entries.size())
return -1;
const Scene_item* item = entries[index];
Scene_item* new_item = item->clone();
if(new_item) {
new_item->setName(tr("%1 (copy)").arg(item->name()));
new_item->setColor(item->color());
new_item->setVisible(item->visible());
Item_id new_index = addItem(new_item);
return new_index;
}
else
return -1;
}
// Converts a polyhedron to a point set.
// Returns the ID of the new item (-1 on error).
Scene::Item_id
Scene::convertToPointSet(Item_id index)
{
// Check index
if(index < 0 || index >= entries.size())
return -1;
// Check if scene item is a polyhedron
Scene_item* item = entries[index];
Scene_polyhedron_item* poly_item =
qobject_cast<Scene_polyhedron_item*>(item);
if(poly_item == NULL || poly_item->polyhedron() == NULL)
return -1;
// Converts polyhedron to a point set
Point_set_scene_item* new_item = new Point_set_scene_item(*poly_item->polyhedron());
if(new_item) {
new_item->setName(tr("%1 (point set)").arg(item->name()));
new_item->setColor(item->color());
new_item->setVisible(item->visible());
Item_id new_index = addItem(new_item);
// Hide polyhedron
poly_item->setVisible(false);
itemChanged(index);
return new_index;
}
else
return -1;
}
// Delete selection in a scene item
void Scene::deleteSelection(Item_id index)
{
// Check index
if(index < 0 || index >= entries.size())
return;
Scene_item* item = entries[index];
if (item->isSelectionEmpty())
return;
item->deleteSelection();
itemChanged(index);
}
// Reset selection mark in a scene item
void Scene::resetSelection(Item_id index)
{
if(index < 0 || index >= entries.size())
return;
Scene_item* item = entries[index];
item->resetSelection();
itemChanged(index);
}
void Scene::initializeGL()
{
#ifdef CGAL_GLEW_ENABLED
ms_splatting->init();
#endif
}
// workaround for Qt-4.2.
#if QT_VERSION < 0x040300
# define lighter light
#endif
void
Scene::draw()
{
draw_aux(false);
}
void
Scene::drawWithNames()
{
draw_aux(true);
}
void
Scene::draw_aux(bool with_names)
{
// Flat/Gouraud OpenGL drawing
for(int index = 0; index < entries.size(); ++index)
{
if(with_names) {
::glPushName(index);
}
Scene_item& item = *entries[index];
if(item.visible())
{
if(item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud)
{
::glEnable(GL_LIGHTING);
::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
::glPointSize(2.f);
::glLineWidth(1.0f);
if(index == selected_item)
CGALglcolor(item.color().lighter(120));
else
CGALglcolor(item.color());
if(item.renderingMode() == Gouraud)
::glShadeModel(GL_SMOOTH);
else
::glShadeModel(GL_FLAT);
item.draw();
}
}
if(with_names) {
::glPopName();
}
}
// Wireframe OpenGL drawing
for(int index = 0; index < entries.size(); ++index)
{
if(with_names) {
::glPushName(index);
}
Scene_item& item = *entries[index];
if(item.visible())
{
if(item.renderingMode() == FlatPlusEdges || item.renderingMode() == Wireframe)
{
::glDisable(GL_LIGHTING);
::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
::glPointSize(2.f);
::glLineWidth(1.0f);
if(index == selected_item)
CGALglcolor(Qt::black);
else
CGALglcolor(item.color().lighter(50));
item.draw_edges();
}
if(with_names) {
::glPopName();
}
}
}
// Points OpenGL drawing
for(int index = 0; index < entries.size(); ++index)
{
if(with_names) {
::glPushName(index);
}
Scene_item& item = *entries[index];
if(item.visible())
{
if(item.renderingMode() == Points || item.renderingMode() == PointsPlusNormals)
{
::glDisable(GL_LIGHTING);
::glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
::glPointSize(2.f);
::glLineWidth(1.0f);
if(index == selected_item)
CGALglcolor(Qt::black);
else
CGALglcolor(item.color().lighter(50));
item.draw_points();
}
if(with_names) {
::glPopName();
}
}
}
#ifdef CGAL_GLEW_ENABLED
// Splatting
if(ms_splatting->isSupported())
{
ms_splatting->beginVisibilityPass();
for(int index = 0; index < entries.size(); ++index)
{
Scene_item& item = *entries[index];
if(item.visible() && item.renderingMode() == Splatting)
{
item.draw_splats();
}
}
ms_splatting->beginAttributePass();
for(int index = 0; index < entries.size(); ++index)
{
Scene_item& item = *entries[index];
if(item.visible() && item.renderingMode() == Splatting)
{
if(index == selected_item)
CGALglcolor(item.color().lighter(120));
else
CGALglcolor(item.color());
item.draw_splats();
}
}
ms_splatting->finalize();
}
#endif
// Normals OpenGL drawing
for(int index = 0; index < entries.size(); ++index)
{
if(with_names) {
::glPushName(index);
}
Scene_item& item = *entries[index];
if(item.visible())
{
if(item.renderingMode() == PointsPlusNormals)
{
::glDisable(GL_LIGHTING);
::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
::glPointSize(2.f);
::glLineWidth(1.0f);
if(index == selected_item)
CGALglcolor(item.color().lighter(120));
else
CGALglcolor(item.color());
item.draw_normals();
}
if(with_names) {
::glPopName();
}
}
}
}
// workaround for Qt-4.2 (see above)
#undef lighter
int
Scene::rowCount(const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
else
return entries.size();
}
int
Scene::columnCount(const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
else
return NumberOfColumns;
}
QVariant
Scene::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if(index.row() < 0 || index.row() >= entries.size())
return QVariant();
if(role == ::Qt::ToolTipRole)
{
return entries[index.row()]->toolTip();
}
switch(index.column())
{
case ColorColumn:
if(role == ::Qt::DisplayRole || role == ::Qt::EditRole)
return entries.value(index.row())->color();
else if(role == ::Qt::DecorationRole)
return entries.value(index.row())->color();
break;
case NameColumn:
if(role == ::Qt::DisplayRole || role == ::Qt::EditRole)
return entries.value(index.row())->name();
if(role == ::Qt::FontRole)
return entries.value(index.row())->font();
break;
case RenderingModeColumn:
if(role == ::Qt::DisplayRole) {
return entries.value(index.row())->renderingModeName();
}
else if(role == ::Qt::EditRole) {
return static_cast<int>(entries.value(index.row())->renderingMode());
}
else if(role == ::Qt::TextAlignmentRole) {
return ::Qt::AlignCenter;
}
break;
case VisibleColumn:
if(role == ::Qt::DisplayRole || role == ::Qt::EditRole)
return entries.value(index.row())->visible();
break;
default:
return QVariant();
}
return QVariant();
}
QVariant
Scene::headerData ( int section, ::Qt::Orientation orientation, int role ) const
{
if(orientation == ::Qt::Horizontal) {
if (role == ::Qt::DisplayRole)
{
switch(section)
{
case NameColumn:
return tr("Name");
break;
case ColorColumn:
return tr("Color");
break;
case RenderingModeColumn:
return tr("Mode");
case VisibleColumn:
return tr("View");
break;
default:
return QVariant();
}
}
else if(role == ::Qt::ToolTipRole) {
if(section == RenderingModeColumn) {
return Scene_item::renderingModeNameList();
}
}
}
return QAbstractListModel::headerData(section, orientation, role);
}
Qt::ItemFlags
Scene::flags ( const QModelIndex & index ) const
{
if (index.isValid() && index.column() == NameColumn) {
return QAbstractListModel::flags(index) | ::Qt::ItemIsEditable;
}
else {
return QAbstractListModel::flags(index);
}
}
bool
Scene::setData(const QModelIndex &index,
const QVariant &value,
int role)
{
if( role != ::Qt::EditRole || !index.isValid() )
return false;
if(index.row() < 0 || index.row() >= entries.size())
return false;
Scene_item* item = entries[index.row()];
if(!item) return false;
switch(index.column())
{
case NameColumn:
item->setName(value.toString());
item->changed();
emit dataChanged(index, index);
return true;
break;
case ColorColumn:
item->setColor(value.value<QColor>());
item->changed();
emit dataChanged(index, index);
return true;
break;
case RenderingModeColumn:
{
RenderingMode rendering_mode = static_cast<RenderingMode>(value.toInt());
// Find next supported rendering mode
while ( !item->supportsRenderingMode(rendering_mode)
#ifdef CGAL_GLEW_ENABLED
|| (rendering_mode==Splatting && !Scene::splatting()->isSupported())
#endif
)
{
rendering_mode = static_cast<RenderingMode>( (rendering_mode+1) % NumberOfRenderingMode );
}
item->setRenderingMode(rendering_mode);
item->changed();
emit dataChanged(index, index);
return true;
break;
}
case VisibleColumn:
item->setVisible(value.toBool());
item->changed();
emit dataChanged(index, index);
return true;
default:
return false;
}
return false;
}
Scene::Item_id Scene::mainSelectionIndex() const {
return selected_item;
}
QItemSelection Scene::createSelection(int i)
{
return QItemSelection(QAbstractItemModel::createIndex(i, 0),
QAbstractItemModel::createIndex(i, LastColumn));
}
void Scene::itemChanged(Item_id i)
{
if(i < 0 || i >= entries.size())
return;
entries[i]->changed();
emit dataChanged(QAbstractItemModel::createIndex(i, 0),
QAbstractItemModel::createIndex(i, LastColumn));
}
void Scene::itemChanged(Scene_item* item)
{
item->changed();
emit dataChanged(QAbstractItemModel::createIndex(0, 0),
QAbstractItemModel::createIndex(entries.size() - 1, LastColumn));
}
bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option,
const QModelIndex &index)
{
// Scene *scene = static_cast<Scene*>(model);
switch(index.column()) {
case Scene::VisibleColumn:
if (event->type() == QEvent::MouseButtonPress) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if(mouseEvent->button() == ::Qt::LeftButton) {
int x = mouseEvent->pos().x() - option.rect.x();
if(x >= (option.rect.width() - size)/2 &&
x <= (option.rect.width() + size)/2) {
model->setData(index, ! model->data(index).toBool() );
}
}
return false; //so that the selection can change
}
return true;
break;
case Scene::ColorColumn:
if (event->type() == QEvent::MouseButtonPress) {
QColor color =
QColorDialog::getColor(model->data(index).value<QColor>(),
0/*,
tr("Select color"),
QColorDialog::ShowAlphaChannel*/);
if (color.isValid()) {
model->setData(index, color );
}
}
else if(event->type() == QEvent::MouseButtonDblClick) {
return true; // block double-click
}
return false;
break;
case Scene::RenderingModeColumn:
if (event->type() == QEvent::MouseButtonPress) {
// Switch rendering mode
/*RenderingMode*/int rendering_mode = model->data(index, ::Qt::EditRole).toInt();
rendering_mode = (rendering_mode+1) % NumberOfRenderingMode;
model->setData(index, rendering_mode);
}
else if(event->type() == QEvent::MouseButtonDblClick) {
return true; // block double-click
}
return false;
break;
default:
return QItemDelegate::editorEvent(event, model, option, index);
}
}
void SceneDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (index.column() != Scene::VisibleColumn) {
QItemDelegate::paint(painter, option, index);
} else {
const QAbstractItemModel *model = index.model();
QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ?
(option.state & QStyle::State_Active) ? QPalette::Normal : QPalette::Inactive : QPalette::Disabled;
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.color(cg, QPalette::Highlight));
bool checked = model->data(index, ::Qt::DisplayRole).toBool();
int width = option.rect.width();
int height = option.rect.height();
size = (std::min)(width, height);
int x = option.rect.x() + (option.rect.width() / 2) - (size / 2);;
int y = option.rect.y() + (option.rect.height() / 2) - (size / 2);
if(checked) {
painter->drawPixmap(x, y, checkOnPixmap.scaled(QSize(size, size),
::Qt::KeepAspectRatio,
::Qt::SmoothTransformation));
}
else {
painter->drawPixmap(x, y, checkOffPixmap.scaled(QSize(size, size),
::Qt::KeepAspectRatio,
::Qt::SmoothTransformation));
}
drawFocus(painter, option, option.rect); // since we draw the grid ourselves
}
}
void Scene::setItemVisible(int index, bool b)
{
if( index < 0 || index >= entries.size() )
return;
entries[index]->setVisible(b);
emit dataChanged(QAbstractItemModel::createIndex(index, VisibleColumn),
QAbstractItemModel::createIndex(index, VisibleColumn));
}
Scene::Bbox Scene::bbox() const
{
if(entries.empty())
return Bbox();
bool bbox_initialized = false;
Bbox bbox;
Q_FOREACH(Scene_item* item, entries)
{
if(item->isFinite() && !item->isEmpty()) {
if(bbox_initialized) {
bbox = bbox + item->bbox();
}
else {
bbox = item->bbox();
bbox_initialized = true;
}
}
}
return bbox;
}

View File

@ -1,148 +0,0 @@
#ifndef SCENE_H
#define SCENE_H
#include "config.h"
#include "Scene_interface.h"
#include "Scene_draw_interface.h"
#include <QtOpenGL/qgl.h>
#include <QAbstractListModel>
#include <QString>
#include <QColor>
#include <QList>
#include <QItemDelegate>
#include <QPixmap>
#include <QItemSelection>
#include <iostream>
#include <cmath>
#include <boost/variant.hpp>
class QEvent;
class QMouseEvent;
namespace GlSplat { class SplatRenderer; }
class Scene :
public QAbstractListModel, public Scene_interface, public Scene_draw_interface
{
Q_OBJECT
friend class SceneDelegate;
public:
enum Columns { NameColumn = 0,
ColorColumn,
RenderingModeColumn,
VisibleColumn,
LastColumn = VisibleColumn,
NumberOfColumns = LastColumn + 1};
Scene(QObject* parent);
~Scene();
Item_id addItem(Scene_item* item);
// Erases a scene item.
// Returns the index of the polyhedra just before the one that is erased,
// or just after. Returns -1 if the list is empty.
Item_id erase(Item_id index);
// Duplicates a scene item. Returns the ID of the new item (-1 on error).
Item_id duplicate(Item_id index);
// Converts a polyhedron to a point set.
// Returns the ID of the new item (-1 on error).
Item_id convertToPointSet(Item_id index);
// Delete selection in a scene item
void deleteSelection(Item_id index);
// Reset selection mark in a scene item.
void resetSelection(Item_id index);
// Accessors (getters)
size_t numberOfEntries() const;
Scene_item* item(Item_id) const ;
Item_id mainSelectionIndex() const;
// initializeGL() is called by Viewer::initializeGL()
void initializeGL();
// draw() is called by Viewer::draw()
void draw();
void drawWithNames();
// Gets scene bounding box
Bbox bbox() const;
double len_diagonal() const
{
Bbox box = bbox();
double dx = box.xmax - box.xmin;
double dy = box.ymax - box.ymin;
double dz = box.zmax - box.zmin;
return std::sqrt(dx*dx + dy*dy + dz*dz);
}
// QAbstractItemModel functions
int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
QVariant data ( const QModelIndex & index, int role = ::Qt::DisplayRole ) const;
QVariant headerData ( int section, ::Qt::Orientation orientation, int role = ::Qt::DisplayRole ) const;
::Qt::ItemFlags flags ( const QModelIndex & index ) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
// auxiliary public function for QMainWindow
QItemSelection createSelection(int i);
public slots:
// Notify the scene that an item was modified
void itemChanged(Item_id i);
void itemChanged(Scene_item*);
void setSelectedItem(Item_id i )
{
selected_item = i;
};
// Accessors (setters)
void setItemVisible(int, bool b);
signals:
void updated_bbox();
void updated();
void itemAboutToBeDestroyed(Scene_item*);
private:
void draw_aux(bool with_names);
typedef QList<Scene_item*> Entries;
Entries entries;
int selected_item;
#ifdef CGAL_GLEW_ENABLED
static GlSplat::SplatRenderer* ms_splatting;
static int ms_splattingCounter;
public:
static GlSplat::SplatRenderer* splatting();
#endif
}; // end class Scene
class SceneDelegate : public QItemDelegate
{
public:
SceneDelegate(QObject * parent = 0)
: QItemDelegate(parent),
checkOnPixmap(":/cgal/icons/check-on.png"),
checkOffPixmap(":/cgal/icons/check-off.png")
{
}
bool editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option,
const QModelIndex &index);
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
private:
QPixmap checkOnPixmap;
QPixmap checkOffPixmap;
mutable int size;
}; // end class SceneDelegate
#endif // SCENE_H

View File

@ -1,10 +0,0 @@
#ifndef SCENE_BASIC_OBJECTS_CONFIG_H
#define SCENE_BASIC_OBJECTS_CONFIG_H
#ifdef PS_demo_scene_basic_objects_EXPORTS
# define SCENE_BASIC_OBJECTS_EXPORT Q_DECL_EXPORT
#else
# define SCENE_BASIC_OBJECTS_EXPORT Q_DECL_IMPORT
#endif
#endif // SCENE_BASIC_OBJECTS_CONFIG_H

View File

@ -1,12 +0,0 @@
#ifndef SCENE_DRAW_INTERFACE_H
#define SCENE_DRAW_INTERFACE_H
class Scene_draw_interface {
public:
virtual ~Scene_draw_interface(){}
virtual void initializeGL() = 0;
virtual void draw() = 0;
virtual void drawWithNames() = 0;
};
#endif // SCENE_DRAW_INTERFACE_H;

View File

@ -1,82 +0,0 @@
#ifndef SCENE_INTERFACE_H
#define SCENE_INTERFACE_H
#include <QString>
#include <QColor>
#include <algorithm>
class Scene_item;
// OpenGL rendering mode
enum RenderingMode { Points = 0,
PointsPlusNormals,
Splatting,
Wireframe,
Flat,
FlatPlusEdges,
Gouraud,
LastRenderingMode = Gouraud,
NumberOfRenderingMode = LastRenderingMode+1 };
// Interface of Scene class exported to plugins
class Scene_interface {
public:
struct Bbox {
double xmin, ymin, zmin;
double xmax, ymax, zmax;
Bbox(const double _xmin,const double _ymin,const double _zmin,
const double _xmax,const double _ymax,const double _zmax)
: xmin(_xmin), ymin(_ymin), zmin(_zmin),
xmax(_xmax), ymax(_ymax), zmax(_zmax)
{
}
Bbox()
: xmin(0.0), ymin(0.0), zmin(0.0),
xmax(1.0), ymax(1.0), zmax(1.0)
{
}
Bbox operator+(const Bbox& b) const {
return Bbox((std::min)(xmin, b.xmin),
(std::min)(ymin, b.ymin),
(std::min)(zmin, b.zmin),
(std::max)(xmax, b.xmax),
(std::max)(ymax, b.ymax),
(std::max)(zmax, b.zmax));
}
}; // struct BBox (ad hoc class, does not depend on CGAL kernels
typedef int Item_id;
virtual ~Scene_interface() {};
virtual Item_id addItem(Scene_item* item) = 0;
virtual Item_id erase(Item_id) = 0;
// Returns the index of the item just before the one that is erased,
// or just after. Returns -1 if the list is empty.
virtual Item_id duplicate(Item_id) = 0;
// Returns the index of the new item
// If no new item has been created (because the item type is note
// clonable), returns -1.
// Accessors (getters)
virtual size_t numberOfEntries() const = 0;
virtual Scene_item* item(Item_id) const = 0;
virtual Item_id mainSelectionIndex() const = 0;
// Gets scene bounding box
virtual Bbox bbox() const = 0;
virtual double len_diagonal() const = 0;
public:
// Notify the scene that an item was modified
virtual void itemChanged(Item_id i) = 0;
virtual void itemChanged(Scene_item*) = 0;
}; // end interface Scene_interface
#endif // SCENE_INTERFACE_H

View File

@ -1,44 +0,0 @@
#include "Scene_item.h"
const QColor Scene_item::defaultColor = QColor(100, 100, 255);
Scene_item::~Scene_item() {}
void Scene_item::itemAboutToBeDestroyed(Scene_item* item) {
if(this == item)
emit aboutToBeDestroyed();
}
// Rendering mode list as a human readable string
QString Scene_item::renderingModeNameList()
{
return tr("Rendering mode (points/points+normals/splatting/wireframe/flat/flat+edges/Gouraud)");
}
// Rendering mode as a human readable string
QString Scene_item::renderingModeName() const
{
switch(renderingMode())
{
case Points:
return tr("points");
case PointsPlusNormals:
return tr("pts+normals");
case Splatting:
return tr("splats");
case Wireframe:
return tr("wire");
case Flat:
return tr("flat");
case FlatPlusEdges:
return tr("flat+edges");
case Gouraud:
return tr("Gouraud");
default:
Q_ASSERT(false);
return tr("unknown");
}
}
#include "Scene_item.moc"

View File

@ -1,106 +0,0 @@
#ifndef SCENE_ITEM_H
#define SCENE_ITEM_H
#include "Scene_item_config.h"
#include "Scene_interface.h"
#include <QString>
#include <QFont>
namespace qglviewer {
class ManipulatedFrame;
}
// This class represents an object in the OpenGL scene
class SCENE_ITEM_EXPORT Scene_item : public QObject {
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor)
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(bool visible READ visible WRITE setVisible)
Q_ENUMS(RenderingMode)
Q_PROPERTY(RenderingMode renderingMode READ renderingMode WRITE setRenderingMode)
public:
typedef Scene_interface::Bbox Bbox;
typedef qglviewer::ManipulatedFrame ManipulatedFrame;
static const QColor defaultColor; // defined in Scene_item.cpp
static QString renderingModeNameList(); // Rendering mode list as a human readable string
Scene_item()
: name_("unamed"),
color_(defaultColor),
visible_(true),
rendering_mode(FlatPlusEdges)
{};
virtual ~Scene_item();
virtual Scene_item* clone() const = 0;
// Is selection empty?
virtual bool isSelectionEmpty() const { return true; }
// Delete selection
virtual void deleteSelection() {}
// Reset selection mark
virtual void resetSelection() {}
// Indicate if rendering mode is supported
virtual bool supportsRenderingMode(RenderingMode m) const = 0;
// Flat/Gouraud OpenGL drawing
virtual void draw() const = 0;
// Wireframe OpenGL drawing
virtual void draw_edges() const { draw(); }
// Points OpenGL drawing
virtual void draw_points() const { draw(); }
// Normals OpenGL drawing
virtual void draw_normals() const {}
// Draws oriented points with radius
virtual void draw_splats() const {}
// Functions for displaying meta-data of the item
virtual QString toolTip() const = 0;
virtual QFont font() const { return QFont(); }
// Functions that help the Scene to compute its bbox
virtual bool isFinite() const { return true; }
virtual bool isEmpty() const { return true; }
virtual Bbox bbox() const { return Bbox(); }
// Function about manipulation
virtual bool manipulatable() const { return false; }
virtual ManipulatedFrame* manipulatedFrame() { return 0; }
// Getters for the four basic properties
virtual QColor color() const { return color_; }
virtual QString name() const { return name_; }
virtual bool visible() const { return visible_; }
virtual RenderingMode renderingMode() const { return rendering_mode; }
virtual QString renderingModeName() const; // Rendering mode as a human readable string
public slots:
// Call that once you have finished changing something in the item
// (either the properties or internal data)
virtual void changed() {}
// Setters for the four basic properties
virtual void setColor(QColor c) { color_ = c; }
virtual void setName(QString n) { name_ = n; }
virtual void setVisible(bool b) { visible_ = b; }
virtual void setRenderingMode(RenderingMode m) {
if (supportsRenderingMode(m))
rendering_mode = m;
}
virtual void itemAboutToBeDestroyed(Scene_item*);
signals:
void aboutToBeDestroyed();
protected:
// The four basic properties
QString name_;
QColor color_;
bool visible_;
RenderingMode rendering_mode;
}; // end class Scene_item
#endif // SCENE_ITEM_H

View File

@ -1,12 +0,0 @@
#ifndef SCENE_ITEM_CONFIG_H
#define SCENE_ITEM_CONFIG_H
#include <QtCore/qglobal.h>
#ifdef PS_demo_scene_item_EXPORTS
# define SCENE_ITEM_EXPORT Q_DECL_EXPORT
#else
# define SCENE_ITEM_EXPORT Q_DECL_IMPORT
#endif
#endif // SCENE_ITEM_CONFIG_H

View File

@ -1,51 +0,0 @@
#include "Scene_item_with_display_list.h"
#include <iostream>
Scene_item_with_display_list::Scene_item_with_display_list()
: display_list(0),
display_list_built(false)
{}
// Scene_item_with_display_list::
// Scene_item_with_display_list(const Scene_item_with_display_list& item)
// : Scene_item(item),
// display_list(0),
// display_list_built(false)
// {}
Scene_item_with_display_list::~Scene_item_with_display_list()
{
if(display_list_built && display_list != 0) {
::glDeleteLists(display_list,1);
}
}
// Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list
void Scene_item_with_display_list::draw() const
{
if(!display_list_built)
{
if(display_list == 0) {
display_list = ::glGenLists(1);
if(display_list == 0)
{
std::cerr << "Unable to create display list" << std::endl;
return;
}
}
// draw the item in a display list
::glNewList(display_list,GL_COMPILE_AND_EXECUTE);
direct_draw();
::glEndList();
display_list_built = true;
}
else {
// draw using the display list
::glCallList(display_list);
}
}
void Scene_item_with_display_list::changed()
{
display_list_built = false;
}

View File

@ -1,33 +0,0 @@
#ifndef SCENE_ITEM_WITH_DISPLAY_LIST_H
#define SCENE_ITEM_WITH_DISPLAY_LIST_H
#include "Scene_item.h"
#include <CGAL/gl.h>
// This class represents an object in the scene with an OpenGL rendering using display lists
class SCENE_ITEM_EXPORT Scene_item_with_display_list
: public Scene_item
{
public:
Scene_item_with_display_list();
// Scene_item_with_display_list(const Scene_item_with_display_list&);
~Scene_item_with_display_list();
// Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list
virtual void direct_draw() const = 0;
// OpenGL drawing using a display list
virtual void draw() const;
public slots:
// Call that once you have finished changing something in the item
// (either the properties or internal data).
virtual void changed();
private:
// display lists
mutable GLuint display_list;
mutable bool display_list_built;
}; // end class Scene_item_with_display_list
#endif // SCENE_ITEM_WITH_DISPLAY_LIST_H

View File

@ -1,3 +0,0 @@
#include "Scene_plane_item.h"
#include "Scene_plane_item.moc"

View File

@ -1,168 +0,0 @@
#ifndef SCENE_PLANE_ITEM_H
#define SCENE_PLANE_ITEM_H
#include "Scene_item.h"
#include "Scene_interface.h"
#include "Scene_basic_objects_config.h"
#include <QGLViewer/manipulatedFrame.h>
#include <QGLViewer/qglviewer.h>
#include <cmath>
#include "Kernel_type.h"
class SCENE_BASIC_OBJECTS_EXPORT Scene_plane_item
: public Scene_item
{
Q_OBJECT
public:
typedef qglviewer::ManipulatedFrame ManipulatedFrame;
Scene_plane_item(const Scene_interface* scene_interface)
: scene(scene_interface),
manipulable(false),
can_clone(true),
frame(new ManipulatedFrame())
{
setNormal(0., 0., 1.);
}
~Scene_plane_item() {
delete frame;
}
bool isFinite() const { return false; }
bool isEmpty() const { return false; }
Bbox bbox() const { return Bbox(); }
bool manipulatable() const {
return manipulable;
}
ManipulatedFrame* manipulatedFrame() {
return frame;
}
Scene_plane_item* clone() const {
if(can_clone)
{
Scene_plane_item* item = new Scene_plane_item(scene);
item->manipulable = manipulable;
item->can_clone = true;
item->frame = new ManipulatedFrame;
item->frame->setPosition(frame->position());
item->frame->setOrientation(frame->orientation());
return item;
}
else
return 0;
}
QString toolTip() const {
const qglviewer::Vec& pos = frame->position();
const qglviewer::Vec& n = frame->orientation().axis();
return
tr("<p><b>%1</b> (mode: %2, color: %3)<br />")
.arg(this->name())
.arg(this->renderingModeName())
.arg(this->color().name())
+
tr("<i>Plane</i></p>"
"<p>Equation: %1*x + %2*y + %3*z + %4 = 0<br />"
"Normal vector: (%1, %2, %3)<br />"
"Point: (%5, %6, %7)</p>")
.arg(n[0]).arg(n[1]).arg(n[2])
.arg( - pos * n)
.arg(pos[0]).arg(pos[1]).arg(pos[2])
+
tr("<p>Can clone: %1<br />"
"Manipulatable: %2</p>")
.arg(can_clone?tr("true"):tr("false"))
.arg(manipulable?tr("true"):tr("false"));
}
// Indicate if rendering mode is supported
bool supportsRenderingMode(RenderingMode m) const {
return (m == Wireframe || m == Flat);
}
// Flat OpenGL drawing
void draw() const {
const double diag = scene_diag();
::glPushMatrix();
::glMultMatrixd(frame->matrix());
GLboolean lighting;
::glGetBooleanv(GL_LIGHTING, &lighting);
::glDisable(GL_LIGHTING);
::glBegin(GL_POLYGON);
::glVertex3d(-diag, -diag, 0.);
::glVertex3d(-diag, diag, 0.);
::glVertex3d( diag, diag, 0.);
::glVertex3d( diag, -diag, 0.);
::glEnd();
if(lighting)
::glEnable(GL_LIGHTING);
::glPopMatrix();
};
// Wireframe OpenGL drawing
void draw_edges() const {
::glPushMatrix();
::glMultMatrixd(frame->matrix());
QGLViewer::drawGrid((float)scene_diag());
::glPopMatrix();
}
Plane_3 plane() const {
const qglviewer::Vec& pos = frame->position();
const qglviewer::Vec& n =
frame->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f));
return Plane_3(n[0], n[1], n[2], - n * pos);
}
private:
double scene_diag() const {
const Bbox& bbox = scene->bbox();
const double& xdelta = bbox.xmax-bbox.xmin;
const double& ydelta = bbox.ymax-bbox.ymin;
const double& zdelta = bbox.zmax-bbox.zmin;
const double diag = std::sqrt(xdelta*xdelta +
ydelta*ydelta +
zdelta*zdelta);
return diag * 0.7;
}
public slots:
void setPosition(float x, float y, float z) {
frame->setPosition(x, y, z);
}
void setPosition(double x, double y, double z) {
frame->setPosition((float)x, (float)y, (float)z);
}
void setNormal(float x, float y, float z) {
frame->setOrientation(x, y, z, 0.f);
}
void setNormal(double x, double y, double z) {
frame->setOrientation((float)x, (float)y, (float)z, 0.f);
}
void setClonable(bool b = true) {
can_clone = b;
}
void setManipulatable(bool b = true) {
manipulable = b;
}
private:
const Scene_interface* scene;
bool manipulable;
bool can_clone;
qglviewer::ManipulatedFrame* frame;
};
#endif // SCENE_PLANE_ITEM_H

View File

@ -1,109 +0,0 @@
#include "Scene_polyhedron_item.h"
#include "Polyhedron_type.h"
#include <CGAL/IO/Polyhedron_iostream.h>
#include <QObject>
#include <CGAL/gl_render.h>
Scene_polyhedron_item::Scene_polyhedron_item()
: Scene_item_with_display_list(),
poly(new Polyhedron)
{
}
Scene_polyhedron_item::Scene_polyhedron_item(Polyhedron* const p)
: Scene_item_with_display_list(),
poly(p)
{
}
Scene_polyhedron_item::Scene_polyhedron_item(const Polyhedron& p)
: Scene_item_with_display_list(),
poly(new Polyhedron(p))
{
}
// Scene_polyhedron_item::Scene_polyhedron_item(const Scene_polyhedron_item& item)
// : Scene_item_with_display_list(item),
// poly(new Polyhedron(*item.poly))
// {
// }
Scene_polyhedron_item::~Scene_polyhedron_item()
{
delete poly;
}
Scene_polyhedron_item*
Scene_polyhedron_item::clone() const {
return new Scene_polyhedron_item(*poly);
}
// Loads polyhedron from .OFF file
bool
Scene_polyhedron_item::load(std::istream& in)
{
in >> *poly;
return in && !isEmpty();
}
// Write polyhedron to .OFF file
bool
Scene_polyhedron_item::save(std::ostream& out) const
{
out << *poly;
return (bool) out;
}
QString
Scene_polyhedron_item::toolTip() const
{
if(!poly)
return QString();
return QObject::tr("<p><b>%1</b> (mode: %5, color: %6)</p>"
"<p>Number of vertices: %2<br />"
"Number of edges: %3<br />"
"Number of facets: %4</p>")
.arg(this->name())
.arg(poly->size_of_vertices())
.arg(poly->size_of_halfedges()/2)
.arg(poly->size_of_facets())
.arg(this->renderingModeName())
.arg(this->color().name());
}
bool Scene_polyhedron_item::supportsRenderingMode(RenderingMode m) const {
return m != PointsPlusNormals && m != Splatting;
}
// Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list
void Scene_polyhedron_item::direct_draw() const {
gl_render_facets(*poly);
}
Polyhedron*
Scene_polyhedron_item::polyhedron() { return poly; }
const Polyhedron*
Scene_polyhedron_item::polyhedron() const { return poly; }
bool
Scene_polyhedron_item::isEmpty() const {
return (poly == 0) || poly->empty();
}
Scene_polyhedron_item::Bbox
Scene_polyhedron_item::bbox() const {
const Point& p = *(poly->points_begin());
CGAL::Bbox_3 bbox(p.x(), p.y(), p.z(), p.x(), p.y(), p.z());
for(Polyhedron::Point_iterator it = poly->points_begin();
it != poly->points_end();
++it) {
bbox = bbox + it->bbox();
}
return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(),
bbox.xmax(),bbox.ymax(),bbox.zmax());
}
#include "Scene_polyhedron_item.moc"

View File

@ -1,48 +0,0 @@
#ifndef SCENE_POLYHEDRON_ITEM_H
#define SCENE_POLYHEDRON_ITEM_H
#include "Scene_polyhedron_item_config.h"
#include "Scene_item_with_display_list.h"
#include "Polyhedron_type_fwd.h"
#include <iostream>
// This class represents a polyhedron in the OpenGL scene
class SCENE_POLYHEDRON_ITEM_EXPORT Scene_polyhedron_item
: public Scene_item_with_display_list {
Q_OBJECT
public:
Scene_polyhedron_item();
// Scene_polyhedron_item(const Scene_polyhedron_item&);
Scene_polyhedron_item(const Polyhedron& p);
Scene_polyhedron_item(Polyhedron* const p);
~Scene_polyhedron_item();
Scene_polyhedron_item* clone() const;
// IO
bool load(std::istream& in);
bool save(std::ostream& out) const;
// Function for displaying meta-data of the item
virtual QString toolTip() const;
// Indicate if rendering mode is supported
virtual bool supportsRenderingMode(RenderingMode m) const;
// Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list
virtual void direct_draw() const;
// Gets wrapped polyhedron
Polyhedron* polyhedron();
const Polyhedron* polyhedron() const;
// Gets dimensions
bool isFinite() const { return true; }
bool isEmpty() const;
Bbox bbox() const;
private:
Polyhedron* poly;
}; // end class Scene_polyhedron_item
#endif // SCENE_POLYHEDRON_ITEM_H

View File

@ -1,10 +0,0 @@
#ifndef SCENE_POLYHEDRON_ITEM_CONFIG_H
#define SCENE_POLYHEDRON_ITEM_CONFIG_H
#ifdef PS_demo_scene_polyhedron_item_EXPORTS
# define SCENE_POLYHEDRON_ITEM_EXPORT Q_DECL_EXPORT
#else
# define SCENE_POLYHEDRON_ITEM_EXPORT Q_DECL_IMPORT
#endif
#endif // SCENE_POLYHEDRON_ITEM_CONFIG_H

View File

@ -1,92 +0,0 @@
#include "Viewer.h"
#include "Scene_draw_interface.h"
Viewer::Viewer(QWidget* parent, bool antialiasing)
: QGLViewer(parent),
scene(0),
antialiasing(antialiasing),
twosides(false),
m_isInitialized(false)
{
setBackgroundColor(::Qt::white);
}
void Viewer::setScene(Scene_draw_interface* scene)
{
this->scene = scene;
}
void Viewer::setAntiAliasing(bool b)
{
antialiasing = b;
if(m_isInitialized)
updateGL();
}
void Viewer::setTwoSides(bool b)
{
twosides = b;
if(m_isInitialized)
updateGL();
}
void Viewer::draw()
{
draw_aux(false);
}
void Viewer::initializeGL()
{
m_isInitialized = true;
QGLViewer::initializeGL();
scene->initializeGL();
}
void Viewer::draw_aux(bool with_names)
{
QGLViewer::draw();
if(scene == 0)
return;
::glLineWidth(1.0f);
::glPointSize(2.f);
::glEnable(GL_POLYGON_OFFSET_FILL);
::glPolygonOffset(1.0f,1.0f);
::glClearColor(1.0f,1.0f,1.0f,0.0f);
::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
if(twosides)
::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
else
::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
if(antiAliasing())
{
::glEnable(GL_BLEND);
::glEnable(GL_LINE_SMOOTH);
::glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else
{
::glDisable(GL_BLEND);
::glDisable(GL_LINE_SMOOTH);
::glDisable(GL_POLYGON_SMOOTH_HINT);
::glBlendFunc(GL_ONE, GL_ZERO);
::glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
}
if(with_names)
scene->drawWithNames();
else
scene->draw();
}
void Viewer::drawWithNames()
{
draw_aux(true);
}
void Viewer::postSelection(const QPoint&)
{
emit selected(this->selectedName());
}

View File

@ -1,43 +0,0 @@
#ifndef VIEWER_H
#define VIEWER_H
#include <QGLViewer/qglviewer.h>
// forward declarations
class QWidget;
class Scene_draw_interface;
class Viewer : public QGLViewer {
Q_OBJECT
public:
Viewer(QWidget * parent, bool antialiasing = false);
// overload several QGLViewer virtual functions
void draw();
void initializeGL();
void drawWithNames();
void postSelection(const QPoint&);
void setScene(Scene_draw_interface* scene);
bool antiAliasing() const { return antialiasing; }
signals:
void selected(int);
public slots:
void setAntiAliasing(bool b);
void setTwoSides(bool b);
private:
void draw_aux(bool with_names);
Scene_draw_interface* scene;
bool antialiasing;
bool twosides;
bool m_isInitialized;
}; // end class Viewer
#endif // VIEWER_H

View File

@ -1,251 +0,0 @@
#! /bin/sh
#
# This script is a modified version of cgal_test_with_cmake which:
# - is cross-platform Unix/make and Cygwin/VisualC++
# - concats all log files to cgal_test_with_cmake.log
# - does not clean up object files and executables if $NEED_CLEAN==n
#
# This is a script for the CGAL test suite. Such a script must obey
# the following rules:
#
# - the name of the script is cgal_test_with_cmake
# - for every target two one line messages are written to the file 'error.txt'
# the first one indicates if the compilation was successful
# the second one indicates if the execution was successful
# if one of the two was not successful, the line should start with 'ERROR:'
# - running the script should not require any user interaction
# - the script should clean up object files and executables
ERRORFILE=error.txt
DO_RUN=
case "$CMAKE_GENERATOR" in
-GVisual* ) # if Visual Studio
MAKE_CMD="devenv.com *.sln /Build Release /Project"
MAKE_CLEAN_CMD="devenv.com *.sln /Clean Release"
;;
-GNMake* ) # if nmake
if [ -z "$MAKE_CMD" ]; then
MAKE_CMD="nmake"
fi
MAKE_CMD="${MAKE_CMD} -fMakefile"
MAKE_CLEAN_CMD="${MAKE_CMD} clean"
;;
* ) # if make
if [ -z "${MAKE_CMD}" ]; then
MAKE_CMD=make
fi
MAKE_CMD="${MAKE_CMD} -fMakefile"
MAKE_CLEAN_CMD="${MAKE_CMD} clean"
;;
esac
#---------------------------------------------------------------------#
# configure
#---------------------------------------------------------------------#
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
}
#---------------------------------------------------------------------#
# find_executable <target>
#---------------------------------------------------------------------#
find_executable()
{
PARAM_APPLICATION=""
[ -f ./release/$1.exe ] && PARAM_APPLICATION="./release/$1.exe"
[ -x ./$1 ] && PARAM_APPLICATION="./$1"
echo "$PARAM_APPLICATION"
}
#---------------------------------------------------------------------#
# can_compile <target>
#---------------------------------------------------------------------#
can_compile()
{
case "$CMAKE_GENERATOR" in
-GVisual* ) # if Visual Studio
if [ -f "$1.vcproj" ]; then
echo y
else
echo n
fi
;;
* ) # if make or nmake
if ${MAKE_CMD} help | grep "$1\$" > /dev/null; then
echo y
else
echo n
fi
;;
esac
}
#---------------------------------------------------------------------#
# compile_and_run <target>
#---------------------------------------------------------------------#
compile_and_run()
{
echo "Compiling $1 ... "
SUCCESS="y"
if eval '${MAKE_CMD} $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="`find_executable $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
}
#---------------------------------------------------------------------#
# catenate all logs in cgal_test_with_cmake.log
#---------------------------------------------------------------------#
[ -f cgal_test_with_cmake.log ] && mv -f cgal_test_with_cmake.log cgal_test_with_cmake.log.bak
echo "------------------------------------------------------------------" >> cgal_test_with_cmake.log
echo "- Compiler output from platform $PLATFORM" >> cgal_test_with_cmake.log
echo "------------------------------------------------------------------" >> cgal_test_with_cmake.log
echo >> cgal_test_with_cmake.log
(
#---------------------------------------------------------------------#
# remove the previous error file
#---------------------------------------------------------------------#
rm -f $ERRORFILE
touch $ERRORFILE
#---------------------------------------------------------------------#
# configure, compile and run the tests
#---------------------------------------------------------------------#
configure
if [ $# -ne 0 ] ; then
for file in $* ; do
compile_and_run $file
done
else
echo "Run all tests."
if [ `can_compile Point_set_demo` = "y" ]; then
compile_and_run Point_set_demo
[ -z "${NEED_CLEAN}" ] && NEED_CLEAN=y
fi
if [ `can_compile PS_demo_APSS_plugin` = "y" ]; then
compile_and_run PS_demo_APSS_plugin
[ -z "${NEED_CLEAN}" ] && NEED_CLEAN=y
fi
if [ `can_compile PS_demo_average_spacing_plugin` = "y" ]; then
compile_and_run PS_demo_average_spacing_plugin
[ -z "${NEED_CLEAN}" ] && NEED_CLEAN=y
fi
if [ `can_compile PS_demo_cleaning_plugin` = "y" ]; then
compile_and_run PS_demo_cleaning_plugin
[ -z "${NEED_CLEAN}" ] && NEED_CLEAN=y
fi
if [ `can_compile PS_demo_inside_out_plugin` = "y" ]; then
compile_and_run PS_demo_inside_out_plugin
[ -z "${NEED_CLEAN}" ] && NEED_CLEAN=y
fi
if [ `can_compile PS_demo_local_spacing_plugin` = "y" ]; then
compile_and_run PS_demo_local_spacing_plugin
[ -z "${NEED_CLEAN}" ] && NEED_CLEAN=y
fi
if [ `can_compile PS_demo_normal_estimation_plugin` = "y" ]; then
compile_and_run PS_demo_normal_estimation_plugin
[ -z "${NEED_CLEAN}" ] && NEED_CLEAN=y
fi
if [ `can_compile PS_demo_off_plugin` = "y" ]; then
compile_and_run PS_demo_off_plugin
[ -z "${NEED_CLEAN}" ] && NEED_CLEAN=y
fi
if [ `can_compile PS_demo_poisson_plugin` = "y" ]; then
compile_and_run PS_demo_poisson_plugin
[ -z "${NEED_CLEAN}" ] && NEED_CLEAN=y
fi
if [ `can_compile PS_demo_simplification_plugin` = "y" ]; then
compile_and_run PS_demo_simplification_plugin
[ -z "${NEED_CLEAN}" ] && NEED_CLEAN=y
fi
if [ `can_compile PS_demo_smoothing_plugin` = "y" ]; then
compile_and_run PS_demo_smoothing_plugin
[ -z "${NEED_CLEAN}" ] && NEED_CLEAN=y
fi
if [ `can_compile PS_demo_xyz_plugin` = "y" ]; then
compile_and_run PS_demo_xyz_plugin
[ -z "${NEED_CLEAN}" ] && NEED_CLEAN=y
fi
fi
#
# The clean target generated by CMake under cygwin
# always fails for some reason
#
if [ "${NEED_CLEAN}" = "y" ]; then
if ! ( uname | grep -q "CYGWIN" ) ; then
${MAKE_CLEAN_CMD}
fi
fi
) 2>&1 | tee -a cgal_test_with_cmake.log
echo >> cgal_test_with_cmake.log
#---------------------------------------------------------------------#
# catenate all logs in cgal_test_with_cmake.log
#---------------------------------------------------------------------#
if [ -n "$DO_RUN" ] ; then
for f in ProgramOutput.*.$PLATFORM ; do
echo "------------------------------------------------------------------" >> cgal_test_with_cmake.log
echo "- $f" >> cgal_test_with_cmake.log
echo "------------------------------------------------------------------" >> cgal_test_with_cmake.log
cat $f >> cgal_test_with_cmake.log
echo >> cgal_test_with_cmake.log
done
fi
echo "------------------------------------------------------------------" >> cgal_test_with_cmake.log
echo "- Error output from platform $PLATFORM" >> cgal_test_with_cmake.log
echo "------------------------------------------------------------------" >> cgal_test_with_cmake.log
echo >> cgal_test_with_cmake.log
cat $ERRORFILE >> cgal_test_with_cmake.log

View File

@ -1,20 +0,0 @@
@echo off
rem Double-clickable version of cgal_test_with_cmake on Windows/Cygwin/VisualC++
rem Path to Cygwin is hard-coded
PATH=c:\Applis\cygwin\bin;%PATH%
rem Add path to VisualC++
if "%CMAKE_GENERATOR%"=="-GVisual Studio 8 2005" PATH=%VS80COMNTOOLS%\..\IDE;%PATH%
if "%CMAKE_GENERATOR%"=="-GVisual Studio 8 2005 Win64" PATH=%VS80COMNTOOLS%\..\IDE;%PATH%
if "%CMAKE_GENERATOR%"=="-GVisual Studio 9 2008" PATH=%VS90COMNTOOLS%\..\IDE;%PATH%
if "%CMAKE_GENERATOR%"=="-GVisual Studio 9 2008 Win64" PATH=%VS90COMNTOOLS%\..\IDE;%PATH%
rem Call shell script
sh ./cgal_test_with_cmake
pause
rem Compare logs with Beyond Compare
BC2.exe ./cgal_test_with_cmake.log.bak ./cgal_test_with_cmake.log

View File

@ -1,10 +0,0 @@
#ifndef CGAL_POINT_SET_DEMO_CONFIG_H
#define CGAL_POINT_SET_DEMO_CONFIG_H
//
// Empty
//
#endif // CGAL_POINT_SET_DEMO_CONFIG_H

View File

@ -1,96 +0,0 @@
#ifndef _MAKE_BAR_
#define _MAKE_BAR_
#include <CGAL/Polyhedron_incremental_builder_3.h>
template <class HDS,class Polyhedron,class Kernel>
class CModifierBar : public CGAL::Modifier_base<HDS>
{
private:
typedef typename Kernel::Point_3 Point;
typedef typename CGAL::Polyhedron_incremental_builder_3<HDS> builder;
Point m_points[8];
public:
// life cycle
CModifierBar(Point points[8])
{
for(int i=0;i<8;i++)
m_points[i] = points[i];
}
~CModifierBar() {}
void operator()( HDS& hds)
{
builder B(hds,true);
B.begin_surface(3,1,6);
for(int i=0;i<8;i++)
B.add_vertex(m_points[i]);
B.begin_facet();
B.add_vertex_to_facet(0);
B.add_vertex_to_facet(1);
B.add_vertex_to_facet(2);
B.add_vertex_to_facet(3);
B.end_facet();
B.begin_facet();
B.add_vertex_to_facet(0);
B.add_vertex_to_facet(4);
B.add_vertex_to_facet(5);
B.add_vertex_to_facet(1);
B.end_facet();
B.begin_facet();
B.add_vertex_to_facet(1);
B.add_vertex_to_facet(5);
B.add_vertex_to_facet(6);
B.add_vertex_to_facet(2);
B.end_facet();
B.begin_facet();
B.add_vertex_to_facet(2);
B.add_vertex_to_facet(6);
B.add_vertex_to_facet(7);
B.add_vertex_to_facet(3);
B.end_facet();
B.begin_facet();
B.add_vertex_to_facet(3);
B.add_vertex_to_facet(7);
B.add_vertex_to_facet(4);
B.add_vertex_to_facet(0);
B.end_facet();
B.begin_facet();
B.add_vertex_to_facet(4);
B.add_vertex_to_facet(7);
B.add_vertex_to_facet(6);
B.add_vertex_to_facet(5);
B.end_facet();
B.end_surface();
}
};
template <class Polyhedron,class Kernel>
class Make_bar
{
public:
typedef typename Polyhedron::HalfedgeDS HalfedgeDS;
typedef typename Kernel::Point_3 Point;
Make_bar() {}
~Make_bar() {}
public:
void run(Point points[8],
Polyhedron &output)
{
CModifierBar<HalfedgeDS,Polyhedron,Kernel> bar(points);
output.delegate(bar);
}
};
#endif // _MAKE_BAR_

View File

@ -1,44 +0,0 @@
#ifndef _COMPUTE_NORMAL_
#define _COMPUTE_NORMAL_
template <class Facet, class Kernel>
typename Kernel::Vector_3 compute_facet_normal(const Facet& f)
{
typedef typename Kernel::Point_3 Point;
typedef typename Kernel::Vector_3 Vector;
typedef typename Facet::Halfedge_around_facet_const_circulator HF_circulator;
Vector normal = CGAL::NULL_VECTOR;
HF_circulator he = f.facet_begin();
HF_circulator end = he;
CGAL_For_all(he,end)
{
const Point& prev = he->prev()->vertex()->point();
const Point& curr = he->vertex()->point();
const Point& next = he->next()->vertex()->point();
Vector n = CGAL::cross_product(next-curr,prev-curr);
normal = normal + (n / std::sqrt(n*n));
}
return normal / std::sqrt(normal * normal);
}
template <class Vertex, class Kernel>
typename Kernel::Vector_3 compute_vertex_normal(const Vertex& v)
{
typedef typename Kernel::Vector_3 Vector;
typedef typename Vertex::Halfedge_around_vertex_const_circulator HV_circulator;
typedef typename Vertex::Facet Facet;
Vector normal = CGAL::NULL_VECTOR;
HV_circulator he = v.vertex_begin();
HV_circulator end = he;
CGAL_For_all(he,end)
{
if(!he->is_border())
{
Vector n = compute_facet_normal<Facet,Kernel>(*he->facet());
normal = normal + (n / std::sqrt(n*n));
}
}
return normal / std::sqrt(normal * normal);
}
#endif // _COMPUTE_NORMAL_

View File

@ -1,80 +0,0 @@
#ifndef _GL_RENDER_
#define _GL_RENDER_
#include <CGAL/gl.h>
#include "CGAL/compute_normal.h"
template <class Polyhedron>
void gl_render_facets(Polyhedron& polyhedron)
{
typedef typename Polyhedron::Traits Kernel;
typedef typename Kernel::Point_3 Point;
typedef typename Kernel::Vector_3 Vector;
typedef typename Polyhedron::Facet Facet;
typedef typename Polyhedron::Facet_iterator Facet_iterator;
typedef typename Polyhedron::Halfedge_around_facet_circulator HF_circulator;
// Gets current shading model
GLint shading;
::glGetIntegerv(GL_SHADE_MODEL, &shading);
Facet_iterator f;
for(f = polyhedron.facets_begin();
f != polyhedron.facets_end();
f++)
{
::glBegin(GL_POLYGON);
// If Flat shading: 1 normal per polygon
if (shading == GL_FLAT)
{
Vector n = compute_facet_normal<Facet,Kernel>(*f);
::glNormal3d(n.x(),n.y(),n.z());
}
// revolve around current face to get vertices
HF_circulator he = f->facet_begin();
HF_circulator end = he;
CGAL_For_all(he,end)
{
// If Gouraud shading: 1 normal per vertex
if (shading == GL_SMOOTH)
{
Vector n = compute_vertex_normal<typename Polyhedron::Vertex,Kernel>(*he->vertex());
::glNormal3d(n.x(),n.y(),n.z());
}
const Point& p = he->vertex()->point();
::glVertex3d(p.x(),p.y(),p.z());
}
::glEnd();
}
} // end gl_render_facets
template <class Polyhedron>
void gl_render_edges(Polyhedron& polyhedron)
{
typedef typename Polyhedron::Traits Kernel;
typedef typename Kernel::Point_3 Point;
typedef typename Polyhedron::Edge_iterator Edge_iterator;
::glBegin(GL_LINES);
Edge_iterator he;
for(he = polyhedron.edges_begin();
he != polyhedron.edges_end();
he++)
{
const Point& a = he->vertex()->point();
const Point& b = he->opposite()->vertex()->point();
::glVertex3d(a.x(),a.y(),a.z());
::glVertex3d(b.x(),b.y(),b.z());
}
::glEnd();
} // end gl_render_edges
#endif // _GL_RENDER_

View File

@ -1,377 +0,0 @@
// Author: Laurent Saboret, Nader Salman, Gael Guennebaud
#ifndef POINT_SET_3_H
#define POINT_SET_3_H
#include <CGAL/property_map.h>
#include <CGAL/Min_sphere_of_spheres_d.h>
#include <CGAL/Min_sphere_of_spheres_d_traits_3.h>
#include <UI_point_3.h>
#include <algorithm>
#include <deque>
#ifdef CGAL_GLEW_ENABLED
# include <GL/glew.h>
#else
# include <CGAL/gl.h>
#endif
/// The Point_set_3 class is array of points + normals of type
/// Point_with_normal_3<Gt> (in fact
/// UI_point_3 to support a selection flag and an optional radius).
/// It provides:
/// - accessors: points and normals iterators, property maps
/// - OpenGL rendering
/// - bounding box
///
/// CAUTION:
/// - User is responsible to call invalidate_bounds() after adding, moving or removing points.
///
/// @heading Parameters:
/// @param Gt Geometric traits class.
template <class Gt>
class Point_set_3 : public std::deque<UI_point_3<Gt> >
{
// Private types
private:
// Base class
typedef std::deque<UI_point_3<Gt> > Base;
// Public types
public:
// Repeat base class' types
/// @cond SKIP_IN_MANUAL
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
using Base::erase;
/// @endcond
// Classic CGAL geometric types
typedef Gt Geom_traits; ///< Geometric traits class.
typedef typename Geom_traits::FT FT;
typedef typename Geom_traits::Point_3 Point; ///< typedef to Geom_traits::Point_3
typedef typename Geom_traits::Vector_3 Vector; ///< typedef to Geom_traits::Vector_3
typedef typename Geom_traits::Iso_cuboid_3 Iso_cuboid;
typedef typename Geom_traits::Sphere_3 Sphere;
/// Type of points in Point_set_3
typedef UI_point_3<Gt> UI_point; ///< Position + normal + selection flag
// Its superclass:
typedef typename UI_point::Point_with_normal Point_with_normal; ///< Position + normal
// Iterator over Point_3 points
typedef typename std::deque<UI_point>::iterator Point_iterator;
typedef typename std::deque<UI_point>::const_iterator Point_const_iterator;
// Data members
private:
// Indicate if m_barycenter, m_bounding_box, m_bounding_sphere and
// m_diameter_standard_deviation below are valid.
mutable bool m_bounding_box_is_valid;
mutable Iso_cuboid m_bounding_box; // point set's bounding box
mutable Sphere m_bounding_sphere; // point set's bounding sphere
mutable Point m_barycenter; // point set's barycenter
mutable FT m_diameter_standard_deviation; // point set's standard deviation
unsigned int m_nb_selected_points; // number of selected points
bool m_radii_are_uptodate;
// Public methods
public:
/// Default constructor.
Point_set_3()
{
m_nb_selected_points = 0;
m_bounding_box_is_valid = false;
m_radii_are_uptodate = false;
}
// Default copy constructor and operator =() are fine.
// Repeat base class' public methods used below
/// @cond SKIP_IN_MANUAL
using Base::begin;
using Base::end;
using Base::size;
/// @endcond
/// Gets the number of selected points.
unsigned int nb_selected_points() const { return m_nb_selected_points; }
/// Mark a point as selected/not selected.
void select(UI_point* point, bool is_selected = true)
{
if (point->is_selected() != is_selected)
{
point->select(is_selected);
m_nb_selected_points += (is_selected ? 1 : -1);
}
}
/// Mark a range of points as selected/not selected.
///
/// @param first Iterator over first point to select/unselect.
/// @param beyond Past-the-end iterator.
void select(iterator first, iterator beyond,
bool is_selected = true)
{
for (iterator it = first; it != beyond; it++)
it->select(is_selected);
m_nb_selected_points = std::count_if(begin(), end(),
std::mem_fun_ref(&UI_point::is_selected));
}
/// Deletes selected points.
void delete_selection()
{
// Deletes selected points using erase-remove idiom
erase(std::remove_if(begin(), end(), std::mem_fun_ref(&UI_point::is_selected)),
end());
// after erase(), use Scott Meyer's "swap trick" to trim excess capacity
Point_set_3(*this).swap(*this);
m_nb_selected_points = 0;
invalidate_bounds();
}
/// Gets the bounding box.
Iso_cuboid bounding_box() const
{
if (!m_bounding_box_is_valid)
update_bounds();
return m_bounding_box;
}
/// Gets bounding sphere.
Sphere bounding_sphere() const
{
if (!m_bounding_box_is_valid)
update_bounds();
return m_bounding_sphere;
}
/// Gets points barycenter.
Point barycenter() const
{
if (!m_bounding_box_is_valid)
update_bounds();
return m_barycenter;
}
/// Gets the standard deviation of the distance to barycenter.
FT diameter_standard_deviation() const
{
if (!m_bounding_box_is_valid)
update_bounds();
return m_diameter_standard_deviation;
}
// Gets the region of interest, ignoring the outliers.
// This method is used to define the OpenGL arcball sphere.
Sphere region_of_interest() const
{
if (!m_bounding_box_is_valid)
update_bounds();
// A good candidate is a sphere containing the dense region of the point cloud:
// - center point is barycenter
// - Radius is 2 * standard deviation
float radius = 2.f * (float)m_diameter_standard_deviation;
return Sphere(m_barycenter, radius*radius);
}
/// Update barycenter, bounding box, bounding sphere and standard deviation.
/// User is responsible to call invalidate_bounds() after adding, moving or removing points.
void invalidate_bounds()
{
m_bounding_box_is_valid = false;
}
// Draw points using OpenGL calls.
// Preconditions: OpenGL point size and color must be set.
void gl_draw_vertices() const
{
// Draw *non-selected* points
if (m_nb_selected_points < size())
{
::glBegin(GL_POINTS);
for (const_iterator it = begin(); it != end(); it++)
{
const UI_point& p = *it;
if ( ! p.is_selected() )
::glVertex3dv(&p.x());
}
::glEnd();
}
// Draw *selected* points
if (m_nb_selected_points > 0)
{
::glPointSize(4.f); // selected => bigger
::glColor3ub(255,0,0); // selected => red
::glBegin(GL_POINTS);
for (const_iterator it = begin(); it != end(); it++)
{
const UI_point& p = *it;
if (p.is_selected())
::glVertex3dv(&p.x());
}
::glEnd();
}
}
// Draw normals using OpenGL calls.
// Preconditions: OpenGL line width and color must be set.
void gl_draw_normals(float scale = 1.0) const // scale applied to normal length
{
// Draw normals of *non-selected* points
if (m_nb_selected_points < size())
{
// Draw normals
::glBegin(GL_LINES);
for (const_iterator it = begin(); it != end(); it++)
{
const UI_point& p = *it;
const Vector& n = p.normal();
if (!p.is_selected())
{
Point q = p + scale * n;
::glVertex3d(p.x(),p.y(),p.z());
::glVertex3d(q.x(),q.y(),q.z());
}
}
::glEnd();
}
// Draw normals of *selected* points
if (m_nb_selected_points > 0)
{
::glColor3ub(255,0,0); // selected => red
::glBegin(GL_LINES);
for (const_iterator it = begin(); it != end(); it++)
{
const UI_point& p = *it;
const Vector& n = p.normal();
if (p.is_selected())
{
Point q = p + scale * n;
::glVertex3d(p.x(),p.y(),p.z());
::glVertex3d(q.x(),q.y(),q.z());
}
}
::glEnd();
}
}
// Draw oriented points with radius using OpenGL calls.
// Preconditions: must be used inbetween calls to GlSplat library
void gl_draw_splats() const
{
// TODO add support for selection
::glBegin(GL_POINTS);
for (const_iterator it = begin(); it != end(); it++)
{
const UI_point& p = *it;
::glNormal3dv(&p.normal().x());
#ifdef CGAL_GLEW_ENABLED
::glMultiTexCoord1d(GL_TEXTURE2, p.radius());
#endif
::glVertex3dv(&p.x());
}
::glEnd();
}
bool are_radii_uptodate() const { return m_radii_are_uptodate; }
void set_radii_uptodate(bool /*on*/) { m_radii_are_uptodate = false; }
// Private methods:
private:
/// Recompute barycenter, bounding box, bounding sphere and standard deviation.
void update_bounds() const
{
if (begin() == end())
return;
// Update bounding box and barycenter.
// TODO: we should use the functions in PCA component instead.
FT xmin,xmax,ymin,ymax,zmin,zmax;
xmin = ymin = zmin = 1e38;
xmax = ymax = zmax = -1e38;
Vector v = CGAL::NULL_VECTOR;
FT norm = 0;
for (Point_const_iterator it = begin(); it != end(); it++)
{
const Point& p = *it;
// update bbox
xmin = (std::min)(p.x(),xmin);
ymin = (std::min)(p.y(),ymin);
zmin = (std::min)(p.z(),zmin);
xmax = (std::max)(p.x(),xmax);
ymax = (std::max)(p.y(),ymax);
zmax = (std::max)(p.z(),zmax);
// update barycenter
v = v + (p - CGAL::ORIGIN);
norm += 1;
}
//
Point p(xmin,ymin,zmin);
Point q(xmax,ymax,zmax);
m_bounding_box = Iso_cuboid(p,q);
//
m_barycenter = CGAL::ORIGIN + v / norm;
// Computes bounding sphere
typedef CGAL::Min_sphere_of_spheres_d_traits_3<Gt,FT> Traits;
typedef CGAL::Min_sphere_of_spheres_d<Traits> Min_sphere;
typedef typename Traits::Sphere Traits_sphere;
//
// Represents points by a set of spheres with 0 radius
std::vector<Traits_sphere> spheres;
for (Point_const_iterator it = begin(); it != end(); it++)
spheres.push_back(Traits_sphere(*it,0));
//
// Computes min sphere
Min_sphere ms(spheres.begin(),spheres.end());
typename Min_sphere::Cartesian_const_iterator coord = ms.center_cartesian_begin();
FT cx = *coord++;
FT cy = *coord++;
FT cz = *coord++;
m_bounding_sphere = Sphere(Point(cx,cy,cz), ms.radius()*ms.radius());
// Computes standard deviation of the distance to barycenter
typename Geom_traits::Compute_squared_distance_3 sqd;
FT sq_radius = 0;
for (Point_const_iterator it = begin(); it != end(); it++)
sq_radius += sqd(*it, m_barycenter);
sq_radius /= size();
m_diameter_standard_deviation = CGAL::sqrt(sq_radius);
m_bounding_box_is_valid = true;
}
}; // end of class Point_set_3
#endif // POINT_SET_3_H

View File

@ -1,132 +0,0 @@
// Author: Laurent Saboret
#ifndef UI_POINT_3_H
#define UI_POINT_3_H
#include <CGAL/Point_with_normal_3.h>
#include <CGAL/Iterator_project.h>
#include <set>
#include <algorithm>
/// The UI_point_3 class represents a 3D point in Surface_reconstruction_points_3 demo.
/// It contains:
/// - a position,
/// - a normal,
/// - a radius,
/// - a selection flag.
///
/// @heading Parameters:
/// @param Gt Geometric traits class.
template<class Gt>
class UI_point_3
: public CGAL::Point_with_normal_3<Gt>
{
// Private types
private:
// Base class
typedef CGAL::Point_with_normal_3<Gt> Base;
// Public types
public:
/// Base class
typedef Base Point_with_normal;
// Repeat base class public types
typedef Gt Geom_traits; ///< Geometric traits class.
typedef typename Geom_traits::FT FT;
typedef typename Geom_traits::RT RT;
typedef typename Geom_traits::Point_2 Point_2; ///< typedef to Geom_traits::Point_2
typedef typename Geom_traits::Point_3 Point_3; ///< typedef to Geom_traits::Point_3
typedef typename Geom_traits::Vector_3 Vector_3; ///< typedef to Geom_traits::Vector_3
// Public methods
public:
/// Point is (0,0,0) by default.
/// Normal is (0,0,0) by default.
UI_point_3(const CGAL::Origin& o = CGAL::ORIGIN)
: Base(o)
{
m_is_selected = false;
m_radius = FT(0);
}
UI_point_3(FT x, FT y, FT z,
const Vector_3& normal = CGAL::NULL_VECTOR)
: Base(x,y,z,normal)
{
m_is_selected = false;
m_radius = FT(0);
}
UI_point_3(RT hx, RT hy, RT hz, RT hw,
const Vector_3& normal = CGAL::NULL_VECTOR)
: Base(hx,hy,hz,hw,normal)
{
m_is_selected = false;
m_radius = FT(0);
}
UI_point_3(const Point_3& point,
const Vector_3& normal = CGAL::NULL_VECTOR)
: Base(point, normal)
{
m_is_selected = false;
m_radius = FT(0);
}
template <class K>
UI_point_3(const CGAL::Point_with_normal_3<K>& pwn)
: Base(pwn)
{
m_is_selected = false;
m_radius = FT(0);
}
/// Copy constructor
UI_point_3(const UI_point_3& upt)
: Base(upt)
{
m_is_selected = upt.m_is_selected;
m_radius = upt.m_radius;
}
template<class K>
UI_point_3(const UI_point_3<K>& upt)
: Base(upt)
{
m_is_selected = upt.is_selected();
m_radius = upt.radius();
}
/// Operator =()
UI_point_3& operator=(const UI_point_3& upt)
{
Base::operator=(upt);
m_is_selected = upt.m_is_selected;
m_radius = upt.m_radius;
return *this;
}
// Inherited operators ==() and !=() are fine.
/// Selection flag.
bool is_selected() const { return m_is_selected; }
void select(bool is_selected=true) { m_is_selected = is_selected; }
/// Gets/sets radius.
FT radius() const { return m_radius; }
FT& radius() { return m_radius; }
// Data
private:
// Selection flag.
bool m_is_selected;
/// radius.
FT m_radius;
};
#endif //UI_POINT_3_H

View File

@ -1,574 +0,0 @@
#ifndef MARCHINGCUBES_H
#define MARCHINGCUBES_H
#include <CGAL/Polyhedron_incremental_builder_3.h>
namespace internal
{
//************************************************************************
// Static precalculated table
//************************************************************************
int msEdgeTable[256]={
0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0};
int msTriTable[256][16] = {
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
{3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
{3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
{3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
{9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
{9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
{2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
{8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
{9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
{4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
{3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
{1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
{4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
{4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
{5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
{2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
{9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
{0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
{2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
{10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
{4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
{5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
{5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
{9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
{0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
{10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
{8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
{2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
{7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
{2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
{11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
{5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
{11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
{11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
{1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
{9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
{5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
{2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
{5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
{6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
{3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
{6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
{5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
{1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
{10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
{6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
{8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
{7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
{3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
{5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
{0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
{9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
{8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
{5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
{0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
{6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
{10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
{10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
{8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
{1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
{0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
{10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
{3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
{6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
{9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
{8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
{3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
{6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
{0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
{10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
{10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
{2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
{7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
{7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
{2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
{1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
{11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
{8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
{0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
{7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
{10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
{2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
{6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
{7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
{2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
{1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
{10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
{10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
{0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
{7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
{6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
{8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
{9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
{6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
{4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
{10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
{8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
{0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
{1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
{8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
{10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
{4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
{10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
{5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
{11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
{9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
{6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
{7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
{3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
{7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
{9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
{3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
{6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
{9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
{1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
{4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
{7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
{6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
{3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
{0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
{6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
{0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
{11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
{6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
{5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
{9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
{1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
{1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
{10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
{0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
{5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
{10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
{11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
{9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
{7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
{2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
{8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
{9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
{9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
{1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
{9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
{9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
{5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
{0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
{10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
{2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
{0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
{0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
{9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
{5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
{3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
{5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
{8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
{0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
{9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
{0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
{1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
{3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
{4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
{9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
{11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
{11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
{2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
{9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
{3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
{1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
{4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
{4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
{0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
{3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
{3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
{0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
{9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
{1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}};
} // end of namespace internal
namespace CGAL {
template <class Surface, class HDS>
class Marching_cubes : public CGAL::Modifier_base<HDS>
{
typedef typename Surface::Geom_traits Traits;
typedef typename Traits::FT FT;
typedef typename Traits::Point_3 Point_3;
typedef typename Traits::Vector_3 Vector_3;
typedef typename Surface::BBox BBox;
// represent a vertices of the lattice
struct GridElement
{
Point_3 position;
FT value;
inline bool isInvalid() const { return value == Invalid; }
inline void markInvalid() { value = Invalid; }
};
static const long Invalid = 987654321;
public:
Marching_cubes(const Surface& s, int gs) : surface(s), grid_size(gs) {}
void operator() (HDS& hds)
{
const FT iso_value = FT(0);
// size of the blocks
static const int maxBlockSize = 128;
// precomputed offsets to access the cell corners
static const int offsets[8] = {
0,
1,
1+maxBlockSize*maxBlockSize,
maxBlockSize*maxBlockSize,
maxBlockSize,
1+maxBlockSize,
1+maxBlockSize+maxBlockSize*maxBlockSize,
maxBlockSize+maxBlockSize*maxBlockSize};
// returns the local extremity indices of an edge from its local index
static const int edge_to_vertex[12][2] = {
{0,1}, // 0
{1,2}, // 1
{2,3}, // 2
{0,3}, // 3
{4,5}, // 4
{5,6}, // 5
{6,7}, // 6
{4,7}, // 7
{0,4}, // 8
{1,5}, // 9
{2,6}, // 10
{3,7}}; // 11
// get the bouding box:
BBox bbox = surface.bounding_box();
Vector_3 diag = Vector_3(bbox.xmax() - bbox.xmin(), bbox.ymax() - bbox.ymin(), bbox.zmax() - bbox.zmin());
if ( (diag.x()<=0.)
|| (diag.y()<=0.)
|| (diag.z()<=0.)
|| (grid_size<=0))
{
return;
}
std::vector<GridElement> grid(maxBlockSize*maxBlockSize*maxBlockSize);
// start a new 3D mesh
int vertex_count = 0;
Polyhedron_incremental_builder_3<HDS> B(hds, true); // true means verbose ??
B.begin_surface(10,10,10);
typedef std::pair<int,int> EdgeKey;
FT step = (std::max)( (std::max)(diag.x(), diag.y()), diag.z())/FT(grid_size);
unsigned int nbCells[3];
unsigned int nbBlocks[3];
for (int k=0 ; k<3 ; ++k)
{
nbCells[k] = int(diag[k]/step)+2;
nbBlocks[k] = nbCells[k]/maxBlockSize + ( (nbCells[k]%maxBlockSize)==0 ? 0 : 1);
}
// for each macro block
uint bi[3]; // block id
for(bi[2]=0 ; bi[2]<nbBlocks[2] ; ++bi[2])
for(bi[1]=0 ; bi[1]<nbBlocks[1] ; ++bi[1])
for(bi[0]=0 ; bi[0]<nbBlocks[0] ; ++bi[0])
{
// record all vertices
std::map<EdgeKey, int> unique_vertex_map;
// compute the size of the local grid
uint gridSize[3];
for (uint k=0 ; k<3 ; ++k)
{
gridSize[k] = std::min<int>(maxBlockSize, nbCells[k]-(maxBlockSize-1)*bi[k]);
}
Point_3 origin = Point_3(bbox.xmin(),bbox.ymin(),bbox.zmin()) + step * (maxBlockSize-1) * Vector_3(bi[0],bi[1],bi[2]);
// fill the grid
uint ci[3]; // local cell id
// for each vertex...
for(ci[0]=0 ; ci[0]<gridSize[0] ; ++ci[0])
for(ci[1]=0 ; ci[1]<gridSize[1] ; ++ci[1])
for(ci[2]=0 ; ci[2]<gridSize[2] ; ++ci[2])
{
GridElement& el = grid[(ci[2]*maxBlockSize + ci[1])*maxBlockSize + ci[0]];
el.position = origin + step*Vector_3(ci[0],ci[1],ci[2]);
bool ok;
el.value = surface(el.position, &ok);
if (!ok)
el.markInvalid();
}
// polygonize the grid (marching cube)
// for each cell...
for(ci[0]=0 ; ci[0]<gridSize[0]-1 ; ++ci[0])
for(ci[1]=0 ; ci[1]<gridSize[1]-1 ; ++ci[1])
for(ci[2]=0 ; ci[2]<gridSize[2]-1 ; ++ci[2])
{
uint cellId = ci[0]+maxBlockSize*(ci[1]+maxBlockSize*ci[2]);
// FIXME check if one corner is outside the surface definition domain
bool out = grid[cellId+offsets[0]].isInvalid() || grid[cellId+offsets[1]].isInvalid()
|| grid[cellId+offsets[2]].isInvalid() || grid[cellId+offsets[3]].isInvalid()
|| grid[cellId+offsets[4]].isInvalid() || grid[cellId+offsets[5]].isInvalid()
|| grid[cellId+offsets[6]].isInvalid() || grid[cellId+offsets[7]].isInvalid();
for (int k=0; k<8 && (!out); ++k)
out = out || (!is_finite(grid[cellId+offsets[k]].value));
if (!out)
{
// compute the mask
int mask = 0;
if (grid[cellId+offsets[0]].value <= iso_value) mask |= 1;
if (grid[cellId+offsets[1]].value <= iso_value) mask |= 2;
if (grid[cellId+offsets[2]].value <= iso_value) mask |= 4;
if (grid[cellId+offsets[3]].value <= iso_value) mask |= 8;
if (grid[cellId+offsets[4]].value <= iso_value) mask |= 16;
if (grid[cellId+offsets[5]].value <= iso_value) mask |= 32;
if (grid[cellId+offsets[6]].value <= iso_value) mask |= 64;
if (grid[cellId+offsets[7]].value <= iso_value) mask |= 128;
if (::internal::msEdgeTable[mask] != 0)
{
Point_3 edges[12];
if (::internal::msEdgeTable[mask] & 1)
edges[0] = interpolEdge(grid[cellId+offsets[0]],grid[cellId+offsets[1]]);
if (::internal::msEdgeTable[mask] & 2)
edges[1] = interpolEdge(grid[cellId+offsets[1]],grid[cellId+offsets[2]]);
if (::internal::msEdgeTable[mask] & 4)
edges[2] = interpolEdge(grid[cellId+offsets[2]],grid[cellId+offsets[3]]);
if (::internal::msEdgeTable[mask] & 8)
edges[3] = interpolEdge(grid[cellId+offsets[3]],grid[cellId+offsets[0]]);
if (::internal::msEdgeTable[mask] & 16)
edges[4] = interpolEdge(grid[cellId+offsets[4]],grid[cellId+offsets[5]]);
if (::internal::msEdgeTable[mask] & 32)
edges[5] = interpolEdge(grid[cellId+offsets[5]],grid[cellId+offsets[6]]);
if (::internal::msEdgeTable[mask] & 64)
edges[6] = interpolEdge(grid[cellId+offsets[6]],grid[cellId+offsets[7]]);
if (::internal::msEdgeTable[mask] & 128)
edges[7] = interpolEdge(grid[cellId+offsets[7]],grid[cellId+offsets[4]]);
if (::internal::msEdgeTable[mask] & 256)
edges[8] = interpolEdge(grid[cellId+offsets[0]],grid[cellId+offsets[4]]);
if (::internal::msEdgeTable[mask] & 512)
edges[9] = interpolEdge(grid[cellId+offsets[1]],grid[cellId+offsets[5]]);
if (::internal::msEdgeTable[mask] & 1024)
edges[10] = interpolEdge(grid[cellId+offsets[2]],grid[cellId+offsets[6]]);
if (::internal::msEdgeTable[mask] & 2048)
edges[11] = interpolEdge(grid[cellId+offsets[3]],grid[cellId+offsets[7]]);
for (int i=0 ; ::internal::msTriTable[mask][i]!=-1 ; i+=3)
{
int auxId[3];
int countAddedVertex = 0;
for (int j=0;j<3;++j)
{
int local_edge_id = ::internal::msTriTable[mask][i+j];
int v0 = cellId + offsets[edge_to_vertex[local_edge_id][0]];
int v1 = cellId + offsets[edge_to_vertex[local_edge_id][1]];
if (v0>v1)
std::swap(v0,v1);
EdgeKey key(v0,v1);
std::map<EdgeKey, int>::iterator it = unique_vertex_map.find(key);
if (it!=unique_vertex_map.end())
{
//int count
// the vertex already exist
auxId[j] = it->second;
}
else
{
const Point_3& p = edges[::internal::msTriTable[mask][i+j]];
// add a new vertex
auxId[j] = vertex_count;
countAddedVertex++;
B.add_vertex(p);
unique_vertex_map[key] = vertex_count;
vertex_count++;
}
}
if (auxId[0]!=auxId[1] && auxId[1]!=auxId[2] && auxId[2]!=auxId[0])
{
B.begin_facet();
for (uint j=0;j<3;++j)
B.add_vertex_to_facet(auxId[j]);
B.end_facet();
}
}
}
}
}
}
B.end_surface();
}
protected:
inline Point_3 interpolEdge(const GridElement& v1, const GridElement& v2)
{
FT epsilon = 1e-6; // FIXME not very nice ;)
if (std::abs(v1.value) < epsilon)
return v1.position;
if (std::abs(v2.value) < epsilon)
return v2.position;
if (std::abs(v1.value-v2.value) < epsilon)
return v1.position + FT(0.5) * (v2.position - v1.position);
FT a = (-v1.value) / (v2.value - v1.value);
return v1.position + a * (v2.position - v1.position);
}
inline bool is_finite(FT x)
{
return (x >= -(std::numeric_limits<FT>::max)()) && (x <= (std::numeric_limits<FT>::max)());
}
protected:
const Surface surface;
int grid_size;
};
template<typename Surface, typename Polyhedron>
void marching_cubes(const Surface& surface, int grid_size, Polyhedron& target)
{
Marching_cubes<Surface, typename Polyhedron::HalfedgeDS> mc(surface, grid_size);
target.delegate(mc);
}
} // end of namespace CGAL
#endif // MARCHINGCUBES_H

View File

@ -1,29 +0,0 @@
<html>
<body>
<h2>Point Set Demo</h2>
<p>Copyright &copy;2008-2009
<a href="http://www.geometryfactory.com/">GeometryFactory</a>
and <a href="http://www-sop.inria.fr/">INRIA Sophia Antipolis - Mediterranee<a/></p>
<p>This application illustrates <a href="http://www.cgal.org/">CGAL</a>
algorithms on point sets.</p>
<p>See also the following chapters of the manual:
<ul>
<li><a href="http://www.cgal.org/Pkg/Point_set_processing_3">
Point Set Processing</a>,
</li>
<li><a href="http://www.cgal.org/Pkg/Surface_reconstruction_points_3">
Surface Reconstruction from Point Sets</a>,
</li>
<li><a href="http://www.cgal.org/Pkg/Principal_component_analysis">
Principal Component Analysis</a>,
</li>
<li><a href="http://www.cgal.org/Pkg/Jet_fitting_3">
Estimation of Local Differential Properties</a>.
</li>
<li><a href="http://www.cgal.org/Pkg/Surface_mesher">
3D Surface Mesh Generation</a>,
</li>
</ul>
</p>
</body>
</html>

View File

@ -1,24 +0,0 @@
/* XPM */
const char * demoicon_xpm[] = {
/* columns rows colors chars-per-pixel */
"16 16 3 1",
" c None",
". c #FFFF00",
"+ c #000000",
/* pixels */
"................",
"...++++...++++..",
"..+....+.+....+.",
"..+......+......",
"..+......+..+++.",
"..+......+....+.",
"..+....+.+....+.",
"...++++...++++..",
"................",
"...++++...+.....",
"..+....+..+.....",
"..+....+..+.....",
"..++++++..+.....",
"..+....+..+.....",
"..+....+..+++++.",
"................"};

Some files were not shown because too many files have changed in this diff Show More