Subject: CGAL users discussion list
List archive
- 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; }
- [cgal-discuss] 3D surface mesh generation of two implicit spheres, Gaetan, 10/28/2019
- Re: [cgal-discuss] 3D surface mesh generation of two implicit spheres, Laurent Rineau (CGAL/GeometryFactory), 10/29/2019
- Re: [cgal-discuss] 3D surface mesh generation of two implicit spheres, Gaetan, 10/29/2019
- Re: [cgal-discuss] 3D surface mesh generation of two implicit spheres, Laurent Rineau (CGAL/GeometryFactory), 10/29/2019
- Re: [cgal-discuss] 3D surface mesh generation of two implicit spheres, Gaetan, 10/29/2019
- Re: [cgal-discuss] 3D surface mesh generation of two implicit spheres, Laurent Rineau (CGAL/GeometryFactory), 10/29/2019
Archive powered by MHonArc 2.6.18.