Skip to main content

Outie

Turns each face of a triangle mesh to point out, even when the mesh is open.

Outie is A Simple Method for Correcting Facet Orientations in Polygon Meshes Based on Ray Casting (PDF) by Kenshi Takayama, Alec Jacobson, Ladislav Kavan and Olga Sorkine-Hornung, 2014, ported from libigl's reorient_facets_raycast to Rust and Embree. All credit goes to them and libigl's contributors. For a geometry processing library, use libigl. To only turn faces, outie is small, fast and has wheels for every system.

I personally use it on city massing datasets like Toronto's 3D Massing, drawn by many people in tools that hide which way faces point, and often not closed, so the usual repairs fail. With faces pointing out, a model needs no two-sided materials, and everything just works the way it should.

One mass as published and as each method leaves it, with times

Figure 1. One mass, 29,878 triangles, as published and as each method leaves it, with the time each took.

Method Backfacingness Time
As published 0.5121
trimesh fix_normals 0.4169 0.77 s
libigl orient_outward 0.1991 0.01 s
libigl reorient_facets_raycast, the paper's code 0.0011 31.26 s
outie 0.0011 0.24 s

Table 1. The methods of Figure 1, libigl's and outie's with the same settings.

Use

pip install outie
import outie

# vertices: corner positions, n by 3   [[0, 0, 0], [1, 0, 0], [1, 1, 0], ...]
# faces:    triangles, m by 3          [[0, 2, 1], [0, 3, 2], ...]
faces = outie.reorient(vertices, faces)  # the same faces, each turned to point out

As in libigl's function, faces are triangles, and removing duplicate triangles, which the paper's command does with -u, is left to the caller.

To know which faces turned, the paper's function gives it per face, with the component each was decided with:

flip, component = outie.reorient_facets_raycast(vertices, faces)  # [False, True, ...], [0, 1, ...]
Option Default
facet_wise True Decide each face alone. False decides faces joined by edges together.
use_parity False Count the faces each ray crosses instead of whether it escapes. For closed meshes.
rays_total 100 a face Fewer is faster, see Figure 4.
rays_minimum 10 Rays at least for each component.
seed 0 Repeats the random rays.
outie.measure_backfacingness(vertices, faces)  # the paper's measure: 0 when no face shows its back

Differences from libigl

  • Speed. libigl's function finds every hit along each ray, though the vote uses only the first. Stopping at the first takes its C++ from 26 s to 2.5 s on Figure 1's mass. Outie does that and casts on every core.
  • Names. vertices and faces for libigl's V and F, and component throughout for what the paper, and libigl in places, also call a patch. The options keep libigl's names.
  • Defaults. facet_wise=True, as the paper's results are made. libigl's Python binding defaults to False.

Results

The data is 60 masses from the City of Toronto's 3D Massing, 318 to 49,118 triangles each, in data/.

Six views, fronts red and backs blue

Figure 2. Backfacingness: the share of a mesh, seen from six sides, that shows the backs of faces, blue.

60 masses Backfacingness Time
As published 0.4233 ± 0.1590
outie 0.0140 ± 0.0409 5.0 s
facet_wise=False 0.0233 ± 0.0528 5.5 s
use_parity=True 0.0426 ± 0.0489 26.4 s

Table 2. Apple M1 Max, 10 cores. use_parity=True is slower because each ray counts every face it passes, not just the first it hits.

Every mass before and after

Figure 3. Every mass, as published and after outie. The few left high are mostly floorless masses: the view from beneath sees into them whichever way their faces turn. Seen from above, the worst, at 0.30, falls to 0.07, and the next four to under 0.05.

Backfacingness against time for 1 to 500 rays a face

Figure 4. Rays a face against backfacingness and time, all 60 masses, with rays_minimum=1 so each setting's count is what it says.

Three masses before and after

Figure 5. The three masses outie improves most.

Three masses after outie that stay worst

Figure 6. The three masses outie leaves worst: mostly thin, single-sided parts, where neither way round is better.

The largest mass, whole and cut open

Figure 7. The largest mass, as published and after, whole above and cut open below: faces left inside a model are turned too, though not all of them correctly.

Method

The default outside and inside a closed room, and use_parity=True

Figure 8. How the default and use_parity=True decide. facet_wise=False is Figure 9.

Two masses decided component by component and face by face

