Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Compute winding order of triangles #14

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions quantized_mesh_encoder/util.py
Original file line number Diff line number Diff line change
@@ -13,3 +13,42 @@ def zig_zag_encode(arr):
int16
"""
return np.bitwise_xor(np.right_shift(arr, 15), np.left_shift(arr, 1))


def is_ccw(positions, indices):
"""For each triangle, determine if in counter-clockwise winding order

Implements algorithm from here:
https://stackoverflow.com/a/1165943

NOTE: this algorithm is reversed if the origin is the top left (i.e. as in a
PNG), rather than the standard origin of the bottom left.

Args:
positions: numpy array of shape (-1, 3) defining positions. Each row is a single coordinate
indices: numpy array either flat or of shape (-1, 3) defining triangles

Returns:
1d numpy array where each value represents a single triangle formed by a
triple within `indices`. The value is `True` if the triangle is
counter-clockwise or `False` if clockwise.
"""
# Make sure indices
indices = indices.reshape(-1, 3)

# Perform coordinate lookup in positions using indices
# `coords` is then an array of shape (-1, 3, 3) where each block of (i, 3,
# 3) represents all the coordinates of a single triangle
coords = positions[indices]

# x2 - x1 for every edge of every triangle
x2x1 = np.roll(coords[:, :, 0], -1, axis=1) - coords[:, :, 0]

# y2 + y1 for every edge of every triangle
y2y1 = np.roll(coords[:, :, 1], -1, axis=1) + coords[:, :, 1]

# Sum edge weights for each triangle
axissum = (x2x1 * y2y1).sum(axis=1)

# Values <0 represent counter-clockwise triangles
return axissum < 0