Commit work of previous days (week-end, yesterday and this morning):

The surface mesher Qt4 demo can now deal with labellized images.
This commit is contained in:
Laurent Rineau 2008-10-07 13:00:59 +00:00
parent e23bac61be
commit 43cc745311
23 changed files with 861 additions and 223 deletions

5
.gitattributes vendored
View File

@ -3862,12 +3862,13 @@ Surface_mesher/demo/Surface_mesher/qt4-demo/icons/surface.png -text svneol=unset
Surface_mesher/demo/Surface_mesher/qt4-demo/icons/surface.svg -text svneol=unset#image/svg%2Bxml Surface_mesher/demo/Surface_mesher/qt4-demo/icons/surface.svg -text svneol=unset#image/svg%2Bxml
Surface_mesher/demo/Surface_mesher/qt4-demo/icons/twosides.png -text svneol=unset#image/png Surface_mesher/demo/Surface_mesher/qt4-demo/icons/twosides.png -text svneol=unset#image/png
Surface_mesher/demo/Surface_mesher/qt4-demo/icons/twosides.svg -text svneol=unset#image/svg%2Bxml Surface_mesher/demo/Surface_mesher/qt4-demo/icons/twosides.svg -text svneol=unset#image/svg%2Bxml
Surface_mesher/demo/Surface_mesher/qt4-demo/isovalues_list.qrc -text
Surface_mesher/demo/Surface_mesher/qt4-demo/surface_mesher.qrc -text Surface_mesher/demo/Surface_mesher/qt4-demo/surface_mesher.qrc -text
Surface_mesher/demo/Surface_mesher/qt4-demo/ui/isovalues_list.ui -text
Surface_mesher/demo/Surface_mesher/qt4-demo/ui/mainwindow.ui -text Surface_mesher/demo/Surface_mesher/qt4-demo/ui/mainwindow.ui -text
Surface_mesher/demo/Surface_mesher/qt4-demo/ui/meshing_bar.ui -text Surface_mesher/demo/Surface_mesher/qt4-demo/ui/meshing_bar.ui -text
Surface_mesher/demo/Surface_mesher/qt4-demo/ui/optionsdialog.ui -text Surface_mesher/demo/Surface_mesher/qt4-demo/ui/optionsdialog.ui -text
Surface_mesher/demo/Surface_mesher/qt4-demo/ui/raw_image.ui -text
Surface_mesher/demo/Surface_mesher/qt4-demo/ui/values_list.ui -text
Surface_mesher/demo/Surface_mesher/qt4-demo/values_list.qrc -text
Surface_mesher/demo/Surface_mesher/replay-tangle -text Surface_mesher/demo/Surface_mesher/replay-tangle -text
Surface_mesher/demo/Surface_mesher/windows/Mesh.sln eol=crlf Surface_mesher/demo/Surface_mesher/windows/Mesh.sln eol=crlf
Surface_mesher/demo/Surface_mesher/windows/Mesh.suo -text Surface_mesher/demo/Surface_mesher/windows/Mesh.suo -text

3
.gitignore vendored
View File

