Skip to content

Commit

Permalink
Merge pull request #107 from nschloe/better-interface
Browse files Browse the repository at this point in the history
Better interface
  • Loading branch information
nschloe authored Sep 6, 2020
2 parents d1d92ce + 93464e7 commit d7b16bb
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 258 deletions.
41 changes: 0 additions & 41 deletions .circleci/config.yml

This file was deleted.

1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
comment: no
25 changes: 11 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v1
- uses: actions/setup-python@v2
with:
python-version: "3.x"
- uses: actions/checkout@v2
Expand All @@ -20,29 +20,26 @@ jobs:
black --check .
build:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/setup-python@v1
- uses: actions/setup-python@v2
with:
python-version: "3.x"
- uses: actions/checkout@v2
with:
lfs: true
- name: Install dependencies
run: |
sudo apt-get install -y libcgal-dev libeigen3-dev python3-pip clang
- name: install cgal-5 from ppa
- name: Install CGAL 5 from PPA
run: |
sudo apt-get install -y software-properties-common
sudo apt-add-repository -y ppa:nschloe/cgal-backports
sudo apt update
sudo apt install -y libcgal-dev
- name: Install package
- name: Install other dependencies
run: |
CC="clang" pip install .[all]
pip install pytest pytest-cov
- name: Test with pytest
sudo apt-get install -y libeigen3-dev python3-pip clang
- name: Test with tox
run: |
cd test && pytest --cov pygalmesh
# - name: Submit to codecov
# run: bash <(curl -s https://codecov.io/bash)
pip install tox
CC="clang" tox
- name: Submit to codecov
run: bash <(curl -s https://codecov.io/bash)
56 changes: 38 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@

[![PyPi Version](https://img.shields.io/pypi/v/pygalmesh.svg?style=flat-square)](https://pypi.org/project/pygalmesh)
[![Anaconda Cloud](https://anaconda.org/conda-forge/pygalmesh/badges/version.svg?=style=flat-square)](https://anaconda.org/conda-forge/pygalmesh/)
[![Debian CI](https://badges.debian.net/badges/debian/testing/python3-pygalmesh/version.svg?style=flat-square)](https://tracker.debian.org/pkg/python3-pygalmesh)
[![Packaging status](https://repology.org/badge/tiny-repos/pygalmesh.svg)](https://repology.org/project/pygalmesh/versions)
[![PyPI pyversions](https://img.shields.io/pypi/pyversions/pygalmesh.svg?style=flat-square)](https://pypi.org/pypi/pygalmesh/)
[![GitHub stars](https://img.shields.io/github/stars/nschloe/pygalmesh.svg?style=flat-square&label=Stars&logo=github)](https://github.com/nschloe/pygalmesh)
[![PyPi downloads](https://img.shields.io/pypi/dm/pygalmesh.svg?style=flat-square)](https://pypistats.org/packages/pygalmesh)

[![Slack](https://img.shields.io/static/v1?logo=slack&label=chat&message=on%20slack&color=4a154b&style=flat-square)](https://join.slack.com/t/nschloe/shared_invite/zt-cofhrwm8-BgdrXAtVkOjnDmADROKD7A
)

[![CircleCI](https://img.shields.io/circleci/project/github/nschloe/pygalmesh/master.svg?style=flat-square)](https://circleci.com/gh/nschloe/pygalmesh/tree/master)
[![gh-actions](https://img.shields.io/github/workflow/status/nschloe/pygalmesh/ci?style=flat-square)](https://github.com/nschloe/pygalmesh/actions?query=workflow%3Aci)
[![codecov](https://img.shields.io/codecov/c/github/nschloe/pygalmesh.svg?style=flat-square)](https://codecov.io/gh/nschloe/pygalmesh)
[![LGTM](https://img.shields.io/lgtm/grade/python/github/nschloe/pygalmesh.svg?style=flat-square)](https://lgtm.com/projects/g/nschloe/pygalmesh)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square)](https://github.com/psf/black)

Expand Down Expand Up @@ -62,13 +63,15 @@ mesh = pygalmesh.generate_mesh(s, cell_size=0.2)
# mesh.points, mesh.cells, ...
```
You can write the mesh with
<!--exdown-skip-->
```python
mesh.write("out.vtk")
```
You can use any format supported by [meshio](https://github.com/nschloe/meshio).

The mesh generation comes with many more options, described
[here](https://doc.cgal.org/latest/Mesh_3/). Try, for example,
<!--exdown-skip-->
```python
mesh = pygalmesh.generate_mesh(
s, cell_size=0.2, edge_size=0.1, odt=True, lloyd=True, verbose=False
Expand Down Expand Up @@ -106,6 +109,16 @@ u = pygalmesh.Difference(s0, s1)
```
To sharpen the intersection circle, add it as a feature edge polygon line, e.g.,
```python
import numpy
import pygalmesh

radius = 1.0
displacement = 0.5
s0 = pygalmesh.Ball([displacement, 0, 0], radius)
s1 = pygalmesh.Ball([-displacement, 0, 0], radius)
u = pygalmesh.Difference(s0, s1)

# add circle
a = numpy.sqrt(radius ** 2 - displacement ** 2)
edge_size = 0.15
n = int(2 * numpy.pi * a / edge_size)
Expand Down Expand Up @@ -209,17 +222,18 @@ to CGAL's mesh generator.
#### Local refinement
<img src="https://nschloe.github.io/pygalmesh/ball-local-refinement.png" width="30%">

If you want to have local refinement, you can use
`generate_with_sizing_field`. It works just like `generate_mesh` except that it takes a
`SizingFieldBase` object as `cell_size`.
Use `generate_mesh` with a `SizingFieldBase` object as `cell_size`.
```python
import numpy
import pygalmesh

# define a cell_size function
class Field(pygalmesh.SizingFieldBase):
def eval(self, x):
return abs(numpy.sqrt(numpy.dot(x, x)) - 0.5) / 5 + 0.025


mesh = pygalmesh.generate_with_sizing_field(
mesh = pygalmesh.generate_mesh(
pygalmesh.Ball([0.0, 0.0, 0.0], 1.0),
facet_angle=30,
facet_size=0.1,
Expand Down Expand Up @@ -254,6 +268,7 @@ mesh generation](https://doc.cgal.org/latest/Periodic_3_mesh_3/index.html). Besi
domain, one needs to specify a bounding box, and optionally the number of copies in the
output (1, 2, 4, or 8). Example:
```python
import numpy
import pygalmesh


Expand Down Expand Up @@ -295,6 +310,7 @@ pygalmesh-volume-from-surface elephant.vtu out.vtk --cell-size 1.0 --odt
(See `pygalmesh-volume-from-surface -h` for all options.)

In Python, do
<!--exdown-skip-->
```python
import pygalmesh

Expand All @@ -318,6 +334,7 @@ either on the command line
pygalmesh-from-inr skull_2.9.inr out.vtu --cell-size 5.0 --odt
```
(see `pygalmesh-from-inr -h` for all options) or from Python
<!--exdown-skip-->
```python
import pygalmesh

Expand All @@ -328,14 +345,18 @@ mesh = pygalmesh.generate_from_inr(
)
```

## Meshes from numpy array representing 3D images
#### Meshes from numpy arrays representing 3D images
<img src="https://nschloe.github.io/pygalmesh/phantom.png" width="30%">

pygalmesh can help generating unstructed meshes from 3D numpy arrays.

The code below creates a mesh from the 3D breast phantom from [Lou et al](http://biomedicaloptics.spiedigitallibrary.org/article.aspx?articleid=2600985) available [here](https://wustl.app.box.com/s/rqivtin0xcofjwlkz43acou8jknsbfx8/file/127108205145).
The phantom comprises four tissue types (background, fat, fibrograndular, skin, vascular tissues). The generated mesh conforms to tissues interfaces.

The code below creates a mesh from the 3D breast phantom from [Lou et
al](http://biomedicaloptics.spiedigitallibrary.org/article.aspx?articleid=2600985)
available
[here](https://wustl.app.box.com/s/rqivtin0xcofjwlkz43acou8jknsbfx8/file/127108205145).
The phantom comprises four tissue types (background, fat, fibrograndular, skin, vascular
tissues). The generated mesh conforms to tissues interfaces.
<!--exdown-skip-->
```python
import pygalmesh
import meshio
Expand All @@ -350,17 +371,18 @@ with open("MergedPhantom.DAT", "rb") as fid:

vol = vol.reshape((Nx, Ny, Nz))


mesh = pygalmesh.generate_from_array(vol, h, facet_distance=0.2, cell_size=1.0)
mesh.write("breast.vtk")
```

In addition, we can specify different mesh sizes for each tissue type. The code below sets the mesh size to *1 mm* for the skin tissue (label `4`), *0.5 mm* for the vascular tissue (label `5`), and *2 mm* for all other tissues (`default`).
In addition, we can specify different mesh sizes for each tissue type. The code below
sets the mesh size to *1 mm* for the skin tissue (label `4`), *0.5 mm* for the vascular
tissue (label `5`), and *2 mm* for all other tissues (`default`).

<!--exdown-skip-->
```python
cell_sizes_map = {"default": 2.0, 4: 1.0, 5: 0.5}
mesh = pygalmesh.generate_from_array_with_subdomain_sizing(
vol, h, facet_distance=0.2, cell_sizes_map=cell_sizes_map
mesh = pygalmesh.generate_from_array(
vol, h, facet_distance=0.2, cell_size={"default": 2.0, 4: 1.0, 5: 0.5}
)
mesh.write("breast_adapted.vtk")
```
Expand All @@ -377,6 +399,7 @@ the command line, use
pygalmesh-remesh-surface lion-head.off out.vtu -e 0.025 -a 25 -s 0.1 -d 0.001
```
(see `pygalmesh-remesh-surface -h` for all options) or from Python
<!--exdown-skip-->
```python
import pygalmesh

Expand Down Expand Up @@ -406,9 +429,6 @@ pip install -U pygalmesh
```
you can install/upgrade.

[meshio](https://github.com/nschloe/meshio) (`pip install meshio`)
can be helpful in processing the meshes.

#### Manual installation

For manual installation (if you're a developer or just really keen on getting
Expand Down
10 changes: 2 additions & 8 deletions pygalmesh/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,13 @@
from .__about__ import __version__
from .main import (
generate_from_array,
generate_from_array_with_subdomain_sizing,
generate_from_inr,
generate_from_inr_with_subdomain_sizing,
generate_mesh,
generate_periodic_mesh,
generate_surface_mesh,
generate_volume_mesh_from_surface_mesh,
generate_with_sizing_field,
remesh_surface,
saveinr,
save_inr,
)

__all__ = [
Expand Down Expand Up @@ -62,14 +59,11 @@
"RingExtrude",
#
"generate_mesh",
"generate_with_sizing_field",
"generate_periodic_mesh",
"generate_surface_mesh",
"generate_volume_mesh_from_surface_mesh",
"generate_from_array",
"generate_from_array_with_subdomain_sizing",
"generate_from_inr",
"generate_from_inr_with_subdomain_sizing",
"remesh_surface",
"saveinr",
"save_inr",
]
Loading

0 comments on commit d7b16bb

Please sign in to comment.