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.1

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.1
File Size Uploaded
outie-0.2.1.tar.gz 89.3 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for outie 0.2.1
File
outie-0.2.1-cp314-cp314t-win_amd64.whl CPython 3.14 CPython 3.14 free-threading Windows x86-64 Details
outie-0.2.1-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.1-cp314-cp314t-musllinux_1_2_aarch64.whl CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ ARM64 Details
outie-0.2.1-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.1-cp314-cp314t-manylinux_2_28_aarch64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ ARM64 Details
outie-0.2.1-cp314-cp314t-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64 Details
outie-0.2.1-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details
outie-0.2.1-cp312-abi3-musllinux_1_2_x86_64.whl CPython 3.12 abi3 Linux musl 1.2+ x86-64 Details
outie-0.2.1-cp312-abi3-musllinux_1_2_aarch64.whl CPython 3.12 abi3 Linux musl 1.2+ ARM64 Details
outie-0.2.1-cp312-abi3-manylinux_2_28_x86_64.whl CPython 3.12 abi3 Linux glibc 2.28+ x86-64 Details
outie-0.2.1-cp312-abi3-manylinux_2_28_aarch64.whl CPython 3.12 abi3 Linux glibc 2.28+ ARM64 Details
outie-0.2.1-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.1.tar.gz

Download URL outie-0.2.1.tar.gz
Size 89.3 kB
Tags Source
SHA-256 checksum
How to use checksums
4ddd45f22b24964c87ccb82adaabfa2f51ca15ecb32aafa072ea0122c33e1532
BLAKE2b-256 checksum
How to use checksums
f10208c060e24237acc8580e4f44d8a700fd7d2e3aac4ac4cf13f93532b723ea
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 11, 2026.

Transparency log

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

Download URL outie-0.2.1-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
c6626521df7f64456e744315c9661c988abdb33825cab8e211e4b98babcc5678
BLAKE2b-256 checksum
How to use checksums
323ead317f071c8f5892d9871356c77aff2267b01ac80b523ba351220d047978
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 11, 2026.

Transparency log

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

Download URL outie-0.2.1-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
cade8295ec621944975552021fe36b1d2a49a0dd01a660b60509124dcf7813bd
BLAKE2b-256 checksum
How to use checksums
903aaed6c488fd476bd7cb0bb83c982a026ca5aa831759b80eecd2bee43d4520
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 11, 2026.

Transparency log

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

Download URL outie-0.2.1-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
81b123c0be2d20ce4f1e38a15027caaca74f20fe3fbb151f3b65f1b440acd779
BLAKE2b-256 checksum
How to use checksums
0c70cc41fa882aca58252ab84fe275fcac6069e86dcc74729b2fe22f38382ba9
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 11, 2026.

Transparency log

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

Download URL outie-0.2.1-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
86925edf2d2c72a819e0321cd85408bc0bbbd4978638d800b881666ee315f441
BLAKE2b-256 checksum
How to use checksums
7d9e7fdbaa8475a9c8a6edf22b27c8dd4dec8460f884348b80393428b59c88d0
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 11, 2026.

Transparency log

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

Download URL outie-0.2.1-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
7aa216c96632ff6ec9b36ad060c606ba1cc05c430921f9b092850d6143830ae9
BLAKE2b-256 checksum
How to use checksums
e23fca1ad9082b13c79cc6345e93ee11a9862744dd70728965cef416f6e6571c
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 11, 2026.

Transparency log

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

Download URL outie-0.2.1-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
45aa5a5bd19a18ac0fe95b2a7f26d1b534eca50b6664ab7e12c5f2f901fdcd50
BLAKE2b-256 checksum
How to use checksums
2f6568a31f2f77cf740cd50ad778ea920d2c461da1de1eb2fbfa3c7d8e2de007
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 11, 2026.

Transparency log

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

Download URL outie-0.2.1-cp312-abi3-win_amd64.whl
Size 1.1 MB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
24053d3a1dbbb676ab49435f33d15315b55619f9beee0745b8d93c53b3dc5b8b
BLAKE2b-256 checksum
How to use checksums
2c96456f4ca0572b7a8d1ec529cf8bf184718c3c7c367c9adf80125ee9d3294d
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 11, 2026.

Transparency log

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

Download URL outie-0.2.1-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
2e9a108220009a93be4ee17da95cd3c0a8d338233f1c40a244898d7fcc26d09c
BLAKE2b-256 checksum
How to use checksums
879e39baf2d67f4480f949aef39012e541826f60f5235a8013844c47a3f0025f
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 11, 2026.

Transparency log

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

Download URL outie-0.2.1-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
620ed2c815626fce83766a165ccfd09530f1ff60fceac84e23de90e0a4eed37c
BLAKE2b-256 checksum
How to use checksums
3ee115114a449821f5cc577aa195f34cd1c864d23f8cf29e25c8f27422182195
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 11, 2026.

Transparency log

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

Download URL outie-0.2.1-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
a7acc3f905119308ae39fa60969b7cf1ad62ebea338e4a5d128e685a75a6101f
BLAKE2b-256 checksum
How to use checksums
6c83864fb70eb6d4e3ae7288f00f61c789f09accc50462bbf92b1edeec0d74f2
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 11, 2026.

Transparency log

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

Download URL outie-0.2.1-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
2218bd395a4fe262e7f18416bad51c6c7ac20ee058288d11a5eb2ead2d238e66
BLAKE2b-256 checksum
How to use checksums
45537371356ff8350cc5e7195aabc2bd3f4f5fb6a1d62449afa27b6afcca7cc0
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 11, 2026.

Transparency log

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

Download URL outie-0.2.1-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
da7f27a890e29eacd43a6af91bde6ab468808672d9241727ae0f0e16fd4d435c
BLAKE2b-256 checksum
How to use checksums
c5645a0e0df975c7beb3840988e8c4ddd58efde84345707f2b7e72280424b70a
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 11, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.2

13 release files

This release

0.2.1 This release

13 release files

0.2.0

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