@ -23,6 +23,7 @@ Boolean_set_operations_2/demo/Boolean_set_operations_2/*.vcproj
Boolean_set_operations_2/demo/Boolean_set_operations_2/Makefile Boolean_set_operations_2/demo/Boolean_set_operations_2/Makefile
Boolean_set_operations_2/demo/Boolean_set_operations_2/boolean_operations_2 Boolean_set_operations_2/demo/Boolean_set_operations_2/boolean_operations_2
CGALimageIO/demo/CGALimageIO/Makefile CGALimageIO/demo/CGALimageIO/Makefile
CGALimageIO/demo/CGALimageIO/cgal_test_with_cmake
CGALimageIO/demo/CGALimageIO/cmake_install.cmake CGALimageIO/demo/CGALimageIO/cmake_install.cmake
CGALimageIO/demo/CGALimageIO/image_to_vtk_viewer CGALimageIO/demo/CGALimageIO/image_to_vtk_viewer
CGALimageIO/examples/CGALimageIO/*.exe CGALimageIO/examples/CGALimageIO/*.exe
@ -30,6 +31,7 @@ CGALimageIO/examples/CGALimageIO/Makefile
CGALimageIO/examples/CGALimageIO/convert_raw_image_to_inr CGALimageIO/examples/CGALimageIO/convert_raw_image_to_inr
CGALimageIO/examples/CGALimageIO/makefile CGALimageIO/examples/CGALimageIO/makefile
CGALimageIO/examples/CGALimageIO/test_imageio CGALimageIO/examples/CGALimageIO/test_imageio
CGALimageIO/src/CGALimageIO/Makefile
Distance_3/include Distance_3/include
GraphicsView/TAGS GraphicsView/TAGS
GraphicsView/demo/Alpha_shapes_3/*.exe GraphicsView/demo/Alpha_shapes_3/*.exe
@ -411,6 +413,7 @@ Surface_mesher/demo/Surface_mesher/qt4-demo/.qglviewer.xml
Surface_mesher/demo/Surface_mesher/qt4-demo/CMakeCache.txt Surface_mesher/demo/Surface_mesher/qt4-demo/CMakeCache.txt
Surface_mesher/demo/Surface_mesher/qt4-demo/CMakeFiles Surface_mesher/demo/Surface_mesher/qt4-demo/CMakeFiles
Surface_mesher/demo/Surface_mesher/qt4-demo/Makefile Surface_mesher/demo/Surface_mesher/qt4-demo/Makefile
Surface_mesher/demo/Surface_mesher/qt4-demo/Surface_mesher
Surface_mesher/demo/Surface_mesher/qt4-demo/Surface_mesher_Qt4_Demo Surface_mesher/demo/Surface_mesher/qt4-demo/Surface_mesher_Qt4_Demo
Surface_mesher/demo/Surface_mesher/qt4-demo/cgal.prf Surface_mesher/demo/Surface_mesher/qt4-demo/cgal.prf
Surface_mesher/demo/Surface_mesher/qt4-demo/cmake_install.cmake Surface_mesher/demo/Surface_mesher/qt4-demo/cmake_install.cmake

View File

@ -382,7 +382,8 @@ _image* _readImage_raw(const char *name,
const unsigned int rz, const unsigned int rz,
const double vx = 1., const double vx = 1.,
const double vy = 1., const double vy = 1.,
const double vz = 1.); const double vz = 1.,
const unsigned int offset = 0);
/** Writes given image in file 'name'.<br> /** Writes given image in file 'name'.<br>

View File

@ -113,11 +113,12 @@ public:
const unsigned int rz, const unsigned int rz,
const double vx = 1, const double vx = 1,
const double vy = 1, const double vy = 1,
const double vz = 1) const double vz = 1,
const unsigned int offset = 0)
{ {
return private_read(::_readImage_raw(file, return private_read(::_readImage_raw(file,
rx,ry,rz, rx,ry,rz,
vx,vy,vz)); vx,vy,vz,offset));
} }
#ifdef CGAL_USE_VTK #ifdef CGAL_USE_VTK

View File

@ -1 +1 @@
cgal-develop Laurent Rineau <Laurent.Rineau@geometryfactory.com>

View File

@ -560,7 +560,8 @@ _image* _readImage_raw(const char *name,
const unsigned int rz, const unsigned int rz,
const double vx, const double vx,
const double vy, const double vy,
const double vz) const double vz,
const unsigned int offset)
{ {
_image *im = NULL; _image *im = NULL;
im = (_image *) ImageIO_alloc(sizeof(_image)); im = (_image *) ImageIO_alloc(sizeof(_image));
@ -610,8 +611,14 @@ _image* _readImage_raw(const char *name,
return NULL; return NULL;
} }
// read offset
if(offset > 0) {
im->data = ImageIO_alloc(offset+1);
ImageIO_read(im, im->data, offset);
ImageIO_free(im->data);
}
// allocate memory // allocate memory
im->data = (void *)new unsigned char[rx*ry*rz]; im->data = ImageIO_alloc(rx*ry*rz);
if(im->data == NULL) if(im->data == NULL)
return NULL; return NULL;

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 2.4.5) cmake_minimum_required(VERSION 2.4.5)
set ( prj Surface_mesher_Qt4_Demo ) set ( prj Surface_mesher )
project ( ${prj} ) project ( ${prj} )
@ -29,7 +29,7 @@ set( QT_USE_QTOPENGL TRUE )
set( QT_USE_QTXML TRUE ) set( QT_USE_QTXML TRUE )
set( QT_USE_QTMAIN TRUE ) set( QT_USE_QTMAIN TRUE )
find_package(CGAL REQUIRED ) find_package(CGAL REQUIRED COMPONENTS ImageIO Qt4)
if ( CGAL_FOUND ) if ( CGAL_FOUND )
include( ${CGAL_USE_FILE} ) include( ${CGAL_USE_FILE} )
@ -38,7 +38,7 @@ if ( CGAL_FOUND )
find_package(QGLViewer REQUIRED ) find_package(QGLViewer REQUIRED )
find_package(OpenGL REQUIRED ) find_package(OpenGL REQUIRED )
find_package(ZLIB REQUIRED ) find_package(ZLIB REQUIRED )
# find_package(VTK QUIET) find_package(VTK QUIET)
find_path(bimap_DIR boost/bimap/bimap.hpp ${Boost_INCLUDE_DIRS} DOC "The directory containing the bimap subdirectory.") find_path(bimap_DIR boost/bimap/bimap.hpp ${Boost_INCLUDE_DIRS} DOC "The directory containing the bimap subdirectory.")
@ -50,7 +50,7 @@ if ( CGAL_FOUND )
endif() endif()
endif(EXISTS ${bimap_DIR}/boost/bimap/bimap.hpp) endif(EXISTS ${bimap_DIR}/boost/bimap/bimap.hpp)
if( VTK_FOUND ) if( VTK_FOUND AND EXISTS ${VTK_USE_FILE})
# if( ${VTK_MAJOR_VERSION} STRGREATER "5") # if( ${VTK_MAJOR_VERSION} STRGREATER "5")
message(STATUS "VTK-${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION}.${VTK_BUILD_VERSION} found in ${VTK_DIR}.") message(STATUS "VTK-${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION}.${VTK_BUILD_VERSION} found in ${VTK_DIR}.")
set(VTK_BUILD_SETTINGS_FILE "") set(VTK_BUILD_SETTINGS_FILE "")
@ -58,9 +58,9 @@ if ( CGAL_FOUND )
add_definitions(-DCGAL_USE_VTK) add_definitions(-DCGAL_USE_VTK)
# endif( ${VTK_MAJOR_VERSION} GREATER 5) # endif( ${VTK_MAJOR_VERSION} GREATER 5)
SET(PRJ_VTK_LIBS vtkImaging vtkIO) SET(PRJ_VTK_LIBS vtkImaging vtkIO)
else( VTK_FOUND) else( VTK_FOUND AND EXISTS ${VTK_USE_FILE})
message(STATUS "VTK not found.") message(STATUS "VTK not found.")
endif( VTK_FOUND ) endif( VTK_FOUND AND EXISTS ${VTK_USE_FILE})
add_definitions(-DCGAL_USE_ZLIB) add_definitions(-DCGAL_USE_ZLIB)
@ -80,7 +80,7 @@ if ( CGAL_FOUND )
include_directories( ${QGLVIEWER_INCLUDE_DIR} ) include_directories( ${QGLVIEWER_INCLUDE_DIR} )
set( sources colorlisteditor.cpp isovalues_list.cpp mainwindow.cpp surface_mesher.cpp viewer.cpp volume.cpp ${PACKAGE_ROOT}/../Marching_cube/src/mc/ply.c) set( sources colorlisteditor.cpp values_list.cpp mainwindow.cpp Surface_mesher.cpp viewer.cpp volume.cpp polyhedral_surface.cpp ${PACKAGE_ROOT}/../Marching_cube/src/mc/ply.c)
qt4_automoc( ${sources} ) qt4_automoc( ${sources} )
@ -88,18 +88,16 @@ if ( CGAL_FOUND )
set( sources ${sources} moc_surface.cpp) set( sources ${sources} moc_surface.cpp)
qt4_wrap_ui( uis ui/isovalues_list.ui ui/mainwindow.ui ui/meshing_bar.ui ui/optionsdialog.ui ) qt4_wrap_ui( uis ui/values_list.ui ui/mainwindow.ui ui/meshing_bar.ui ui/optionsdialog.ui ui/raw_image.ui )
qt4_add_resources( qrc_sources isovalues_list.qrc surface_mesher.qrc ) qt4_add_resources( qrc_sources values_list.qrc surface_mesher.qrc )
add_executable ( ${prj} ${sources} ${uis} ${qrc_sources} ) add_executable ( ${prj} ${sources} ${uis} ${qrc_sources} )
# Link the executable to CGAL and third-party libraries # Link the executable to CGAL and third-party libraries
if ( NOT AUTO_LINK_ENABLED ) target_link_libraries( ${prj} ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES})
target_link_libraries( ${prj} CGAL CGAL-ImageIO ${CGAL_3RD_PARTY_LIBRARIES})
endif()
target_link_libraries( ${prj} CGAL-Qt4 ${QT_LIBRARIES} ${QGLVIEWER_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ) # ${PRJ_VTK_LIBS} target_link_libraries( ${prj} ${QT_LIBRARIES} ${QGLVIEWER_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PRJ_VTK_LIBS} )
endif() endif()
endif(CGAL_FOUND) endif(CGAL_FOUND)

View File

@ -0,0 +1,9 @@
#include "ui_raw_image.h"
struct Raw_image_dialog : public QDialog, public Ui::Raw_image_dialog {
Raw_image_dialog(QWidget* parent = 0) : QDialog(parent)
{
setupUi(this);
}
};

View File

@ -31,6 +31,8 @@
template <typename FT_, typename Point> template <typename FT_, typename Point>
class CBinary_image_3 : public CGAL::Image_3 class CBinary_image_3 : public CGAL::Image_3
{ {
bool interpolate_;
public: public:
float min_value; float min_value;
float max_value; float max_value;
@ -38,11 +40,12 @@ public:
typedef FT_ FT; typedef FT_ FT;
public: public:
CBinary_image_3() : Image_3() CBinary_image_3() : Image_3(), interpolate_(true)
{ {
} }
CBinary_image_3(const CBinary_image_3& bi) : Image_3(bi) CBinary_image_3(const CBinary_image_3& bi)
: Image_3(bi), interpolate_(bi.interpolate_)
{ {
std::cerr << "CBinary_image_3::copy_constructor\n"; std::cerr << "CBinary_image_3::copy_constructor\n";
min_value = bi.min_value; min_value = bi.min_value;
@ -151,16 +154,55 @@ public:
float rand_y() { return (float)rand() / (float)RAND_MAX * ymax(); } float rand_y() { return (float)rand() / (float)RAND_MAX * ymax(); }
float rand_z() { return (float)rand() / (float)RAND_MAX * zmax(); } float rand_z() { return (float)rand() / (float)RAND_MAX * zmax(); }
void set_interpolation(const bool b)
{
interpolate_ = b;
}
bool interpolation() const {
return interpolate_;
}
FT operator()(Point p) const FT operator()(Point p) const
{ {
const float x = static_cast<float>(CGAL::to_double(p.x())); const float x = static_cast<float>(CGAL::to_double(p.x()));
const float y = static_cast<float>(CGAL::to_double(p.y())); const float y = static_cast<float>(CGAL::to_double(p.y()));
const float z = static_cast<float>(CGAL::to_double(p.z())); const float z = static_cast<float>(CGAL::to_double(p.z()));
if(inside(x,y,z)) if(interpolation()) {
return FT(::trilinear_interpolation(image_ptr.get(),x,y,z)); std::cerr << "interpolation\n";
else if(inside(x,y,z))
return 0; return FT(::trilinear_interpolation(image_ptr.get(),x,y,z));
else
return 0;
}
else {
const int i = static_cast<int>(x/image()->vx + 0.5f);
const int j = static_cast<int>(y/image()->vy + 0.5f);
const int k = static_cast<int>(z/image()->vz + 0.5f);
if( i < 0 ||
j < 0 ||
k < 0 )
{
return 0;
}
else
{
const unsigned int ui = static_cast<unsigned int>(i);
const unsigned int uj = static_cast<unsigned int>(j);
const unsigned int uk = static_cast<unsigned int>(k);
if( ui >= image()->xdim ||
uj >= image()->ydim ||
uk >= image()->zdim )
{
return 0;
}
else
{
return this->value(ui, uj, uk);
}
}
}
} }
}; // end CBinary_image_3 }; // end CBinary_image_3

View File

@ -24,6 +24,7 @@
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include "volume.h" #include "volume.h"
#include "polyhedral_surface.h"
MainWindow::MainWindow(MainWindow* other_window /* = 0 */) : MainWindow::MainWindow(MainWindow* other_window /* = 0 */) :
CGAL::Qt::DemosMainWindow(), CGAL::Qt::DemosMainWindow(),
@ -42,6 +43,7 @@ MainWindow::MainWindow(MainWindow* other_window /* = 0 */) :
QToolBar* tb_meshing = qFindChild<QToolBar*>(this, "toolBar_meshing"); QToolBar* tb_meshing = qFindChild<QToolBar*>(this, "toolBar_meshing");
// tb_meshing->setVisible(false); // tb_meshing->setVisible(false);
QAction* action_mc = qFindChild<QAction*>(this, "actionMarching_cubes"); QAction* action_mc = qFindChild<QAction*>(this, "actionMarching_cubes");
if(tb_meshing && action_mc) { if(tb_meshing && action_mc) {
@ -51,10 +53,11 @@ MainWindow::MainWindow(MainWindow* other_window /* = 0 */) :
tb_meshing->insertWidget(action_mc, tb_meshing->insertWidget(action_mc,
meshing_bar); meshing_bar);
tb_meshing->insertSeparator(action_mc); tb_meshing->insertSeparator(action_mc);
meshing_bar->setProperty("show_only_in", QStringList() << "volume");
} }
show_only(""); show_only("");
surface = new Volume(this); // surface = new Volume(this);
addAboutCGAL(); addAboutCGAL();
this->addRecentFiles(this->menu_File, this->addRecentFiles(this->menu_File,
@ -78,8 +81,17 @@ void MainWindow::dropEvent(QDropEvent *event)
void MainWindow::surface_open(const QString& filename) void MainWindow::surface_open(const QString& filename)
{ {
surface->open(filename); surface = new Polyhedral_surface(this);
this->addToRecentFiles(filename); if(surface->open(filename)) {
this->addToRecentFiles(filename);
}
else {
delete surface;
surface = new Volume(this);
if(surface->open(filename)) {
this->addToRecentFiles(filename);
}
}
} }
void MainWindow::show_only(QString tag) void MainWindow::show_only(QString tag)
@ -98,9 +110,12 @@ void MainWindow::show_only(QString tag)
err << s << " "; err << s << " ";
const bool visible = show_only_in.contains(tag); const bool visible = show_only_in.contains(tag);
err << (visible ? "(enabled)\n" : "(disabled)\n"); err << (visible ? "(enabled)\n" : "(disabled)\n");
object->setProperty("visible", QVariant::fromValue<bool>(visible)); if(QMenu* menu = qobject_cast<QMenu*>(object)) {
if(QMenu* menu = qobject_cast<QMenu*>(object))
menu->menuAction()->setVisible(visible); menu->menuAction()->setVisible(visible);
}
else {
object->setProperty("visible", QVariant::fromValue<bool>(visible));
}
} }
} }
} }

View File

@ -2,6 +2,7 @@
#include "get_polyhedral_surface.h" #include "get_polyhedral_surface.h"
#include <QMainWindow> #include <QMainWindow>
#include <QString>
#include <QStatusBar> #include <QStatusBar>
#include <QApplication> #include <QApplication>
#include <QAction> #include <QAction>
@ -123,8 +124,11 @@ void Polyhedral_surface::connect_actions()
this, it->second.second); this, it->second.second);
} }
MainWindow* mw = qobject_cast<MainWindow *>(parent); MainWindow* mw = qobject_cast<MainWindow *>(parent);
if(mw) if(mw) {
mw->fix_menus_visibility(); // mw->fix_menus_visibility();
mw->show_only("polyhedral");
}
connect(this, SIGNAL(changed()), this, SLOT(display_nb_elements_in_status_bar())); connect(this, SIGNAL(changed()), this, SLOT(display_nb_elements_in_status_bar()));
} }
@ -241,7 +245,7 @@ void Polyhedral_surface::make_one_subdivision_step()
if(surface_ptr) if(surface_ptr)
{ {
Polyhedron output; Polyhedron output;
CSubdivider_loop<Polyhedron , Kernel> pw_loop_subdiviser; CSubdivider_loop<Polyhedron , Poly_kernel> pw_loop_subdiviser;
pw_loop_subdiviser.subdivide(*surface_ptr, output); pw_loop_subdiviser.subdivide(*surface_ptr, output);
static_cast<Polyhedron&>(*surface_ptr) = output; static_cast<Polyhedron&>(*surface_ptr) = output;
@ -252,14 +256,15 @@ void Polyhedral_surface::make_one_subdivision_step()
} }
} }
void Polyhedral_surface::open(const QString& filename) bool Polyhedral_surface::open(const QString& filename)
{ {
clear(); clear();
std::cerr << "Opening file \"" << filename.toLocal8Bit() << "\"..."; std::cerr << "Opening file \"" << qPrintable(filename) << "\"...";
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
std::ifstream in(filename.toUtf8()); std::ifstream in(filename.toUtf8());
if(!in) return; if(!in) return false;
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
if(surface_ptr) if(surface_ptr)
delete surface_ptr; delete surface_ptr;
@ -268,6 +273,10 @@ void Polyhedral_surface::open(const QString& filename)
sharp_edges_angle_upper_bound, sharp_edges_angle_upper_bound,
false /*do not construct false /*do not construct
octree*/); octree*/);
if(!in) {
QApplication::restoreOverrideCursor();
return false;
}
is_octree_initialized = false; is_octree_initialized = false;
selected_facet = selected_edge = -1; selected_facet = selected_edge = -1;
update_data_structures(); update_data_structures();
@ -299,6 +308,7 @@ void Polyhedral_surface::open(const QString& filename)
QAction* actionInverse_normals = qFindChild<QAction*>(this, "actionInverse_normals"); QAction* actionInverse_normals = qFindChild<QAction*>(this, "actionInverse_normals");
if(actionInverse_normals) actionInverse_normals->setChecked(false); if(actionInverse_normals) actionInverse_normals->setChecked(false);
emit set_dirty(); emit set_dirty();
return true;
} }
void Polyhedral_surface::close() void Polyhedral_surface::close()

View File

@ -25,15 +25,14 @@ typedef std::map<const char*, Signal_slot_pair> Connection_map;
// piece-wise loop subdivision // piece-wise loop subdivision
#include <CGAL/pws_loop_subdivision.h> #include <CGAL/pws_loop_subdivision.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Poly_kernel;
typedef Poly_kernel::FT FT;
typedef Poly_kernel::Point_3 Poly_point;
typedef Poly_kernel::Sphere_3 Sphere;
typedef Poly_kernel::Vector_3 Vector;
typedef Poly_kernel::Triangle_3 Triangle_3;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef CGAL::Polyhedral_surface_3<Poly_kernel,
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point;
typedef Kernel::Sphere_3 Sphere;
typedef Kernel::Vector_3 Vector;
typedef Kernel::Triangle_3 Triangle_3;
typedef CGAL::Polyhedral_surface_3<Kernel,
CGAL::Surface_mesher::Has_edges> CGAL_polyhedral_surface; CGAL::Surface_mesher::Has_edges> CGAL_polyhedral_surface;
@ -43,8 +42,8 @@ class Polyhedral_surface : public Surface
public: public:
Polyhedral_surface(QObject* parent, Polyhedral_surface(QObject* parent,
double sharp_edges_angle_lower_bound, double sharp_edges_angle_lower_bound = 90,
double sharp_edges_angle_upper_bound); double sharp_edges_angle_upper_bound = 120);
~Polyhedral_surface(); ~Polyhedral_surface();
public slots: public slots:
@ -67,7 +66,7 @@ public slots:
void on_action_Options_triggered(); void on_action_Options_triggered();
public: public:
void open(const QString& filename); bool open(const QString& filename);
void close(); void close();
void draw(); void draw();
void drawWithNames(); void drawWithNames();

View File

