diff --git a/schnapps/core/schnapps.cpp b/schnapps/core/schnapps.cpp index dda90cc..108f8db 100644 --- a/schnapps/core/schnapps.cpp +++ b/schnapps/core/schnapps.cpp @@ -156,12 +156,19 @@ void SCHNApps::register_plugins_directory(const QString& path) #else QString plugin_name = pfi.baseName().remove(0, 3); #endif + if (plugin_name.endsWith("_d")) + plugin_name = plugin_name.left(plugin_name.size() -2); + if(plugin_name.startsWith("plugin_", Qt::CaseInsensitive)) + plugin_name = plugin_name.right(plugin_name.size() - 7); + QString plugin_file_path = directory.absoluteFilePath(plugin_file); if (available_plugins_.count(plugin_name) == 0ul) { available_plugins_.insert(std::make_pair(plugin_name, plugin_file_path)); emit(plugin_available_added(plugin_name)); + } else { + std::cout << "Plugin \"" << plugin_name.toStdString() << "\" already loaded." << std::endl; } } } diff --git a/schnapps/plugins/CMakeLists.txt b/schnapps/plugins/CMakeLists.txt index 05dec31..8a9009e 100644 --- a/schnapps/plugins/CMakeLists.txt +++ b/schnapps/plugins/CMakeLists.txt @@ -5,5 +5,6 @@ add_subdirectory(surface_differential_properties) add_subdirectory(surface_render) add_subdirectory(surface_render_vector) add_subdirectory(surface_render_scalar) -add_subdirectory(volume_mesh_from_surface) add_subdirectory(volume_render) +add_subdirectory(image) +add_subdirectory(volume_mesh_from_surface) diff --git a/schnapps/plugins/image/CMakeLists.txt b/schnapps/plugins/image/CMakeLists.txt new file mode 100644 index 0000000..ef1b17b --- /dev/null +++ b/schnapps/plugins/image/CMakeLists.txt @@ -0,0 +1,55 @@ +project(plugin_image + LANGUAGES CXX +) + +find_package(cgogn_core REQUIRED) +find_package(cgogn_io REQUIRED) +find_package(Qt5 COMPONENTS Widgets REQUIRED) +find_package(QOGLViewer REQUIRED) + +find_package(CGAL COMPONENTS Core ImageIO) +if(CGAL_FOUND) + include(${CGAL_USE_FILE}) + find_package(MPFR REQUIRED) + find_package(GMP REQUIRED) + find_package(Boost REQUIRED) +endif(CGAL_FOUND) + +set(HEADER_FILES + dll.h + image.h + image_dock_tab.h + cgal/cgal_image.h +) + +set(SOURCE_FILES + image.cpp + image_dock_tab.cpp + cgal/cgal_image.cpp +) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) + +add_library(${PROJECT_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES}) + +set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "_d") + +target_include_directories(${PROJECT_NAME} PUBLIC + $ + $ + $ + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} +) + +#target_compile_definitions(${PROJECT_NAME} PUBLIC "-Dcimg_display=0") + +target_link_libraries(${PROJECT_NAME} + schnapps_core + ${cgogn_core_LIBRARIES} + ${cgogn_io_LIBRARIES} + ${Qt5Widgets_LIBRARIES} + ${QOGLViewer_LIBRARIES} + ${CGAL_LIB} +) diff --git a/schnapps/plugins/image/cgal/cgal_image.cpp b/schnapps/plugins/image/cgal/cgal_image.cpp new file mode 100644 index 0000000..ed1c774 --- /dev/null +++ b/schnapps/plugins/image/cgal/cgal_image.cpp @@ -0,0 +1,99 @@ +/******************************************************************************* +* SCHNApps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* Plugin Image * +* Author Etienne Schmitt (etienne.schmitt@inria.fr) Inria/Mimesis * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#define SCHNAPPS_PLUGIN_IMAGE_DLL_EXPORT + +#include "cgal_image.h" + +namespace schnapps +{ + +namespace plugin_image +{ + +SCHNAPPS_PLUGIN_IMAGE_API CGAL::Image_3 export_to_cgal_image(const Image3D& im) +{ + using DataType = cgogn::io::DataType; + + const auto& dims = im.get_image_dimensions(); + const auto& voxel_dims = im.get_voxel_dimensions(); + + _image* image =_createImage(dims[0], dims[1], dims[2], + im.get_nb_components(), + voxel_dims[0], voxel_dims[1], voxel_dims[2], + im.get_data_size(), + get_cgal_word_kind(im.get_data_type()), + get_cgal_sign(im.get_data_type())); + + image->endianness = cgogn::internal::cgogn_is_little_endian? END_LITTLE : END_BIG; + + image->vectMode = im.get_nb_components() == 1u ? VM_SCALAR : VM_NON_INTERLACED; + const auto& trans = im.get_translation(); + image->tx = trans[0]; + image->ty = trans[1]; + image->tz = trans[2]; + + const auto& rot = im.get_rotation(); + image->rx = rot[0]; + image->ry = rot[1]; + image->rz = rot[2]; + + const auto& origin = im.get_origin(); + image->cx = origin[0]; + image->cy = origin[1]; + image->cz = origin[2]; + + + std::memcpy(image->data,im.data(), dims[0]*dims[1]*dims[2]*image->wdim * image->vdim); + + return CGAL::Image_3(image); +} + +SCHNAPPS_PLUGIN_IMAGE_API WORD_KIND get_cgal_word_kind(cgogn::io::DataType data_type) +{ + using DataType = cgogn::io::DataType; + + if (data_type == DataType::FLOAT || data_type == DataType::DOUBLE) + return WK_FLOAT; + else + return WK_FIXED; +} + +SCHNAPPS_PLUGIN_IMAGE_API SIGN get_cgal_sign(cgogn::io::DataType data_type) +{ + using DataType = cgogn::io::DataType; + + switch(data_type) { + case DataType::UINT8: + case DataType::UINT16: + case DataType::UINT32: + case DataType::UINT64: return SGN_UNSIGNED; + default: + return SGN_SIGNED; + } +} + + +} // namespace plugin_image +} // namespace schnapps diff --git a/schnapps/plugins/image/cgal/cgal_image.h b/schnapps/plugins/image/cgal/cgal_image.h new file mode 100644 index 0000000..f6b4d2f --- /dev/null +++ b/schnapps/plugins/image/cgal/cgal_image.h @@ -0,0 +1,42 @@ +/******************************************************************************* +* SCHNApps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* Plugin Image * +* Author Etienne Schmitt (etienne.schmitt@inria.fr) Inria/Mimesis * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef SCHNAPPS_PLUGIN_IMAGE_CGAL_IMAGE_H_ +#define SCHNAPPS_PLUGIN_IMAGE_CGAL_IMAGE_H_ + +#include +#include "image.h" + +namespace schnapps +{ + +namespace plugin_image +{ + SCHNAPPS_PLUGIN_IMAGE_API CGAL::Image_3 export_to_cgal_image(const schnapps::plugin_image::Image3D& im); + SCHNAPPS_PLUGIN_IMAGE_API WORD_KIND get_cgal_word_kind(cgogn::io::DataType data_type); + SCHNAPPS_PLUGIN_IMAGE_API SIGN get_cgal_sign(cgogn::io::DataType data_type); +} // namespace plugin_image +} // namespace schnapps + +#endif // SCHNAPPS_PLUGIN_IMAGE_CGAL_IMAGE_H_ diff --git a/schnapps/plugins/image/dll.h b/schnapps/plugins/image/dll.h new file mode 100644 index 0000000..af5e4a4 --- /dev/null +++ b/schnapps/plugins/image/dll.h @@ -0,0 +1,41 @@ +/******************************************************************************* +* SCHNApps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* Plugin Image * +* Author Etienne Schmitt (etienne.schmitt@inria.fr) Inria/Mimesis * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef SCHNAPPS_PLUGIN_IMAGE_H_ +#define SCHNAPPS_PLUGIN_IMAGE_H_ + + +#ifdef WIN32 +#ifndef SCHNAPPS_PLUGIN_IMAGE_API +#if defined SCHNAPPS_PLUGIN_IMAGE_DLL_EXPORT +#define SCHNAPPS_PLUGIN_IMAGE_API __declspec(dllexport) +#else +#define SCHNAPPS_PLUGIN_IMAGE_API __declspec(dllimport) +#endif +#endif +#else +#define SCHNAPPS_PLUGIN_IMAGE_API +#endif + +#endif // SCHNAPPS_PLUGIN_IMAGE_H_ diff --git a/schnapps/plugins/image/image.cpp b/schnapps/plugins/image/image.cpp new file mode 100644 index 0000000..2605264 --- /dev/null +++ b/schnapps/plugins/image/image.cpp @@ -0,0 +1,452 @@ +/******************************************************************************* +* SCHNApps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* Plugin Image * +* Author Etienne Schmitt (etienne.schmitt@inria.fr) Inria/Mimesis * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#define SCHNAPPS_PLUGIN_IMAGE_DLL_EXPORT + +#include "image.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace schnapps +{ + +namespace plugin_image +{ + +Plugin_Image::Plugin_Image() : + images_(), + import_image_action_(nullptr), + dock_tab_(nullptr) +{} + +const std::list >& Plugin_Image::get_images() const +{ + return images_; +} + +const Image3D*Plugin_Image::get_image(const QString& im_path) +{ + if (images_.empty()) + return nullptr; + for (const auto& it : images_) + if (it.first == im_path) + return &(it.second); + return nullptr; +} + +bool Plugin_Image::enable() +{ + import_image_action_ = schnapps_->add_menu_action("Import;3D Image", "import image"); + connect(import_image_action_, SIGNAL(triggered()), this, SLOT(import_image_dialog())); + + dock_tab_ = new Image_DockTab(this->schnapps_, this); + schnapps_->add_plugin_dock_tab(this, dock_tab_, "Image3D"); + return true; +} + +void Plugin_Image::disable() +{ + schnapps_->remove_menu_action(import_image_action_); + import_image_action_ = nullptr; + schnapps_->remove_plugin_dock_tab(this, dock_tab_); + delete dock_tab_; + dock_tab_ = nullptr; +} + +void Plugin_Image::draw(schnapps::View* view, const QMatrix4x4& proj, const QMatrix4x4& mv) +{ +} + +void Plugin_Image::draw_map(schnapps::View* view, schnapps::MapHandlerGen* map, const QMatrix4x4& proj, const QMatrix4x4& mv) +{ +} + +void Plugin_Image::keyPress(schnapps::View* view, QKeyEvent* event) +{ +} + +void Plugin_Image::keyRelease(schnapps::View* view, QKeyEvent* event) +{ +} + +void Plugin_Image::mousePress(schnapps::View* view, QMouseEvent* event) +{ +} + +void Plugin_Image::mouseRelease(schnapps::View* view, QMouseEvent* event) +{ +} + +void Plugin_Image::mouseMove(schnapps::View* view, QMouseEvent* event) +{ +} + +void Plugin_Image::wheelEvent(schnapps::View* view, QWheelEvent* event) +{ +} + +void Plugin_Image::view_linked(schnapps::View* view) +{ +} + +void Plugin_Image::view_unlinked(schnapps::View* view) +{ +} + +void Plugin_Image::import_image(const QString& image_path) +{ + QFileInfo fileinfo(image_path); + if (fileinfo.exists() && fileinfo.isFile()) + { + images_.push_back({image_path, Image3D::new_image_3d(image_path)}); + emit(image_added(image_path)); + } + +} + +void Plugin_Image::import_image_dialog() +{ + auto filenames = QFileDialog::getOpenFileNames(nullptr, "Import 3D images", schnapps_->get_app_path(), "3DImages (*.inr *.vtk)"); + for (const auto& im : filenames) + import_image(im); +} + +void Plugin_Image::image_removed() +{ + const int current_image_id = dock_tab_->listWidget_images->currentRow(); + if (current_image_id >= 0) + { + QListWidgetItem* curr_item = dock_tab_->listWidget_images->currentItem(); + emit(image_removed(curr_item->text())); + dock_tab_->listWidget_images->removeItemWidget(curr_item); + delete curr_item; + + auto it = images_.begin(); + std::advance(it, current_image_id); + images_.erase(it); + } +} + +Q_PLUGIN_METADATA(IID "SCHNApps.Plugin") + +Image3D::Image3D() : + data_(nullptr), + image_dim_{}, + origin_(), + voxel_dim_{}, + translation_(), + rotation_(), + nb_components_(0u) +{ + image_dim_.fill(0); + translation_.fill(0); + rotation_.fill(0); + origin_.fill(0); + voxel_dim_.fill(0); +} + +Image3D::Image3D(Image3D&& im) : + data_(std::move(im.data_)), + image_dim_(im.image_dim_), + origin_(im.origin_), + voxel_dim_(im.voxel_dim_), + translation_(im.translation_), + rotation_(im.rotation_), + nb_components_(im.nb_components_) +{} + + +Image3D& Image3D::operator=(Image3D&& im) +{ + if (this != &im) + { + data_ = std::move(im.data_); + image_dim_ = im.image_dim_; + origin_ = im.origin_; + voxel_dim_ = im.voxel_dim_; + translation_ = im.translation_; + rotation_ = im.rotation_; + nb_components_ = im.nb_components_; + } + + return *this; +} + +Image3D Image3D::new_image_3d(const QString& image_path) +{ + QFileInfo fileinfo(image_path); + Image3D res_img; + if (fileinfo.exists() && fileinfo.isFile()) + { + cgogn::Scoped_C_Locale locale; + std::ifstream in(image_path.toStdString(), std::ios_base::binary | std::ios_base::in); + const auto& suffix = fileinfo.suffix(); + if(suffix == "inr") + res_img.import_inr(in); + else + { + if (suffix == "vtk") + res_img.import_vtk(in); + else + return res_img; + + } + + export_to_cgal_image(res_img); + } + return res_img; +} + +void Image3D::import_inr(std::istream& inr_data) +{ + std::array buffer; + std::string line; + std::string type; + std::string cpu; + std::size_t data_size = 0ul; + + inr_data.read(&buffer[0], buffer.size()); + std::stringstream sstream(std::string(&buffer[0], buffer.size())); + std::getline(sstream, line); + if (line != "#INRIMAGE-4#{") + return; + + std::getline(sstream, line); + + while (!line.empty() && line[0] != '#') + { + if (line.compare(0,5,"XDIM=") == 0) + this->image_dim_[0] = std::stoul(line.substr(5)); + if (line.compare(0,5,"YDIM=") == 0) + this->image_dim_[1] = std::stoul(line.substr(5)); + if (line.compare(0,5,"ZDIM=") == 0) + this->image_dim_[2] = std::stoul(line.substr(5)); + + if (line.compare(0,5,"VDIM=") == 0) + this->nb_components_ = std::stoul(line.substr(5)); + + if (line.compare(0,3,"VX=") == 0) + this->voxel_dim_[0] = std::stod(line.substr(3)); + if (line.compare(0,3,"VY=") == 0) + this->voxel_dim_[1] = std::stod(line.substr(3)); + if (line.compare(0,3,"VZ=") == 0) + this->voxel_dim_[2] = std::stod(line.substr(3)); + + if (line.compare(0,3,"XO=") == 0) + this->origin_[0] = std::stod(line.substr(3)); + if (line.compare(0,3,"YO=") == 0) + this->origin_[1] = std::stod(line.substr(3)); + if (line.compare(0,3,"ZO=") == 0) + this->origin_[2] = std::stod(line.substr(3)); + + if (line.compare(0,3,"TX=") == 0) + this->translation_[0] = std::stod(line.substr(3)); + if (line.compare(0,3,"TY=") == 0) + this->translation_[1] = std::stod(line.substr(3)); + if (line.compare(0,3,"TZ=") == 0) + this->translation_[2] = std::stod(line.substr(3)); + + if (line.compare(0,3,"RX=") == 0) + this->rotation_[0] = std::stod(line.substr(3)); + if (line.compare(0,3,"RY=") == 0) + this->rotation_[1] = std::stod(line.substr(3)); + if (line.compare(0,3,"RZ=") == 0) + this->rotation_[2] = std::stod(line.substr(3)); + + if (line.compare(0,5,"TYPE=") == 0) + type = line.substr(5); + + if (line.compare(0,8,"PIXSIZE=") == 0) + data_size = std::stoul(line.substr(8,2))/8ul; + + if (line.compare(0,4,"CPU=") == 0) + cpu = line.substr(4); + + std::getline(sstream, line); + } + + cpu = cgogn::to_lower(cpu); + type = cgogn::to_lower(type); + + const bool little_endian = (cpu == "decm" || cpu == "pc" || cpu == "alpha"); + + + if (type == "unsigned fixed") + switch (data_size) { + case 1: data_ = cgogn::make_unique>(); break; + case 2: data_ = cgogn::make_unique>(); break; + case 4: data_ = cgogn::make_unique>(); break; + case 8: data_ = cgogn::make_unique>(); break; + default: break; + } else { + if (type == "signed fixed") + switch (data_size) { + case 1: data_ = cgogn::make_unique>(); break; + case 2: data_ = cgogn::make_unique>(); break; + case 4: data_ = cgogn::make_unique>(); break; + case 8: data_ = cgogn::make_unique>(); break; + default: break; + } else { + if (type == "float") + switch (data_size) { + case 4: data_ = cgogn::make_unique>(); break; + case 8: data_ = cgogn::make_unique>(); break; + default: break; + } + } + } + if (data_) + { + data_->read_n(inr_data, image_dim_[0] * image_dim_[1] * image_dim_[2] * nb_components_ , true, !little_endian); + data_ = data_->simplify(); + } + +} + +void Image3D::import_vtk(std::istream& vtk_data) +{ + const auto to_upper = [=](const std::string& s) { return cgogn::to_upper(s); }; + + std::string line; + std::string word; + line.reserve(512); + word.reserve(128); + + // 2 first lines = trash + std::getline(vtk_data, line); + std::getline(vtk_data, line); + + vtk_data >> word; + bool ascii_file = to_upper(word) == "ASCII"; + if (!(ascii_file || to_upper(word) == "BINARY")) + return; + + vtk_data >> word; + if (to_upper(word) != "DATASET") + return; + + vtk_data >> word; + const std::string& dataset = to_upper(word); + if (dataset != "STRUCTURED_POINTS") + return; + + + while(!vtk_data.eof()) + { + std::getline(vtk_data,line); + word.clear(); + std::istringstream sstream(line); + sstream >> word; + word = to_upper(word); + + + if (word == "DIMENSIONS") + sstream >> image_dim_[0] >> image_dim_[1] >> image_dim_[2]; + + if (word == "SPACING") + sstream >> voxel_dim_[0] >> voxel_dim_[1] >> voxel_dim_[2]; + + if (word == "ORIGIN") + { + sstream >> origin_[0] >> origin_[1] >> origin_[2]; + origin_.fill(0); + } + + + if (word == "POINT_DATA") + { + std::size_t nb_data; + sstream >> nb_data; + + std::ifstream::pos_type previous_pos; + do { + previous_pos = vtk_data.tellg(); + std::getline(vtk_data, line); + sstream.str(line); + sstream.clear(); + word.clear(); + sstream >> word; + word = to_upper(word); + if (word == "SCALARS" || word == "VECTOR") + { + const bool is_vector = !(word == "SCALARS"); + std::string att_name; + std::string att_type; + nb_components_ = is_vector? 3u : 1u; + sstream >> att_name >> att_type >> nb_components_; + att_type = cgogn::io::vtk_data_type_to_cgogn_name_of_type(att_type); + + const auto pos_before_lookup_table = vtk_data.tellg(); // the lookup table might (or might not) be defined + std::getline(vtk_data,line); + sstream.str(line); + sstream.clear(); + std::string lookup_table; + std::string lookup_table_name; + sstream >> lookup_table >> lookup_table_name; + if (to_upper(lookup_table) != "LOOKUP_TABLE") + vtk_data.seekg(pos_before_lookup_table); // if there wasn't a lookup table we go back and start reading the numerical values + + data_ = DataInputGen::template newDataIO<1, float32>(att_type, nb_components_); + data_->read_n(vtk_data, nb_data, !ascii_file, true); + data_ = data_->simplify(); + } + else + { + if (word == "LOOKUP_TABLE") + { + std::string table_name; + /*uint32*/ nb_data = 0u; + sstream >> table_name >> nb_data; + if (ascii_file) + { + DataInput trash; + trash.skip_n(vtk_data, nb_data, false); + } + else + { + DataInput trash; + trash.skip_n(vtk_data, nb_data, true); + } + } + } + } while ((word == "SCALARS" || word == "LOOKUP_TABLE" || word == "VECTOR")&& (!vtk_data.eof())); + if (!vtk_data.eof()) + { + vtk_data.seekg(previous_pos); + word.clear(); + } + else + break; + } + } +} + +} // namespace plugin_image +} // namespace schnapps diff --git a/schnapps/plugins/image/image.h b/schnapps/plugins/image/image.h new file mode 100644 index 0000000..a5c7962 --- /dev/null +++ b/schnapps/plugins/image/image.h @@ -0,0 +1,135 @@ +/******************************************************************************* +* SCHNApps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* Plugin Image * +* Author Etienne Schmitt (etienne.schmitt@inria.fr) Inria/Mimesis * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef SCHNAPPS_PLUGIN_IMAGE_IMAGE_H_ +#define SCHNAPPS_PLUGIN_IMAGE_IMAGE_H_ + +#include +#include +#include +#include "dll.h" +#include +#include +#include +#include +#include + +namespace schnapps +{ + +namespace plugin_image +{ + +using namespace cgogn::numerics; +class Image_DockTab; + + +class Image3D +{ +public: + using DataInputGen = cgogn::io::DataInputGen; + template + using DataInput = cgogn::io::DataInput; + using DataType = cgogn::io::DataType; + + Image3D(); + Image3D(const Image3D&) = delete; + Image3D(Image3D&& im); + Image3D& operator=(Image3D&& im); + Image3D& operator=(const Image3D&) = delete; + + void const * data() const { return data_->data(); } + inline std::array const& get_image_dimensions() const { return image_dim_; } + inline std::array const& get_origin() const { return origin_; } + inline std::array const& get_voxel_dimensions() const { return voxel_dim_; } + inline std::array const& get_translation() const { return translation_; } + inline std::array const& get_rotation() const { return rotation_; } + inline uint8 get_nb_components() const { return nb_components_; } + inline bool is_little_endian() const { return cgogn::internal::cgogn_is_little_endian ; } + inline std::size_t get_data_size() const { return data_->data_size();} + inline DataType get_data_type() const { return data_->data_type(); } + + + static Image3D new_image_3d(const QString& image_path); +private: + void import_inr(std::istream& inr_data); + void import_vtk(std::istream& vtk_data); + +private: + std::unique_ptr data_; + std::array image_dim_; + std::array origin_; + std::array voxel_dim_; + std::array translation_; + std::array rotation_; + uint32 nb_components_; +}; + +class Plugin_Image : public PluginInteraction +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "SCHNApps.Plugin") + Q_INTERFACES(schnapps::Plugin) + +public: + Plugin_Image(); + + std::list> const& get_images() const; + const Image3D* get_image(const QString& im_path); +private: + bool enable() override; + void disable() override; + +private: + void draw(View* view, const QMatrix4x4& proj, const QMatrix4x4& mv) override; + void draw_map(View* view, MapHandlerGen* map, const QMatrix4x4& proj, const QMatrix4x4& mv) override; + void keyPress(View* view, QKeyEvent* event) override; + void keyRelease(View* view, QKeyEvent* event) override; + void mousePress(View* view, QMouseEvent* event) override; + void mouseRelease(View* view, QMouseEvent* event) override; + void mouseMove(View* view, QMouseEvent* event) override; + void wheelEvent(View* view, QWheelEvent* event) override; + void view_linked(View* view) override; + void view_unlinked(View* view) override; + + void import_image(const QString& image_path); + +private slots: + void import_image_dialog(); + void image_removed(); + +signals: + void image_added(QString im_path); + void image_removed(QString im_path); + +private: + std::list> images_; + QAction* import_image_action_; + Image_DockTab* dock_tab_; +}; + +} // namespace plugin_image +} // namespace schnapps + +#endif // SCHNAPPS_PLUGIN_IMAGE_IMAGE_H_ diff --git a/schnapps/plugins/image/image.ui b/schnapps/plugins/image/image.ui new file mode 100644 index 0000000..bcff62d --- /dev/null +++ b/schnapps/plugins/image/image.ui @@ -0,0 +1,81 @@ + + + ImagePlugin_TabWidget + + + + 0 + 0 + 276 + 600 + + + + Form + + + + + + images + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + remove + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/schnapps/plugins/volume_mesh_from_surface/cgal/types.h b/schnapps/plugins/image/image_dock_tab.cpp similarity index 72% rename from schnapps/plugins/volume_mesh_from_surface/cgal/types.h rename to schnapps/plugins/image/image_dock_tab.cpp index 3ac9819..55c5fb2 100644 --- a/schnapps/plugins/volume_mesh_from_surface/cgal/types.h +++ b/schnapps/plugins/image/image_dock_tab.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * SCHNApps * -* Copyright (C) 2016, IGG Group, ICube, University of Strasbourg, France * -* Plugin Volume Mesh From Surface * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* Plugin Image * * Author Etienne Schmitt (etienne.schmitt@inria.fr) Inria/Mimesis * * This library is free software; you can redistribute it and/or modify it * * under the terms of the GNU Lesser General Public License as published by the * @@ -22,25 +22,32 @@ * * *******************************************************************************/ -#ifndef SCHNAPPS_PLUGIN_VOLUME_MESH_FROM_SURFACE_TYPES_H -#define SCHNAPPS_PLUGIN_VOLUME_MESH_FROM_SURFACE_TYPES_H +#define SCHNAPPS_PLUGIN_IMAGE_DLL_EXPORT -#include -#include -#include -#include +#include "image_dock_tab.h" +#include +#include namespace schnapps { -namespace plugin_vmfs +namespace plugin_image { -using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; -using Polyhedron = CGAL::Polyhedron_3 ; -using HalfedgeDS = Polyhedron::HalfedgeDS; +Image_DockTab::Image_DockTab(SCHNApps* s, Plugin_Image* p) : + schnapps_(s), + plugin_(p), + updating_ui_(false) +{ + setupUi(this); -} // namespace plugin_vmfs -} // namespace schnapps + connect(p,&Plugin_Image::image_added, [=](const QString& im_path) { + new QListWidgetItem(im_path, this->listWidget_images); + }); + + connect(this->pushButton_remove, SIGNAL(pressed()), p, SLOT(image_removed())); -#endif // SCHNAPPS_PLUGIN_VOLUME_MESH_FROM_SURFACE_TYPES_H +} + +} // namespace schnapps +} // namespace plugin_image diff --git a/schnapps/plugins/image/image_dock_tab.h b/schnapps/plugins/image/image_dock_tab.h new file mode 100644 index 0000000..ce6fcd6 --- /dev/null +++ b/schnapps/plugins/image/image_dock_tab.h @@ -0,0 +1,58 @@ +/******************************************************************************* +* SCHNApps * +* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France * +* Plugin Image * +* Author Etienne Schmitt (etienne.schmitt@inria.fr) Inria/Mimesis * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: http://cgogn.unistra.fr/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef SCHNAPPS_PLUGIN_IMAGE_IMAGE_DOCK_TAB_H_ +#define SCHNAPPS_PLUGIN_IMAGE_IMAGE_DOCK_TAB_H_ + +#include + +namespace schnapps +{ + +class SCHNApps; + +namespace plugin_image +{ + +class Plugin_Image; + +class Image_DockTab : public QWidget, public Ui::ImagePlugin_TabWidget +{ + Q_OBJECT + + friend class Plugin_Image; + +public: + Image_DockTab(SCHNApps* s, Plugin_Image* p); + +private: + SCHNApps* schnapps_; + Plugin_Image* plugin_; + bool updating_ui_; +}; + +} // namespace schnapps +} // namespace plugin_image + +#endif // SCHNAPPS_PLUGIN_IMAGE_IMAGE_DOCK_TAB_H_ diff --git a/schnapps/plugins/image/todo.txt b/schnapps/plugins/image/todo.txt new file mode 100644 index 0000000..bc80625 --- /dev/null +++ b/schnapps/plugins/image/todo.txt @@ -0,0 +1,2 @@ +lire les vtk (structured_points) +rendu des images avec des points (cf cgal) diff --git a/schnapps/plugins/volume_mesh_from_surface/CMakeLists.txt b/schnapps/plugins/volume_mesh_from_surface/CMakeLists.txt index 7683605..2858eed 100644 --- a/schnapps/plugins/volume_mesh_from_surface/CMakeLists.txt +++ b/schnapps/plugins/volume_mesh_from_surface/CMakeLists.txt @@ -7,7 +7,7 @@ project(plugin_volume_mesh_from_surface find_package(cgogn_core REQUIRED) find_package(cgogn_io REQUIRED) find_package(Qt5 COMPONENTS Widgets REQUIRED) -find_package(CGAL COMPONENTS Core ImageIO) +find_package(CGAL COMPONENTS Core) if(CGAL_FOUND) include(${CGAL_USE_FILE}) find_package(MPFR REQUIRED) @@ -33,7 +33,6 @@ if(CGAL_FOUND) ${HEADER_FILES} cgal/cgogn_surface_to_cgal_polyhedron.h cgal/c3t3_import.h - cgal/types.h ) set(SOURCE_FILES ${SOURCE_FILES} @@ -58,6 +57,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC $ $ $ + $ ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) @@ -65,6 +65,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC target_link_libraries(${PROJECT_NAME} schnapps_core tet + plugin_image ${CGAL_LIBRARIES} ${cgogn_core_LIBRARIES} ${cgogn_io_LIBRARIES} diff --git a/schnapps/plugins/volume_mesh_from_surface/cgal/c3t3_import.cpp b/schnapps/plugins/volume_mesh_from_surface/cgal/c3t3_import.cpp index d32c956..f16add3 100644 --- a/schnapps/plugins/volume_mesh_from_surface/cgal/c3t3_import.cpp +++ b/schnapps/plugins/volume_mesh_from_surface/cgal/c3t3_import.cpp @@ -26,10 +26,9 @@ #include "c3t3_import.h" #include "cgogn_surface_to_cgal_polyhedron.h" - -#include - -#include +#include +#include +#include namespace schnapps { @@ -37,108 +36,67 @@ namespace schnapps namespace plugin_vmfs { -bool C3T3VolumeImport::import_file_impl(const std::string&) +SCHNAPPS_PLUGIN_VMFS_API void tetrahedralize(const MeshGeneratorParameters& param, MapHandler* input_surface_map, const CMap2::VertexAttribute& position_attribute, MapHandler* output_volume_map) { - const Triangulation& triangulation = cpx_.triangulation(); - std::map vertices_indices; - ChunkArray* position = this->template position_attribute(); - const uint32 num_vertices = triangulation.number_of_vertices(); - const uint32 num_cells = cpx_.number_of_cells_in_complex(); + using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; + using Polyhedron = CGAL::Polyhedron_3; + using Domain = CGAL::Polyhedral_mesh_domain_3; + using Triangulation = CGAL::Mesh_triangulation_3::type; + using Criteria = CGAL::Mesh_criteria_3; + using C3T3 = CGAL::Mesh_complex_3_in_triangulation_3; + using namespace CGAL::parameters; - this->set_nb_volumes(num_cells); - this->set_nb_vertices(num_vertices); + if (!input_surface_map || !output_volume_map || !position_attribute.is_valid()) + return; - for (auto vit = triangulation.finite_vertices_begin(), vend = triangulation.finite_vertices_end(); vit != vend; ++vit) + auto poly = build_polyhedron(input_surface_map, position_attribute); + if (poly) { - const auto& P = vit->point(); - const uint32 id = this->insert_line_vertex_container(); - vertices_indices[vit] = id; - position->operator [](id) = VEC3(SCALAR(P.x()), SCALAR(P.y()), SCALAR(P.z())); - } - - for (auto cit = cpx_.cells_in_complex_begin(), cend = cpx_.cells_in_complex_end(); cit != cend; ++cit) - this->add_tetra(*position, vertices_indices[cit->vertex(0)], vertices_indices[cit->vertex(1)], vertices_indices[cit->vertex(2)], vertices_indices[cit->vertex(3)], true); - ChunkArray* subdomain_indices = this->volume_attributes_container().template add_chunk_array("subdomain index"); - for (auto cit = cpx_.cells_in_complex_begin(), cend = cpx_.cells_in_complex_end(); cit != cend; ++cit) - { - const uint32 id = this->volume_attributes_container().template insert_lines<1>(); - subdomain_indices->operator [](id) = cpx_.subdomain_index(cit); - } - - return true; -} + Criteria criteria( + cell_size = param.cell_size_, + facet_angle = param.facet_angle_, + facet_size = param.facet_size_, + facet_distance= param.facet_distance_, + cell_radius_edge_ratio = param.cell_radius_edge_ratio_); -SCHNAPPS_PLUGIN_VMFS_API void import_c3t3(const C3T3& c3t3_in, MapHandler* map_out) -{ - if (!map_out) - return; + Domain mesh_domain(*poly); - C3T3VolumeImport volume_import(c3t3_in); - volume_import.import_file(""); - volume_import.create_map(*map_out->get_map()); + tetrahedralize(param, mesh_domain, criteria, output_volume_map); + } } -SCHNAPPS_PLUGIN_VMFS_API void tetrahedralize(const MapParameters& param, MapHandler* input_surface_map, const std::string& pos_att_name, MapHandler* output_volume_map) +SCHNAPPS_PLUGIN_VMFS_API void tetrahedralize(const MeshGeneratorParameters& param, const plugin_image::Image3D* im, MapHandler* output_volume_map) { + using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; + using Mesh_domain = CGAL::Labeled_image_mesh_domain_3; + using Tr = CGAL::Mesh_triangulation_3::type; + using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; + using Mesh_criteria = CGAL::Mesh_criteria_3; using namespace CGAL::parameters; - if (!input_surface_map || !output_volume_map || pos_att_name.empty()) + if (!im || !output_volume_map) return; - auto poly = build_polyhedron(input_surface_map, pos_att_name); - if (poly) + if (im->get_data_type() != cgogn::io::DataType::FLOAT) { - const Criteria criteria( - cell_size = param.cell_size_, - facet_angle = param.facet_angle_, - facet_size = param.facet_size_, - facet_distance= param.facet_distance_, - cell_radius_edge_ratio = param.cell_radius_edge_ratio_); - - Domain mesh_domain(*poly); - auto c3t3 = CGAL::make_mesh_3(mesh_domain, criteria, no_features(), no_perturb(), no_exude(), no_lloyd(), no_odt()); - - if (param.do_lloyd_) - { - CGAL::lloyd_optimize_mesh_3(c3t3, - mesh_domain, - time_limit = 0, - max_iteration_number = param.lloyd_max_iter_, - convergence = param.lloyd_convergence_, - freeze_bound = param.lloyd_freeze_bound_, - do_freeze = param.do_lloyd_freeze_); - } - - if (param.do_odt_) - { - CGAL::odt_optimize_mesh_3(c3t3, - mesh_domain, - time_limit = 0, - max_iteration_number = param.odt_max_iter_, - convergence = param.odt_convergence_, - freeze_bound = param.odt_freeze_bound_, - do_freeze = param.do_odt_freeze_); - } - - if (param.do_perturber_) - { - CGAL::perturb_mesh_3(c3t3, - mesh_domain, - time_limit = 0, - sliver_bound = param.perturber_sliver_bound_); - } - - if (param.do_exuder_) - { - CGAL::exude_mesh_3(c3t3, - time_limit = 0, - sliver_bound = param.exuder_sliver_bound_); - } - - import_c3t3(c3t3,output_volume_map); + std::cerr << "Error : CGAL::Labeled_image_mesh_domain_3 requires labels to be of type float32." << std::endl; + return; } + + Mesh_criteria criteria( + cell_size = param.cell_size_, + facet_angle = param.facet_angle_, + facet_size = param.facet_size_, + facet_distance= param.facet_distance_, + cell_radius_edge_ratio = param.cell_radius_edge_ratio_); + + auto cgal_im = plugin_image::export_to_cgal_image(*im); + + Mesh_domain domain(cgal_im); + + tetrahedralize(param, domain, criteria, output_volume_map); } } // namespace plugin_vmfs diff --git a/schnapps/plugins/volume_mesh_from_surface/cgal/c3t3_import.h b/schnapps/plugins/volume_mesh_from_surface/cgal/c3t3_import.h index 1ab44b5..93b2f46 100644 --- a/schnapps/plugins/volume_mesh_from_surface/cgal/c3t3_import.h +++ b/schnapps/plugins/volume_mesh_from_surface/cgal/c3t3_import.h @@ -25,37 +25,35 @@ #ifndef SCHNAPPS_PLUGIN_VOLUME_MESH_FROM_SURFACE_C3T3_IMPORT_H #define SCHNAPPS_PLUGIN_VOLUME_MESH_FROM_SURFACE_C3T3_IMPORT_H -#include "dll.h" -#include "types.h" +#include "../dll.h" #include - +#include #include #include #include #include #include +#include +#include namespace schnapps { -namespace plugin_vmfs +namespace plugin_image { +class Image3D; +} -// forward declaration of MapParameters -class MapParameters; - -using Domain = CGAL::Polyhedral_mesh_domain_3; -using Triangulation = CGAL::Mesh_triangulation_3::type; -using Criteria = CGAL::Mesh_criteria_3; -using C3T3 = CGAL::Mesh_complex_3_in_triangulation_3; - +namespace plugin_vmfs +{ -class SCHNAPPS_PLUGIN_VMFS_API C3T3VolumeImport : public cgogn::io::VolumeImport +template +class C3T3VolumeImport : public cgogn::io::VolumeImport { public: using Inherit = VolumeImport; - using Self = C3T3VolumeImport; + using Self = C3T3VolumeImport; inline C3T3VolumeImport(const C3T3& cpx) : Inherit(), cpx_(cpx) @@ -65,17 +63,110 @@ class SCHNAPPS_PLUGIN_VMFS_API C3T3VolumeImport : public cgogn::io::VolumeImport template using ChunkArray = Inherit::ChunkArray; - using Triangulation = C3T3::Triangulation; - using Vertex_handle = Triangulation::Vertex_handle; + using Triangulation = typename C3T3::Triangulation; + using Vertex_handle = typename Triangulation::Vertex_handle; protected: - virtual bool import_file_impl(const std::string& /*filename*/) override; + virtual bool import_file_impl(const std::string& /*filename*/) override + { + const Triangulation& triangulation = cpx_.triangulation(); + std::map vertices_indices; + ChunkArray* position = this->template position_attribute(); + + const uint32 num_vertices = triangulation.number_of_vertices(); + const uint32 num_cells = cpx_.number_of_cells_in_complex(); + + this->set_nb_volumes(num_cells); + this->set_nb_vertices(num_vertices); + + for (auto vit = triangulation.finite_vertices_begin(), vend = triangulation.finite_vertices_end(); vit != vend; ++vit) + { + const auto& P = vit->point(); + const uint32 id = this->insert_line_vertex_container(); + vertices_indices[vit] = id; + position->operator [](id) = VEC3(SCALAR(P.x()), SCALAR(P.y()), SCALAR(P.z())); + } + + for (auto cit = cpx_.cells_in_complex_begin(), cend = cpx_.cells_in_complex_end(); cit != cend; ++cit) + this->add_tetra(*position, vertices_indices[cit->vertex(0)], vertices_indices[cit->vertex(1)], vertices_indices[cit->vertex(2)], vertices_indices[cit->vertex(3)], true); + + ChunkArray* subdomain_indices = this->volume_attributes_container().template add_chunk_array("subdomain index"); + for (auto cit = cpx_.cells_in_complex_begin(), cend = cpx_.cells_in_complex_end(); cit != cend; ++cit) + { + const uint32 id = this->volume_attributes_container().template insert_lines<1>(); + subdomain_indices->operator [](id) = float32(cpx_.subdomain_index(cit)); + } + + return true; + } private: const C3T3& cpx_; }; -SCHNAPPS_PLUGIN_VMFS_API void import_c3t3(const C3T3& c3t3_in, MapHandler* map_out); -SCHNAPPS_PLUGIN_VMFS_API void tetrahedralize(const MapParameters& param, MapHandler* input_surface_map, const std::string& pos_att_name, MapHandler* output_volume_map); +template +void import_c3t3(const C3T3& c3t3_in, MapHandler* map_out) +{ + if (!map_out) + return; + + C3T3VolumeImport volume_import(c3t3_in); + volume_import.import_file(""); + volume_import.create_map(*map_out->get_map()); + map_out->attribute_added(C3T3VolumeImport::Volume::ORBIT, "subdomain index"); +} + + +SCHNAPPS_PLUGIN_VMFS_API void tetrahedralize(const MeshGeneratorParameters& param, MapHandler* input_surface_map, const CMap2::VertexAttribute& position_attribute, MapHandler* output_volume_map); +SCHNAPPS_PLUGIN_VMFS_API void tetrahedralize(const MeshGeneratorParameters& param, const plugin_image::Image3D* im, MapHandler* output_volume_map); + +template +void tetrahedralize(const MeshGeneratorParameters& param, Domain_& dom, CGAL::Mesh_criteria_3::type>& criteria, MapHandler* output_volume_map) +{ + using namespace CGAL::parameters; + using Triangulation_ = typename CGAL::Mesh_triangulation_3::type; + using C3T3_ = typename CGAL::Mesh_complex_3_in_triangulation_3; + + auto c3t3 = CGAL::make_mesh_3(dom, criteria, no_features(), no_perturb(), no_exude(), no_lloyd(), no_odt()); + + if (param.do_lloyd_) + { + CGAL::lloyd_optimize_mesh_3(c3t3, + dom, + time_limit = 0, + max_iteration_number = param.lloyd_max_iter_, + convergence = param.lloyd_convergence_, + freeze_bound = param.lloyd_freeze_bound_, + do_freeze = param.do_lloyd_freeze_); + } + + if (param.do_odt_) + { + CGAL::odt_optimize_mesh_3(c3t3, + dom, + time_limit = 0, + max_iteration_number = param.odt_max_iter_, + convergence = param.odt_convergence_, + freeze_bound = param.odt_freeze_bound_, + do_freeze = param.do_odt_freeze_); + } + + if (param.do_perturber_) + { + CGAL::perturb_mesh_3(c3t3, + dom, + time_limit = 0, + sliver_bound = param.perturber_sliver_bound_); + } + + if (param.do_exuder_) + { + CGAL::exude_mesh_3(c3t3, + time_limit = 0, + sliver_bound = param.exuder_sliver_bound_); + } + + import_c3t3(c3t3,output_volume_map); +} } // namespace plugin_vmfs } // namespace schnapps diff --git a/schnapps/plugins/volume_mesh_from_surface/cgal/cgogn_surface_to_cgal_polyhedron.cpp b/schnapps/plugins/volume_mesh_from_surface/cgal/cgogn_surface_to_cgal_polyhedron.cpp index ad8c82e..aa478e5 100644 --- a/schnapps/plugins/volume_mesh_from_surface/cgal/cgogn_surface_to_cgal_polyhedron.cpp +++ b/schnapps/plugins/volume_mesh_from_surface/cgal/cgogn_surface_to_cgal_polyhedron.cpp @@ -35,24 +35,16 @@ namespace schnapps namespace plugin_vmfs { -PolyhedronBuilder::PolyhedronBuilder(MapHandler* mh, std::string position_att_name) : +PolyhedronBuilder::PolyhedronBuilder(MapHandler* mh, const CMap2::VertexAttribute& position_attribute) : map_(mh), - pos_att_name_(std::move(position_att_name)) + position_attribute_(position_attribute) {} void PolyhedronBuilder::operator()(HalfedgeDS& hds) { - if (!map_) + if (!map_ || !position_attribute_.is_valid()) return; - const auto pos_att = map_->get_attribute(QString::fromStdString(pos_att_name_)); - if (!pos_att.is_valid()) - { - cgogn_log_info("PolyhedronBuilder") << "The position attribute has to be of type VEC3."; - return; - } - - uint32 id{0u}; auto id_attribute = map_->add_attribute("ids_polyhedron_builder"); @@ -64,7 +56,7 @@ void PolyhedronBuilder::operator()(HalfedgeDS& hds) cmap2.foreach_cell([&](CMap2::Vertex v) { - const auto& P = pos_att[v]; + const auto& P = position_attribute_[v]; B.add_vertex((Point(P[0], P[1], P[2]))); }); @@ -83,12 +75,12 @@ void PolyhedronBuilder::operator()(HalfedgeDS& hds) map_->remove_attribute(id_attribute); } -SCHNAPPS_PLUGIN_VMFS_API std::unique_ptr build_polyhedron(MapHandler* mh, const std::string& position_att_name) +SCHNAPPS_PLUGIN_VMFS_API std::unique_ptr> build_polyhedron(MapHandler* mh, const CMap2::VertexAttribute& position_attribute) { - if (!mh) + if (!mh || !position_attribute.is_valid()) return nullptr; - auto poly = cgogn::make_unique(); - PolyhedronBuilder builder(mh, position_att_name); + auto poly = cgogn::make_unique>(); + PolyhedronBuilder builder(mh, position_attribute); poly->delegate(builder); return poly; } diff --git a/schnapps/plugins/volume_mesh_from_surface/cgal/cgogn_surface_to_cgal_polyhedron.h b/schnapps/plugins/volume_mesh_from_surface/cgal/cgogn_surface_to_cgal_polyhedron.h index b9a4960..7aa26f3 100644 --- a/schnapps/plugins/volume_mesh_from_surface/cgal/cgogn_surface_to_cgal_polyhedron.h +++ b/schnapps/plugins/volume_mesh_from_surface/cgal/cgogn_surface_to_cgal_polyhedron.h @@ -28,7 +28,8 @@ #include "dll.h" #include #include -#include "types.h" +#include +#include namespace schnapps { @@ -36,20 +37,22 @@ namespace schnapps namespace plugin_vmfs { -class SCHNAPPS_PLUGIN_VMFS_API PolyhedronBuilder : public CGAL::Modifier_base { +class SCHNAPPS_PLUGIN_VMFS_API PolyhedronBuilder : public CGAL::Modifier_base::HalfedgeDS> { public: - + using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; + using Polyhedron = CGAL::Polyhedron_3 ; + using HalfedgeDS = Polyhedron::HalfedgeDS; using Vertex = typename HalfedgeDS::Vertex; using Point = typename Vertex::Point ; - PolyhedronBuilder(MapHandler* mh, std::string position_att_name); + PolyhedronBuilder(MapHandler* mh, const CMap2::VertexAttribute& position_attribute); void operator()( HalfedgeDS& hds); private: MapHandler* map_; - std::string pos_att_name_; + const CMap2::VertexAttribute position_attribute_; }; -SCHNAPPS_PLUGIN_VMFS_API std::unique_ptr build_polyhedron(MapHandler* mh, const std::string& position_att_name); +SCHNAPPS_PLUGIN_VMFS_API std::unique_ptr> build_polyhedron(MapHandler* mh, const CMap2::VertexAttribute& position_attribute); } // namespace plugin_vmfs } // namespace schnapps diff --git a/schnapps/plugins/volume_mesh_from_surface/export_dialog.ui b/schnapps/plugins/volume_mesh_from_surface/export_dialog.ui index fb2c3cb..fa527bf 100644 --- a/schnapps/plugins/volume_mesh_from_surface/export_dialog.ui +++ b/schnapps/plugins/volume_mesh_from_surface/export_dialog.ui @@ -6,83 +6,201 @@ 0 0 - 261 - 152 + 270 + 162 Make Mesh - - - - - generate with tetgen - - + + + + + + + + 64 + 0 + + + + boundary + + + + + + + + -select map- + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - - 0 - 0 - - + + - - -select attribute- - + + + + 64 + 0 + + + + position + + - + + + + + -select attribute- + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - generate with cgal + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + or + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 64 + 0 + + + + 3d image + + + + + + + + -select image- + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal - - - - - 64 - 0 - - + + - Surface : + generate with tetgen - - - - - 0 - 0 - + + + + generate with cgal - - - -select map- - - - - - + + + + Qt::Vertical + + - 64 - 0 + 20 + 40 - - Position : - - + diff --git a/schnapps/plugins/volume_mesh_from_surface/tetgen/predicates.cxx b/schnapps/plugins/volume_mesh_from_surface/tetgen/predicates.cxx index 33817d7..b1f5b00 100644 --- a/schnapps/plugins/volume_mesh_from_surface/tetgen/predicates.cxx +++ b/schnapps/plugins/volume_mesh_from_surface/tetgen/predicates.cxx @@ -125,6 +125,11 @@ #include "tetgen.h" // Defines the symbol REAL (float or double). + +namespace tetgen +{ + + #ifdef USE_CGAL_PREDICATES #include typedef CGAL::Exact_predicates_inexact_constructions_kernel cgalEpick; @@ -4702,5 +4707,5 @@ REAL orient4d(REAL* pa, REAL* pb, REAL* pc, REAL* pd, REAL* pe, aheight, bheight, cheight, dheight, eheight, permanent); } - +} // namespace tetgen diff --git a/schnapps/plugins/volume_mesh_from_surface/tetgen/tetgen.cxx b/schnapps/plugins/volume_mesh_from_surface/tetgen/tetgen.cxx index 4f26e87..e0c83ab 100644 --- a/schnapps/plugins/volume_mesh_from_surface/tetgen/tetgen.cxx +++ b/schnapps/plugins/volume_mesh_from_surface/tetgen/tetgen.cxx @@ -34,6 +34,9 @@ // // /////////////////////////////////////////////////////////////////////////////// +namespace tetgen +{ + bool tetgenio::load_node_call(FILE* infile, int markers, int uvflag, char* infilename) { @@ -31243,6 +31246,8 @@ void tetrahedralize(const char *switches, tetgenio *in, tetgenio *out, #endif // not TETLIBRARY } +} // namespace tetgen + //// //// //// //// //// main_cxx ///////////////////////////////////////////////////////////////// diff --git a/schnapps/plugins/volume_mesh_from_surface/tetgen/tetgen.h b/schnapps/plugins/volume_mesh_from_surface/tetgen/tetgen.h index 16c4b66..ecd72be 100644 --- a/schnapps/plugins/volume_mesh_from_surface/tetgen/tetgen.h +++ b/schnapps/plugins/volume_mesh_from_surface/tetgen/tetgen.h @@ -113,6 +113,9 @@ // // /////////////////////////////////////////////////////////////////////////////// +namespace tetgen +{ + class tetgenio { public: @@ -3331,6 +3334,7 @@ inline REAL tetgenmesh::norm2(REAL x, REAL y, REAL z) return (x) * (x) + (y) * (y) + (z) * (z); } +} // namespace tetgen #endif // #ifndef tetgenH diff --git a/schnapps/plugins/volume_mesh_from_surface/tetgen_structure_io.cpp b/schnapps/plugins/volume_mesh_from_surface/tetgen_structure_io.cpp index 5bd2d39..2a8e33d 100644 --- a/schnapps/plugins/volume_mesh_from_surface/tetgen_structure_io.cpp +++ b/schnapps/plugins/volume_mesh_from_surface/tetgen_structure_io.cpp @@ -25,6 +25,7 @@ #define SCHNAPPS_PLUGIN_VMFS_DLL_EXPORT #include +#include namespace schnapps { @@ -32,10 +33,11 @@ namespace schnapps namespace plugin_vmfs { -SCHNAPPS_PLUGIN_VMFS_API std::unique_ptr export_tetgen(CMap2& map, const CMap2::VertexAttribute& pos) +SCHNAPPS_PLUGIN_VMFS_API std::unique_ptr export_tetgen(CMap2& map, const CMap2::VertexAttribute& pos) { using Vertex = typename CMap2::Vertex; using Face = typename CMap2::Face; + using tetgenio = tetgen::tetgenio; using TetgenReal = REAL; map.compact_embedding(Vertex::ORBIT); diff --git a/schnapps/plugins/volume_mesh_from_surface/tetgen_structure_io.h b/schnapps/plugins/volume_mesh_from_surface/tetgen_structure_io.h index db5ae5e..e07e143 100644 --- a/schnapps/plugins/volume_mesh_from_surface/tetgen_structure_io.h +++ b/schnapps/plugins/volume_mesh_from_surface/tetgen_structure_io.h @@ -27,10 +27,14 @@ #include "dll.h" #include -#include #include #include + +namespace tetgen +{ +class tetgenio; +} namespace schnapps { @@ -45,6 +49,7 @@ class SCHNAPPS_PLUGIN_VMFS_API TetgenStructureVolumeImport : public cgogn::io::V using Scalar = typename cgogn::geometry::vector_traits::Scalar; template using ChunkArray = typename Inherit::template ChunkArray; + using tetgenio = tetgen::tetgenio; explicit TetgenStructureVolumeImport(tetgenio * tetgen_output); CGOGN_NOT_COPYABLE_NOR_MOVABLE(TetgenStructureVolumeImport); @@ -56,7 +61,7 @@ class SCHNAPPS_PLUGIN_VMFS_API TetgenStructureVolumeImport : public cgogn::io::V tetgenio* volume_; }; -SCHNAPPS_PLUGIN_VMFS_API std::unique_ptr export_tetgen(CMap2& map, const CMap2::VertexAttribute& pos); +SCHNAPPS_PLUGIN_VMFS_API std::unique_ptr export_tetgen(CMap2& map, const CMap2::VertexAttribute& pos); } // namespace plugin_vmfs } // namespace schnapps diff --git a/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface.cpp b/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface.cpp index 196a550..7760dd5 100644 --- a/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface.cpp +++ b/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface.cpp @@ -33,6 +33,8 @@ #ifdef PLUGIN_VMFS_WITH_CGAL #include #endif // PLUGIN_VMFS_WITH_CGAL +#include +#include namespace schnapps { @@ -40,7 +42,7 @@ namespace schnapps namespace plugin_vmfs { -MapParameters::MapParameters() : +MeshGeneratorParameters::MeshGeneratorParameters() : tetgen_command_line("-pqY"), cell_size_(8), cell_radius_edge_ratio_(3), @@ -63,8 +65,18 @@ MapParameters::MapParameters() : exuder_sliver_bound_(0) {} +Plugin_VolumeMeshFromSurface::Plugin_VolumeMeshFromSurface() : + gen_mesh_action_(nullptr), + plugin_image_(nullptr), + generation_parameters_(), + dialog_(nullptr) +{} + bool Plugin_VolumeMeshFromSurface::enable() { + connect(schnapps_, SIGNAL(plugin_enabled(Plugin*)), this, SLOT(plugin_enabled(Plugin*))); + connect(schnapps_, SIGNAL(plugin_disabled(Plugin*)), this, SLOT(plugin_disabled(Plugin*))); + if (!dialog_) dialog_ = cgogn::make_unique(schnapps_, this); @@ -76,6 +88,13 @@ bool Plugin_VolumeMeshFromSurface::enable() dialog_->map_added(mhg); }); + Plugin* image_plugin_gen = schnapps_->get_plugin("image"); + plugin_enabled(image_plugin_gen); + + if (plugin_image_) + for (const auto& im : plugin_image_->get_images()) + dialog_->image_added(im.first); + return true; } @@ -86,7 +105,7 @@ void Plugin_VolumeMeshFromSurface::disable() void Plugin_VolumeMeshFromSurface::generate_button_tetgen_pressed() { - MapHandlerGen* mhg = schnapps_->get_map(selected_map_); + MapHandlerGen* mhg = schnapps_->get_map(dialog_->get_selected_map()); MapHandler2* handler_map2 = dynamic_cast(mhg); if (handler_map2) { @@ -99,43 +118,118 @@ void Plugin_VolumeMeshFromSurface::generate_button_tetgen_pressed() cgogn_log_info("Plugin_VolumeMeshFromSurface") << "The position attribute has to be of type VEC3."; return; } - auto tetgen_input = export_tetgen(*map, position_att); - tetgenio tetgen_output; + const std::string& tetgen_command_line = generation_parameters_.tetgen_command_line; + generate_tetgen(handler_map2, position_att, tetgen_command_line.c_str()); + } +} - tetrahedralize(this->tetgen_args.toStdString().c_str(), tetgen_input.get(), &tetgen_output); +Plugin_VolumeMeshFromSurface::MapHandler3* Plugin_VolumeMeshFromSurface::generate_tetgen(MapHandler2* mh2, CMap2::Attribute position_att, const std::string& tetgen_args) +{ + if (!mh2 || !position_att.is_valid()) + return nullptr; - TetgenStructureVolumeImport tetgen_import(&tetgen_output); - tetgen_import.import_file(""); + Map2* map = mh2->get_map(); - MapHandler3* handler_map3 = dynamic_cast(schnapps_->add_map("tetgen_export", 3)); - tetgen_import.create_map(*handler_map3->get_map()); - } + auto tetgen_input = export_tetgen(*map, position_att); + tetgen::tetgenio tetgen_output; + + tetgen::tetrahedralize(tetgen_args.c_str(), tetgen_input.get(), &tetgen_output); + + TetgenStructureVolumeImport tetgen_import(&tetgen_output); + tetgen_import.import_file(""); + + MapHandler3* handler_map3 = dynamic_cast(schnapps_->add_map("tetgen_export", 3)); + tetgen_import.create_map(*handler_map3->get_map()); + + return handler_map3; +} + +Plugin_VolumeMeshFromSurface::MapHandler3* Plugin_VolumeMeshFromSurface::generate_cgal(MapHandler2* mh2, CMap2::Attribute position_att, const MeshGeneratorParameters& params) +{ +#ifdef PLUGIN_VMFS_WITH_CGAL + if (!mh2 || !position_att.is_valid()) + return nullptr; + + MapHandler3* mh3 = dynamic_cast(schnapps_->add_map("cgal_export", 3)); + tetrahedralize(params, mh2, position_att, mh3); + return mh3; +#else + return nullptr; +#endif // PLUGIN_VMFS_WITH_CGAL +} + +Plugin_VolumeMeshFromSurface::MapHandler3* Plugin_VolumeMeshFromSurface::generate_cgal(const plugin_image::Image3D* im, const MeshGeneratorParameters& params) +{ +#ifdef PLUGIN_VMFS_WITH_CGAL + if (!im) + return nullptr; + MapHandler3* mh3 = dynamic_cast(schnapps_->add_map("cgal_image_export", 3)); + tetrahedralize(params, im, mh3); + return mh3; +#else + return nullptr; +#endif // PLUGIN_VMFS_WITH_CGAL } void Plugin_VolumeMeshFromSurface::generate_button_cgal_pressed() { #ifdef PLUGIN_VMFS_WITH_CGAL - MapHandlerGen* mhg = schnapps_->get_map(selected_map_); + MapHandlerGen* mhg = schnapps_->get_map(dialog_->get_selected_map()); if (mhg) { - const MapParameters& param = this->parameter_set_[mhg]; MapHandler2* mh2 = dynamic_cast(mhg); - MapHandler3* mh3 = dynamic_cast(schnapps_->add_map("cgal_export", 3)); const std::string& position_att_name = dialog_->export_dialog_->comboBoxPositionSelection->currentText().toStdString(); - tetrahedralize(param, mh2, position_att_name, mh3); + auto position_att = mh2->template get_attribute(QString::fromStdString(position_att_name)); + generate_cgal(mh2, position_att, generation_parameters_); + + } else { + if (dialog_->export_dialog_->comboBox_images->currentIndex() > 0) + { + const QString& im_path = dialog_->export_dialog_->comboBox_images->currentText(); + if (plugin_image_) + { + plugin_image::Image3D const * im = plugin_image_->get_image(im_path); + if (im) + { + generate_cgal(im, generation_parameters_); + } + } + } } #endif // PLUGIN_VMFS_WITH_CGAL } -void Plugin_VolumeMeshFromSurface::tetgen_args_updated(QString str) +void Plugin_VolumeMeshFromSurface::plugin_enabled(Plugin* plugin) { - this->tetgen_args = std::move(str); + if (!plugin_image_) + { + plugin_image_ = dynamic_cast(plugin); + if (plugin_image_) + { + connect(plugin_image_, SIGNAL(image_added(QString)), dialog_.get(), SLOT(image_added(QString))); + connect(plugin_image_, SIGNAL(image_removed(QString)), dialog_.get(), SLOT(image_removed(QString))); + } + } } -void Plugin_VolumeMeshFromSurface::remove_map(MapHandlerGen* mhg) +void Plugin_VolumeMeshFromSurface::plugin_disabled(Plugin* plugin) { - this->parameter_set_.erase(mhg); + if (plugin_image_) + { + if (plugin_image_ == plugin) + { + disconnect(plugin_image_, SIGNAL(image_added(QString)), dialog_.get(), SLOT(image_added(QString))); + disconnect(plugin_image_, SIGNAL(image_removed(QString)), dialog_.get(), SLOT(image_removed(QString))); + plugin_image_ = nullptr; + + for(int i = 1, size = dialog_->export_dialog_->comboBox_images->count(); i < size; ++i) + { + dialog_->export_dialog_->comboBox_images->removeItem(i); + } + } + } } + } // namespace plugin_vmfs } // namespace schnapps diff --git a/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface.h b/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface.h index bea9016..56412f6 100644 --- a/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface.h +++ b/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface.h @@ -28,17 +28,26 @@ #include "dll.h" #include #include -#include namespace schnapps { +class MapHandlerGen; +template +class MapHandler; + +namespace plugin_image +{ +class Plugin_Image; +class Image3D; +} // namespace plugin_image + namespace plugin_vmfs { class Plugin_VolumeMeshFromSurface; -struct SCHNAPPS_PLUGIN_VMFS_API MapParameters +struct SCHNAPPS_PLUGIN_VMFS_API MeshGeneratorParameters { friend class Plugin_VolumeMeshFromSurface; @@ -67,7 +76,7 @@ struct SCHNAPPS_PLUGIN_VMFS_API MapParameters bool do_exuder_; float64 exuder_sliver_bound_; - MapParameters(); + MeshGeneratorParameters(); }; class SCHNAPPS_PLUGIN_VMFS_API Plugin_VolumeMeshFromSurface : public PluginProcessing @@ -83,21 +92,26 @@ class SCHNAPPS_PLUGIN_VMFS_API Plugin_VolumeMeshFromSurface : public PluginProce using MapHandler2 = schnapps::MapHandler; using MapHandler3 = schnapps::MapHandler; + Plugin_VolumeMeshFromSurface(); + + MapHandler3* generate_tetgen(MapHandler2* mh2, CMap2::Attribute position_att, const std::string& tetgen_args); + MapHandler3* generate_cgal(MapHandler2* mh2, CMap2::Attribute position_att, const MeshGeneratorParameters& params); + MapHandler3* generate_cgal(plugin_image::Image3D const * im, const MeshGeneratorParameters& params); + private: virtual bool enable() override; virtual void disable() override; QAction* gen_mesh_action_; - std::map parameter_set_; + plugin_image::Plugin_Image* plugin_image_; + MeshGeneratorParameters generation_parameters_; std::unique_ptr dialog_; - QString tetgen_args; - QString selected_map_; public slots: void generate_button_tetgen_pressed(); void generate_button_cgal_pressed(); - void tetgen_args_updated(QString str); - void remove_map(MapHandlerGen*); + void plugin_enabled(Plugin*); + void plugin_disabled(Plugin*); }; } // namespace plugin_vmfs diff --git a/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface_dialog.cpp b/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface_dialog.cpp index 21300fd..ca83d55 100644 --- a/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface_dialog.cpp +++ b/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface_dialog.cpp @@ -28,6 +28,7 @@ #include #include #include +#include "image.h" namespace schnapps { @@ -57,7 +58,7 @@ VolumeMeshFromSurfaceDialog::VolumeMeshFromSurfaceDialog(SCHNApps* s, Plugin_Vol connect(this->tetgen_dialog_->buttonBox,SIGNAL(accepted()), plugin_, SLOT(generate_button_tetgen_pressed())); connect(this->cgal_dialog_->buttonBox, SIGNAL(accepted()), plugin_, SLOT(generate_button_cgal_pressed())); - connect(this->tetgen_dialog_->lineEdit_tetgen_args, SIGNAL(textChanged(QString)), plugin_, SLOT(tetgen_args_updated(QString))); + connect(this->tetgen_dialog_->lineEdit_tetgen_args, SIGNAL(textChanged(QString)), this, SLOT(tetgen_args_updated(QString))); connect(this->cgal_dialog_->doubleSpinBox_CellSize, SIGNAL(valueChanged(double)), this, SLOT(cell_size_changed(double))); connect(this->cgal_dialog_->doubleSpinBox_Radius, SIGNAL(valueChanged(double)), this, SLOT(cell_radius_edge_ratio_changed(double))); @@ -86,6 +87,10 @@ VolumeMeshFromSurfaceDialog::VolumeMeshFromSurfaceDialog(SCHNApps* s, Plugin_Vol connect(schnapps_, SIGNAL(map_added(MapHandlerGen*)), this, SLOT(map_added(MapHandlerGen*))); connect(schnapps_, SIGNAL(map_removed(MapHandlerGen*)), this, SLOT(map_removed(MapHandlerGen*))); + connect(this->export_dialog_->comboBox_images, SIGNAL(currentIndexChanged(QString)), this, SLOT(selected_image_changed(QString))); + + update_mesh_generatuion_ui(); + this->export_dialog_->pushButton_gen_volume_meshTetgen->setDisabled(true); this->export_dialog_->pushButtonGenMeshCGAL->setDisabled(true); @@ -105,11 +110,22 @@ void VolumeMeshFromSurfaceDialog::map_added(MapHandlerGen* mhg) void VolumeMeshFromSurfaceDialog::map_removed(MapHandlerGen* mhg) { if (mhg && dynamic_cast*>(mhg)) - { this->export_dialog_->comboBoxMapSelection->removeItem(this->export_dialog_->comboBoxMapSelection->findText(mhg->get_name())); - plugin_->remove_map(mhg); - } +} +void VolumeMeshFromSurfaceDialog::image_added(QString im_path) +{ + this->export_dialog_->comboBox_images->addItem(im_path); +} + +void VolumeMeshFromSurfaceDialog::image_removed(QString im_path) +{ + this->export_dialog_->comboBox_images->removeItem(this->export_dialog_->comboBox_images->findText(im_path)); +} + +QString VolumeMeshFromSurfaceDialog::get_selected_map() const +{ + return export_dialog_->comboBoxMapSelection->currentText(); } void VolumeMeshFromSurfaceDialog::selected_map_changed(QString map_name) @@ -118,53 +134,61 @@ void VolumeMeshFromSurfaceDialog::selected_map_changed(QString map_name) if (mhg && dynamic_cast*>(mhg)) { - const MapParameters& p = plugin_->parameter_set_[mhg]; - update_map_parameters(mhg, p); - plugin_->selected_map_ = mhg->get_name(); + this->export_dialog_->comboBox_images->setCurrentIndex(0); this->export_dialog_->pushButton_gen_volume_meshTetgen->setDisabled(false); this->export_dialog_->pushButtonGenMeshCGAL->setDisabled(false); + this->export_dialog_->comboBoxPositionSelection->clear(); const auto& vert_att_cont = mhg->const_attribute_container(CellType::Vertex_Cell); for (const auto& att_name : vert_att_cont.names()) this->export_dialog_->comboBoxPositionSelection->addItem(QString::fromStdString(att_name)); } else { - plugin_->selected_map_ = QString(); this->export_dialog_->pushButton_gen_volume_meshTetgen->setDisabled(true); this->export_dialog_->pushButtonGenMeshCGAL->setDisabled(true); } } +void VolumeMeshFromSurfaceDialog::selected_image_changed(QString /*image_name*/) +{ + this->export_dialog_->comboBoxMapSelection->setCurrentIndex(0); + if (this->export_dialog_->comboBox_images->currentIndex() >= 1) + { + this->export_dialog_->pushButton_gen_volume_meshTetgen->setDisabled(true); + this->export_dialog_->pushButtonGenMeshCGAL->setDisabled(false); + } +} + void VolumeMeshFromSurfaceDialog::cell_size_changed(double cs) { - plugin_->parameter_set_[schnapps_->get_selected_map()].cell_size_ = cs; + plugin_->generation_parameters_.cell_size_ = cs; } void VolumeMeshFromSurfaceDialog::cell_radius_edge_ratio_changed(double ratio) { - plugin_->parameter_set_[schnapps_->get_selected_map()].cell_radius_edge_ratio_ = ratio; + plugin_->generation_parameters_.cell_radius_edge_ratio_ = ratio; } void VolumeMeshFromSurfaceDialog::facet_angle_changed(double fa) { - plugin_->parameter_set_[schnapps_->get_selected_map()].facet_angle_ = fa; + plugin_->generation_parameters_.facet_angle_ = fa; } void VolumeMeshFromSurfaceDialog::facet_size_changed(double fs) { - plugin_->parameter_set_[schnapps_->get_selected_map()].facet_size_ = fs; + plugin_->generation_parameters_.facet_size_ = fs; } void VolumeMeshFromSurfaceDialog::facet_distance_changed(double fd) { - plugin_->parameter_set_[schnapps_->get_selected_map()].facet_distance_ = fd; + plugin_->generation_parameters_.facet_distance_ = fd; } void VolumeMeshFromSurfaceDialog::odt_changed(bool b) { - plugin_->parameter_set_[schnapps_->get_selected_map()].do_odt_ = b; + plugin_->generation_parameters_.do_odt_ = b; this->cgal_dialog_->doubleSpinBox_OdtConvergence->setDisabled(!b); this->cgal_dialog_->spinBox_ODTMaxIter->setDisabled(!b); this->cgal_dialog_->checkBox_FreezeODT->setDisabled(!b); @@ -173,28 +197,28 @@ void VolumeMeshFromSurfaceDialog::odt_changed(bool b) void VolumeMeshFromSurfaceDialog::odt_freeze_changed(bool b) { - plugin_->parameter_set_[schnapps_->get_selected_map()].do_odt_freeze_ = b; + plugin_->generation_parameters_.do_odt_freeze_ = b; this->cgal_dialog_->doubleSpinBox_8OdtFreeze->setDisabled(!b); } void VolumeMeshFromSurfaceDialog::odt_max_iter_changed(int nb_it) { - plugin_->parameter_set_[schnapps_->get_selected_map()].odt_max_iter_ = nb_it; + plugin_->generation_parameters_.odt_max_iter_ = nb_it; } void VolumeMeshFromSurfaceDialog::odt_convergence_changed(double cv) { - plugin_->parameter_set_[schnapps_->get_selected_map()].odt_convergence_ = cv; + plugin_->generation_parameters_.odt_convergence_ = cv; } void VolumeMeshFromSurfaceDialog::odt_freeze_bound_changed(double fb) { - plugin_->parameter_set_[schnapps_->get_selected_map()].odt_freeze_bound_ = fb; + plugin_->generation_parameters_.odt_freeze_bound_ = fb; } void VolumeMeshFromSurfaceDialog::lloyd_changed(bool b) { - plugin_->parameter_set_[schnapps_->get_selected_map()].do_lloyd_ = b; + plugin_->generation_parameters_.do_lloyd_ = b; this->cgal_dialog_->doubleSpinBox_FreezeBoundLLoyd->setDisabled(!b); this->cgal_dialog_->doubleSpinBox_ConvergenceLloyd->setDisabled(!b); this->cgal_dialog_->spinBoxMaxITLloyd->setDisabled(!b); @@ -203,90 +227,97 @@ void VolumeMeshFromSurfaceDialog::lloyd_changed(bool b) void VolumeMeshFromSurfaceDialog::lloyd_freeze_changed(bool b) { - plugin_->parameter_set_[schnapps_->get_selected_map()].do_lloyd_freeze_ = b; + plugin_->generation_parameters_.do_lloyd_freeze_ = b; this->cgal_dialog_->doubleSpinBox_FreezeBoundLLoyd->setDisabled(!b); } void VolumeMeshFromSurfaceDialog::lloyd_max_iter_changed(int nb_it) { - plugin_->parameter_set_[schnapps_->get_selected_map()].lloyd_max_iter_ = nb_it; + plugin_->generation_parameters_.lloyd_max_iter_ = nb_it; } void VolumeMeshFromSurfaceDialog::lloyd_convergence_changed(double cv) { - plugin_->parameter_set_[schnapps_->get_selected_map()].lloyd_convergence_ = cv; + plugin_->generation_parameters_.lloyd_convergence_ = cv; } void VolumeMeshFromSurfaceDialog::lloyd_freeze_bound_changed(double fb) { - plugin_->parameter_set_[schnapps_->get_selected_map()].lloyd_freeze_bound_ = fb; + plugin_->generation_parameters_.lloyd_freeze_bound_ = fb; } void VolumeMeshFromSurfaceDialog::perturber_changed(bool b) { this->cgal_dialog_->doubleSpinBox_PerturberSliver->setDisabled(!b); - plugin_->parameter_set_[schnapps_->get_selected_map()].do_perturber_ = b; + plugin_->generation_parameters_.do_perturber_ = b; } void VolumeMeshFromSurfaceDialog::perturber_sliver_changed(double sb) { - this->cgal_dialog_->doubleSpinBox_PerturberSliver->setValue(sb); + plugin_->generation_parameters_.perturber_sliver_bound_ = sb; } void VolumeMeshFromSurfaceDialog::exuder_changed(bool b) { this->cgal_dialog_->doubleSpinBox_ExuderSliver->setDisabled(!b); - plugin_->parameter_set_[schnapps_->get_selected_map()].do_exuder_ = b; + plugin_->generation_parameters_.do_exuder_ = b; } void VolumeMeshFromSurfaceDialog::exuder_sliver_changed(double sb) { - this->cgal_dialog_->doubleSpinBox_ExuderSliver->setValue(sb); + plugin_->generation_parameters_.exuder_sliver_bound_ = sb; +} + +void VolumeMeshFromSurfaceDialog::tetgen_args_updated(QString str) +{ + + plugin_->generation_parameters_.tetgen_command_line = str.toStdString(); } -void VolumeMeshFromSurfaceDialog::update_map_parameters(MapHandlerGen* map, const MapParameters& p) +void VolumeMeshFromSurfaceDialog::update_mesh_generatuion_ui() { updating_ui_ = true; - if (map && dynamic_cast*>(map)) - { - plugin_->tetgen_args_updated(QString::fromStdString(p.tetgen_command_line)); - - this->cgal_dialog_->doubleSpinBox_CellSize->setValue(p.cell_size_); - this->cgal_dialog_->doubleSpinBox_Radius->setValue(p.cell_radius_edge_ratio_); - this->cgal_dialog_->doubleSpinBoxFacetAngle->setValue(p.facet_angle_); - this->cgal_dialog_->doubleSpinBox_FacetSize->setValue(p.facet_size_); - this->cgal_dialog_->doubleSpinBox_3FacetDistance->setValue(p.facet_distance_); - - this->cgal_dialog_->checkBox_ODT->setChecked(p.do_odt_); - this->cgal_dialog_->checkBox_FreezeODT->setChecked(p.do_odt_freeze_); - this->cgal_dialog_->spinBox_ODTMaxIter->setValue(p.odt_max_iter_); - this->cgal_dialog_->doubleSpinBox_OdtConvergence->setValue(p.odt_convergence_); - this->cgal_dialog_->doubleSpinBox_8OdtFreeze->setValue(p.odt_freeze_bound_); - this->cgal_dialog_->doubleSpinBox_OdtConvergence->setDisabled(!p.do_odt_); - this->cgal_dialog_->spinBox_ODTMaxIter->setDisabled(!p.do_odt_); - this->cgal_dialog_->checkBox_FreezeODT->setDisabled(!p.do_odt_); - this->cgal_dialog_->checkBox_ODT->setDisabled(!p.do_odt_); - - this->cgal_dialog_->checkBoxLloyd->setChecked(p.do_lloyd_); - this->cgal_dialog_->checkBox_FreezeLloyd->setChecked(p.do_lloyd_freeze_); - this->cgal_dialog_->spinBoxMaxITLloyd->setValue(p.lloyd_max_iter_); - this->cgal_dialog_->doubleSpinBox_ConvergenceLloyd->setValue(p.lloyd_convergence_); - this->cgal_dialog_->doubleSpinBox_FreezeBoundLLoyd->setValue(p.lloyd_freeze_bound_); - this->cgal_dialog_->doubleSpinBox_FreezeBoundLLoyd->setDisabled(!p.do_lloyd_); - this->cgal_dialog_->doubleSpinBox_ConvergenceLloyd->setDisabled(!p.do_lloyd_); - this->cgal_dialog_->spinBoxMaxITLloyd->setDisabled(!p.do_lloyd_); - this->cgal_dialog_->checkBox_FreezeLloyd->setDisabled(!p.do_lloyd_); - - this->cgal_dialog_->checkBox_Perturber->setChecked(p.do_perturber_); - this->cgal_dialog_->doubleSpinBox_PerturberSliver->setValue(p.perturber_sliver_bound_); - this->cgal_dialog_->doubleSpinBox_PerturberSliver->setDisabled(!p.do_perturber_); - - this->cgal_dialog_->checkBox_5Exuder->setChecked(p.do_exuder_); - this->cgal_dialog_->doubleSpinBox_ExuderSliver->setValue(p.exuder_sliver_bound_); - this->cgal_dialog_->doubleSpinBox_ExuderSliver->setDisabled(!p.do_exuder_); - } + + const auto& p = plugin_->generation_parameters_; + this->tetgen_dialog_->lineEdit_tetgen_args->setText(QString::fromStdString(p.tetgen_command_line)); + + this->cgal_dialog_->doubleSpinBox_CellSize->setValue(p.cell_size_); + this->cgal_dialog_->doubleSpinBox_Radius->setValue(p.cell_radius_edge_ratio_); + this->cgal_dialog_->doubleSpinBoxFacetAngle->setValue(p.facet_angle_); + this->cgal_dialog_->doubleSpinBox_FacetSize->setValue(p.facet_size_); + this->cgal_dialog_->doubleSpinBox_3FacetDistance->setValue(p.facet_distance_); + + this->cgal_dialog_->checkBox_ODT->setChecked(p.do_odt_); + this->cgal_dialog_->checkBox_FreezeODT->setChecked(p.do_odt_freeze_); + this->cgal_dialog_->spinBox_ODTMaxIter->setValue(p.odt_max_iter_); + this->cgal_dialog_->doubleSpinBox_OdtConvergence->setValue(p.odt_convergence_); + this->cgal_dialog_->doubleSpinBox_8OdtFreeze->setValue(p.odt_freeze_bound_); + this->cgal_dialog_->doubleSpinBox_OdtConvergence->setDisabled(!p.do_odt_); + this->cgal_dialog_->spinBox_ODTMaxIter->setDisabled(!p.do_odt_); + this->cgal_dialog_->checkBox_FreezeODT->setDisabled(!p.do_odt_); + this->cgal_dialog_->checkBox_ODT->setDisabled(!p.do_odt_); + + this->cgal_dialog_->checkBoxLloyd->setChecked(p.do_lloyd_); + this->cgal_dialog_->checkBox_FreezeLloyd->setChecked(p.do_lloyd_freeze_); + this->cgal_dialog_->spinBoxMaxITLloyd->setValue(p.lloyd_max_iter_); + this->cgal_dialog_->doubleSpinBox_ConvergenceLloyd->setValue(p.lloyd_convergence_); + this->cgal_dialog_->doubleSpinBox_FreezeBoundLLoyd->setValue(p.lloyd_freeze_bound_); + this->cgal_dialog_->doubleSpinBox_FreezeBoundLLoyd->setDisabled(!p.do_lloyd_); + this->cgal_dialog_->doubleSpinBox_ConvergenceLloyd->setDisabled(!p.do_lloyd_); + this->cgal_dialog_->spinBoxMaxITLloyd->setDisabled(!p.do_lloyd_); + this->cgal_dialog_->checkBox_FreezeLloyd->setDisabled(!p.do_lloyd_); + + this->cgal_dialog_->checkBox_Perturber->setChecked(p.do_perturber_); + this->cgal_dialog_->doubleSpinBox_PerturberSliver->setValue(p.perturber_sliver_bound_); + this->cgal_dialog_->doubleSpinBox_PerturberSliver->setDisabled(!p.do_perturber_); + + this->cgal_dialog_->checkBox_5Exuder->setChecked(p.do_exuder_); + this->cgal_dialog_->doubleSpinBox_ExuderSliver->setValue(p.exuder_sliver_bound_); + this->cgal_dialog_->doubleSpinBox_ExuderSliver->setDisabled(!p.do_exuder_); + updating_ui_ = false; } + } // namespace plugin_vmfs } // namespace schnapps diff --git a/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface_dialog.h b/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface_dialog.h index d0ce464..285ff71 100644 --- a/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface_dialog.h +++ b/schnapps/plugins/volume_mesh_from_surface/volume_mesh_from_surface_dialog.h @@ -40,7 +40,7 @@ namespace plugin_vmfs { class Plugin_VolumeMeshFromSurface; -struct MapParameters; +struct MeshGeneratorParameters; class SCHNAPPS_PLUGIN_VMFS_API ExportDialog : public QDialog, public Ui::Dialog_export {}; @@ -72,6 +72,7 @@ public slots: private slots: void selected_map_changed(QString map_name); + void selected_image_changed(QString image_name); void cell_size_changed(double cs); void cell_radius_edge_ratio_changed(double ratio); @@ -98,12 +99,19 @@ private slots: void map_added(MapHandlerGen* mhg); void map_removed(MapHandlerGen* mhg); + + void image_added(QString im_path); + void image_removed(QString im_path); + void tetgen_args_updated(QString str); + private: - void update_map_parameters(MapHandlerGen* map, const MapParameters& p); + QString get_selected_map() const ; + void update_mesh_generatuion_ui(); std::unique_ptr cgal_dialog_; std::unique_ptr tetgen_dialog_; std::unique_ptr export_dialog_; + }; } // namespace plugin_vmfs