123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- #!/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)
|