Skip to content

Instantly share code, notes, and snippets.

@nh2
Last active August 20, 2020 21:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nh2/72dc964b1cf3966feda30d9ffe93518b to your computer and use it in GitHub Desktop.
Save nh2/72dc964b1cf3966feda30d9ffe93518b to your computer and use it in GitHub Desktop.
Script to scale texture coordinates
#! /usr/bin/env nix-shell
#! nix-shell -i python3 -p python3Packages.plyfile
import argparse
import sys
import numpy as np
from plyfile import PlyData, PlyElement
parser = argparse.ArgumentParser(description='''
Halves texture coordinates of a PLY file along the vertical axis
(Y axis, "V" in "UV-mapping") axis.
Intended to be used when merging 2 mesh textures with
https://github.com/theFroh/imagepacker
(which simply puts them next to each other horizontally),
and if you want to keep the aspect ratio of the content of the texture
file (if not, you can just stretch-scale it).
To bring the texture back to a standard format like 4096x4096, you can
scale it so that the X axis (e.g. with GIMP) has that dimension, and
fill up the Y axis with some color (unused).
Then you can run this script on the corresponding PLY file to ensure that
it uses only the corresponding half of the image.
IMPORTANT:
The Y-axis filling has to be on the TOP of the image, file, and the
textures have to be at the BOTTOM, because texture mapping starts from
the bottom (V=0).
''')
parser.add_argument("--in-ply", dest='in_ply', help="Input PLY file", required=True)
parser.add_argument("--out-ply", dest='out_ply', help="Output PLY file", required=True)
parser.add_argument("--in-width", dest='in_width', help="Input texture width in px", type=int, required=True)
parser.add_argument("--in-height", dest='in_height', help="Input texture height in px", type=int, required=True)
args = parser.parse_args()
aspect_ratio = float(args.in_height) / float(args.in_width)
print(f"Scale factor is {aspect_ratio}")
print("Reading data...")
with open(args.in_ply, 'rb') as f:
p = PlyData.read(f)
# `p` is immutable; make writeable copy of the texcoords.
print("Making texcoords copy...")
texcoords = [np.array(arr) for arr in p['face']['texcoord']]
print("Mutating texcoords...")
for t in texcoords:
t[[1,3,5]] *= aspect_ratio # 3 triangle edges of UV coordinates; we change the Vs
print("Writing file...")
p['face']['texcoord'] = texcoords
p.write(args.out_ply)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment