You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
320 lines
8.5 KiB
320 lines
8.5 KiB
#!/usr/bin/python |
|
|
|
# Copyright (C) 2016 Intel Corporation. All rights reserved. |
|
# |
|
# This file is free software: you can redistribute it and/or modify it |
|
# under the terms of the GNU General Public License as published by the |
|
# Free Software Foundation, either version 3 of the License, or |
|
# (at your option) any later version. |
|
# |
|
# This file is distributed in the hope that it will be useful, but |
|
# WITHOUT ANY WARRANTY; without even the implied warranty of |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
# See the GNU General Public License for more details. |
|
# |
|
# You should have received a copy of the GNU General Public License along |
|
# with this program. If not, see <http://www.gnu.org/licenses/>. |
|
from __future__ import print_function |
|
import argparse |
|
import numpy as np |
|
import sys |
|
|
|
import icosahedron as ico |
|
import grid |
|
|
|
def print_code_gen_notice(): |
|
print("/* This was generated with") |
|
print(" * libraries/AP_Math/tools/geodesic_grid/geodesic_grid.py */") |
|
|
|
def header_neighbor_umbrella(index): |
|
t = ico.triangles[0] |
|
a, b, c = t |
|
|
|
triangle, edge = ( |
|
( t, ( a, b)), |
|
( t, ( b, c)), |
|
( t, ( c, a)), |
|
(-t, (-a, -b)), |
|
(-t, (-b, -c)), |
|
(-t, (-c, -a)), |
|
)[index] |
|
|
|
return ico.neighbor_umbrella(triangle, edge), edge |
|
|
|
parser = argparse.ArgumentParser( |
|
description=""" |
|
Utility script for helping to understand concepts used by AP_GeodesicGrid as |
|
well as for aiding its development. |
|
|
|
When passing a vertex as argument to one of the options, the valid values for |
|
the coordinates are 0, -1, 1, g and -g, where g is the golden ratio. |
|
""", |
|
) |
|
|
|
parser.add_argument( |
|
'-p', '--plot', |
|
action='store_true', |
|
help=""" |
|
Plot results when applicable. |
|
""", |
|
) |
|
|
|
parser.add_argument( |
|
'-b', '--plot-subtriangles', |
|
action='store_true', |
|
help=""" |
|
Plot subtriangles as well. This implies -p. |
|
""", |
|
) |
|
|
|
parser.add_argument( |
|
'--icosahedron', |
|
action='store_true', |
|
help='Get the icosahedron triangles.', |
|
) |
|
|
|
parser.add_argument( |
|
'-t', '--triangle', |
|
action='append', |
|
type=int, |
|
nargs='+', |
|
metavar='INDEX', |
|
help=""" |
|
Get the icosahedron triangle at INDEX. |
|
""", |
|
) |
|
|
|
parser.add_argument( |
|
'-s', '--section', |
|
action='append', |
|
type=int, |
|
nargs='+', |
|
help=""" |
|
Get the grid section SECTION. If --plot is passed, then --plot-subtriangles is |
|
implied. |
|
""", |
|
) |
|
|
|
parser.add_argument( |
|
'-u', '--umbrella', |
|
action='append', |
|
nargs=3, |
|
metavar=('X', 'Y', 'Z'), |
|
help=""" |
|
Get the umbrella with pivot denoted by (X, Y, Z). The pivot must be one of the |
|
icosahedron's vertices. |
|
""", |
|
) |
|
|
|
parser.add_argument( |
|
'-n', '--neighbor-umbrella', |
|
action='append', |
|
nargs='+', |
|
metavar='INDEX', |
|
help=""" |
|
Get the neighbor umbrella at INDEX as described by _neighbor_umbrellas in |
|
AP_GeodesicGrid.h. The special value "all" for INDEX is also accepted, which |
|
will make it ignore other indexes passed and get all neighbor umbrellas for |
|
that member. |
|
""", |
|
) |
|
|
|
parser.add_argument( |
|
'--neighbor-umbrella-gen', |
|
action='store_true', |
|
help=""" |
|
Generate C++ code for the initialization of the member _neighbor_umbrellas |
|
described in AP_GeodesicGrid.h. |
|
""", |
|
) |
|
|
|
parser.add_argument( |
|
'--inverses-gen', |
|
action='store_true', |
|
help=""" |
|
Generate C++ code for the initialization of members _inverses and _mid_inverses |
|
declared in AP_GeodesicGrid.h. |
|
""") |
|
|
|
|
|
args = parser.parse_args() |
|
|
|
if args.plot_subtriangles: |
|
args.plot = True |
|
|
|
if args.plot: |
|
import plot |
|
|
|
polygons_to_plot = [] |
|
|
|
if args.triangle: |
|
indexes = [] |
|
for l in args.triangle: |
|
indexes += l |
|
|
|
for i in indexes: |
|
if 0 > i or i >= len(ico.triangles): |
|
print( |
|
'Triangle index must be in the range [0,%d)' % len(ico.triangles), |
|
file=sys.stderr, |
|
) |
|
sys.exit(1) |
|
|
|
print(ico.triangles[i]) |
|
if args.plot: |
|
plot.polygon(ico.triangles[i]) |
|
|
|
if args.section: |
|
sections = [] |
|
for l in args.section: |
|
sections += l |
|
|
|
for s in sections: |
|
if 0 > s or s >= 4 * len(ico.triangles): |
|
print( |
|
'Section must be in the range [0,%d)' % 4 * len(ico.triangles), |
|
file=sys.stderr, |
|
) |
|
sys.exit(1) |
|
print(grid.section_triangle(s)) |
|
if args.plot: |
|
args.plot_subtriangles = True |
|
plot.sections(sections) |
|
|
|
if args.umbrella: |
|
for pivot in args.umbrella: |
|
for i, x in enumerate(pivot): |
|
if x == 'g': |
|
x = ico.g |
|
elif x == '-g': |
|
x = -ico.g |
|
else: |
|
try: |
|
x = int(x) |
|
if x not in (0, -1, 1): |
|
raise ValueError() |
|
except ValueError: |
|
print( |
|
'umbrella: invalid pivot coordinate: %s' % str(x), |
|
file=sys.stderr, |
|
) |
|
sys.exit(1) |
|
pivot[i] = x |
|
|
|
pivot = ico.Vertex(*pivot) |
|
if pivot not in ico.vertices: |
|
print( |
|
'umbrella: invalid pivot:', pivot, |
|
file=sys.stderr, |
|
) |
|
sys.exit(1) |
|
u = ico.umbrella(pivot) |
|
|
|
print("Components of the umbrella of %s:" % str(pivot)) |
|
for c in u.components: |
|
print(" %s" % str(c)) |
|
|
|
if args.plot: |
|
plot.polygons(u.components) |
|
|
|
if args.neighbor_umbrella: |
|
indexes = [] |
|
for l in args.neighbor_umbrella: |
|
indexes += l |
|
|
|
if 'all' in indexes: |
|
indexes = range(6) |
|
else: |
|
for i, arg in enumerate(indexes): |
|
try: |
|
arg = int(arg) |
|
if arg not in range(6): |
|
raise ValueError() |
|
except ValueError: |
|
print( |
|
'neighbor_umbrella: invalid index %s' % str(arg), |
|
file=sys.stderr, |
|
) |
|
sys.exit(1) |
|
indexes[i] = arg |
|
|
|
for i in indexes: |
|
u, order_edge = header_neighbor_umbrella(i) |
|
print("Header umbrella %d:" % i) |
|
print(" Pivot:", u.pivot) |
|
for i in range(5): |
|
print(" Vertex %d:" % i, u.vertex(i, order_edge)) |
|
for i in range(5): |
|
print(" Component %d:" % i, u.component(i, order_edge)) |
|
|
|
if args.plot: |
|
plot.polygons(u.components) |
|
|
|
if args.neighbor_umbrella_gen: |
|
print("Header neighbor umbrellas code generation:") |
|
print_code_gen_notice() |
|
print("const struct AP_GeodesicGrid::neighbor_umbrella") |
|
print("AP_GeodesicGrid::_neighbor_umbrellas[3]{") |
|
for i in range(6): |
|
u, order_edge = header_neighbor_umbrella(i) |
|
|
|
components = tuple( |
|
ico.triangles.index(u.component(i, order_edge)) for i in range(5) |
|
) |
|
|
|
def vi_cj(i, j): |
|
v = u.vertex(i, order_edge) |
|
t = u.component(j, order_edge) |
|
return t.index(v) |
|
|
|
vi_cj_values = tuple( |
|
vi_cj(a, b) for a, b in ((0, 0), (1, 1), (2, 1), (4, 4), (0, 4)) |
|
) |
|
|
|
print(" {{%s}, %s}," % ( |
|
", ".join("%2d" % i for i in components), |
|
", ".join(str(i) for i in vi_cj_values), |
|
)) |
|
print("};") |
|
|
|
if args.inverses_gen: |
|
print("Header inverses code generation:") |
|
print_code_gen_notice() |
|
print("const Matrix3f AP_GeodesicGrid::_inverses[10]{") |
|
for i in range(10): |
|
a, b, c = ico.triangles[i] |
|
m = np.matrix(( |
|
(a.x, b.x, c.x), |
|
(a.y, b.y, c.y), |
|
(a.z, b.z, c.z), |
|
)).getI() |
|
print(" {{%9.6ff, %9.6ff, %9.6ff}," % (m[0,0], m[0,1], m[0,2])) |
|
print(" {%9.6ff, %9.6ff, %9.6ff}," % (m[1,0], m[1,1], m[1,2])) |
|
print(" {%9.6ff, %9.6ff, %9.6ff}}," % (m[2,0], m[2,1], m[2,2])) |
|
print("};") |
|
print() |
|
print_code_gen_notice() |
|
print("const Matrix3f AP_GeodesicGrid::_mid_inverses[10]{") |
|
for i in range(10): |
|
a, b, c = ico.triangles[i] |
|
ma, mb, mc = .5 * (a + b), .5 * (b + c), .5 * (c + a) |
|
m = np.matrix(( |
|
(ma.x, mb.x, mc.x), |
|
(ma.y, mb.y, mc.y), |
|
(ma.z, mb.z, mc.z), |
|
)).getI() |
|
print(" {{%9.6ff, %9.6ff, %9.6ff}," % (m[0,0], m[0,1], m[0,2])) |
|
print(" {%9.6ff, %9.6ff, %9.6ff}," % (m[1,0], m[1,1], m[1,2])) |
|
print(" {%9.6ff, %9.6ff, %9.6ff}}," % (m[2,0], m[2,1], m[2,2])) |
|
print("};") |
|
|
|
|
|
if args.icosahedron: |
|
print('Icosahedron:') |
|
for i, t in enumerate(ico.triangles): |
|
print(' %s' % str(t)) |
|
if args.plot: |
|
plot.polygons(ico.triangles) |
|
|
|
if args.plot: |
|
plot.show(subtriangles=args.plot_subtriangles)
|
|
|