{"id":13422176,"url":"https://github.com/meshpro/pygalmesh","last_synced_at":"2026-02-20T16:02:11.774Z","repository":{"id":41936857,"uuid":"66091934","full_name":"meshpro/pygalmesh","owner":"meshpro","description":":spider_web: A Python interface to CGAL's meshing tools","archived":false,"fork":false,"pushed_at":"2024-07-22T09:26:24.000Z","size":4389,"stargazers_count":665,"open_issues_count":33,"forks_count":66,"subscribers_count":21,"default_branch":"main","last_synced_at":"2026-02-13T04:00:09.553Z","etag":null,"topics":["cgal","engineering","mathematics","mesh","mesh-generation","meshing","python"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meshpro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-08-19T15:21:39.000Z","updated_at":"2026-02-05T13:54:17.000Z","dependencies_parsed_at":"2024-01-16T21:22:31.764Z","dependency_job_id":"598902e4-7f3f-4a30-96c0-375d7d182d24","html_url":"https://github.com/meshpro/pygalmesh","commit_stats":{"total_commits":548,"total_committers":10,"mean_commits":54.8,"dds":"0.038321167883211715","last_synced_commit":"d1d7873ef572a3c02a2153fb875021a922fc3748"},"previous_names":["nschloe/pygalmesh"],"tags_count":54,"template":false,"template_full_name":null,"purl":"pkg:github/meshpro/pygalmesh","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meshpro%2Fpygalmesh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meshpro%2Fpygalmesh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meshpro%2Fpygalmesh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meshpro%2Fpygalmesh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meshpro","download_url":"https://codeload.github.com/meshpro/pygalmesh/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meshpro%2Fpygalmesh/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29656589,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T09:27:29.698Z","status":"ssl_error","status_checked_at":"2026-02-20T09:26:12.373Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cgal","engineering","mathematics","mesh","mesh-generation","meshing","python"],"created_at":"2024-07-30T23:00:38.552Z","updated_at":"2026-02-20T16:02:11.752Z","avatar_url":"https://github.com/meshpro.png","language":"C++","readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/nschloe/pygalmesh\"\u003e\u003cimg alt=\"pygalmesh\" src=\"https://meshpro.github.io/pygalmesh/pygalmesh-logo.svg\" width=\"60%\"\u003e\u003c/a\u003e\n  \u003cp align=\"center\"\u003eCreate high-quality meshes with ease.\u003c/p\u003e\n\u003c/p\u003e\n\n[![PyPi Version](https://img.shields.io/pypi/v/pygalmesh.svg?style=flat-square)](https://pypi.org/project/pygalmesh)\n[![Anaconda Cloud](https://anaconda.org/conda-forge/pygalmesh/badges/version.svg?=style=flat-square)](https://anaconda.org/conda-forge/pygalmesh/)\n[![Packaging status](https://repology.org/badge/tiny-repos/pygalmesh.svg)](https://repology.org/project/pygalmesh/versions)\n[![PyPI pyversions](https://img.shields.io/pypi/pyversions/pygalmesh.svg?style=flat-square)](https://pypi.org/pypi/pygalmesh/)\n[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.5564818.svg?style=flat-square)](https://doi.org/10.5281/zenodo.5564818)\n[![GitHub stars](https://img.shields.io/github/stars/nschloe/pygalmesh.svg?style=flat-square\u0026label=Stars\u0026logo=github)](https://github.com/nschloe/pygalmesh)\n[![Downloads](https://pepy.tech/badge/pygalmesh/month?style=flat-square)](https://pepy.tech/project/pygalmesh)\n\u003c!--[![PyPi downloads](https://img.shields.io/pypi/dm/pygalmesh.svg?style=flat-square)](https://pypistats.org/packages/pygalmesh)--\u003e\n\n[![Discord](https://img.shields.io/static/v1?logo=discord\u0026label=chat\u0026message=on%20discord\u0026color=7289da\u0026style=flat-square)](https://discord.gg/Z6DMsJh4Hr)\n\n[![gh-actions](https://img.shields.io/github/workflow/status/nschloe/pygalmesh/ci?style=flat-square)](https://github.com/nschloe/pygalmesh/actions?query=workflow%3Aci)\n[![codecov](https://img.shields.io/codecov/c/github/nschloe/pygalmesh.svg?style=flat-square)](https://codecov.io/gh/nschloe/pygalmesh)\n[![LGTM](https://img.shields.io/lgtm/grade/python/github/nschloe/pygalmesh.svg?style=flat-square)](https://lgtm.com/projects/g/nschloe/pygalmesh)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square)](https://github.com/psf/black)\n\npygalmesh is a Python frontend to [CGAL](https://www.cgal.org/)'s\n[2D](https://doc.cgal.org/latest/Mesh_2/index.html) and [3D mesh generation\ncapabilities](https://doc.cgal.org/latest/Mesh_3/index.html). pygalmesh makes it easy\nto create high-quality 2D, 3D volume meshes, periodic volume meshes, and surface meshes.\n\n### Examples\n\n#### 2D meshes\n\n\u003cimg src=\"https://meshpro.github.io/pygalmesh/rect.svg\" width=\"30%\"\u003e\n\nCGAL generates 2D meshes from linear constraints.\n\n```python\nimport numpy as np\nimport pygalmesh\n\npoints = np.array([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]])\nconstraints = [[0, 1], [1, 2], [2, 3], [3, 0]]\n\nmesh = pygalmesh.generate_2d(\n    points,\n    constraints,\n    max_edge_size=1.0e-1,\n    num_lloyd_steps=10,\n)\n# mesh.points, mesh.cells\n```\n\nThe quality of the mesh isn't very good, but can be improved with\n[optimesh](https://github.com/nschloe/optimesh).\n\n#### A simple ball\n\n\u003cimg src=\"https://meshpro.github.io/pygalmesh/ball.png\" width=\"30%\"\u003e\n\n```python\nimport pygalmesh\n\ns = pygalmesh.Ball([0, 0, 0], 1.0)\nmesh = pygalmesh.generate_mesh(s, max_cell_circumradius=0.2)\n\n# mesh.points, mesh.cells, ...\n```\n\nYou can write the mesh with\n\n\u003c!--pytest-codeblocks:skip--\u003e\n\n```python\nmesh.write(\"out.vtk\")\n```\n\nYou can use any format supported by [meshio](https://github.com/nschloe/meshio).\n\nThe mesh generation comes with many more options, described\n[here](https://doc.cgal.org/latest/Mesh_3/). Try, for example,\n\n\u003c!--pytest-codeblocks:skip--\u003e\n\n```python\nmesh = pygalmesh.generate_mesh(\n    s, max_cell_circumradius=0.2, odt=True, lloyd=True, verbose=False\n)\n```\n\n#### Other primitive shapes\n\n\u003cimg src=\"https://meshpro.github.io/pygalmesh/tetra.png\" width=\"30%\"\u003e\n\npygalmesh provides out-of-the-box support for balls, cuboids, ellipsoids, tori, cones,\ncylinders, and tetrahedra. Try for example\n\n```python\nimport pygalmesh\n\ns0 = pygalmesh.Tetrahedron(\n    [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]\n)\nmesh = pygalmesh.generate_mesh(\n    s0,\n    max_cell_circumradius=0.1,\n    max_edge_size_at_feature_edges=0.1,\n)\n```\n\n#### Domain combinations\n\n\u003cimg src=\"https://meshpro.github.io/pygalmesh/ball-difference.png\" width=\"30%\"\u003e\n\nSupported are unions, intersections, and differences of all domains. As mentioned above,\nhowever, the sharp intersections between two domains are not automatically handled. Try\nfor example\n\n```python\nimport pygalmesh\n\nradius = 1.0\ndisplacement = 0.5\ns0 = pygalmesh.Ball([displacement, 0, 0], radius)\ns1 = pygalmesh.Ball([-displacement, 0, 0], radius)\nu = pygalmesh.Difference(s0, s1)\n```\n\nTo sharpen the intersection circle, add it as a feature edge polygon line, e.g.,\n\n```python\nimport numpy as np\nimport pygalmesh\n\nradius = 1.0\ndisplacement = 0.5\ns0 = pygalmesh.Ball([displacement, 0, 0], radius)\ns1 = pygalmesh.Ball([-displacement, 0, 0], radius)\nu = pygalmesh.Difference(s0, s1)\n\n# add circle\na = np.sqrt(radius**2 - displacement**2)\nmax_edge_size_at_feature_edges = 0.15\nn = int(2 * np.pi * a / max_edge_size_at_feature_edges)\nalpha = np.linspace(0.0, 2 * np.pi, n + 1)\nalpha[-1] = alpha[0]\ncirc = a * np.column_stack([np.zeros(n + 1), np.cos(alpha), np.sin(alpha)])\n\nmesh = pygalmesh.generate_mesh(\n    u,\n    extra_feature_edges=[circ],\n    max_cell_circumradius=0.15,\n    max_edge_size_at_feature_edges=max_edge_size_at_feature_edges,\n    min_facet_angle=25,\n    max_radius_surface_delaunay_ball=0.15,\n    max_circumradius_edge_ratio=2.0,\n)\n```\n\nNote that the length of the polygon legs are kept in sync with\n`max_edge_size_at_feature_edges` of the mesh generation. This makes sure that it fits in\nnicely with the rest of the mesh.\n\n#### Domain deformations\n\n\u003cimg src=\"https://meshpro.github.io/pygalmesh/egg.png\" width=\"30%\"\u003e\n\nYou can of course translate, rotate, scale, and stretch any domain. Try, for example,\n\n```python\nimport pygalmesh\n\ns = pygalmesh.Stretch(pygalmesh.Ball([0, 0, 0], 1.0), [1.0, 2.0, 0.0])\n\nmesh = pygalmesh.generate_mesh(s, max_cell_circumradius=0.1)\n```\n\n#### Extrusion of 2D polygons\n\n\u003cimg src=\"https://meshpro.github.io/pygalmesh/triangle-rotated.png\" width=\"30%\"\u003e\n\npygalmesh lets you extrude any polygon into a 3D body. It even supports rotation\nalongside!\n\n```python\nimport pygalmesh\n\np = pygalmesh.Polygon2D([[-0.5, -0.3], [0.5, -0.3], [0.0, 0.5]])\nmax_edge_size_at_feature_edges = 0.1\ndomain = pygalmesh.Extrude(\n    p,\n    [0.0, 0.0, 1.0],\n    0.5 * 3.14159265359,\n    max_edge_size_at_feature_edges,\n)\nmesh = pygalmesh.generate_mesh(\n    domain,\n    max_cell_circumradius=0.1,\n    max_edge_size_at_feature_edges=max_edge_size_at_feature_edges,\n    verbose=False,\n)\n```\n\nFeature edges are automatically preserved here, which is why an edge length needs to be\ngiven to `pygalmesh.Extrude`.\n\n#### Rotation bodies\n\n\u003cimg src=\"https://meshpro.github.io/pygalmesh/circle-rotate-extr.png\" width=\"30%\"\u003e\n\nPolygons in the x-z-plane can also be rotated around the z-axis to yield a rotation\nbody.\n\n```python\nimport pygalmesh\n\np = pygalmesh.Polygon2D([[0.5, -0.3], [1.5, -0.3], [1.0, 0.5]])\nmax_edge_size_at_feature_edges = 0.1\ndomain = pygalmesh.RingExtrude(p, max_edge_size_at_feature_edges)\nmesh = pygalmesh.generate_mesh(\n    domain,\n    max_cell_circumradius=0.1,\n    max_edge_size_at_feature_edges=max_edge_size_at_feature_edges,\n    verbose=False,\n)\n```\n\n#### Your own custom level set function\n\n\u003cimg src=\"https://meshpro.github.io/pygalmesh/heart.png\" width=\"30%\"\u003e\n\nIf all of the variety is not enough for you, you can define your own custom level set\nfunction. You simply need to subclass `pygalmesh.DomainBase` and specify a function,\ne.g.,\n\n```python\nimport pygalmesh\n\n\nclass Heart(pygalmesh.DomainBase):\n    def __init__(self):\n        super().__init__()\n\n    def eval(self, x):\n        return (\n            (x[0] ** 2 + 9.0 / 4.0 * x[1] ** 2 + x[2] ** 2 - 1) ** 3\n            - x[0] ** 2 * x[2] ** 3\n            - 9.0 / 80.0 * x[1] ** 2 * x[2] ** 3\n        )\n\n    def get_bounding_sphere_squared_radius(self):\n        return 10.0\n\n\nd = Heart()\nmesh = pygalmesh.generate_mesh(d, max_cell_circumradius=0.1)\n```\n\nNote that you need to specify the square of a bounding sphere radius, used as an input\nto CGAL's mesh generator.\n\n#### Local refinement\n\n\u003cimg src=\"https://meshpro.github.io/pygalmesh/ball-local-refinement.png\" width=\"30%\"\u003e\n\nUse `generate_mesh` with a function (regular or lambda) as `max_cell_circumradius`. The\nsame goes for `max_edge_size_at_feature_edges`, `max_radius_surface_delaunay_ball`, and\n`max_facet_distance`.\n\n```python\nimport numpy as np\nimport pygalmesh\n\nmesh = pygalmesh.generate_mesh(\n    pygalmesh.Ball([0.0, 0.0, 0.0], 1.0),\n    min_facet_angle=30.0,\n    max_radius_surface_delaunay_ball=0.1,\n    max_facet_distance=0.025,\n    max_circumradius_edge_ratio=2.0,\n    max_cell_circumradius=lambda x: abs(np.sqrt(np.dot(x, x)) - 0.5) / 5 + 0.025,\n)\n```\n\n#### Surface meshes\n\nIf you're only after the surface of a body, pygalmesh has `generate_surface_mesh` for\nyou. It offers fewer options (obviously, `max_cell_circumradius` is gone), but otherwise\nworks the same way:\n\n```python\nimport pygalmesh\n\ns = pygalmesh.Ball([0, 0, 0], 1.0)\nmesh = pygalmesh.generate_surface_mesh(\n    s,\n    min_facet_angle=30.0,\n    max_radius_surface_delaunay_ball=0.1,\n    max_facet_distance=0.1,\n)\n```\n\nRefer to [CGAL's\ndocumentation](https://doc.cgal.org/latest/Surface_mesher/index.html) for the\noptions.\n\n#### Periodic volume meshes\n\n\u003cimg src=\"https://meshpro.github.io/pygalmesh/periodic.png\" width=\"30%\"\u003e\n\npygalmesh also interfaces CGAL's [3D periodic\nmesh generation](https://doc.cgal.org/latest/Periodic_3_mesh_3/index.html). Besides a\ndomain, one needs to specify a bounding box, and optionally the number of copies in the\noutput (1, 2, 4, or 8). Example:\n\n```python\nimport numpy as np\nimport pygalmesh\n\n\nclass Schwarz(pygalmesh.DomainBase):\n    def __init__(self):\n        super().__init__()\n\n    def eval(self, x):\n        x2 = np.cos(x[0] * 2 * np.pi)\n        y2 = np.cos(x[1] * 2 * np.pi)\n        z2 = np.cos(x[2] * 2 * np.pi)\n        return x2 + y2 + z2\n\n\nmesh = pygalmesh.generate_periodic_mesh(\n    Schwarz(),\n    [0, 0, 0, 1, 1, 1],\n    max_cell_circumradius=0.05,\n    min_facet_angle=30,\n    max_radius_surface_delaunay_ball=0.05,\n    max_facet_distance=0.025,\n    max_circumradius_edge_ratio=2.0,\n    number_of_copies_in_output=4,\n    # odt=True,\n    # lloyd=True,\n    verbose=False,\n)\n```\n\n#### Volume meshes from surface meshes\n\n\u003cimg src=\"https://meshpro.github.io/pygalmesh/elephant.png\" width=\"30%\"\u003e\n\nIf you have a surface mesh at hand (like\n[elephant.vtu](http://meshpro.github.io/pygalmesh/elephant.vtu)), pygalmesh generates a\nvolume mesh on the command line via\n\n```\npygalmesh volume-from-surface elephant.vtu out.vtk --cell-size 1.0 --odt\n```\n\n(See `pygalmesh volume-from-surface -h` for all options.)\n\nIn Python, do\n\n\u003c!--pytest-codeblocks:skip--\u003e\n\n```python\nimport pygalmesh\n\nmesh = pygalmesh.generate_volume_mesh_from_surface_mesh(\n    \"elephant.vtu\",\n    min_facet_angle=25.0,\n    max_radius_surface_delaunay_ball=0.15,\n    max_facet_distance=0.008,\n    max_circumradius_edge_ratio=3.0,\n    verbose=False,\n)\n```\n\n#### Meshes from INR voxel files\n\n\u003cimg src=\"https://meshpro.github.io/pygalmesh/liver.png\" width=\"30%\"\u003e\n\nIt is also possible to generate meshes from INR voxel files, e.g.,\n[here](https://github.com/CGAL/cgal/tree/master/Mesh_3/examples/Mesh_3/data) either on\nthe command line\n\n```\npygalmesh from-inr skull_2.9.inr out.vtu --cell-size 5.0 --odt\n```\n\n(see `pygalmesh from-inr -h` for all options) or from Python\n\n\u003c!--pytest-codeblocks:skip--\u003e\n\n```python\nimport pygalmesh\n\nmesh = pygalmesh.generate_from_inr(\n    \"skull_2.9.inr\",\n    max_cell_circumradius=5.0,\n    verbose=False,\n)\n```\n\n#### Meshes from numpy arrays representing 3D images\n\n| \u003cimg src=\"https://meshpro.github.io/pygalmesh/voxel-ball.png\" width=\"70%\"\u003e | \u003cimg src=\"https://meshpro.github.io/pygalmesh/phantom.png\" width=\"70%\"\u003e |\n| :------------------------------------------------------------------------: | :---------------------------------------------------------------------: |\n\npygalmesh can help generating unstructed meshes from 3D numpy int arrays specifying the\nsubdomains. Subdomains with key `0` are not meshed.\n\n```python\nimport pygalmesh\nimport numpy as np\n\nx_ = np.linspace(-1.0, 1.0, 50)\ny_ = np.linspace(-1.0, 1.0, 50)\nz_ = np.linspace(-1.0, 1.0, 50)\nx, y, z = np.meshgrid(x_, y_, z_)\n\nvol = np.empty((50, 50, 50), dtype=np.uint8)\nidx = x**2 + y**2 + z**2 \u003c 0.5**2\nvol[idx] = 1\nvol[~idx] = 0\n\nvoxel_size = (0.1, 0.1, 0.1)\n\nmesh = pygalmesh.generate_from_array(\n    vol, voxel_size, max_facet_distance=0.2, max_cell_circumradius=0.1\n)\nmesh.write(\"ball.vtk\")\n```\n\nThe code below creates a mesh from the 3D breast phantom from [Lou et\nal](http://biomedicaloptics.spiedigitallibrary.org/article.aspx?articleid=2600985)\navailable\n[here](https://wustl.app.box.com/s/rqivtin0xcofjwlkz43acou8jknsbfx8/file/127108205145).\nThe phantom comprises four tissue types (background, fat, fibrograndular, skin, vascular\ntissues). The generated mesh conforms to tissues interfaces.\n\n\u003c!--pytest-codeblocks:skip--\u003e\n\n```python\nimport pygalmesh\nimport meshio\n\nwith open(\"MergedPhantom.DAT\", \"rb\") as fid:\n    vol = np.fromfile(fid, dtype=np.uint8)\n\nvol = vol.reshape((722, 411, 284))\nvoxel_size = (0.2, 0.2, 0.2)\n\nmesh = pygalmesh.generate_from_array(\n    vol, voxel_size, max_facet_distance=0.2, max_cell_circumradius=1.0\n)\nmesh.write(\"breast.vtk\")\n```\n\nIn addition, we can specify different mesh sizes for each tissue type. The code below\nsets the mesh size to _1 mm_ for the skin tissue (label `4`), _0.5 mm_ for the vascular\ntissue (label `5`), and _2 mm_ for all other tissues (`default`).\n\n\u003c!--pytest-codeblocks:skip--\u003e\n\n```python\nmesh = pygalmesh.generate_from_array(\n    vol,\n    voxel_size,\n    max_facet_distance=0.2,\n    max_cell_circumradius={\"default\": 2.0, 4: 1.0, 5: 0.5},\n)\nmesh.write(\"breast_adapted.vtk\")\n```\n\n#### Surface remeshing\n\n| \u003cimg src=\"https://meshpro.github.io/pygalmesh/lion-head0.png\" width=\"100%\"\u003e | \u003cimg src=\"https://meshpro.github.io/pygalmesh/lion-head1.png\" width=\"100%\"\u003e |\n| :-------------------------------------------------------------------------: | :-------------------------------------------------------------------------: |\n\npygalmesh can help remeshing an existing surface mesh, e.g.,\n[`lion-head.off`](https://github.com/nschloe/pygalmesh/raw/gh-pages/lion-head.off). On\nthe command line, use\n\n```\npygalmesh remesh-surface lion-head.off out.vtu -e 0.025 -a 25 -s 0.1 -d 0.001\n```\n\n(see `pygalmesh remesh-surface -h` for all options) or from Python\n\n\u003c!--pytest-codeblocks:skip--\u003e\n\n```python\nimport pygalmesh\n\nmesh = pygalmesh.remesh_surface(\n    \"lion-head.off\",\n    max_edge_size_at_feature_edges=0.025,\n    min_facet_angle=25,\n    max_radius_surface_delaunay_ball=0.1,\n    max_facet_distance=0.001,\n    verbose=False,\n)\n```\n\n### Installation\n\nFor installation, pygalmesh needs [CGAL](https://www.cgal.org/) and\n[Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page) installed on your\nsystem. They are typically available on your Linux distribution, e.g., on\nUbuntu\n\n```\nsudo apt install libcgal-dev libeigen3-dev\n```\n\nOn MacOS with homebrew,\n\n```\nbrew install cgal eigen\n```\n\nAfter that, pygalmesh can be [installed from the Python Package\nIndex](https://pypi.org/project/pygalmesh/), so with\n\n```\npip install -U pygalmesh\n```\n\nyou can install/upgrade.\n\n#### Troubleshooting\n\nIf pygalmesh fails to build due to `fatal error: 'Eigen/Dense' file not found`\nyou will need to create a symbolic link for Eigen to be detected, e.g.\n\n```\ncd /usr/local/include\nsudo ln -sf eigen3/Eigen Eigen\n```\n\nIt's possible that `eigen3` could be in `/usr/include` instead of\n`/usr/local/install`.\n\n#### Manual installation\n\nFor manual installation (if you're a developer or just really keen on getting\nthe bleeding edge version of pygalmesh), there are two possibilities:\n\n- Get the sources, type `python3 setup.py install`. This does the trick\n  most the time.\n- As a fallback, there's a CMake-based installation. Simply go `cmake /path/to/sources/` and `make`.\n\n### Testing\n\nTo run the pygalmesh unit tests, check out this repository and type\n\n```\npytest\n```\n\n### Background\n\nCGAL offers two different approaches for mesh generation:\n\n1. Meshes defined implicitly by level sets of functions.\n2. Meshes defined by a set of bounding planes.\n\npygalmesh provides a front-end to the first approach, which has the following advantages\nand disadvantages:\n\n- All boundary points are guaranteed to be in the level set within any specified\n  residual. This results in smooth curved surfaces.\n- Sharp intersections of subdomains (e.g., in unions or differences of sets) need to be\n  specified manually (via feature edges, see below), which can be tedious.\n\nOn the other hand, the bounding-plane approach (realized by\n[mshr](https://bitbucket.org/fenics-project/mshr)), has the following properties:\n\n- Smooth, curved domains are approximated by a set of bounding planes, resulting in more\n  of less visible edges.\n- Intersections of domains can be computed automatically, so domain unions etc. have\n  sharp edges where they belong.\n\nSee [here](https://github.com/nschloe/awesome-scientific-computing#meshing) for other\nmesh generation tools.\n\n### License\n\nThis software is available under the [GPLv3\nlicense](https://www.gnu.org/licenses/gpl-3.0.en.html) as well as a commercial\nlicense. If you'd like to use this software commercially, please contact the\nauthor.\n","funding_links":[],"categories":["Meshing","Modeling and Meshes"],"sub_categories":["Triangular and tetrahedral meshing"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeshpro%2Fpygalmesh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeshpro%2Fpygalmesh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeshpro%2Fpygalmesh/lists"}