Skip to Content.
Sympa Menu

cgal-discuss - Re: [cgal-discuss] 3D surface mesh generation of two implicit spheres

Subject: CGAL users discussion list

List archive

Re: [cgal-discuss] 3D surface mesh generation of two implicit spheres


Chronological Thread 
  • From: "Laurent Rineau (CGAL/GeometryFactory)" <>
  • To:
  • Subject: Re: [cgal-discuss] 3D surface mesh generation of two implicit spheres
  • Date: Tue, 29 Oct 2019 09:35:03 +0100
  • Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None ; spf=SoftFail ; spf=None
  • Ironport-phdr: 9a23:xKGbdBSC1vJgr7G3vRs/GtTrZdpsv+yvbD5Q0YIujvd0So/mwa6zZxyN2/xhgRfzUJnB7Loc0qyK6vumADRYqs/b6TgrS99lb1c9k8IYnggtUoauKHbQC7rUVRE8B9lIT1R//nu2YgB/Ecf6YEDO8DXptWZBUhrwOhBoKevrB4Xck9q41/yo+53Ufg5EmCexbal9IRmrowjdrNQajZd+Jqo+1xfFvGZEcPlKyG11Il6egwzy7dqq8p559CRQtfMh98peXqj/Yq81U79WAik4Pm4s/MHkugXNQgWJ5nsHT2UZiQFIDBTf7BH7RZj+rC33vfdg1SaAPM32Sbc0WSm+76puVRTlhjsLOyI//WrKjMF7kaBVrw+7pxFnw4DafpybOvR9cKPaf9waS2VOUdpeWSFaB4OycpECAvAdMepEsYXwoUYFoxukBQmrAePi0jFEiHns0q0nyeQuDwfG3BA9FNwSsXTUqsv6O70PUeuoyKXF0zTNYu9Q1zvm6YbHbBchofSSUrJsa8rQyUkhGBnZgVWMrozlJTOU2uEDv2OG6OdgUfigi3M9qw5vpDiv2t0gipPIhoIT1F/L7zh5zZ0pKt23UkF7ZcSoEJxKtyGVLoZ7RN4pTW9vuCY/0LIGuJi7cTAMyJs93BHQcPiHfJaS7h3/U+aRJC90hH1keLKjhxay7FOvxvfgWcmz1VZGtjZKktbWuXAJzRDT7dKHSvRl8keuxzmP0AXT5f9YIUAulavbJYQuzaIslpoUq0TCHjX6l1nxjK+TcEgv5+um6/z/b7n7uJORM5V4hhz6P6kqgMCyBeU1PhIBUmSH4eiwyqfv8VD5TblQk/E7kKfUvIrHKckap6O0BRJe3Jw55BalFTim1cwVnXkZI1JBfxKKl47pNE/AIPziE/i/hU+snC1lx/DcJrHhA5PNIWbfkLr5YLpx9UpRxBAuwd1b459YELUMLfPpVkL+qNDUFho5PBa1w+bjBtV9zIQeWWeXD6+dKqzSrEWI6fwpI+mQfoMVojf9K/476PH0kH80gkMSfaaz0psTcny4Ge5mI0qBbXr2ntgBCXsKvhY5TOHylFKCXiRcZ3KrU60h5zE7E56pDZrYRoC2m7GBxye6HphOZm9cEFyMEHHod5+FW/gWci6SLNVhwXQ4Uu2qRIYlkB2vrwTn0KFPL+zO+yReu4iw+sJy4riZsRgv7zFyE4yn0meARnw83kgnbhtx8614pEFh0Eat2KNkhOZJVJYbs/dATx03M4Ka1e18BtnvcgnOd9PPT0ypFIb1SQotR848loddK312HM+v20iag3iaRoQNnrnOP6Qat7rG1iGpdc1ywnKA07Mu3QF/H5l/cFa+j6s6zDD9Qo7El0LAzfSseKpa0SjWsmmZnzLX7RNoFTVoWKCAZkgxI07frND3/ETHFuf8ArsuNk1G08HQcaY=
  • Organization: GeometryFactory

