Skip to content

Commit

Permalink
Update Python support scripts to Python 3.8 from Python 2. (#24)
Browse files Browse the repository at this point in the history
* Update Python support scripts to Python 3.8 from Python 2.
Python 2.7 is now deprecated.

* Python3 fixes for Mac
- Thanks @b-camacho & @mikeage.

* Change executable name to OpenBrush.

* Fix shebangs so Python3 used.

* Rename Tilt Brush to Open Brush for more automated processes.
  • Loading branch information
billyquith authored Feb 8, 2021
1 parent 0673dd4 commit d4373e6
Show file tree
Hide file tree
Showing 31 changed files with 258 additions and 254 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

*.pyc
.DS_Store
*.bak

# mono debugging files, automatically created by UnityVS
*.dll.mdb
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ Get the Tilt Brush open-source application running on your own devices.

* [Unity 2018.4.11f1](unityhub://2018.4.11f1/7098af2f11ea) (Unity 2019.4.18f1 for this fork)
* [SteamVR](https://store.steampowered.com/app/250820/SteamVR/)
* [Python 2.7.0](https://www.python.org/download/releases/2.7/) (Optional —
* [Python 3](https://www.python.org/downloads/) (Optional —
needed only if you wish to run the scripts in the `Support/bin` directory)
Tested with Python 3.8.

### Changing the application name

Expand Down
2 changes: 1 addition & 1 deletion Support/Python/tbdata/brush_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def __init__(self, tilt_brush_dir):
self.guid_to_name = dict(self.iter_brush_guid_and_name(tilt_brush_dir))
# Maps name -> list of guids
self.name_to_guids = defaultdict(list)
for guid, name in self.guid_to_name.iteritems():
for guid, name in self.guid_to_name.items():
self.name_to_guids[name].append(guid)
self.name_to_guids = dict(self.name_to_guids)

Expand Down
10 changes: 5 additions & 5 deletions Support/Python/tbdata/bvh.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
import os
import struct
import sys
from cStringIO import StringIO
from io import StringIO

try:
import rtree
except ImportError:
print "You need to install rtree (https://pypi.org/project/Rtree/)."
print("You need to install rtree (https://pypi.org/project/Rtree/).")
sys.exit(1)


Expand All @@ -43,7 +43,7 @@ def union(lhs, rhs):
nmax = ( max(lmax[0], rmax[0]),
max(lmax[1], rmax[1]),
max(lmax[2], rmax[2]) )
for i in xrange(3):
for i in range(3):
assert nmax[i] > nmin[i], self
return BBox((nmin, nmax))

Expand Down Expand Up @@ -112,7 +112,7 @@ def destroy(self, returnError):
pass

def loadByteArray(self, page, returnError):
print "RTreeStorageDict: load", page
print("RTreeStorageDict: load", page)
assert page >= 0
try:
data = self.datas[page]
Expand Down Expand Up @@ -240,7 +240,7 @@ def __init__(self, node_id, inf_or_data):
self.node_id = node_id
reader = BinaryReader(inf_or_data)
(self.nodeType, self.level, nChildren) = reader.read("III")
self.children = [ RTreeChild(reader) for i in xrange(nChildren) ]
self.children = [ RTreeChild(reader) for i in range(nChildren) ]
self.bounds = reader.read_bounds()

def is_index(self):
Expand Down
8 changes: 4 additions & 4 deletions Support/Python/tbdata/glb.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function


import itertools
import json
Expand Down Expand Up @@ -43,7 +43,7 @@
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return itertools.izip_longest(fillvalue=fillvalue, *args)
return itertools.zip_longest(fillvalue=fillvalue, *args)


class binfile(object):
Expand Down Expand Up @@ -127,7 +127,7 @@ def deref_all(source_type, prop, dest_type=None):
for _, mesh in self.iter_objs('mesh'):
for prim in mesh['primitives']:
attrs = prim['attributes']
for attr_name in attrs.keys():
for attr_name in list(attrs.keys()):
deref_property(attrs, attr_name, 'accessor')
deref_property(prim, 'indices', 'accessor')
deref_property(prim, 'material')
Expand All @@ -137,7 +137,7 @@ def iter_objs(self, obj_type):
In gltf1 the keys are names; in gltf2 the keys are indices."""
if self.version == 1:
plural = self.PLURAL_SUFFIX.get(obj_type, 's')
return self.json[obj_type + plural].items()
return list(self.json[obj_type + plural].items())
elif self.version == 2:
plural = self.PLURAL_SUFFIX.get(obj_type, 's')
return enumerate(self.json[obj_type + plural])
Expand Down
72 changes: 35 additions & 37 deletions Support/Python/tbdata/printing.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
try:
from tiltbrush.tilt import Tilt
except ImportError:
print "You need the Tilt Brush Toolkit (https://github.com/googlevr/tilt-brush-toolkit)"
print "and then put its Python directory in your PYTHONPATH."
print("You need the Tilt Brush Toolkit (https://github.com/googlevr/tilt-brush-toolkit)")
print("and then put its Python directory in your PYTHONPATH.")
sys.exit(1)

from tbdata.brush_lookup import BrushLookup
Expand Down Expand Up @@ -157,9 +157,9 @@ def convert_brushes(tilt, replacements_by_name, show_removed=False):
for stroke in tilt.sketch.strokes:
guid = index_to_guid[stroke.brush_idx]
used_guids[guid] += 1
print "Brushes used:"
for guid, n in sorted(used_guids.items(), key=lambda p:-p[1]):
print " %5d %s" % (n, brush_lookup.guid_to_name.get(guid))
print("Brushes used:")
for guid, n in sorted(list(used_guids.items()), key=lambda p:-p[1]):
print(" %5d %s" % (n, brush_lookup.guid_to_name.get(guid)))
sys.stdout.flush()
del used_guids

Expand All @@ -170,28 +170,28 @@ def convert_brushes(tilt, replacements_by_name, show_removed=False):
try:
new_guid = replacements[guid]
except KeyError:
print "%d: Don't know what to do with brush %s" % (i, name)
print("%d: Don't know what to do with brush %s" % (i, name))
index_to_new_index[i] = i
else:
new_name = brush_lookup.guid_to_name.get(new_guid, new_guid)
if new_guid is None:
print "%d: Remove %s" % (i, name)
print("%d: Remove %s" % (i, name))
index_to_new_index[i] = None
else:
if guid == new_guid:
print "%d: Keep %s" % (i, name)
print("%d: Keep %s" % (i, name))
elif name == new_name:
print "%d: Replace %s/%s -> %s/%s" % (i, name, guid, new_name, new_guid)
print("%d: Replace %s/%s -> %s/%s" % (i, name, guid, new_name, new_guid))
else:
print "%d: Replace %s -> %s" % (i, name, new_name)
print("%d: Replace %s -> %s" % (i, name, new_name))
try:
new_idx = index_to_guid.index(new_guid)
except ValueError:
new_idx = len(index_to_guid)
index_to_guid.append(new_guid)
index_to_new_index[i] = new_idx

brush_indices_to_remove = set(i for (i, new_i) in index_to_new_index.items() if new_i is None)
brush_indices_to_remove = set(i for (i, new_i) in list(index_to_new_index.items()) if new_i is None)

if brush_indices_to_remove:
old_len = len(tilt.sketch.strokes)
Expand All @@ -203,11 +203,9 @@ def convert_brushes(tilt, replacements_by_name, show_removed=False):
else:
stroke.brush_color = stroke.brush_color
else:
tilt.sketch.strokes[:] = filter(
lambda s: s.brush_idx not in brush_indices_to_remove,
tilt.sketch.strokes)
tilt.sketch.strokes[:] = [s for s in tilt.sketch.strokes if s.brush_idx not in brush_indices_to_remove]
new_len = len(tilt.sketch.strokes)
print "Strokes %d -> %d" % (old_len, new_len)
print("Strokes %d -> %d" % (old_len, new_len))

for stroke in tilt.sketch.strokes:
new_idx = index_to_new_index[stroke.brush_idx]
Expand Down Expand Up @@ -317,13 +315,13 @@ def iter_pos(tilt):
if False:
# Print out x/y/z histograms
histograms = [np.histogram(positions[... , i], bins=30) for i in range(3)]
for irow in xrange(len(histograms[0][0])+1):
for irow in range(len(histograms[0][0])+1):
for axis, histogram in enumerate(histograms):
try:
print "%s %3d %6d " % ('xyz'[axis], histogram[1][irow], histogram[0][irow]),
print("%s %3d %6d " % ('xyz'[axis], histogram[1][irow], histogram[0][irow]), end=' ')
except IndexError:
print "%s %3d %6s " % ('xyz'[axis], histogram[1][irow], ''),
print
print("%s %3d %6s " % ('xyz'[axis], histogram[1][irow], ''), end=' ')
print()

if max_dist > 0:
# Convert replacement guid -> replacement index
Expand Down Expand Up @@ -351,7 +349,7 @@ def mahalanobis_distance(v):
def out_of_bounds(stroke):
i0 = stroke._first_cp
i1 = i0 + len(stroke.controlpoints)
dists = np.array(map(mahalanobis_distance, positions[i0 : i1]))
dists = np.array(list(map(mahalanobis_distance, positions[i0 : i1])))
return np.any(dists > max_dist)

msg("Finding OOB strokes")
Expand All @@ -365,11 +363,11 @@ def out_of_bounds(stroke):
if len(oob_strokes):
if replacement_brush_index is not None:
for i, stroke in oob_strokes:
print "Replacing out-of-bounds stroke", i
print("Replacing out-of-bounds stroke", i)
stroke.brush_idx = replacement_brush_index
stroke.brush_color = (1,0,1,1)
else:
print "Removing %d strokes" % len(oob_strokes)
print("Removing %d strokes" % len(oob_strokes))
remove_indices = set(pair[0] for pair in oob_strokes)
tilt.sketch.strokes[:] = [
stroke for i, stroke in enumerate(tilt.sketch.stroke)
Expand Down Expand Up @@ -443,28 +441,28 @@ def by_color_similarity(counter_pair):
counter = Counter()
for color, n in iter_rgb8_colors(tilt):
counter[color] += n
most_used_color, amt = max(counter.iteritems(), key=lambda pair: pair[1])
most_used_color, amt = max(iter(counter.items()), key=lambda pair: pair[1])

for rgb8 in preserve_colors:
if rgb8 not in counter:
print "Ignoring: #%02x%02x%02x is not in the image" % rgb8
print("Ignoring: #%02x%02x%02x is not in the image" % rgb8)
else:
counter[rgb8] += amt / 2

# Find a "nice" width and height, possibly adjusting the number of texels
num_texels = sum(counter.itervalues())
num_texels = sum(counter.values())
width, height = get_good_factors(num_texels, max_aspect_ratio)
if width * height != num_texels:
counter[most_used_color] += width * height - num_texels
assert counter[most_used_color] > 0
num_texels = sum(counter.itervalues())
num_texels = sum(counter.values())
assert width * height == num_texels

# Expand the colors into a 1d array, then turn into an Image
colors_array = np.zeros(shape=(num_texels, 3), dtype='uint8')
i = 0
# The sort used here only matters to humans when they look at the images
colors_and_counts = sorted(counter.iteritems(), key=by_color_similarity)
colors_and_counts = sorted(iter(counter.items()), key=by_color_similarity)
# colors_and_counts = sorted(counter.iteritems(), key=by_decreasing_usage)
for (color, count) in colors_and_counts:
colors_array[i:i+count] = color
Expand All @@ -475,7 +473,7 @@ def by_color_similarity(counter_pair):

def get_quantized_image_pillow(im, num_colors):
MAXIMUM_COVERAGE = 1
print "Falling back to old color quantization"
print("Falling back to old color quantization")
return im.quantize(colors=num_colors, method=MAXIMUM_COVERAGE), 'pillow'

def get_quantized_image_pngquant(im, num_colors):
Expand Down Expand Up @@ -510,10 +508,10 @@ def get_quantized_image(im, num_colors):
try:
return get_quantized_image_pngquant(im, num_colors)
except subprocess.CalledProcessError as e:
print "Error running pngquant: %s" % e
print("Error running pngquant: %s" % e)
except OSError as e:
print "Missing pngquant: %s" % e
print "Download pngquant.exe it and put it in your PATH."
print("Missing pngquant: %s" % e)
print("Download pngquant.exe it and put it in your PATH.")
return get_quantized_image_pillow(im, num_colors)


Expand All @@ -526,7 +524,7 @@ def simplify_colors(tilt, num_colors, preserve_colors):
imq, method = get_quantized_image(im, num_colors)

def iter_rgb8(im):
return itertools.izip(im.getdata(0), im.getdata(1), im.getdata(2))
return zip(im.getdata(0), im.getdata(1), im.getdata(2))

def get_imq_color(ipixel, data=imq.getdata(), palette=imq.getpalette()):
# Look up color in imq, which is awkward because it's palettized
Expand All @@ -547,15 +545,15 @@ def get_imq_color(ipixel, data=imq.getdata(), palette=imq.getpalette()):

if True:
import numpy as np
for old8, newf in old_to_new.iteritems():
for old8, newf in old_to_new.items():
oldv = np.array(rgb8_to_rgbaf(old8)[0:3])
newv = np.array(newf[0:3])
err = oldv - newv
err = math.sqrt(np.dot(err, err))
if err > .2:
print "High color error: #%02x%02x%02x" % old8
print("High color error: #%02x%02x%02x" % old8)

num_colors = len(set(map(tuple, old_to_new.values())))
num_colors = len(set(map(tuple, list(old_to_new.values()))))
base, _ = os.path.splitext(tilt.filename)
im.save('%s_%s.png' % (base, 'orig'))
imq.save('%s_%s_%d.png' % (base, method, num_colors))
Expand All @@ -575,7 +573,7 @@ def by_color(m): return m.c[0]


def write_simple_obj(mesh, outf_name):
from cStringIO import StringIO
from io import StringIO
tmpf = StringIO()

for v in mesh.v:
Expand Down Expand Up @@ -641,7 +639,7 @@ def process_tilt(filename, args):
if args.debug:
final_strokes = []
# interleave them so it renders semi-nicely...
for before, after in itertools.izip_longest(before_strokes, tilt.sketch.strokes):
for before, after in itertools.zip_longest(before_strokes, tilt.sketch.strokes):
if before is not None:
for cp in before.controlpoints:
cp.position[1] += 10
Expand Down
10 changes: 5 additions & 5 deletions Support/Python/unitybuild/credentials.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3

# Copyright 2020 The Tilt Brush Authors
#
Expand All @@ -15,7 +15,7 @@
# limitations under the License.

"""Helpers for getting credentials, either from the command line or saved in keyrings."""
from __future__ import print_function


import sys

Expand Down Expand Up @@ -45,7 +45,7 @@ def import_keyring():


class Credential(object):
KEYRING_USERNAME = 'Tilt Brush Build'
KEYRING_USERNAME = 'Open Brush Build'

def __init__(self, name, location, **extra):
self.name = name % extra
Expand Down Expand Up @@ -93,9 +93,9 @@ def delete_secret(self):
Credential('%(app_id)s',
'https://dashboard.oculus.com/application/%(app_id)s/api',
app_id=TB_OCULUS_QUEST_APP_ID),
Credential('Tilt Brush keystore password',
Credential('Open Brush keystore password',
None), # Redacted
Credential('Tilt Brush Oculus Quest signing key password',
Credential('Open Brush Oculus Quest signing key password',
None), # Redacted
])

Expand Down
Loading

0 comments on commit d4373e6

Please sign in to comment.