mirror of https://github.com/CGAL/cgal
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:
commit
45f7298ce7
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ class Scene_item;
|
|||
// OpenGL rendering mode
|
||||
enum RenderingMode { Points = 0,
|
||||
PointsPlusNormals,
|
||||
Splatting,
|
||||
Wireframe,
|
||||
Flat,
|
||||
FlatPlusEdges,
|
||||
|
|
|
|||
|
|
@ -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} )
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include <QtCore/qglobal.h>
|
||||
#include "opengl_tools.h"
|
||||
|
||||
#include "Messages_interface.h"
|
||||
#include "Scene_polyhedron_item.h"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include <QtCore/qglobal.h>
|
||||
#include "opengl_tools.h"
|
||||
|
||||
#include "Messages_interface.h"
|
||||
#include "Scene_polyhedron_item.h"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include "opengl_tools.h"
|
||||
#include "Scene_edit_polyhedron_item.h"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <algorithm>
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ Scene_implicit_function_item::supportsRenderingMode(RenderingMode m) const
|
|||
{
|
||||
switch ( m )
|
||||
{
|
||||
case Splatting:
|
||||
case Gouraud:
|
||||
return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 "";
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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>&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>&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>&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>&Quit</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Q</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSimplify">
|
||||
<property name="text">
|
||||
<string>&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>&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>&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>&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>&Antialiasing</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="dummyAction">
|
||||
<property name="text">
|
||||
<string>n/a</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionFileCloseAll">
|
||||
<property name="text">
|
||||
<string>&Close All</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionOptions">
|
||||
<property name="text">
|
||||
<string>&Options...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveAs">
|
||||
<property name="text">
|
||||
<string>Save &as...</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Alt+S</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave">
|
||||
<property name="text">
|
||||
<string>&Save</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveAll">
|
||||
<property name="text">
|
||||
<string>Save a&ll</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionMergeAll">
|
||||
<property name="text">
|
||||
<string>Mer&ge all</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionMerge">
|
||||
<property name="text">
|
||||
<string>&Merge</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSelectAll">
|
||||
<property name="text">
|
||||
<string>Select &all</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSelectNone">
|
||||
<property name="text">
|
||||
<string>Select &none</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSelectInvert">
|
||||
<property name="text">
|
||||
<string>&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>
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
@ -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"
|
||||
|
|
@ -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>
|
||||
|
|
@ -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"
|
||||
|
|
@ -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"
|
||||
|
|
@ -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"
|
||||
|
|
@ -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>
|
||||
|
|
@ -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"
|
||||
|
|
@ -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"
|
||||
|
|
@ -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>
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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"
|
||||
|
|
@ -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>
|
||||
|
|
@ -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"
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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()
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#include "Scene_plane_item.h"
|
||||
|
||||
#include "Scene_plane_item.moc"
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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());
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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_
|
||||
|
|
@ -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_
|
||||
|
|
@ -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_
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<h2>Point Set Demo</h2>
|
||||
<p>Copyright ©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>
|
||||
|
|
@ -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
Loading…
Reference in New Issue