Figure 9. facet_wise=False, left of each pair, against the default, right. As the paper found, how well joined faces vote together depends on how a model was built: the first building is joined badly, so one vote turns whole wrong groups, and deciding each face alone is better. The second is built cleanly, so joining works.

Acknowledgements

  • Kenshi Takayama, Alec Jacobson, Ladislav Kavan and Olga Sorkine-Hornung, for the method and its code.
  • libigl, whose code outie ports.
  • Embree, which casts the rays.
  • The City of Toronto. Contains information licensed under the Open Government Licence - Toronto.

Citation

@article{Takayama2014Orientation,
  author  = {Kenshi Takayama and Alec Jacobson and Ladislav Kavan and Olga Sorkine-Hornung},
  title   = {A Simple Method for Correcting Facet Orientations in Polygon Meshes Based on Ray Casting},
  journal = {Journal of Computer Graphics Techniques (JCGT)},
  volume  = {3},
  number  = {4},
  pages   = {53--63},
  year    = {2014}
}

Licence

MPL-2.0, as libigl's. The wheels carry Embree, under Apache-2.0, LICENSE-EMBREE. The paper is under CC BY-ND 3.0, the data under the Open Government Licence - Toronto.

Metadata

Release files for outie 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for outie 0.2.0
File Size Uploaded
outie-0.2.0.tar.gz 89.1 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for outie 0.2.0
File
outie-0.2.0-cp314-cp314t-win_amd64.whl CPython 3.14 CPython 3.14 free-threading Windows x86-64 Details
outie-0.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ x86-64 Details
outie-0.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ ARM64 Details
outie-0.2.0-cp314-cp314t-manylinux_2_28_x86_64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ x86-64 Details
outie-0.2.0-cp314-cp314t-manylinux_2_28_aarch64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ ARM64 Details
outie-0.2.0-cp314-cp314t-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64 Details
outie-0.2.0-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details
outie-0.2.0-cp312-abi3-musllinux_1_2_x86_64.whl CPython 3.12 abi3 Linux musl 1.2+ x86-64 Details
outie-0.2.0-cp312-abi3-musllinux_1_2_aarch64.whl CPython 3.12 abi3 Linux musl 1.2+ ARM64 Details
outie-0.2.0-cp312-abi3-manylinux_2_28_x86_64.whl CPython 3.12 abi3 Linux glibc 2.28+ x86-64 Details
outie-0.2.0-cp312-abi3-manylinux_2_28_aarch64.whl CPython 3.12 abi3 Linux glibc 2.28+ ARM64 Details
outie-0.2.0-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details

Total release size: 41.8 MB

Release files / outie-0.2.0.tar.gz

Download URL outie-0.2.0.tar.gz
Size 89.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9b4ca1c2ff18e6314eb787d504ad5f9e6778974c6743e0e3c71f38f2f0e1e408
BLAKE2b-256 checksum
How to use checksums
4d380cc58b21748e56fbea888cd48ddf6430b83cf146ab0eb0ca6e72a4189eaa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / outie-0.2.0-cp314-cp314t-win_amd64.whl

Download URL outie-0.2.0-cp314-cp314t-win_amd64.whl
Size 1.1 MB
Tags CPython 3.14 CPython 3.14 free-threading Windows x86-64
SHA-256 checksum
How to use checksums
af4f9c95fb23dc4eb89008d454aae5a619013e8a87eadd0cec2390a09498c18c
BLAKE2b-256 checksum
How to use checksums
447885cd41255096d12e123a7d30af6b5e55306eb751239a1785c6f96c953d31
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / outie-0.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl

Download URL outie-0.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl
Size 8.5 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
c4a0a93a22adc18d53c7d1770e700bb1b27728bb9b944bc95935f15ea0b7ecbf
BLAKE2b-256 checksum
How to use checksums
7150692bc25798ca4238d5235fe044748aaf5305640b08537e91228043b50212
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / outie-0.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl

Download URL outie-0.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl
Size 7.4 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ ARM64
SHA-256 checksum
How to use checksums
83cceff33733728641d97b419113ba10f7bfc603a27d0b1abc29745e1cfa7cf3
BLAKE2b-256 checksum
How to use checksums
612e8df9a862fc41495c4ab2bbbaaf701e8d4b06fde93a63a91071040940eb95
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / outie-0.2.0-cp314-cp314t-manylinux_2_28_x86_64.whl

