CGAL / cgal

The public CGAL repository, see the README below
https://github.com/CGAL/cgal#readme
Other
4.87k stars 1.38k forks source link

the output file *.mesh of make_mesh_3 has duplicated facets #3965

Closed zoelshi closed 5 years ago

zoelshi commented 5 years ago

I do not know exactly why, but I think you can work around that issue with extra parameters ", false, false" to outpout_to_medit, with this patch for example:

--- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain.cpp
+++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_domain.cpp
@@ -72,7 +72,7 @@ int main(int argc, char*argv[])

   // Output
   medit_file.open("out_2.mesh");
-  c3t3.output_to_medit(medit_file);
+  c3t3.output_to_medit(medit_file, false, false);

   return EXIT_SUCCESS;
 }

It still doesn't work. TetGen still tell me that a self-intersection was detected. why are the face indices in *.mesh repeated? repeat

Originally posted by @zoelsherry in https://github.com/CGAL/cgal/issues/3962#issuecomment-496811526

Issue Details

This is an issue following https://github.com/CGAL/cgal/issues/3962#issuecomment-496811526_ above. When I run the example of Mesh_3/mesh_polyhedral_domain.cpp to generate 3D mesh(triangle or tetrahedron), I advert the output mesh in *.mesh file format has duplicated faces. This results in error using TetGen(a software for generating tetrahedral meshes) to remesh the output mesh(*.mesh file format). The figure below shows the duplicated indices in out_2.mesh and the error in TetGen. Besides, here is my input file and output file. input_and_output_file.zip

repeat repeat2

Source Code

#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/Polyhedron_3.h>
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/Polyhedral_mesh_domain_3.h>
#include <CGAL/make_mesh_3.h>
#include <CGAL/refine_mesh_3.h>

#define CGAL_LINKED_WITH_TBB
#define CGAL_CONCURRENT_MESH_3

// Domain
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Polyhedron_3<K> Polyhedron;
typedef CGAL::Polyhedral_mesh_domain_3<Polyhedron, K> 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;
// To avoid verbose function and named parameters call
using namespace CGAL::parameters;
int main(int argc, char*argv[])
{
  const char* fname = (argc>1)?argv[1]:"data/elephant.off";
  // Create input polyhedron
  Polyhedron polyhedron;
  std::ifstream input(fname);
  input >> polyhedron;
  if(input.fail()){
    std::cerr << "Error: Cannot read file " <<  fname << std::endl;
    return EXIT_FAILURE;
  }
  input.close();

  if (!CGAL::is_triangle_mesh(polyhedron)){
    std::cerr << "Input geometry is not triangulated." << std::endl;
    return EXIT_FAILURE;
  }
  // Create domain
  Mesh_domain domain(polyhedron);

  // Mesh criteria (no cell_size set)
  Mesh_criteria criteria(facet_angle=25, facet_size=0.15, facet_distance=0.008,
                         cell_radius_edge_ratio=3);

  // Mesh generation
  C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria, no_perturb(), no_exude());
  // Output
  std::ofstream medit_file("out_1.mesh");
  c3t3.output_to_medit(medit_file);
  medit_file.close();
  // Set tetrahedron size (keep cell_radius_edge_ratio), ignore facets
  Mesh_criteria new_criteria(cell_radius_edge_ratio=3, cell_size=0.03);
  // Mesh refinement (and make the output manifold)
  CGAL::refine_mesh_3(c3t3, domain, new_criteria, manifold());
  // Output
  medit_file.open("out_2.mesh");
  c3t3.output_to_medit(medit_file, false, false);
  return EXIT_SUCCESS;
}

Environment

janetournois commented 5 years ago

Hi @zoelsherry actually, you should use c3t3.output_to_medit(medit_file, true, true) or c3t3.output_to_medit(medit_file, false, true).

You can have a look at the documentation written in CGAL/IO/File_medit.h (see below) and see that the third parameter decides whether facets will be written twice or not.

/**
 * @brief outputs mesh to medit format
 * @param os the stream
 * @param c3t3 the mesh
 * @param rebind if true, labels of cells are rebinded into [1..nb_of_labels]
 * @param show_patches if true, patches are labeled with different labels than
 * cells. If false, each surface facet is written twice, using label of
 * each adjacent cell.
 */
template <class C3T3>
void
output_to_medit(std::ostream& os,
                const C3T3& c3t3,
                bool rebind = false,
                bool show_patches = false)

Can you please confirm it's now ok for you?

Best regards, Jane.

lrineau commented 5 years ago

@zoelsherry I close this issue. Please reopen it if you want to more precision. You can also continue discuss in this issue page even if it is officially closed.