import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objects as go
import meshio
import argparse 
import os
import glob
import re


# colors per part category
COLORS = {'cell_': 'fuchsia', 'plate.+thick': 'lightblue', 'plate.+thin': 'blue'}


# get path to obj files from command line
parser = argparse.ArgumentParser(
    description="Show 3D model of battery pack in browser."
)
parser.add_argument('modeldir', type=str, 
    help="path to directory where 3d models (.obj) live."
)
args = parser.parse_args()
# make sure directory exists
assert os.path.exists(args.modeldir), f"Path does not exist: {args.modeldir}"
assert os.path.isdir(args.modeldir), f"Not a directory: {args.modeldir}"


# Build figure
fig = go.Figure()
for fpath in glob.glob(os.path.join(args.modeldir, "*.obj")):
    fname = os.path.basename(fpath)
    # read mesh 
    mesh = meshio.read(fpath, file_format="obj")
    # extract vertices and indices, 
    V = mesh.points
    F = mesh.cells[0].data
    x, y, z = V.T
    i, j, k = F.T

    # assign color, depending on name
    c = "grey"   # fallback
    for pat, col in COLORS.items():
        if re.match(pat, fname):
            c = col

    # create plotly mesh object and add to figure
    msh = go.Mesh3d(x=x, y=y, z=z, i=i, j=j, k=k, 
                    color=c, 
                    opacity=1.00, 
                    text=fname,
                   )
    fig.add_trace(msh)


# aspect ratio (otherwise the dimensions are distorted)
fig.update_scenes(aspectmode='data')


# make dash app and display figure
app = dash.Dash(__name__)

app.layout = html.Div([
    html.H1(children='Battery Pack'),
    dcc.Graph(
        id='3dview',
        figure=fig
    ),
])


# run it
app.run_server(debug=True)