Download URL outie-0.2.0-cp314-cp314t-manylinux_2_28_x86_64.whl
Size 1.8 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
da68413b587677e48a68d54fef01d9cd153dc22acb2867cfee3c1ecc7ce5c38e
BLAKE2b-256 checksum
How to use checksums
ed988b7f11bdf5844caea403153da62ff27841d788171f67b9d5c1ab489ade62
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / outie-0.2.0-cp314-cp314t-manylinux_2_28_aarch64.whl

Download URL outie-0.2.0-cp314-cp314t-manylinux_2_28_aarch64.whl
Size 1.0 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
7a510d82bd6b9593ef7ae8bd0d577aae889a4c913d846f0a0bad8181d515c756
BLAKE2b-256 checksum
How to use checksums
8ffb6ef44b1437ace708b077f044fcc43fec108a20b05a8c6a588c1a0f9aa89d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / outie-0.2.0-cp314-cp314t-macosx_11_0_arm64.whl

Download URL outie-0.2.0-cp314-cp314t-macosx_11_0_arm64.whl
Size 1.0 MB
Tags CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
693c5f8065ef2fcb94b4e70a9d00000d71f15e0360230f02b8c13c4dbed70295
BLAKE2b-256 checksum
How to use checksums
6562c939a8825d12cd5481193a666d433b37caf067a3d1dab3c9153be3796b61
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / outie-0.2.0-cp312-abi3-win_amd64.whl

Download URL outie-0.2.0-cp312-abi3-win_amd64.whl
Size 1.1 MB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
e909c05320bc90a2d49c90e56e4bada976e00174a8b3b55931fae748fa35ff7b
BLAKE2b-256 checksum
How to use checksums
01aaae75cf3cd2524e5e40c293bcda0e1f55fca1a475ea4fa76e487fd2519931
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / outie-0.2.0-cp312-abi3-musllinux_1_2_x86_64.whl

Download URL outie-0.2.0-cp312-abi3-musllinux_1_2_x86_64.whl
Size 8.5 MB
Tags CPython 3.12 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
a2444104cd6628780fe70dc2af6f3c620dd51a3fbe3f23cb9652b6b6a61596a6
BLAKE2b-256 checksum
How to use checksums
c82feeb3b6950b387465f01439173b5fc39a476884c17bbcc4b683d3dd6b8d3c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / outie-0.2.0-cp312-abi3-musllinux_1_2_aarch64.whl

Download URL outie-0.2.0-cp312-abi3-musllinux_1_2_aarch64.whl
Size 7.4 MB
Tags CPython 3.12 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
8ff4dc2d30af8c23c4164a8d0f400094a2f39303f85cd37fdd34d49618be9ed7
BLAKE2b-256 checksum
How to use checksums
65f2ed791c8b5c43eba12d6254c63bd927a71e93e8128d270e9a995549ccbcdd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / outie-0.2.0-cp312-abi3-manylinux_2_28_x86_64.whl

Download URL outie-0.2.0-cp312-abi3-manylinux_2_28_x86_64.whl
Size 1.8 MB
Tags CPython 3.12 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
95c21b4ee702d20b1d44d10660eae9d6aa0cec34bdb656cf760d72b3c1475a5e
BLAKE2b-256 checksum
How to use checksums
f937be61702519c3f2af17e7702aa22713aea66fbce5bfb4aa788d97f6dee234
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / outie-0.2.0-cp312-abi3-manylinux_2_28_aarch64.whl

Download URL outie-0.2.0-cp312-abi3-manylinux_2_28_aarch64.whl
Size 1.0 MB
Tags CPython 3.12 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
191acad8d7fc2ad1c9ba33a7a7a4847a3bd024d1747829ca93c5a900a23344d6
BLAKE2b-256 checksum
How to use checksums
0e76c214d8060893a8efe05109c18cbb2a1e5881fcc9b6a0a5ea0be9b74a21b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / outie-0.2.0-cp312-abi3-macosx_11_0_arm64.whl

Download URL outie-0.2.0-cp312-abi3-macosx_11_0_arm64.whl
Size 1.0 MB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a722e6cd53d73257e0893c0711511565e80da4664a65e2d1a8946c0b203aa1b5
BLAKE2b-256 checksum
How to use checksums
4daff558b4a26ef03d55b0f04ec0794ce5a5150e06193ea8731a5dea71c77fb5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.2

13 release files

0.2.1

13 release files

This release

0.2.0 This release

13 release files

0.1.9

6 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page