{ "info": { "author": "Nico Schl\u00f6mer", "author_email": "nico.schloemer@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering", "Topic :: Scientific/Engineering :: Mathematics", "Topic :: Scientific/Engineering :: Physics", "Topic :: Scientific/Engineering :: Visualization" ], "description": "

\n \"pygalmesh\"\n

Create high-quality 3D meshes with ease.

\n

\n\n[![CircleCI](https://img.shields.io/circleci/project/github/nschloe/pygalmesh/master.svg?style=flat-square)](https://circleci.com/gh/nschloe/pygalmesh/tree/master)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square)](https://github.com/psf/black)\n[![PyPi Version](https://img.shields.io/pypi/v/pygalmesh.svg?style=flat-square)](https://pypi.org/project/pygalmesh)\n[![GitHub stars](https://img.shields.io/github/stars/nschloe/pygalmesh.svg?style=flat-square&label=Stars&logo=github)](https://github.com/nschloe/pygalmesh)\n[![PyPi downloads](https://img.shields.io/pypi/dd/pygalmesh.svg?style=flat-square)](https://pypistats.org/packages/pygalmesh)\n\npygalmesh is a Python frontend to [CGAL](https://www.cgal.org/)'s [3D mesh generation\ncapabilities](https://doc.cgal.org/latest/Mesh_3/index.html).\npygalmesh makes it easy to create high-quality 3D volume meshes, periodic volume meshes,\nand surface meshes.\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### Examples\n\n#### A simple ball\n\n\n```python\nimport pygalmesh\n\ns = pygalmesh.Ball([0, 0, 0], 1.0)\nmesh = pygalmesh.generate_mesh(s, cell_size=0.2)\n\n# mesh.points, mesh.cells, ...\n```\nYou can write the mesh using [meshio](https://github.com/nschloe/meshio), e.g.,\n```python\nimport meshio\nmeshio.write(\"out.vtk\", mesh)\n```\nThe mesh generation comes with many more options, described\n[here](https://doc.cgal.org/latest/Mesh_3/). Try, for example,\n```python\nmesh = pygalmesh.generate_mesh(\n s,\n cell_size=0.2,\n edge_size=0.1,\n odt=True,\n lloyd=True,\n verbose=False\n)\n```\n\n#### Other primitive shapes\n\n\npygalmesh provides out-of-the-box support for balls, cuboids, ellipsoids, tori, cones,\ncylinders, and tetrahedra. Try for example\n```python\nimport pygalmesh\n\ns0 = pygalmesh.Tetrahedron(\n [0.0, 0.0, 0.0],\n [1.0, 0.0, 0.0],\n [0.0, 1.0, 0.0],\n [0.0, 0.0, 1.0]\n)\nmesh = pygalmesh.generate_mesh(s0, cell_size=0.1, edge_size=0.1)\n```\n\n#### Domain combinations\n\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```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```\nTo sharpen the intersection circle, add it as a feature edge polygon line, e.g.,\n```python\na = numpy.sqrt(radius**2 - displacement**2)\nedge_size = 0.15\nn = int(2*numpy.pi*a / edge_size)\ncirc = [\n [\n 0.0,\n a * numpy.cos(i * 2*numpy.pi / n),\n a * numpy.sin(i * 2*numpy.pi / n)\n ] for i in range(n)\n ]\ncirc.append(circ[0])\n\nmesh = pygalmesh.generate_mesh(\n u,\n feature_edges=[circ],\n cell_size=0.15,\n edge_size=edge_size,\n facet_angle=25,\n facet_size=0.15,\n cell_radius_edge_ratio=2.0\n)\n```\nNote that the length of the polygon legs are kept in sync with the `edge_size` of the\nmesh generation. This makes sure that it fits in nicely with the rest of the mesh.\n\n#### Domain deformations\n\n\nYou can of course translate, rotate, scale, and stretch any domain. Try, for example,\n```python\nimport pygalmesh\n\ns = pygalmesh.Stretch(\n pygalmesh.Ball([0, 0, 0], 1.0),\n [1.0, 2.0, 0.0]\n)\n\nmesh = pygalmesh.generate_mesh(s, cell_size=0.1)\n```\n\n#### Extrusion of 2D polygons\n\n\npygalmesh lets you extrude any polygon into a 3D body. It even supports rotation\nalongside!\n```python\nimport pygalmesh\n\np = pygalmesh.Polygon2D([[-0.5, -0.3], [0.5, -0.3], [0.0, 0.5]])\nedge_size = 0.1\ndomain = pygalmesh.Extrude(\n p,\n [0.0, 0.0, 1.0],\n 0.5 * 3.14159265359,\n edge_size\n)\nmesh = pygalmesh.generate_mesh(\n domain,\n cell_size=0.1,\n edge_size=edge_size,\n verbose=False\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\nPolygons in the x-z-plane can also be rotated around the z-axis to yield a rotation\nbody.\n```python\nimport pygalmesh\n\np = pygalmesh.Polygon2D([[0.5, -0.3], [1.5, -0.3], [1.0, 0.5]])\nedge_size = 0.1\ndomain = pygalmesh.RingExtrude(p, edge_size)\nmesh = pygalmesh.generate_mesh(\n domain,\n cell_size=0.1,\n edge_size=edge_size,\n verbose=False\n)\n```\n\n#### Your own custom level set function\n\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```python\nimport pygalmesh\nclass Heart(pygalmesh.DomainBase):\n def __init__(self):\n super(Heart, self).__init__()\n return\n\n def eval(self, x):\n return (x[0]**2 + 9.0/4.0 * x[1]**2 + x[2]**2 - 1)**3 \\\n - x[0]**2 * x[2]**3 - 9.0/80.0 * x[1]**2 * x[2]**3\n\n def get_bounding_sphere_squared_radius(self):\n return 10.0\n\nd = Heart()\nmesh = pygalmesh.generate_mesh(d, cell_size=0.1)\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\n#### Local refinement\n\n\nIf you want to have local refinement, you can use\n`generate_with_sizing_field`. It works just like `generate_mesh` except that it takes a\n`SizingFieldBase` object as `cell_size`.\n```python\n# define a cell_size function\nclass Field(pygalmesh.SizingFieldBase):\n def eval(self, x):\n return abs(numpy.sqrt(numpy.dot(x, x)) - 0.5) / 5 + 0.025\n\nmesh = pygalmesh.generate_with_sizing_field(\n pygalmesh.Ball([0.0, 0.0, 0.0], 1.0),\n facet_angle=30,\n facet_size=0.1,\n facet_distance=0.025,\n cell_radius_edge_ratio=2,\n cell_size=Field(),\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, `cell_size` is gone), but otherwise works the\nsame way:\n```python\nimport pygalmesh\n\ns = pygalmesh.Ball([0, 0, 0], 1.0)\nmesh = pygalmesh.generate_surface_mesh(\n s,\n angle_bound=30,\n radius_bound=0.1,\n distance_bound=0.1\n)\n```\nRefer to [CGAL's\ndocumention](https://doc.cgal.org/latest/Surface_mesher/index.html) for the\noptions.\n\n#### Periodic volume meshes\n\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```python\nimport pygalmesh\n\nclass Schwarz(pygalmesh.DomainBase):\n def __init__(self):\n super(Schwarz, self).__init__()\n return\n\n def eval(self, x):\n x2 = numpy.cos(x[0] * 2 * numpy.pi)\n y2 = numpy.cos(x[1] * 2 * numpy.pi)\n z2 = numpy.cos(x[2] * 2 * numpy.pi)\n return x2 + y2 + z2\n\nmesh = pygalmesh.generate_periodic_mesh(\n Schwarz(),\n [0, 0, 0, 1, 1, 1],\n cell_size=0.05,\n facet_angle=30,\n facet_size=0.05,\n facet_distance=0.025,\n cell_radius_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\nIf you have a surface mesh at hand (like\n[elephant.vtu](http://nschloe.github.io/pygalmesh/elephant.vtu)), pygalmesh generates a\nvolume mesh on the command line via\n```\npygalmesh-volume-from-surface elephant.vtu out.vtk --cell-size 1.0 --odt\n```\n(See `pygalmesh-volume-from-surface -h` for all options.)\n\nIn Python, do\n```python\nimport pygalmesh\n\nmesh = pygalmesh.generate_volume_mesh_from_surface_mesh(\n \"elephant.vtu\",\n facet_angle=25.0,\n facet_size=0.15,\n facet_distance=0.008,\n cell_radius_edge_ratio=3.0,\n verbose=False\n)\n```\n\n#### Meshes from INR voxel files\n\n\nIt is also possible to generate meshes from INR voxel files, e.g.,\n[liver.inr](https://github.com/nschloe/pygalmesh/raw/gh-pages/liver.inr)\neither on the command line\n```\npygalmesh-from-inr liver.inr out.vtu --cell-size 5.0 --odt\n```\n(see `pygalmesh-from-inr -h` for all options) or from Python\n```python\nimport pygalmesh\n\nmesh = pygalmesh.generate_from_inr(\n \"liver.inr\",\n cell_size=5.0,\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```\nsudo apt install libcgal-dev libeigen3-dev\n```\nAfter that, pygalmesh can be [installed from the Python Package\nIndex](https://pypi.org/project/pygalmesh/), so with\n```\npip3 install -U pygalmesh\n```\nyou can install/upgrade.\n\n[meshio](https://github.com/nschloe/meshio) (`pip3 install meshio`)\ncan be helpful in processing the meshes.\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\n /path/to/sources/` and `make`.\n\n### Testing\n\nTo run the pygalmesh unit tests, check out this repository and type\n```\npytest\n```\n\n### License\n\npygalmesh is published under the [MIT license](https://en.wikipedia.org/wiki/MIT_License).", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/nschloe/pygalmesh", "keywords": "", "license": "License :: OSI Approved :: MIT License", "maintainer": "", "maintainer_email": "", "name": "pygalmesh", "package_url": "https://pypi.org/project/pygalmesh/", "platform": "", "project_url": "https://pypi.org/project/pygalmesh/", "project_urls": { "Homepage": "https://github.com/nschloe/pygalmesh" }, "release_url": "https://pypi.org/project/pygalmesh/0.4.0/", "requires_dist": null, "requires_python": ">=3", "summary": "Python frontend to CGAL's 3D mesh generation capabilities", "version": "0.4.0" }, "last_serial": 5657591, "releases": { "0.2.1": [ { "comment_text": "", "digests": { "md5": "d2d19170724f7fc4dc0f78006647628a", "sha256": "0af933f1c168297784a8a903a5b273e527c4274c540e4bc1d246884ad21c8223" }, "downloads": -1, "filename": "pygalmesh-0.2.1.tar.gz", "has_sig": true, "md5_digest": "d2d19170724f7fc4dc0f78006647628a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22580, "upload_time": "2018-02-15T20:59:38", "url": "https://files.pythonhosted.org/packages/57/f4/7edd5dab6e9f1a8a1a6145935c51f3732f86839f3496e4f03f65a829ee2d/pygalmesh-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "d9b40edead46f07f35c4cf6598515723", "sha256": "97d89f06ec0a574a85b50f3a72e4f358dfe6c3a5c207639723dcde194f8cd0ee" }, "downloads": -1, "filename": "pygalmesh-0.2.2.tar.gz", "has_sig": true, "md5_digest": "d9b40edead46f07f35c4cf6598515723", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23080, "upload_time": "2018-03-02T13:34:08", "url": "https://files.pythonhosted.org/packages/88/f1/3bf5a01847983ff7737dc0c9615b82fe69feed70c59f536912577461a59f/pygalmesh-0.2.2.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "85990b18e388823871c6f68529b51984", "sha256": "af9f41648c7fa07e0fed45f7ebd0f514173d3861557271bfea32eab0a8fde17e" }, "downloads": -1, "filename": "pygalmesh-0.2.3.tar.gz", "has_sig": false, "md5_digest": "85990b18e388823871c6f68529b51984", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22238, "upload_time": "2018-03-28T10:00:19", "url": "https://files.pythonhosted.org/packages/0c/32/00393f6b26a410520bf35128b2a9a5902d21c0c31dd0fbfb91812dc251cd/pygalmesh-0.2.3.tar.gz" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "37576f1c8a5aa49633abea16a8e26e28", "sha256": "7953ae07f729911ffee6fb6877641d08c256c34c9314876687b66b3b7f4b4d7e" }, "downloads": -1, "filename": "pygalmesh-0.2.4.tar.gz", "has_sig": false, "md5_digest": "37576f1c8a5aa49633abea16a8e26e28", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21916, "upload_time": "2018-03-28T12:42:04", "url": "https://files.pythonhosted.org/packages/f5/46/b711c1b55d5ca12918a5b3c148db54f6b077008bb6d70ad3dbaf4219c68c/pygalmesh-0.2.4.tar.gz" } ], "0.2.5": [ { "comment_text": "", "digests": { "md5": "30a9844b9ce12c33f579fb3f326eff49", "sha256": "a138d60c2af3e18f421282353cf366d0abcefa8ac0d8e28cdccbba5629b3b119" }, "downloads": -1, "filename": "pygalmesh-0.2.5.tar.gz", "has_sig": false, "md5_digest": "30a9844b9ce12c33f579fb3f326eff49", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22049, "upload_time": "2018-05-20T13:09:45", "url": "https://files.pythonhosted.org/packages/3d/dd/172337d9473dc1b8779838fadf2142a0aa1275fa95155b3a95f985150714/pygalmesh-0.2.5.tar.gz" } ], "0.2.6": [ { "comment_text": "", "digests": { "md5": "fbaa597bf49531c4b267c3087cbe73a2", "sha256": "4546ffe2f81e8c7c4435c694f33c28a61b5a1291fbb6d80555e531da7b456a7f" }, "downloads": -1, "filename": "pygalmesh-0.2.6.tar.gz", "has_sig": false, "md5_digest": "fbaa597bf49531c4b267c3087cbe73a2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21730, "upload_time": "2018-10-08T09:15:48", "url": "https://files.pythonhosted.org/packages/5d/06/17023b1d0375bfceca68e3f88c9a529081e4dd179ce8678b279898a1102e/pygalmesh-0.2.6.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "e1a2002f4449ecca7188d998679dd40a", "sha256": "898b7a30553e7c3d81cc96d295b4b77ccb3e3ebb2e07c36c5117c46c84cce6f4" }, "downloads": -1, "filename": "pygalmesh-0.3.0.tar.gz", "has_sig": false, "md5_digest": "e1a2002f4449ecca7188d998679dd40a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18622, "upload_time": "2019-03-25T11:10:43", "url": "https://files.pythonhosted.org/packages/71/d9/813665ba90b00874a425092e89834ef999bec7719debca63b693fa1ec537/pygalmesh-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "b6ca4fc7fbbc54584430d6e3721dbeb2", "sha256": "2baf6e530852e1293d962f2e47e78822a12c1bf60c60d819b70a8aed3cba5164" }, "downloads": -1, "filename": "pygalmesh-0.3.1.tar.gz", "has_sig": false, "md5_digest": "b6ca4fc7fbbc54584430d6e3721dbeb2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20778, "upload_time": "2019-04-23T14:54:12", "url": "https://files.pythonhosted.org/packages/2b/2e/798619e00ae2a2634ab226f146c24b115e53a6dafac9428a1f14672df349/pygalmesh-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "f04fcad8ce0dabfb5e642ed441a72f8e", "sha256": "377b801888aa35e026ace9c123d9bec64c7ea44aa42dcbeb7a2226aa4c981ef4" }, "downloads": -1, "filename": "pygalmesh-0.3.2.tar.gz", "has_sig": false, "md5_digest": "f04fcad8ce0dabfb5e642ed441a72f8e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20845, "upload_time": "2019-04-29T08:32:46", "url": "https://files.pythonhosted.org/packages/4e/8b/88cd82fcfd017d2e70325ae58cd70fe3963db22c6213fde1465c88c13947/pygalmesh-0.3.2.tar.gz" } ], "0.3.3": [ { "comment_text": "", "digests": { "md5": "2861ff4390bec8786f8cfc8cd9504b56", "sha256": "8a9b7b3e9349db1629ec8c627e4b1102bf46f88ae16c2cd7458e6267fab78a03" }, "downloads": -1, "filename": "pygalmesh-0.3.3.tar.gz", "has_sig": false, "md5_digest": "2861ff4390bec8786f8cfc8cd9504b56", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21768, "upload_time": "2019-05-06T07:49:30", "url": "https://files.pythonhosted.org/packages/7f/a3/752e5f059e2745a9d0ee9f65a1f88de8ae6419d854b8bcd6bae38394aa4c/pygalmesh-0.3.3.tar.gz" } ], "0.3.5": [ { "comment_text": "", "digests": { "md5": "e20bba571c351cf79b77db268b4ddffd", "sha256": "acfa0caba3f66d195f7c4a41f823535daa3bc78eafb0d7a8f74332ba10defce1" }, "downloads": -1, "filename": "pygalmesh-0.3.5.tar.gz", "has_sig": false, "md5_digest": "e20bba571c351cf79b77db268b4ddffd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22579, "upload_time": "2019-05-17T08:26:58", "url": "https://files.pythonhosted.org/packages/17/5e/71285e9c6bf5d18e102eff014daf66f97f236de3041e4257b53982f18221/pygalmesh-0.3.5.tar.gz" } ], "0.3.6": [ { "comment_text": "", "digests": { "md5": "3cc585bd13494859b8fe08b59d0369ad", "sha256": "a86dde7ef0bae7e8726b17a1a72459879409abeb940554a6888f95938a22d55b" }, "downloads": -1, "filename": "pygalmesh-0.3.6.tar.gz", "has_sig": false, "md5_digest": "3cc585bd13494859b8fe08b59d0369ad", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22617, "upload_time": "2019-07-10T17:45:42", "url": "https://files.pythonhosted.org/packages/4e/13/aaa7cecd775040d95eaae6e32cb32b7b8dc6dbc08adc950c0bb5fba7bdf9/pygalmesh-0.3.6.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "e01eec7110a84eba0477ddafe3d8b5d5", "sha256": "6a51dacba362c5fa3ee2c7975500b116ad470a77d15c079d6a07a4a343878ecf" }, "downloads": -1, "filename": "pygalmesh-0.4.0.tar.gz", "has_sig": false, "md5_digest": "e01eec7110a84eba0477ddafe3d8b5d5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 23919, "upload_time": "2019-08-09T20:08:30", "url": "https://files.pythonhosted.org/packages/78/75/a9c03fa76890ec2f1eab766d144493f691e846cf76e17fd17c9464dbcf7e/pygalmesh-0.4.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e01eec7110a84eba0477ddafe3d8b5d5", "sha256": "6a51dacba362c5fa3ee2c7975500b116ad470a77d15c079d6a07a4a343878ecf" }, "downloads": -1, "filename": "pygalmesh-0.4.0.tar.gz", "has_sig": false, "md5_digest": "e01eec7110a84eba0477ddafe3d8b5d5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3", "size": 23919, "upload_time": "2019-08-09T20:08:30", "url": "https://files.pythonhosted.org/packages/78/75/a9c03fa76890ec2f1eab766d144493f691e846cf76e17fd17c9464dbcf7e/pygalmesh-0.4.0.tar.gz" } ] }