#!/usr/bin/env python
# ==============================================================================
import argparse
import numpy as np
import time
from meshpy.tet import MeshInfo, build
from meshpy.geometry import generate_surface_of_revolution, EXT_OPEN, GeometryBuilder

import voropy
#import mesh
#import mesh.meshpy_interface
#import mesh.magnetic_vector_potentials
# ==============================================================================
def _main():

    args = _parse_options()

    radius = 5.0

    radial_subdiv = 2 * args.num_longi_points

    dphi = np.pi / args.num_longi_points

    # Make sure the nodes meet at the poles of the ball.
    def truncate(r):
        if abs(r) < 1e-10:
            return 0
        else:
            return r

    # Compute the volume of a canonical tetrahedron
    # with edgelength radius*dphi.
    a = radius * dphi
    canonical_tet_volume = np.sqrt(2.0) / 12 * a**3

    # Build outline for surface of revolution.
    rz = [(truncate(radius * np.sin(i*dphi)), radius * np.cos(i*dphi))
          for i in xrange(args.num_longi_points+1)
         ]

    print 'Build mesh...',
    start = time.time()
    geob = GeometryBuilder()
    geob.add_geometry( *generate_surface_of_revolution(rz,
                                                       closure=EXT_OPEN,
                                                       radial_subdiv=radial_subdiv)
                     )
    mesh_info = MeshInfo()
    geob.set(mesh_info)
    meshpy_mesh = build(mesh_info, max_volume = canonical_tet_volume)
    elapsed = time.time()-start
    print 'done. (%gs)' % elapsed

    # Fill the data into a voropy mesh object.
    mesh = voropy.mesh3d(meshpy_mesh.points, meshpy_mesh.elements)

    print '\n%d nodes, %d elements' % (len(mesh.node_coords), len(mesh.cells))

    # write the mesh
    print 'Write mesh...',
    start = time.time()
    mesh.write(args.filename)
    elapsed = time.time()-start
    print 'done. (%gs)' % elapsed

    return
# ==============================================================================
def _parse_options():
    '''Parse input options.'''
    import argparse

    parser = argparse.ArgumentParser( description = 'Construct tetrahedrization of a ball.' )


    parser.add_argument( 'filename',
                         metavar = 'FILE',
                         type    = str,
                         help    = 'file to be written to'
                       )

    parser.add_argument( '--numpoints', '-p',
                         metavar = 'N',
                         dest='num_longi_points',
                         nargs='?',
                         type=int,
                         const=10,
                         default=10,
                         help    = 'number of discretization points along a logitudinal line'
                       )

    args = parser.parse_args()

    return args
# ==============================================================================
if __name__ == "__main__":
    _main()
# ==============================================================================