@ -19,7 +19,7 @@ protected:
viewer->set_surface(this); viewer->set_surface(this);
} }
public slots: public slots:
virtual void open(const QString& filename) = 0; virtual bool open(const QString& filename) = 0;
virtual void close() = 0; virtual void close() = 0;
virtual void draw() = 0; virtual void draw() = 0;
virtual void get_bbox(float&, float&, float&, virtual void get_bbox(float&, float&, float&,

View File

@ -5,18 +5,19 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1090</width> <width>1100</width>
<height>570</height> <height>595</height>
</rect> </rect>
</property> </property>
<property name="windowTitle" > <property name="windowTitle" >
<string>Surface mesher demo</string> <string>Surface mesher demo</string>
</property> </property>
<property name="windowIcon" > <property name="windowIcon" >
<iconset resource="../surface_mesher.qrc" >:/icons/cgal_logo.xpm</iconset> <iconset resource="../surface_mesher.qrc" >
<normaloff>:/icons/cgal_logo.xpm</normaloff>:/icons/cgal_logo.xpm</iconset>
</property> </property>
<widget class="QWidget" name="centralwidget" > <widget class="QWidget" name="centralwidget" >
<layout class="QGridLayout" > <layout class="QGridLayout" name="gridLayout" >
<item row="0" column="0" > <item row="0" column="0" >
<widget class="QSplitter" name="splitter" > <widget class="QSplitter" name="splitter" >
<property name="orientation" > <property name="orientation" >
@ -30,12 +31,107 @@
</sizepolicy> </sizepolicy>
</property> </property>
</widget> </widget>
<widget class="Isovalues_list" native="1" name="isovalues" > <widget class="QWidget" name="layoutWidget" >
<property name="show_only_in" stdset="0" > <layout class="QVBoxLayout" name="optionsLayout" >
<stringlist> <item>
<string>volume</string> <widget class="QGroupBox" name="groupBoxImageType" >
</stringlist> <property name="sizePolicy" >
</property> <sizepolicy vsizetype="Expanding" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title" >
<string>Image type</string>
</property>
<property name="show_only_in" stdset="0" >
<stringlist>
<string>volume</string>
</stringlist>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="QRadioButton" name="grayLevelRadioButton" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Minimum" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>Grayscale image</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="labellizedRadioButton" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Minimum" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>Segmented image</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxCriteria" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Minimum" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title" >
<string>Criteria</string>
</property>
<property name="show_only_in" stdset="0" >
<stringlist>
<string>volume</string>
</stringlist>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" >
<item>
<widget class="QCheckBox" name="manifoldCheckBox" >
<property name="text" >
<string>Manifold</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="sameIndexCheckBox" >
<property name="text" >
<string>Facets vertices have same index</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Values_list" native="1" name="values" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="show_only_in" stdset="0" >
<stringlist>
<string>volume</string>
</stringlist>
</property>
</widget>
</item>
</layout>
</widget> </widget>
</widget> </widget>
</item> </item>
@ -46,7 +142,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1090</width> <width>1100</width>
<height>29</height> <height>29</height>
</rect> </rect>
</property> </property>
@ -66,7 +162,7 @@
<property name="show_only_in" stdset="0" > <property name="show_only_in" stdset="0" >
<stringlist> <stringlist>
<string>volume</string> <string>volume</string>
<string>polyhedra</string> <string>polyhedral</string>
</stringlist> </stringlist>
</property> </property>
<addaction name="actionInverse_normals" /> <addaction name="actionInverse_normals" />
@ -113,7 +209,6 @@
</attribute> </attribute>
<addaction name="action_Open" /> <addaction name="action_Open" />
<addaction name="actionExport_surface_mesh_to_OFF" /> <addaction name="actionExport_surface_mesh_to_OFF" />
<addaction name="action_Clone" />
<addaction name="separator" /> <addaction name="separator" />
<addaction name="actionAuto_resize" /> <addaction name="actionAuto_resize" />
<addaction name="actionDisplay_front_and_back" /> <addaction name="actionDisplay_front_and_back" />
@ -141,7 +236,8 @@
</widget> </widget>
<action name="action_Open" > <action name="action_Open" >
<property name="icon" > <property name="icon" >
<iconset resource="../surface_mesher.qrc" >:/icons/fileopen.png</iconset> <iconset resource="../surface_mesher.qrc" >
<normaloff>:/icons/fileopen.png</normaloff>:/icons/fileopen.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>&amp;Open...</string> <string>&amp;Open...</string>
@ -166,7 +262,8 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="icon" > <property name="icon" >
<iconset resource="../surface_mesher.qrc" >:/icons/flip.png</iconset> <iconset resource="../surface_mesher.qrc" >
<normaloff>:/icons/flip.png</normaloff>:/icons/flip.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>&amp;Inverse normals</string> <string>&amp;Inverse normals</string>
@ -189,7 +286,8 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="icon" > <property name="icon" >
<iconset resource="../surface_mesher.qrc" >:/icons/bbox.png</iconset> <iconset resource="../surface_mesher.qrc" >
<normaloff>:/icons/bbox.png</normaloff>:/icons/bbox.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>Display oc&amp;tree</string> <string>Display oc&amp;tree</string>
@ -211,7 +309,8 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="icon" > <property name="icon" >
<iconset resource="../surface_mesher.qrc" >:/icons/surface.png</iconset> <iconset resource="../surface_mesher.qrc" >
<normaloff>:/icons/surface.png</normaloff>:/icons/surface.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>Display &amp;surface</string> <string>Display &amp;surface</string>
@ -288,7 +387,8 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="icon" > <property name="icon" >
<iconset resource="../surface_mesher.qrc" >:/icons/bbox-red.png</iconset> <iconset resource="../surface_mesher.qrc" >
<normaloff>:/icons/bbox-red.png</normaloff>:/icons/bbox-red.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>Display edges octree</string> <string>Display edges octree</string>
@ -333,7 +433,8 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="icon" > <property name="icon" >
<iconset resource="../surface_mesher.qrc" >:/icons/twosides.png</iconset> <iconset resource="../surface_mesher.qrc" >
<normaloff>:/icons/twosides.png</normaloff>:/icons/twosides.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>Display facets with &amp;front and back</string> <string>Display facets with &amp;front and back</string>
@ -347,7 +448,7 @@
<property name="show_only_in" stdset="0" > <property name="show_only_in" stdset="0" >
<stringlist> <stringlist>
<string>volume</string> <string>volume</string>
<string>surface</string> <string>polyhedral</string>
</stringlist> </stringlist>
</property> </property>
</action> </action>
@ -364,7 +465,8 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="icon" > <property name="icon" >
<iconset resource="../surface_mesher.qrc" >:/icons/resize.png</iconset> <iconset resource="../surface_mesher.qrc" >
<normaloff>:/icons/resize.png</normaloff>:/icons/resize.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>Auto-&amp;resize</string> <string>Auto-&amp;resize</string>
@ -460,7 +562,8 @@
</action> </action>
<action name="actionExport_surface_mesh_to_OFF" > <action name="actionExport_surface_mesh_to_OFF" >
<property name="icon" > <property name="icon" >
<iconset resource="../surface_mesher.qrc" >:/icons/filesave.png</iconset> <iconset resource="../surface_mesher.qrc" >
<normaloff>:/icons/filesave.png</normaloff>:/icons/filesave.png</iconset>
</property> </property>
<property name="text" > <property name="text" >
<string>Export surface mesh to OFF...</string> <string>Export surface mesh to OFF...</string>
@ -479,9 +582,9 @@
<header>viewer.h</header> <header>viewer.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>Isovalues_list</class> <class>Values_list</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>isovalues_list.h</header> <header>values_list.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
</customwidgets> </customwidgets>

View File

@ -0,0 +1,282 @@
<ui version="4.0" >
<class>Raw_image_dialog</class>
<widget class="QDialog" name="Raw_image_dialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>479</width>
<height>316</height>
</rect>
</property>
<property name="windowTitle" >
<string>Open raw image</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="QGroupBox" name="groupBox_2" >
<property name="title" >
<string>Image &amp;value type</string>
</property>
<layout class="QGridLayout" name="gridLayout" >
<item row="2" column="0" >
<widget class="QRadioButton" name="short_bt" >
<property name="text" >
<string>Short (16 bits)</string>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QRadioButton" name="float_bt" >
<property name="text" >
<string>Float</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QRadioButton" name="int_bt" >
<property name="text" >
<string>Int (32 bits)</string>
</property>
</widget>
</item>
<item row="3" column="1" >
<widget class="QRadioButton" name="radioButton_6" >
<property name="text" >
<string>Double</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QCheckBox" name="signed_bt" >
<property name="text" >
<string>Signed</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>Image dimensions</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" >
<item>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label_dim" >
<property name="text" >
<string>&amp;Dimensions:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>dim_x</cstring>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label_spacing" >
<property name="text" >
<string>&amp;Spacing:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>spacing_x</cstring>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QSpinBox" name="dim_x" >
<property name="prefix" >
<string>x: </string>
</property>
<property name="maximum" >
<number>100000000</number>
</property>
</widget>
</item>
<item row="0" column="2" >
<widget class="QSpinBox" name="dim_y" >
<property name="prefix" >
<string>y: </string>
</property>
<property name="maximum" >
<number>100000000</number>
</property>
</widget>
</item>
<item row="0" column="3" >
<widget class="QSpinBox" name="dim_z" >
<property name="prefix" >
<string>z: </string>
</property>
<property name="maximum" >
<number>100000000</number>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QDoubleSpinBox" name="spacing_x" >
<property name="prefix" >
<string>vx: </string>
</property>
<property name="decimals" >
<number>3</number>
</property>
<property name="value" >
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="2" >
<widget class="QDoubleSpinBox" name="spacing_y" >
<property name="prefix" >
<string>vy: </string>
</property>
<property name="decimals" >
<number>3</number>
</property>
<property name="value" >
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="3" >
<widget class="QDoubleSpinBox" name="spacing_z" >
<property name="prefix" >
<string>vz: </string>
</property>
<property name="decimals" >
<number>3</number>
</property>
<property name="value" >
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="offset_label" >
<property name="text" >
<string>&amp;Offset:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>offset</cstring>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QSpinBox" name="offset" >
<property name="suffix" >
<string> bytes</string>
</property>
<property name="maximum" >
<number>999999999</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Open</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>int_bt</tabstop>
<tabstop>short_bt</tabstop>
<tabstop>signed_bt</tabstop>
<tabstop>float_bt</tabstop>
<tabstop>radioButton_6</tabstop>
<tabstop>dim_x</tabstop>
<tabstop>dim_y</tabstop>
<tabstop>dim_z</tabstop>
<tabstop>spacing_x</tabstop>
<tabstop>spacing_y</tabstop>
<tabstop>spacing_z</tabstop>
<tabstop>offset</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>float_bt</sender>
<signal>toggled(bool)</signal>
<receiver>signed_bt</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>47</x>
<y>112</y>
</hint>
<hint type="destinationlabel" >
<x>257</x>
<y>83</y>
</hint>
</hints>
</connection>
<connection>
<sender>radioButton_6</sender>
<signal>toggled(bool)</signal>
<receiver>signed_bt</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>281</x>
<y>113</y>
</hint>
<hint type="destinationlabel" >
<x>290</x>
<y>82</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Raw_image_dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>191</x>
<y>290</y>
</hint>
<hint type="destinationlabel" >
<x>183</x>
<y>313</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Raw_image_dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>253</x>
<y>293</y>
</hint>
<hint type="destinationlabel" >
<x>252</x>
<y>312</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,6 +1,6 @@
<ui version="4.0" > <ui version="4.0" >
<class>Isovalues_list</class> <class>Values_list</class>
<widget class="QWidget" name="Isovalues_list" > <widget class="QWidget" name="Values_list" >
<property name="geometry" > <property name="geometry" >
<rect> <rect>
<x>0</x> <x>0</x>
@ -76,7 +76,7 @@
<string>...</string> <string>...</string>
</property> </property>
<property name="icon" > <property name="icon" >
<iconset resource="../isovalues_list.qrc" >:/isovalues/plus.png</iconset> <iconset resource="../values_list.qrc" >:/values/plus.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
@ -86,7 +86,7 @@
<string>...</string> <string>...</string>
</property> </property>
<property name="icon" > <property name="icon" >
<iconset resource="../isovalues_list.qrc" >:/isovalues/minus.png</iconset> <iconset resource="../values_list.qrc" >:/values/minus.png</iconset>
</property> </property>
<property name="shortcut" > <property name="shortcut" >
<string>Del</string> <string>Del</string>
@ -112,7 +112,7 @@
</widget> </widget>
<resources> <resources>
<include location="../surface_mesher.qrc" /> <include location="../surface_mesher.qrc" />
<include location="../isovalues_list.qrc" /> <include location="../values_list.qrc" />
</resources> </resources>
<connections/> <connections/>
</ui> </ui>

View File

@ -1,6 +1,7 @@
#include "isovalues_list.h" #include "values_list.h"
#include "ui_isovalues_list.h" #include "ui_values_list.h"
#include "colorlisteditor.h" #include "colorlisteditor.h"
#include <iostream>
#include <QTreeWidget> #include <QTreeWidget>
#include <QTreeWidgetItem> #include <QTreeWidgetItem>
@ -20,12 +21,12 @@
#include <QLineEdit> #include <QLineEdit>
#include <QDoubleValidator> #include <QDoubleValidator>
Isovalues_delegate::Isovalues_delegate(QWidget* parent) : QItemDelegate(parent) {} Values_delegate::Values_delegate(QWidget* parent) : QItemDelegate(parent) {}
void Isovalues_delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const void Values_delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{ {
switch(index.column()) switch(index.column())
{ {
case Isovalues_list::Color: { case Values_list::Color: {
painter->fillRect(option.rect, index.data().value<QColor>()); painter->fillRect(option.rect, index.data().value<QColor>());
drawFocus(painter, option, option.rect); drawFocus(painter, option, option.rect);
break; break;
@ -35,15 +36,15 @@ void Isovalues_delegate::paint(QPainter * painter, const QStyleOptionViewItem &
} }
} }
QWidget *Isovalues_delegate::createEditor(QWidget *parent, QWidget *Values_delegate::createEditor(QWidget *parent,
const QStyleOptionViewItem & option, const QStyleOptionViewItem & option,
const QModelIndex & index) const const QModelIndex & index) const
{ {
if(index.column() == Isovalues_list::Color) if(index.column() == Values_list::Color)
{ {
return new ColorListEditor(parent); return new ColorListEditor(parent);
} }
else if(index.column() == Isovalues_list::Isovalue) else if(index.column() == Values_list::Value)
{ {
QLineEdit* lineedit = new QLineEdit(parent); QLineEdit* lineedit = new QLineEdit(parent);
lineedit->setAutoFillBackground(true); lineedit->setAutoFillBackground(true);
@ -53,16 +54,16 @@ QWidget *Isovalues_delegate::createEditor(QWidget *parent,
else return QItemDelegate::createEditor(parent, option, index); else return QItemDelegate::createEditor(parent, option, index);
} }
void Isovalues_delegate::setEditorData(QWidget *editor, void Values_delegate::setEditorData(QWidget *editor,
const QModelIndex &index) const const QModelIndex &index) const
{ {
if(index.column() == Isovalues_list::Color) if(index.column() == Values_list::Color)
{ {
ColorListEditor* coloreditor = qobject_cast<ColorListEditor*>(editor); ColorListEditor* coloreditor = qobject_cast<ColorListEditor*>(editor);
if(coloreditor) if(coloreditor)
coloreditor->setColor(index.data().value<QColor>()); coloreditor->setColor(index.data().value<QColor>());
} }
else if(index.column() == Isovalues_list::Isovalue) else if(index.column() == Values_list::Value)
{ {
QLineEdit* lineedit = qobject_cast<QLineEdit*>(editor); QLineEdit* lineedit = qobject_cast<QLineEdit*>(editor);
if(lineedit) if(lineedit)
@ -70,10 +71,10 @@ void Isovalues_delegate::setEditorData(QWidget *editor,
} }
else QItemDelegate::setEditorData(editor, index); else QItemDelegate::setEditorData(editor, index);
} }
void Isovalues_delegate::setModelData(QWidget *editor, QAbstractItemModel *model, void Values_delegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const const QModelIndex &index) const
{ {
if(index.column() == Isovalues_list::Color) if(index.column() == Values_list::Color)
{ {
ColorListEditor* coloreditor = qobject_cast<ColorListEditor*>(editor); ColorListEditor* coloreditor = qobject_cast<ColorListEditor*>(editor);
if(coloreditor) if(coloreditor)
@ -82,44 +83,47 @@ void Isovalues_delegate::setModelData(QWidget *editor, QAbstractItemModel *model
emit new_color(index); emit new_color(index);
} }
} }
else if(index.column() == Isovalues_list::Isovalue) else if(index.column() == Values_list::Value)
{ {
QLineEdit* lineedit = qobject_cast<QLineEdit*>(editor); QLineEdit* lineedit = qobject_cast<QLineEdit*>(editor);
if(lineedit) if(lineedit)
{ {
model->setData(index, lineedit->text().toDouble()); model->setData(index, lineedit->text().toDouble());
emit new_isovalue(index); emit new_value(index);
} }
} }
else QItemDelegate::setModelData(editor, model, index); else QItemDelegate::setModelData(editor, model, index);
} }
const double Isovalues_list::default_isovalue = 0.0; const double Values_list::default_value = 0.0;
Isovalues_list::Isovalues_list(QWidget* parent): Values_list::Values_list(QWidget* parent):
QWidget(parent) QWidget(parent)
{ {
Ui::Isovalues_list().setupUi(this); Ui::Values_list().setupUi(this);
treeWidget = parent->findChild<QTreeWidget*>("treeWidget"); treeWidget = parent->findChild<QTreeWidget*>("treeWidget");
Q_ASSERT_X(treeWidget, "Isovalues_list constructor", "cannot find widget \"treeWidget\""); Q_ASSERT_X(treeWidget, "Values_list constructor", "cannot find widget \"treeWidget\"");
treeWidget->sortByColumn(Isovalue, Qt::AscendingOrder); treeWidget->sortByColumn(Value, Qt::AscendingOrder);
treeWidget->header()->setClickable(false); treeWidget->header()->setClickable(false);
Isovalues_delegate* isovalues_delegate = new Isovalues_delegate(parent); Values_delegate* values_delegate = new Values_delegate(parent);
treeWidget->setItemDelegate(isovalues_delegate); treeWidget->setItemDelegate(values_delegate);
connect(isovalues_delegate, SIGNAL(new_isovalue(const QModelIndex&)), connect(values_delegate, SIGNAL(new_value(const QModelIndex&)),
this, SIGNAL(isovalues_changed())); this, SIGNAL(values_changed()));
connect(isovalues_delegate, SIGNAL(new_color(const QModelIndex&)), connect(values_delegate, SIGNAL(new_color(const QModelIndex&)),
this, SIGNAL(colors_changed())); this, SIGNAL(colors_changed()));
connect(this->treeWidget->model(), connect(this->treeWidget->model(),
SIGNAL(dataChanged (const QModelIndex &, const QModelIndex &)), SIGNAL(dataChanged (const QModelIndex &, const QModelIndex &)),
this, SIGNAL(changed())); this, SIGNAL(changed()));
connect(this, SIGNAL(changed()),
this, SLOT(update_items_cache()));
} }
QColor Isovalues_list::color(const int i) const QColor Values_list::color(const int i) const
{ {
if(i < 0 || i > treeWidget->topLevelItemCount()) if(i < 0 || i > treeWidget->topLevelItemCount())
return QColor(); return QColor();
@ -127,25 +131,25 @@ QColor Isovalues_list::color(const int i) const
return treeWidget->topLevelItem(i)->data(Color, Qt::DisplayRole).value<QColor>(); return treeWidget->topLevelItem(i)->data(Color, Qt::DisplayRole).value<QColor>();
} }
QColor Isovalues_list::color(const QTreeWidgetItem* item) const QColor Values_list::color(const QTreeWidgetItem* item) const
{ {
return item->data(Color, Qt::DisplayRole).value<QColor>(); return item->data(Color, Qt::DisplayRole).value<QColor>();
} }
int Isovalues_list::numberOfIsoValues() const int Values_list::numberOfValues() const
{ {
return treeWidget->topLevelItemCount(); return treeWidget->topLevelItemCount();
} }
double Isovalues_list::isovalue(const int i) const double Values_list::value(const int i) const
{ {
if(i < 0 || i > numberOfIsoValues()) if(i < 0 || i > numberOfValues())
return 0.; return 0.;
else else
return treeWidget->topLevelItem(i)->data(Isovalue, Qt::DisplayRole).toDouble(); return treeWidget->topLevelItem(i)->data(Value, Qt::DisplayRole).toDouble();
} }
QString Isovalues_list::name(const int i) const QString Values_list::name(const int i) const
{ {
if(i < 0 || i > treeWidget->topLevelItemCount()) if(i < 0 || i > treeWidget->topLevelItemCount())
return QString(); return QString();
@ -153,20 +157,20 @@ QString Isovalues_list::name(const int i) const
return treeWidget->topLevelItem(i)->data(Name, Qt::DisplayRole).toString(); return treeWidget->topLevelItem(i)->data(Name, Qt::DisplayRole).toString();
} }
bool Isovalues_list::enabled(const int i) const bool Values_list::enabled(const int i) const
{ {
if(i < 0 || i > treeWidget->topLevelItemCount()) if(i < 0 || i > treeWidget->topLevelItemCount())
return 0.; return 0.;
else else
return treeWidget->topLevelItem(i)->data(Isovalue, Qt::CheckStateRole).toDouble(); return treeWidget->topLevelItem(i)->data(Value, Qt::CheckStateRole).toDouble();
} }
bool Isovalues_list::enabled(const QTreeWidgetItem* item) const bool Values_list::enabled(const QTreeWidgetItem* item) const
{ {
return item->data(Isovalue, Qt::CheckStateRole).toDouble(); return item->data(Value, Qt::CheckStateRole).toDouble();
} }
const QTreeWidgetItem* Isovalues_list::item(const int i) const const QTreeWidgetItem* Values_list::item(const int i) const
{ {
if(i < 0 || i > treeWidget->topLevelItemCount()) if(i < 0 || i > treeWidget->topLevelItemCount())
return 0; return 0;
@ -174,15 +178,15 @@ const QTreeWidgetItem* Isovalues_list::item(const int i) const
return treeWidget->topLevelItem(i); return treeWidget->topLevelItem(i);
} }
void Isovalues_list::save_values(QString filename) const void Values_list::save_values(QString filename) const
{ {
QSettings settings; QSettings settings;
settings.beginGroup(QUrl::toPercentEncoding(filename)); settings.beginGroup(QUrl::toPercentEncoding(filename));
settings.beginWriteArray("isovalues"); settings.beginWriteArray("values");
for (int i = 0; i < numberOfIsoValues(); ++i) { for (int i = 0; i < numberOfValues(); ++i) {
settings.setArrayIndex(i); settings.setArrayIndex(i);
settings.setValue("isovalue", isovalue(i)); settings.setValue("value", value(i));
settings.setValue("color", color(i)); settings.setValue("color", color(i));
settings.setValue("name", name(i)); settings.setValue("name", name(i));
settings.setValue("enabled", enabled(i)); settings.setValue("enabled", enabled(i));
@ -191,18 +195,18 @@ void Isovalues_list::save_values(QString filename) const
settings.endGroup(); settings.endGroup();
} }
void Isovalues_list::load_values(QString filename) void Values_list::load_values(QString filename)
{ {
QSettings settings; QSettings settings;
settings.beginGroup(QUrl::toPercentEncoding(filename)); settings.beginGroup(QUrl::toPercentEncoding(filename));
int nb = settings.beginReadArray("isovalues"); int nb = settings.beginReadArray("values");
for (int i = 0; i < nb; ++i) { for (int i = 0; i < nb; ++i) {
settings.setArrayIndex(i); settings.setArrayIndex(i);
QTreeWidgetItem *newItem = new QTreeWidgetItem(treeWidget); QTreeWidgetItem *newItem = new QTreeWidgetItem(treeWidget);
newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
newItem->setData(Isovalue, Qt::CheckStateRole, settings.value("enabled").toBool() ? Qt::Checked : Qt::Unchecked); newItem->setData(Value, Qt::CheckStateRole, settings.value("enabled").toBool() ? Qt::Checked : Qt::Unchecked);
newItem->setData(Isovalue, Qt::DisplayRole, settings.value("isovalue").toDouble()); newItem->setData(Value, Qt::DisplayRole, settings.value("value").toDouble());
newItem->setData(Color, Qt::DisplayRole, settings.value("color").value<QColor>()); newItem->setData(Color, Qt::DisplayRole, settings.value("color").value<QColor>());
newItem->setData(Name, Qt::DisplayRole, settings.value("name").toString()); newItem->setData(Name, Qt::DisplayRole, settings.value("name").toString());
} }
@ -210,28 +214,51 @@ void Isovalues_list::load_values(QString filename)
settings.endGroup(); settings.endGroup();
} }
void Isovalues_list::on_minusButton_clicked() void Values_list::on_minusButton_clicked()
{ {
Q_FOREACH(QTreeWidgetItem* item, treeWidget->selectedItems()) Q_FOREACH(QTreeWidgetItem* item, treeWidget->selectedItems())
{ {
treeWidget->invisibleRootItem()->removeChild(item); treeWidget->invisibleRootItem()->removeChild(item);
delete item; delete item;
} }
emit isovalues_changed(); emit values_changed();
} }
void Isovalues_list::on_plusButton_clicked() void Values_list::on_plusButton_clicked()
{
addValue();
}
void Values_list::addValue(const double i)
{ {
QTreeWidgetItem *newItem = new QTreeWidgetItem(treeWidget); QTreeWidgetItem *newItem = new QTreeWidgetItem(treeWidget);
newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
newItem->setData(Isovalue, Qt::CheckStateRole, Qt::Checked); newItem->setData(Value, Qt::CheckStateRole, Qt::Checked);
newItem->setData(Isovalue, Qt::DisplayRole, default_isovalue); newItem->setData(Value, Qt::DisplayRole, i);
QStringList colors = QColor::colorNames(); QStringList colors = QColor::colorNames();
const int color_index = qrand() % colors.size(); const int color_index = qrand() % colors.size();
QColor color = QColor(colors[color_index]); QColor color = QColor(colors[color_index]);
newItem->setData(Color, Qt::DisplayRole, color); newItem->setData(Color, Qt::DisplayRole, color);
newItem->setData(Name, Qt::DisplayRole, ""); newItem->setData(Name, Qt::DisplayRole, "");
emit isovalues_changed(); emit values_changed();
} }
#include "isovalues_list.moc" void Values_list::update_items_cache() {
items_cache.clear();
for(int i = 0, nb = numberOfValues(); i < nb; ++i) {
items_cache.insert(std::make_pair(value(i), item(i)));
}
}
const QTreeWidgetItem* Values_list::search(const double value) const
{
Items_cache::const_iterator it = items_cache.find(value);
if(it != items_cache.end()) {
return it->second;
}
else {
return 0;
}
}
#include "values_list.moc"

View File

@ -1,5 +1,5 @@
#ifndef _ISOVALUES_LIST_H #ifndef _VALUES_LIST_H
#define _ISOVALUES_LIST_H #define _VALUES_LIST_H
#include <QWidget> #include <QWidget>
#include <QString> #include <QString>
@ -10,15 +10,15 @@
class QTreeWidget; class QTreeWidget;
class QTreeWidgetItem; class QTreeWidgetItem;
class Isovalues_delegate : public QItemDelegate class Values_delegate : public QItemDelegate
{ {
Q_OBJECT Q_OBJECT
public: public:
Isovalues_delegate(QWidget* parent); Values_delegate(QWidget* parent);
signals: signals:
void new_color(const QModelIndex&) const; void new_color(const QModelIndex&) const;
void new_isovalue(const QModelIndex&) const; void new_value(const QModelIndex&) const;
protected: protected:
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
@ -31,21 +31,23 @@ protected:
const QModelIndex &index) const; const QModelIndex &index) const;
}; };
class Isovalues_list : public QWidget class Values_list : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
enum Field { Isovalue = 0 , Color = 1, Name = 2}; enum Field { Value = 0 , Color = 1, Name = 2};
Isovalues_list(QWidget* parent); Values_list(QWidget* parent);
int numberOfIsoValues() const; // const accessors
int numberOfValues() const;
QColor color(const int i) const; QColor color(const int i) const;
QColor color(const QTreeWidgetItem* i) const; QColor color(const QTreeWidgetItem* i) const;
double isovalue(const int i) const; double value(const int i) const;
QString name(const int i) const; QString name(const int i) const;
bool enabled(const int i) const; bool enabled(const int i) const;
bool enabled(const QTreeWidgetItem* i) const; bool enabled(const QTreeWidgetItem* i) const;
const QTreeWidgetItem* item(const int i) const; const QTreeWidgetItem* item(const int i) const;
const QTreeWidgetItem* search(const double value) const;
public slots: public slots:
void save_values(QString) const; void save_values(QString) const;
@ -53,15 +55,23 @@ public slots:
void on_plusButton_clicked(); void on_plusButton_clicked();
void on_minusButton_clicked(); void on_minusButton_clicked();
// setters
void addValue(const double v = Values_list::default_value);
private slots:
void update_items_cache();
signals: signals:
void changed(); void changed();
void colors_changed(); void colors_changed();
void isovalues_changed(); void values_changed();
private: private:
QTreeWidget* treeWidget; QTreeWidget* treeWidget;
typedef std::map<double, const QTreeWidgetItem*> Items_cache;
Items_cache items_cache;
static const double default_isovalue; static const double default_value;
}; };
#endif // _ISOVALUES_LIST_H #endif // _VALUES_LIST_H

View File

@ -1,5 +1,5 @@
<RCC> <RCC>
<qresource prefix="/isovalues" > <qresource prefix="/values" >
<file alias="minus.png">icons/minus.png</file> <file alias="minus.png">icons/minus.png</file>
<file alias="plus.png">icons/plus.png</file> <file alias="plus.png">icons/plus.png</file>
</qresource> </qresource>

View File

@ -9,7 +9,7 @@
#include "volume.h" #include "volume.h"
#include "viewer.h" #include "viewer.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "isovalues_list.h" #include "values_list.h"
#include "File_XT.h" // format XT from Total/ELF #include "File_XT.h" // format XT from Total/ELF
@ -23,6 +23,9 @@
#include <QTime> #include <QTime>
#include <QColor> #include <QColor>
#include <QColorDialog> #include <QColorDialog>
#include <QSettings>
#include <QUrl>
#include "Raw_image_dialog.h"
#include <GL/glu.h> #include <GL/glu.h>
@ -35,12 +38,15 @@
struct Threshold : public std::unary_function<FT, unsigned char> { struct Threshold : public std::unary_function<FT, unsigned char> {
double isovalue; double isovalue;
bool is_identity;
Threshold(double isovalue) : isovalue(isovalue) {} Threshold(double isovalue) : isovalue(isovalue), is_identity(false) {}
result_type operator()(FT value) result_type operator()(FT value)
{ {
if(value >= isovalue) if(is_identity)
return static_cast<unsigned char>(value);
else if(value >= isovalue)
return 1; return 1;
else else
return 0; return 0;
@ -53,6 +59,7 @@ class Classify_from_isovalue_list :
typedef std::pair<FT, result_type> Isovalue; typedef std::pair<FT, result_type> Isovalue;
typedef std::vector<Isovalue> Isovalues; typedef std::vector<Isovalue> Isovalues;
boost::shared_ptr<Isovalues> isovalues; boost::shared_ptr<Isovalues> isovalues;
bool is_identity;
struct Sort_isovalues : std::binary_function<Isovalue, Isovalue, bool> struct Sort_isovalues : std::binary_function<Isovalue, Isovalue, bool>
{ {
@ -62,16 +69,24 @@ class Classify_from_isovalue_list :
} }
}; };
public: public:
Classify_from_isovalue_list(Isovalues_list * list) Classify_from_isovalue_list(Values_list * list)
: is_identity(false)
{ {
isovalues = boost::shared_ptr<Isovalues>(new Isovalues(list->numberOfIsoValues())); isovalues = boost::shared_ptr<Isovalues>(new Isovalues(list->numberOfValues()));
for(int i = 0, nbs = list->numberOfIsoValues(); i < nbs; ++i ) for(int i = 0, nbs = list->numberOfValues(); i < nbs; ++i )
(*isovalues)[i] = std::make_pair(list->isovalue(i), i); (*isovalues)[i] = std::make_pair(list->value(i), i);
std::sort(isovalues->begin(), isovalues->end(), Sort_isovalues()); std::sort(isovalues->begin(), isovalues->end(), Sort_isovalues());
} }
void set_identity(bool b) {
is_identity = b;
}
result_type operator()(FT value) result_type operator()(FT value)
{ {
if(is_identity) {
return static_cast<unsigned char>(value);
}
result_type result = 0; result_type result = 0;
// std::cerr << "isovalues: "; // std::cerr << "isovalues: ";
for(int i = 1, end = isovalues->size(); i <= end; ++i) for(int i = 1, end = isovalues->size(); i <= end; ++i)
@ -84,7 +99,7 @@ public:
} }
} }
// if(result>1) // if(result>1)
// std::cerr << "result = " << (int)result << "/" << list->numberOfIsoValues() << std::endl; // std::cerr << "result = " << (int)result << "/" << list->numberOfValues() << std::endl;
// else // else
// std::cerr << std::endl; // std::cerr << std::endl;
if(result>0) if(result>0)
@ -99,14 +114,25 @@ class Generate_surface_identifiers :
Classify_from_isovalue_list::result_type, Classify_from_isovalue_list::result_type,
const QTreeWidgetItem*> const QTreeWidgetItem*>
{ {
Isovalues_list* list; Values_list* list;
bool labellized;
public: public:
Generate_surface_identifiers(Isovalues_list* list) : list(list) {}; Generate_surface_identifiers(Values_list* list)
: list(list), labellized(false) {};
void set_labellized_image(bool b)
{
labellized = b;
}
result_type operator()(const Classify_from_isovalue_list::result_type& a, result_type operator()(const Classify_from_isovalue_list::result_type& a,
const Classify_from_isovalue_list::result_type& b) const Classify_from_isovalue_list::result_type& b)
{ {
return list->item((std::min)(a, b)); if(labellized)
return list->search((std::max)(a, b));
else
return list->item((std::min)(a, b));
} }
}; };
@ -179,7 +205,7 @@ Volume::Volume(MainWindow* mw) :
Q_ASSERT_X(spinBox_radius_bound && spinBox_distance_bound, Q_ASSERT_X(spinBox_radius_bound && spinBox_distance_bound,
"Volume::Volume()", "Cannot find spinboxes!"); "Volume::Volume()", "Cannot find spinboxes!");
isovalues_list = mw->isovalues; values_list = mw->values;
connect(spinBox_radius_bound, SIGNAL(valueChanged(double)), connect(spinBox_radius_bound, SIGNAL(valueChanged(double)),
this, SLOT(set_radius_bound(double))); this, SLOT(set_radius_bound(double)));
@ -217,9 +243,9 @@ Volume::Volume(MainWindow* mw) :
connect(this, SIGNAL(new_bounding_box(double, double, double, double, double, double)), connect(this, SIGNAL(new_bounding_box(double, double, double, double, double, double)),
mw->viewer, SLOT(interpolateToFitBoundingBox(double, double, double, double, double, double))); mw->viewer, SLOT(interpolateToFitBoundingBox(double, double, double, double, double, double)));
connect(isovalues_list, SIGNAL(isovalues_changed()), connect(values_list, SIGNAL(values_changed()),
this, SLOT(changed_parameters())); this, SLOT(changed_parameters()));
connect(isovalues_list, SIGNAL(changed()), connect(values_list, SIGNAL(changed()),
mw->viewer, SLOT(updateGL())); mw->viewer, SLOT(updateGL()));
connect(this, SIGNAL(changed()), connect(this, SIGNAL(changed()),
this, SLOT(check_can_export_off())); this, SLOT(check_can_export_off()));
@ -273,13 +299,15 @@ void Volume::set_use_gouraud(const bool b) {
#include <vtkImageReader.h> #include <vtkImageReader.h>
#include <vtkImageGaussianSmooth.h> #include <vtkImageGaussianSmooth.h>
void Volume::opendir(const QString& dirname) bool Volume::opendir(const QString& dirname)
{ {
bool result = true;
if(!fileinfo.isReadable()) if(!fileinfo.isReadable())
{ {
QMessageBox::warning(mw, mw->windowTitle(), QMessageBox::warning(mw, mw->windowTitle(),
tr("Cannot read directory <tt>%1</tt>!").arg(dirname)); tr("Cannot read directory <tt>%1</tt>!").arg(dirname));
status_message(tr("Opening of directory %1 failed!").arg(dirname)); status_message(tr("Opening of directory %1 failed!").arg(dirname));
result = false;
} }
else else
{ {
@ -298,18 +326,21 @@ void Volume::opendir(const QString& dirname)
QMessageBox::warning(mw, mw->windowTitle(), QMessageBox::warning(mw, mw->windowTitle(),
tr("Error with file <tt>%1/</tt>:\nunknown file format!").arg(dirname)); tr("Error with file <tt>%1/</tt>:\nunknown file format!").arg(dirname));
status_message(tr("Opening of file %1/ failed!").arg(dirname)); status_message(tr("Opening of file %1/ failed!").arg(dirname));
result = false;
} }
else else
{ {
status_message(tr("File %1/ successfully opened.").arg(dirname)); status_message(tr("File %1/ successfully opened.").arg(dirname));
finish_open(); finish_open();
result = true;
} }
dicom_reader->Delete(); dicom_reader->Delete();
// smoother->Delete(); // smoother->Delete();
} }
return result;
} }
void Volume::open_vtk(const QString& filename) bool Volume::open_vtk(const QString& filename)
{ {
mw->show_only("volume"); mw->show_only("volume");
@ -317,8 +348,7 @@ void Volume::open_vtk(const QString& filename)
if(fileinfo.isDir()) if(fileinfo.isDir())
{ {
opendir(filename); return opendir(filename);
return;
} }
if(!fileinfo.isReadable()) if(!fileinfo.isReadable())
@ -326,6 +356,7 @@ void Volume::open_vtk(const QString& filename)
QMessageBox::warning(mw, mw->windowTitle(), QMessageBox::warning(mw, mw->windowTitle(),
tr("Cannot read file <tt>%1</tt>!").arg(filename)); tr("Cannot read file <tt>%1</tt>!").arg(filename));
status_message(tr("Opening of file %1 failed!").arg(filename)); status_message(tr("Opening of file %1 failed!").arg(filename));
return false;
} }
else else
{ {
@ -344,11 +375,13 @@ void Volume::open_vtk(const QString& filename)
QMessageBox::warning(mw, mw->windowTitle(), QMessageBox::warning(mw, mw->windowTitle(),
tr("Error with file <tt>%1</tt>:\nunknown file format!").arg(filename)); tr("Error with file <tt>%1</tt>:\nunknown file format!").arg(filename));
status_message(tr("Opening of file %1 failed!").arg(filename)); status_message(tr("Opening of file %1 failed!").arg(filename));
return false;
} }
else else
{ {
status_message(tr("File %1 successfully opened.").arg(filename)); status_message(tr("File %1 successfully opened.").arg(filename));
finish_open(); finish_open();
return true;
} }
} }
} }
@ -421,14 +454,18 @@ bool Volume::open_xt(const QString& filename)
} }
#else // CGAL_USE_VTK #else // CGAL_USE_VTK
void Volume::opendir(const QString&) {} bool Volume::opendir(const QString&)
{
return false;
}
bool Volume::open_xt(const QString&) bool Volume::open_xt(const QString&)
{ {
return false; return false;
} }
#endif // CGAL_USE_VTK #endif // CGAL_USE_VTK
void Volume::open(const QString& filename) bool Volume::open(const QString& filename)
{ {
mw->show_only("volume"); mw->show_only("volume");
@ -436,15 +473,13 @@ void Volume::open(const QString& filename)
if(fileinfo.isDir()) if(fileinfo.isDir())
{ {
opendir(filename); return opendir(filename);
return;
} }
if(!fileinfo.isReadable()) if(!fileinfo.isReadable())
{ {
QMessageBox::warning(mw, mw->windowTitle(), QMessageBox::warning(mw, mw->windowTitle(),
tr("Cannot read file <tt>%1</tt>!").arg(filename)); tr("Cannot read file <tt>%1</tt>!").arg(filename));
status_message(tr("Opening of file %1 failed!").arg(filename));
} }
else else
{ {
@ -452,13 +487,63 @@ void Volume::open(const QString& filename)
{ {
status_message(tr("File %1 successfully opened.").arg(filename)); status_message(tr("File %1 successfully opened.").arg(filename));
finish_open(); finish_open();
return true;
} }
else if(!open_xt(filename)) { else if(!open_xt(filename)) {
QMessageBox::warning(mw, mw->windowTitle(), QSettings settings;
tr("Error with file <tt>%1</tt>:\nunknown file format!").arg(filename)); settings.beginGroup(QUrl::toPercentEncoding(fileinfo.absoluteFilePath()));
status_message(tr("Opening of file %1 failed!").arg(filename)); if( settings.value("is_raw").toBool() &&
m_image.read_raw(filename.toStdString().c_str(),
settings.value("dim_x").toInt(),
settings.value("dim_y").toInt(),
settings.value("dim_z").toInt(),
settings.value("spacing_x").toDouble(),
settings.value("spacing_y").toDouble(),
settings.value("spacing_z").toDouble(),
settings.value("offset").toInt()) )
{
status_message(tr("File %1 successfully opened.").arg(filename));
finish_open();
return true;
}
else if(QMessageBox::warning(mw, mw->windowTitle(),
tr("Error with file <tt>%1</tt>:\n"
"unknown file format!\n"
"\n"
"Open it as a raw image?").arg(filename),
QMessageBox::Yes|QMessageBox::No) == QMessageBox::Yes)
{
Raw_image_dialog raw_dialog;
if( raw_dialog.exec() &&
m_image.read_raw(filename.toStdString().c_str(),
raw_dialog.dim_x->value(),
raw_dialog.dim_y->value(),
raw_dialog.dim_z->value(),
raw_dialog.spacing_x->value(),
raw_dialog.spacing_y->value(),
raw_dialog.spacing_z->value(),
raw_dialog.offset->value()) )
{
status_message(tr("File %1 successfully opened.").arg(filename));
QSettings settings;
settings.beginGroup(QUrl::toPercentEncoding(fileinfo.absoluteFilePath()));
settings.setValue("is_raw", true);
settings.setValue("dim_x", raw_dialog.dim_x->value());
settings.setValue("dim_y", raw_dialog.dim_y->value());
settings.setValue("dim_z", raw_dialog.dim_z->value());
settings.setValue("spacing_x", raw_dialog.spacing_x->value());
settings.setValue("spacing_y", raw_dialog.spacing_y->value());
settings.setValue("spacing_z", raw_dialog.spacing_z->value());
settings.setValue("offset", raw_dialog.offset->value());
settings.endGroup();
finish_open();
return true;
}
}
} }
} }
status_message(tr("Opening of file %1 failed!").arg(filename));
return false;
} }
void Volume::finish_open() void Volume::finish_open()
@ -469,7 +554,7 @@ void Volume::finish_open()
m_image.zmax())); m_image.zmax()));
mw->viewer->showEntireScene(); mw->viewer->showEntireScene();
isovalues_list->load_values(fileinfo.absoluteFilePath()); values_list->load_values(fileinfo.absoluteFilePath());
changed_parameters(); changed_parameters();
emit changed(); emit changed();
} }
@ -531,7 +616,7 @@ void Volume::display_marchin_cube()
QTime total_time; QTime total_time;
total_time.start(); total_time.start();
isovalues_list->save_values(fileinfo.absoluteFilePath()); values_list->save_values(fileinfo.absoluteFilePath());
unsigned int nx = m_image.xdim(); unsigned int nx = m_image.xdim();
unsigned int ny = m_image.ydim(); unsigned int ny = m_image.ydim();
@ -555,13 +640,13 @@ void Volume::display_marchin_cube()
mc.init_all(); mc.init_all();
mc.set_ext_data(static_cast<unsigned char*>(m_image.image()->data)); mc.set_ext_data(static_cast<unsigned char*>(m_image.image()->data));
nbs_of_mc_triangles.resize(isovalues_list->numberOfIsoValues()); nbs_of_mc_triangles.resize(values_list->numberOfValues());
for(int isovalue_id = 0; for(int value_id = 0;
isovalue_id < isovalues_list->numberOfIsoValues(); value_id < values_list->numberOfValues();
++isovalue_id) ++value_id)
{ {
status_message(tr("Marching cubes, isovalue #%1...").arg(isovalue_id)); status_message(tr("Marching cubes, isovalue #%1...").arg(value_id));
// set data // set data
// for(unsigned int i=0;i<nx;i++) // for(unsigned int i=0;i<nx;i++)
@ -572,9 +657,9 @@ void Volume::display_marchin_cube()
// mc.set_data(value,i,j,k); // mc.set_data(value,i,j,k);
// } // }
// compute scaling ratio // compute scaling ratio
if(isovalue_id > 0) if(value_id > 0)
mc.init_temps(); mc.init_temps();
mc.run(isovalues_list->isovalue(isovalue_id), mc.run(values_list->value(value_id),
m_image.vx(), m_image.vx(),
m_image.vy(), m_image.vy(),
m_image.vz()); m_image.vz());
@ -584,7 +669,7 @@ void Volume::display_marchin_cube()
mc.get_facets(facets); mc.get_facets(facets);
mc_timer.stop(); mc_timer.stop();
const unsigned int begin = isovalue_id == 0 ? 0 : nbs_of_mc_triangles[isovalue_id-1]; const unsigned int begin = value_id == 0 ? 0 : nbs_of_mc_triangles[value_id-1];
const unsigned int nbt = facets.size() / 9; const unsigned int nbt = facets.size() / 9;
for(unsigned int i=begin;i<nbt;i++) for(unsigned int i=begin;i<nbt;i++)
{ {
@ -596,9 +681,9 @@ void Volume::display_marchin_cube()
const Vector v = t[2] - t[0]; const Vector v = t[2] - t[0];
Vector n = CGAL::cross_product(u,v); Vector n = CGAL::cross_product(u,v);
n = n / std::sqrt(n*n); n = n / std::sqrt(n*n);
m_surface_mc.push_back(Facet(t,n,isovalues_list->item(isovalue_id))); m_surface_mc.push_back(Facet(t,n,values_list->item(value_id)));
} }
nbs_of_mc_triangles[isovalue_id]=m_surface_mc.size(); nbs_of_mc_triangles[value_id]=m_surface_mc.size();
mc_timer.start(); mc_timer.start();
} }
mc_timer.stop(); mc_timer.stop();
@ -644,7 +729,7 @@ void Volume::display_surface_mesher_result()
QTime total_time; QTime total_time;
total_time.start(); total_time.start();
isovalues_list->save_values(fileinfo.absoluteFilePath()); values_list->save_values(fileinfo.absoluteFilePath());
unsigned int nx = m_image.xdim(); unsigned int nx = m_image.xdim();
unsigned int ny = m_image.ydim(); unsigned int ny = m_image.ydim();
@ -667,15 +752,34 @@ void Volume::display_surface_mesher_result()
del.clear(); del.clear();
Sphere bounding_sphere(m_image.center(),m_image.radius()*m_image.radius()); Sphere bounding_sphere(m_image.center(),m_image.radius()*m_image.radius());
m_image.set_interpolation(mw->grayLevelRadioButton->isChecked());
// definition of the surface // definition of the surface
Surface_3 surface(m_image, bounding_sphere, m_relative_precision); Surface_3 surface(m_image, bounding_sphere, m_relative_precision);
// Threshold threshold(m_image.isovalue()); // Threshold threshold(m_image.isovalue());
Classify_from_isovalue_list classify(isovalues_list); Classify_from_isovalue_list classify(values_list);
Generate_surface_identifiers generate_ids(isovalues_list); Generate_surface_identifiers generate_ids(values_list);
classify.set_identity(mw->labellizedRadioButton->isChecked());
generate_ids.set_labellized_image(mw->labellizedRadioButton->isChecked());
std::vector<Point> seeds; std::vector<Point> seeds;
search_for_connected_components(std::back_inserter(seeds), classify); {
std::set<unsigned char> domains;
search_for_connected_components(std::back_inserter(seeds),
CGAL::inserter(domains),
classify);
if(mw->labellizedRadioButton->isChecked() &&
values_list->numberOfValues() == 0)
{
Q_FOREACH(unsigned char label, domains) {
if(label != 0) {
values_list->addValue(label);
}
}
}
}
// surface mesh traits class // surface mesh traits class
typedef CGAL::Surface_mesher::Implicit_surface_oracle_3<Kernel, typedef CGAL::Surface_mesher::Implicit_surface_oracle_3<Kernel,
// typedef CGAL::Surface_mesher::Image_surface_oracle_3<Kernel, // typedef CGAL::Surface_mesher::Image_surface_oracle_3<Kernel,
@ -722,16 +826,25 @@ void Volume::display_surface_mesher_result()
criterion_vector.push_back(&aspect_ratio_criterion); criterion_vector.push_back(&aspect_ratio_criterion);
criterion_vector.push_back(&uniform_size_criterion); criterion_vector.push_back(&uniform_size_criterion);
criterion_vector.push_back(&curvature_size_criterion); criterion_vector.push_back(&curvature_size_criterion);
criterion_vector.push_back(&vertices_on_the_same_psc_element_criterion); if(mw->sameIndexCheckBox->isChecked()) {
criterion_vector.push_back(&vertices_on_the_same_psc_element_criterion);
std::cerr << "vertices_on_the_same_psc_element_criterion is activated.\n";
}
CGAL::Surface_mesher::Standard_criteria<Criterion> criteria(criterion_vector); CGAL::Surface_mesher::Standard_criteria<Criterion> criteria(criterion_vector);
std::cerr << "Surface_mesher... angle=" << m_sm_angle << ", radius= " << m_sm_radius std::cerr << "Surface_mesher... angle=" << m_sm_angle << ", radius= " << m_sm_radius
<< ", distance=" << m_sm_distance << "\n"; << ", distance=" << m_sm_distance << "\n";
// meshing surface if(mw->manifoldCheckBox->isChecked()) {
make_surface_mesh(c2t3, surface, oracle, criteria, // meshing surface
// CGAL::Non_manifold_tag(), 0); std::cerr << "manifold criteria is activated.\n";
CGAL::Manifold_tag(), 0); make_surface_mesh(c2t3, surface, oracle, criteria,
CGAL::Manifold_tag(), 0);
}
else {
make_surface_mesh(c2t3, surface, oracle, criteria,
CGAL::Non_manifold_tag(), 0);
}
sm_timer.stop(); sm_timer.stop();
not_busy(); not_busy();
@ -909,19 +1022,19 @@ void Volume::gl_draw_surface_mc()
if(lists_draw_surface_mc_is_valid) if(lists_draw_surface_mc_is_valid)
{ {
for(int i = 0, nbs = isovalues_list->numberOfIsoValues(); i < nbs; ++i ) for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i )
{ {
if(isovalues_list->enabled(i)) if(values_list->enabled(i))
{ {
mw->viewer->qglColor(isovalues_list->color(i)); mw->viewer->qglColor(values_list->color(i));
::glCallList(lists_draw_surface_mc[i]); ::glCallList(lists_draw_surface_mc[i]);
} }
} }
} }
else else
{ {
lists_draw_surface_mc.resize(isovalues_list->numberOfIsoValues(), 0); lists_draw_surface_mc.resize(values_list->numberOfValues(), 0);
for(int i = 0, nbs = isovalues_list->numberOfIsoValues(); i < nbs; ++i ) for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i )
{ {
if(!lists_draw_surface_mc[i]) if(!lists_draw_surface_mc[i])
{ {
@ -933,18 +1046,18 @@ void Volume::gl_draw_surface_mc()
% lists_draw_surface_mc[i] % lists_draw_surface_mc[i]
% i; % i;
mw->viewer->qglColor(isovalues_list->color(i)); mw->viewer->qglColor(values_list->color(i));
if(lists_draw_surface_mc[i]) // If if(lists_draw_surface_mc[i]) // If
::glNewList(lists_draw_surface_mc[i], // lists_draw_surface[i]==0 then something ::glNewList(lists_draw_surface_mc[i], // lists_draw_surface[i]==0 then something
isovalues_list->enabled(i) // got wrong in the list generation. values_list->enabled(i) // got wrong in the list generation.
? GL_COMPILE_AND_EXECUTE ? GL_COMPILE_AND_EXECUTE
: GL_COMPILE); : GL_COMPILE);
gl_draw_surface(m_surface_mc.begin(), gl_draw_surface(m_surface_mc.begin(),
m_surface_mc.end(), m_surface_mc.end(),
isovalues_list->item(i)); values_list->item(i));
if(lists_draw_surface_mc[i]) // If lists_draw_surface[i]==0 then if(lists_draw_surface_mc[i]) // If lists_draw_surface[i]==0 then
{ // something got wrong in the list { // something got wrong in the list
@ -957,21 +1070,28 @@ void Volume::gl_draw_surface_mc()
void Volume::gl_draw_surface() void Volume::gl_draw_surface()
{ {
// if(mw->labellizedRadioButton->isChecked()) {
// mw->viewer->qglColor(::Qt::blue);
// gl_draw_surface(m_surface.begin(),
// m_surface.end(),
// 0);
// }
// else
if(lists_draw_surface_is_valid) if(lists_draw_surface_is_valid)
{ {
for(int i = 0, nbs = isovalues_list->numberOfIsoValues(); i < nbs; ++i ) for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i )
{ {
if(isovalues_list->enabled(i)) if(values_list->enabled(i))
{ {
mw->viewer->qglColor(isovalues_list->color(i)); mw->viewer->qglColor(values_list->color(i));
::glCallList(lists_draw_surface[i]); ::glCallList(lists_draw_surface[i]);
} }
} }
} }
else else
{ {
lists_draw_surface.resize(isovalues_list->numberOfIsoValues(), 0); lists_draw_surface.resize(values_list->numberOfValues(), 0);
for(int i = 0, nbs = isovalues_list->numberOfIsoValues(); i < nbs; ++i ) for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i )
{ {
if(!lists_draw_surface[i]) if(!lists_draw_surface[i])
{ {
@ -983,17 +1103,17 @@ void Volume::gl_draw_surface()
% lists_draw_surface[i] % lists_draw_surface[i]
% i; % i;
mw->viewer->qglColor(isovalues_list->color(i)); mw->viewer->qglColor(values_list->color(i));
if(lists_draw_surface[i]) // If if(lists_draw_surface[i]) // If
::glNewList(lists_draw_surface[i], // lists_draw_surface[i]==0 ::glNewList(lists_draw_surface[i], // lists_draw_surface[i]==0
isovalues_list->enabled(i) // then something got wrong values_list->enabled(i) // then something got wrong
? GL_COMPILE_AND_EXECUTE // in the list generation. ? GL_COMPILE_AND_EXECUTE // in the list generation.
: GL_COMPILE); : GL_COMPILE);
gl_draw_surface(m_surface.begin(), gl_draw_surface(m_surface.begin(),
m_surface.end(), m_surface.end(),
isovalues_list->item(i)); values_list->item(i));
if(lists_draw_surface[i]) // If lists_draw_surface[i]==0 then if(lists_draw_surface[i]) // If lists_draw_surface[i]==0 then
{ // something got wrong in the list { // something got wrong in the list
@ -1086,11 +1206,11 @@ void Volume::gl_draw_marchingcube()
if(!m_inverse_normals) if(!m_inverse_normals)
::glEnableClientState(GL_NORMAL_ARRAY); ::glEnableClientState(GL_NORMAL_ARRAY);
for(int i = 0, nbs = isovalues_list->numberOfIsoValues(); i < nbs; ++i) for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i)
{ {
const int begin = i == 0 ? 0 : nbs_of_mc_triangles[i-1]; const int begin = i == 0 ? 0 : nbs_of_mc_triangles[i-1];
const int end = nbs_of_mc_triangles[i]; const int end = nbs_of_mc_triangles[i];
mw->viewer->qglColor(isovalues_list->color(i)); mw->viewer->qglColor(values_list->color(i));
::glBegin(GL_TRIANGLES); ::glBegin(GL_TRIANGLES);
for(int i = begin; i < end; ++i) for(int i = begin; i < end; ++i)
{ {

View File

@ -72,7 +72,7 @@ typedef CGAL::Implicit_surface_3<Kernel, Binary_image> Surface_3;
class MainWindow; class MainWindow;
class QDoubleSpinBox; class QDoubleSpinBox;
class Viewer; class Viewer;
class Isovalues_list; class Values_list;
class Volume : public Surface class Volume : public Surface
{ {
@ -109,7 +109,7 @@ private:
MainWindow* mw; MainWindow* mw;
QFileInfo fileinfo; QFileInfo fileinfo;
Isovalues_list* isovalues_list; Values_list* values_list;
QDoubleSpinBox* spinBox_radius_bound; QDoubleSpinBox* spinBox_radius_bound;
QDoubleSpinBox* spinBox_distance_bound; QDoubleSpinBox* spinBox_distance_bound;
@ -128,8 +128,12 @@ private:
template <typename Iterator> template <typename Iterator>
void gl_draw_surface(Iterator begin, Iterator end, const QTreeWidgetItem* = 0); void gl_draw_surface(Iterator begin, Iterator end, const QTreeWidgetItem* = 0);
template <typename PointsOutputIterator, typename TransformOperator> template <typename PointsOutputIterator,
void search_for_connected_components(PointsOutputIterator, TransformOperator); typename DomainsOutputIterator,
typename TransformOperator>
void search_for_connected_components(PointsOutputIterator,
DomainsOutputIterator,
TransformOperator);
public: public:
void gl_draw_surface(); void gl_draw_surface();
@ -148,12 +152,12 @@ public slots:
void set_triangulation_edges_color(); void set_triangulation_edges_color();
void set_draw_triangulation(const bool); void set_draw_triangulation(const bool);
void set_use_gouraud(const bool); void set_use_gouraud(const bool);
void open(const QString& filename); bool open(const QString& filename);
#ifdef CGAL_USE_VTK #ifdef CGAL_USE_VTK
void open_vtk(const QString& filename); bool open_vtk(const QString& filename);
#endif #endif
bool open_xt(const QString& filename); bool open_xt(const QString& filename);
void opendir(const QString& dirname); bool opendir(const QString& dirname);
void finish_open(); void finish_open();
void export_off(); void export_off();
void check_can_export_off(); void check_can_export_off();
@ -172,8 +176,12 @@ private:
void not_busy() const; void not_busy() const;
}; };
template <typename PointsOutputIterator, typename TransformOperator> template <typename PointsOutputIterator,
void Volume::search_for_connected_components(PointsOutputIterator it, TransformOperator transform) typename DomainsOutputIterator,
typename TransformOperator>
void Volume::search_for_connected_components(PointsOutputIterator it,
DomainsOutputIterator dom_it,
TransformOperator transform)
{ {
const unsigned int nx = m_image.xdim(); const unsigned int nx = m_image.xdim();
const unsigned int ny = m_image.ydim(); const unsigned int ny = m_image.ydim();
@ -195,6 +203,7 @@ void Volume::search_for_connected_components(PointsOutputIterator it, TransformO
if(visited[i][j][k]>0) if(visited[i][j][k]>0)
continue; continue;
const Label current_label = transform(m_image.value(i, j, k)); const Label current_label = transform(m_image.value(i, j, k));
*dom_it++ = current_label;
if(current_label == Label()) { if(current_label == Label()) {
visited[i][j][k] = 3; visited[i][j][k] = 3;
continue; continue;

View File

@ -338,7 +338,8 @@ public:
timer.start(); timer.start();
#endif // CGAL_SURFACE_MESHER_DEBUG_POLYHEDRAL_SURFACE_CONSTRUCTION #endif // CGAL_SURFACE_MESHER_DEBUG_POLYHEDRAL_SURFACE_CONSTRUCTION
CGAL::scan_OFF(input_file, *this, true); CGAL::scan_OFF(input_file, *this, true);
CGAL_assertion(input_file); if(!input_file)
return;
this->compute_bounding_box(); this->compute_bounding_box();
this->compute_normals(); this->compute_normals();