On Monday, October 28, 2019 10:18:15 PM CET Gaetan wrote:
> Hi all,
>
> I want to be able to mesh 3d surfaces from an implicit function representing
> several smooth closed surfaces.
>
> >From what I understand by reading the doc and a previous post
>
> (http://cgal-discuss.949826.n4.nabble.com/About-the-surface-mesh-generator-t
> d952799.html) I need to add one initial sample point for each connected
> component to the initial triangulation.
>
> I did a test with two spheres (inspired from CGAL tests
> @https://github.com/CGAL/cgal/blob/69fad29842b8a3a7316ea478b3a4da3a47d6bf6a/
> Surface_mesher/test/Surface_mesher/implicit_surface_mesher_test.cpp#L138),
> but I can't get the final mesh with both the spheres in it.
>
> <http://cgal-discuss.949826.n4.nabble.com/file/t376135/Capture.png>
>
> Is there something else I need to do after adding the initial points to the
> triangulation or am I doing something wrong?

You are using the Surface_mesh package of CGAL. When using that package, the
initialization is just the insert of a few points in the triangulation. You
were right with that. However, just one point per component is probably not
enough to initialize the Delaunay refinement process.

I have modified your program, and have added eight extra points (four per
sphere), and it was enough. See the attached .cpp file.



--
Laurent Rineau, PhD
R&D Engineer at GeometryFactory http://www.geometryfactory.com/
Release Manager of the CGAL Project http://www.cgal.org/
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh_default_triangulation_3.h>
#include <CGAL/Complex_2_in_triangulation_3.h>
#include <CGAL/make_surface_mesh.h>
#include <CGAL/Implicit_surface_3.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/facets_in_complex_2_to_triangle_mesh.h>

#include <string>
#include <iostream>
#include <fstream>

template <typename K>
class Sphere {
public:
  typedef typename K::FT FT;
  typedef typename K::Point_3 Point_3;
  typedef typename K::Sphere_3 Sphere_3;

  Sphere(Sphere_3 sphere)
    : sphere(sphere)
  {
  }

  FT operator()(const Point_3& p) const
  {
    FT x = p.x();
    FT y = p.y();
    FT z = p.z();
    x-=sphere.center().x();
    y-=sphere.center().y();
    z-=sphere.center().z();
    return x*x+y*y+z*z-sphere.squared_radius();
  }
private:
  const Sphere_3 sphere;
};

template <typename K>
class TwoSpheres 
{
public:
  typedef typename K::FT FT;
  typedef typename K::Point_3 Point_3;
  
  TwoSpheres(Sphere<K> sphere1, Sphere<K> sphere2)
    :  sphere1(sphere1), sphere2(sphere2)
  {
  }

  FT operator()(const Point_3& p) const
  {
    return sphere1(p)*sphere2(p);
  }
private:
  const Sphere<K> sphere1;
  const Sphere<K> sphere2;
};


// Aliases
using Kernel                 =
CGAL::Exact_predicates_inexact_constructions_kernel;
using Sphere_3            = Kernel::Sphere_3;
using Point_3               = Kernel::Point_3;
using FT                      = Kernel::FT;
using Tr                       = CGAL::Surface_mesh_default_triangulation_3;
using C2t3                   = CGAL::Complex_2_in_triangulation_3<Tr>;
using Polyhedron          = CGAL::Polyhedron_3<Kernel>;
using ImplicitSurface_3 = CGAL::Implicit_surface_3<Kernel,TwoSpheres<Kernel>>;


int main() {

  // Construct the spheres
  //  - left  -> center = (-4,0,0), radius = 2
  //  - right -> center = (4, 0,0), radius = 2
  const Sphere<Kernel> sphere_left (Sphere_3(Point_3(-4., 0., 0.), 4.));
  const Sphere<Kernel> sphere_right(Sphere_3(Point_3(4.,  0., 0.), 4.));

  // Assemble the two spheres
  //~ const TwoSpheres<Kernel> two_spheres(sphere_left, sphere_right);
  const TwoSpheres<Kernel> two_spheres(sphere_left, sphere_right);

  // Create the seeds for the 3D-Delaunay triangulation
  //   - one seed per connected component
  const Point_3 point_left (-2,0,0);
  const Point_3 point_right(2,0,0);
  if(two_spheres(point_left) != 0)
    std::cerr << "ERROR: Left seed is not on sphere!" << std::endl;
  if(two_spheres(point_right) != 0)
    std::cerr << "ERROR: Right seed is not on sphere!" << std::endl;

  // Set the 3D-Delaunay triangulation
  Tr tr;
  tr.insert(point_left);
  tr.insert(point_right);
  tr.insert({-4.,  2.,  0.});
  tr.insert({-4., -2.,  0.});
  tr.insert({-4.,  0.,  2.});
  tr.insert({-4.,  0., -2.});
  tr.insert({ 4.,  2.,  0.});
  tr.insert({ 4., -2.,  0.});
  tr.insert({ 4.,  0.,  2.});
  tr.insert({ 4.,  0., -2.});

  // Set the 2D-complex in 3D-Delaunay triangulation
  C2t3 c2t3 (tr);   

  // Define the implicit surface
  const ImplicitSurface_3 surface(two_spheres,
                                                Sphere_3(CGAL::ORIGIN,
100));

  // Define meshing criteria
  const CGAL::Surface_mesh_default_criteria_3<Tr> criteria(30.,  // angular bound
                                                                                       
0.1,  // radius bound
                                                                                       
0.1); // distance bound
  // Mesh surface
  CGAL::make_surface_mesh(c2t3, surface, criteria,
CGAL::Manifold_tag());
  std::cout << "Final number of points: " << tr.number_of_vertices() <<
std::endl;

  // Converts to polyhedron
  Polyhedron output_mesh;
  CGAL::facets_in_complex_2_to_triangle_mesh(c2t3, output_mesh);

  // Save to .off file
  const std::string output_filename = "test.off";
  std::cout << "Write file " << output_filename << std::endl;
  std::ofstream out(output_filename.c_str());
  out << output_mesh;

}



Archive powered by MHonArc 2.6.18.

Top of Page