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

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.2
File Size Uploaded
outie-0.2.2.tar.gz 89.9 kB Details

Built distributions (wheels)

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

Download URL outie-0.2.2.tar.gz
Size 89.9 kB
Tags Source
SHA-256 checksum
How to use checksums
c3330a2a1b223fc55f380461569d932b4634bd7ca8c83ed3f2de22afc21b41fd
BLAKE2b-256 checksum
How to use checksums
804be02e8266ad88df7dd95fe1dccb5444b62e4a899704c910c9d88e93b5a975
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.2-cp314-cp314t-win_amd64.whl

Download URL outie-0.2.2-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
93fe70ae0a14848e435761e561f038e212b85db432a284e4891df431e12703dd
BLAKE2b-256 checksum
How to use checksums
7022926a5680bafb2db00cdec274e229e7e71a21578ff2d23caa656fc8697fe7
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.2-cp314-cp314t-musllinux_1_2_x86_64.whl

Download URL outie-0.2.2-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
39a1b67febdec5731aee999c4c84a128379b4f443d2a9c4650154664bbcd6c83
BLAKE2b-256 checksum
How to use checksums
ae44639dc7222a556c2ed2570f4b1cff1d6600b56c064961010684945ace37aa
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.2-cp314-cp314t-musllinux_1_2_aarch64.whl

Download URL outie-0.2.2-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
52a51cd571872b428b4be1a762dacdb937c38f4f988aaa2de0f173e8c0e26232
BLAKE2b-256 checksum
How to use checksums
e467d71cbc8e60be518b842b48efb06fdbdc444e5d669a7da4e5dc04be90cb41
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.2-cp314-cp314t-manylinux_2_28_x86_64.whl

Download URL outie-0.2.2-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
66df0fed52a1602afb3f2624ea5d8b67b3e7e653699d37f42b4d5055e4a8039a
BLAKE2b-256 checksum
How to use checksums
092db7de333c5a7901e500b1a83b32f1d17ef93bfae4e7dc45c84ba0bb0a9f8f
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.2-cp314-cp314t-manylinux_2_28_aarch64.whl

Download URL outie-0.2.2-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
fdaad4ac4867570f8c0636ae62e5c4a6114e189b042f723ac529d043eff913a2
BLAKE2b-256 checksum
How to use checksums
968e26995fc1846b82a7c625641cc939e05dae412f2b6ca24bff438d363231c1
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.2-cp314-cp314t-macosx_11_0_arm64.whl

Download URL outie-0.2.2-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
e0167a71914b4fe6de350a664a3c5eef665a2893e8769840be57c009249900c2
BLAKE2b-256 checksum
How to use checksums
7aec52303928b347ac31710031644a2a4b3927135bdf25b6d96db6e8378da95d
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.2-cp312-abi3-win_amd64.whl

Download URL outie-0.2.2-cp312-abi3-win_amd64.whl
Size 1.1 MB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
6a4eb2e7f4f8eaafaf1df92e974140f5c6c5d84dc7519ad5c0549c2024d78a6e
BLAKE2b-256 checksum
How to use checksums
bb2981c281d06c52bdeeeaf431c2fc808cdbf18fe179745eb1b3e5aeb5e25d93
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.2-cp312-abi3-musllinux_1_2_x86_64.whl

Download URL outie-0.2.2-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
efae83f79bbf4fa2f6d8884e77519d2835a2ef5b8e6936252f11ad02085b8f2c
BLAKE2b-256 checksum
How to use checksums
fc3a2d7b7c6b4426a9d2abdbe8dde4120b946abc19877d7fefbfa9d9417c32b0
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.2-cp312-abi3-musllinux_1_2_aarch64.whl

Download URL outie-0.2.2-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
24356746f48aadfdfcc7219549f93971ada6961e33bf2cefa08a785107d4a257
BLAKE2b-256 checksum
How to use checksums
34575263494dfa45912817b714aa555a0adad1934bf24c416fbe11ee742d9e83
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.2-cp312-abi3-manylinux_2_28_x86_64.whl

Download URL outie-0.2.2-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
9e5b8df38b4eff8f437440c124f661db32a9719837d5ae4cc9d3cc7eb9acf8cc
BLAKE2b-256 checksum
How to use checksums
322c6b454eba2bb1b1c341888231152902256c0b6b9fad1502bec053b82e75b4
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.2-cp312-abi3-manylinux_2_28_aarch64.whl

Download URL outie-0.2.2-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
76620a3c221d9f7353a15e6908367e419a406a10f51f5e0a319e850b458514ee
BLAKE2b-256 checksum
How to use checksums
5e984fc82217e08fc5c1da8cf4fb58dee3267796a1b4ab5a0cbc64f67e86736b
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.2-cp312-abi3-macosx_11_0_arm64.whl

Download URL outie-0.2.2-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
d975e87f0bae9d34c3ecc0a00b4929f18b1ec0e09f6fd3add6f2d55405c50db0
BLAKE2b-256 checksum
How to use checksums
2aafcbeba4787797975255469336452c86806a1063ddc9abc4c1626daa931743
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

This release

0.2.2 This release

13 release files

0.2.1

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