
import sys
import salome
import numpy as np

salome.salome_init()
theStudy = salome.myStudy

import salome_notebook
notebook = salome_notebook.NoteBook(theStudy)
sys.path.insert( 0, r'/home/schwara2')

import GEOM
from salome.geom import geomBuilder
import math
import SALOMEDS


geompy = geomBuilder.New(theStudy)

O = geompy.MakeVertex(0, 0, 0)
OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)


def parse_fcsv(fileName):
    """function that parses the slicer fiducials (.fscv) file, and save the points in an n by 3 array"""
    with open(fileName) as fids:
        lines = fids.readlines()[3:]  # ignore first 3 lines
        points = np.zeros((len(lines), 3))
        for c, i in enumerate(lines):
            separated_string = i.split(',')
            points[c] = separated_string[1:4]
        return points


def curve_through_points(points, start_from_number):
    """create a smooth curve through the given points. start from number is for naming the points. for example
    if 10 points have already been created, we would want to start from number 11"""
    dict = {}
    v = []
    for c, p in enumerate(points):
        name = 'Vertex_{}'.format(c+start_from_number)
        v_0 = geompy.MakeVertex(p[0],p[1],p[2])
        dict[name] = v_0
        v.append(v_0)
    Curve = geompy.MakeInterpol(v, True, False)
    return Curve, dict


def add_vertices_to_study(curve_dict):
    for key, value in curve_dict.iteritems():
        geompy.addToStudy(value, key)


def create_mesh(fiducial_files, save_as):
    """fiducial files is a list of the fiducial files being used to create the mesh. currenly it is required that
     the points are chosen in the order that the curve should be drawn, and that the first point and direction of
      each curve align, to avoid twisting of the loft"""

    num_files = len(fiducial_files)

    curves = []
    curve_dicts = []
    points_counter = 0
    for file in fiducial_files:
        points = parse_fcsv(file)
        curve, curve_dict = curve_through_points(points,points_counter)
        curves.append(curve)
        curve_dicts.append(curve_dict)
        points_counter += len(points)

    Filling_1 = geompy.MakeFilling(curves)
    Face_1 =  geompy.MakeFaceWires([curves[0]], 0)
    Face_2 =  geompy.MakeFaceWires([curves[-1]], 0)
    Shell_1 = geompy.MakeShell([Filling_1, Face_1, Face_2])

    geompy.addToStudy(O, 'O')
    geompy.addToStudy(OX, 'OX')
    geompy.addToStudy(OY, 'OY')
    geompy.addToStudy(OZ, 'OZ')

    for i in range(num_files):
        add_vertices_to_study(curve_dicts[i])
        geompy.addToStudy(curves[i], 'Curve_{}'.format(i))

    geompy.addToStudy(Filling_1, 'Filling_1')
    geompy.addToStudy(Face_1, 'Face_1')
    geompy.addToStudy(Face_2, 'Face_2')
    geompy.addToStudy(Shell_1, 'Shell_1')

    import SMESH, SALOMEDS
    from salome.smesh import smeshBuilder

    smesh = smeshBuilder.New(theStudy)
    Mesh_1 = smesh.Mesh(Shell_1)
    NETGEN_2D_ONLY = Mesh_1.Triangle(algo=smeshBuilder.NETGEN_2D)
    NETGEN_2D_Parameters_1 = NETGEN_2D_ONLY.Parameters()
    NETGEN_2D_Parameters_1.SetMaxSize(0.95593)
    NETGEN_2D_Parameters_1.SetOptimize(1)
    NETGEN_2D_Parameters_1.SetFineness(2)
    NETGEN_2D_Parameters_1.SetMinSize(0.0895137)
    NETGEN_2D_Parameters_1.SetUseSurfaceCurvature(1)
    NETGEN_2D_Parameters_1.SetQuadAllowed(0)
    NETGEN_2D_Parameters_1.SetSecondOrder(254)
    NETGEN_2D_Parameters_1.SetFuseEdges(120)
    status = Mesh_1.RemoveHypothesis(NETGEN_2D_ONLY)
    Regular_1D = Mesh_1.Segment()
    Max_Size_1 = Regular_1D.MaxSize(0.95593)
    MEFISTO_2D = Mesh_1.Triangle(algo=smeshBuilder.MEFISTO)
    status = Mesh_1.RemoveHypothesis(NETGEN_2D_Parameters_1)
    isDone = Mesh_1.Compute()


    try:
        Mesh_1.ExportSTL(save_as, 1)
    except:
        print 'ExportSTL() failed. Invalid file name?'

    ## Set names of Mesh objects
    smesh.SetName(NETGEN_2D_ONLY.GetAlgorithm(), 'NETGEN_2D_ONLY')
    smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
    smesh.SetName(MEFISTO_2D.GetAlgorithm(), 'MEFISTO_2D')
    smesh.SetName(Max_Size_1, 'Max Size_1')
    smesh.SetName(NETGEN_2D_Parameters_1, 'NETGEN 2D Parameters_1')
    smesh.SetName(Mesh_1.GetMesh(), 'Mesh_1')

    if salome.sg.hasDesktop():
        salome.sg.updateObjBrowser(1)


# # QAT- natural knee
# file1 = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_QAT_PTB_tie.fcsv'
# file2 = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_QAT_TOP_tie.fcsv'
# save_as = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_QAT_loft.stl'
# create_mesh([file1,file2], save_as)

# PTL- natural knee
file1 = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_PTL_TBB_tie.fcsv'
file2 = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_PTL_midsection_a.fcsv'
file3 = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_PTL_midsection_b.fcsv'
file4 = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_PTL_PTB_insertion_a.fcsv'
file5 = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_PTL_PTB_insertion_b.fcsv'
save_as = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_PTL_loft.stl'
create_mesh([file1,file2,file3,file4,file5], save_as)

# # ACL- natrual knee
# file1 = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_ACL_TBB_insertion.fcsv'
# file2 = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_ACL_mid.fcsv'
# file3 = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_ACL_FMB_insertion.fcsv'
# save_as = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_ACL_loft.stl'
# create_mesh([file1,file2,file3], save_as)

# # PCL- natrual knee
# file1 = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_PCL_TBB_insertion.fcsv'
# file2 = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_PCL_mid.fcsv'
# file3 = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_PCL_FMB_insertion.fcsv'
# save_as = '/home/schwara2/Documents/Open_Knees/knee_hub/DU02/geometry/natural_knee_PCL_loft.stl'
# create_mesh([file1,file2,file3], save_as)