Skip to content

smooth subdomain separation from labelled images #8417

@juanSilvaHenao

Description

@juanSilvaHenao

Issue Details

Greetings,

I am using mesh_3D_weighted_image_with_detection_of_features.cpp to generate a 3D mesh from a segmented image with several subdomains. The code works without any compilation issues however, the generated meshes seem to have problems separating the different subdomains like it is shown in the image
grafik

I am using feature protection both inside the image and in bbox and also tried using weights. I also tried tuning the facet parameters (reducing facet size and distance) as well as edge length and cell size but nothing does the trick. Is there any way I can guarantee that there is no cell sharing between certain subdomains? Also, is there a way to force two adjacent subdomain to hace separate nodes in the boudary (e.g. for contact simulation)?

I send attached the image file I am trying to mesh as well as my source code, wich is a modified version of mesh_3D_weighted_image_with_detection_of_features.cpp

case_6.zip

Thanks in advance

Source Code

#define CGAL_MESH_3_WEIGHTED_IMAGES_DEBUG
#define CGAL_MESH_3_VERBOSE 1

#include <vtkNew.h>
#include <vtkImageData.h>
#include <vtkNIFTIImageReader.h>
#include <vtkImageReader.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Mesh_triangulation_3.h>
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
#include <CGAL/Mesh_criteria_3.h>
#include <CGAL/Labeled_mesh_domain_3.h>
#include <CGAL/make_mesh_3.h>
#include <CGAL/Image_3.h>
#include <CGAL/IO/read_vtk_image_data.h>
#include <CGAL/IO/output_to_vtu.h>
#include <boost/lexical_cast.hpp>
#include <boost/functional.hpp>
#include <filesystem>
#include "mesh_3D_gray_vtk_image.h"
#include <CGAL/Mesh_domain_with_polyline_features_3.h>
#include <CGAL/Mesh_3/Detect_features_in_image.h>
#include <CGAL/Mesh_3/generate_label_weights.h>
#include <CGAL/Mesh_constant_domain_field_3.h>

//typedef short Image_word_type;

// Domain

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Labeled_mesh_domain_3<K> Image_domain;
typedef CGAL::Mesh_domain_with_polyline_features_3<Image_domain> Mesh_domain;

#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Parallel_tag Concurrency_tag;
#else
typedef CGAL::Sequential_tag Concurrency_tag;
#endif

// Triangulation
typedef CGAL::Mesh_triangulation_3<Mesh_domain, CGAL::Default, Concurrency_tag>::type Tr;
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;

// Criteria
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
typedef CGAL::Mesh_constant_domain_field_3<Mesh_domain::R,
    Mesh_domain::Index> Sizing_field;


namespace params = CGAL::parameters;



namespace fs = std::filesystem;

int main(int argc, char* argv[])
{
    // Loads image
    if (argc < 5) {
        std::cerr << "Usage: " << argv[0] << " <nii in file> <vtu out file> <cell_size> <element_ratio>"
            << std::endl;
        return 1;
    }

    vtkImageData* vtk_image = nullptr;

    fs::path path(argv[1]);

    vtkNIFTIImageReader* reader = vtkNIFTIImageReader::New();
    reader->SetFileName(argv[1]);
    reader->Update();
    vtk_image = reader->GetOutput();
    vtk_image->Print(std::cerr);
    std::cout << ".nii image loaded";

    if (vtk_image == nullptr) {
        std::cout << "No image loaded" << std::endl;
        return 0;
    }
    CGAL::Image_3 image = CGAL::IO::read_vtk_image_data(vtk_image);
    if (image.image() == nullptr) {
        std::cerr << "could not create a CGAL::Image_3 from the vtk image\n";
        return 0;
    }


    /// [Domain creation]
    const float sigma = (std::max)(image.vx(), (std::max)(image.vy(), image.vz()));
    CGAL::Image_3 img_weights = CGAL::Mesh_3::generate_label_weights(image, sigma);

    Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image,
        params::weights = std::ref(img_weights),
        params::value_outside(0.f),
        params::relative_error_bound(1e-10),
        params::features_detector = CGAL::Mesh_3::Detect_features_in_image());
  
    double cell_size = boost::lexical_cast<double>(argv[3]);
    double facet_angle =30;
    double facet_distance = 0.00001 * cell_size;
    double element_ratio = boost::lexical_cast<double>(argv[4]);;
    double min_size = 0.25 * cell_size;  // element_ratio* cell_size; (used for testing only)
    int volume_dimension = 3;



    // Mesh criteria
    Mesh_criteria criteria(params::facet_angle(facet_angle).
        non_manifold().
        facet_size(cell_size).
        facet_min_size(min_size).
        facet_distance(facet_distance).
        edge_size(cell_size).
        edge_min_size(min_size).
        cell_radius_edge_ratio(3).
        cell_size(cell_size).
        cell_min_size(min_size));


    // Meshing
    C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
        params::lloyd(params::time_limit(30)).
        no_perturb().
        no_exude());
    // Output
    std::ofstream file(argv[2]);
    CGAL::IO::output_to_vtu(file, c3t3, CGAL::IO::ASCII);

    return 0;

Environment

  • Operating system (Windows/Mac/Linux, 32/64 bits): Windows 64 bits
  • Compiler: visual studio
  • Release or debug mode: release
  • Specific flags used (if any):
  • CGAL version: 5.6

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions