# 30.1.2018 9:15
import bpy
bpy.app.debug = True
import re
import sys

part_name = 'Specimen'
filename = "model_apdl.txt"
setup_f = "setup.txt"

e = 2   # number of nodes that an edge connects
nodes = []
loose_edges = [];
forces = 0
index_buf = 0
xcor = 0.0
ycor = 0.0

s = open(setup_f, "r")

if s.closed:
    print("setup file is missing\n")
    sys.exit()

str_E = re.split('{', s.readline())[1]  # youngs modulus
str_E = re.split('}', str_E)[0]
E = int(str_E)
print("E = " + str(E) + "\n")

str_nu = re.split('{', s.readline())[1] # poissons ratio
str_nu = re.split('}', str_nu)[0]
nu = float(str_nu)
print("nu = " + str(nu) + "\n")

str_fm = re.split('{', s.readline())[1] # force multiplier
str_fm = re.split('}', str_fm)[0]
fm = int(str_fm)
print("force_multiplier = " + str(fm) + "\n")

str_rho = re.split('{', s.readline())[1]    # density
str_rho = re.split('}', str_rho)[0]
rho = int(str_rho)
print("density = " + str(rho) + "\n")

str_t = re.split('{', s.readline())[1]  # thickness
str_t = re.split('}', str_t)[0]
t = float(str_t)
print("thickness = " + str(t) + "\n")

s.close()

a = open(filename, "w")

a.write("! " + str(filename) + " generated from Blender 2.76\n")
a.write("! " + bpy.path.basename(bpy.context.blend_data.filepath) + "\n\n")

a.write("/FILNAME,MODEL_APDL!    define filename\n")
a.write("/PREP7!    preprocessor\n\n")

a.write("ET,1,PLANE182!    element type PLANE182\n")
a.write("KEYOPT,1,3,3!  plan stress with thickness\n")
a.write("R,1," + str(t) + "!    plane stress thickness\n\n")

a.write("MPTEMP,1,0\n")
a.write("MPDATA,EX,1,," + str(E) + "!    young's modulus\n")
a.write("MPDATA,PRXY,1,," + str(nu) + "!    poissons ratio\n\n")

for i in range(len(bpy.data.objects[str(part_name)].data.edges)):   # goes through all the edges
    if bpy.data.objects[str(part_name)].data.edges[i].is_loose: # if it finds a loose one
        loose_edges.append(i)   # it adds it to a list
    else:   # if the edge is a connected one
        if bpy.data.objects[str(part_name)].data.edges[i].vertices[0] not in nodes:
            nodes.append(bpy.data.objects[str(part_name)].data.edges[i].vertices[0])
        if bpy.data.objects[str(part_name)].data.edges[i].vertices[1] not in nodes:
            nodes.append(bpy.data.objects[str(part_name)].data.edges[i].vertices[1])
nodes.sort()

#for i in range(len(loose_edges)):   # now going through the loose edge list
#    if bpy.data.objects[str(part_name)].data.edges[i].vertices[0] in nodes:
#        nodes.append(bpy.data.objects[str(part_name)].data.edges[i].vertices[0])
#    elif bpy.data.objects[str(part_name)].data.edges[i].vertices[1] in nodes:
#        nodes.append(bpy.data.objects[str(part_name)].data.edges[i].vertices[1])

#for i in range(len(bpy.data.objects[str(part_name)].data.polygons)):	# goes through all the elements
#    for j in range(len(bpy.data.objects[str(part_name)].data.polygons[i].vertices)):	# goes through all nodes of a given element
#        if bpy.data.objects[str(part_name)].data.polygons[i].vertices[j] not in nodes:	# checks if it is a node or force representation
#            nodes.append(bpy.data.objects[str(part_name)].data.polygons[i].vertices[j])	# if it is a node it adds it to the node list
#nodes.sort()

a.write("! number of nodes = " + str(len(nodes)) + "\n")

po = bpy.data.objects[str(part_name)].data  # making the "path" shorter

for i in range(len(nodes)):    # goes through all the nodes
    xcor = po.vertices[nodes[i]].co.x
    ycor = po.vertices[nodes[i]].co.y
    a.write("N,{0:d},{1:.6f},{2:.6f},0,0,0,0!    node {3:d}\n".format(i+1, xcor, ycor, i+1))
a.write("\n")

a.write("! number of elements = " + str(len(bpy.data.objects[str(part_name)].data.polygons)) + "\n")

for i in range(len(bpy.data.objects[str(part_name)].data.polygons)):    # goes through all the elements
    a.write("E")
    for j in range(len(bpy.data.objects[str(part_name)].data.polygons[i].vertices)):    # goes through all nodes of a given element
        for k in range(len(nodes)):
            if str(bpy.data.objects[str(part_name)].data.polygons[i].vertices[j]) == str(nodes[k]): # error
                a.write("," + str(k + 1))
    a.write("!    element " + str(i+1) + "\n")
a.write("\n")

buf = []    # buffer for membership indices of investigated substructures and supports

for i in range(len(bpy.data.objects[str(part_name)].data.materials)):   # goes through all substructures
    del buf[:]
    for j in range(len(bpy.data.objects[str(part_name)].data.polygons)): # digs through all the elements
        if i == bpy.data.objects[str(part_name)].data.polygons[j].material_index:   # and if the element belongs to the currently investigated substructure
            buf.append(j)    # it stores the element index

sups = len(bpy.data.objects[str(part_name)].vertex_groups)  # number of support types
for i in range(sups):   # goes through the whole list of support type names
    del buf[:]
    for j in range(len(nodes)): # goes through all nodes
        if len(bpy.data.objects[str(part_name)].data.vertices[j].groups) > 0:   # if the node belongs to any group
            for k in range(len(bpy.data.objects[str(part_name)].data.vertices[j].groups)):  # checks all its memberships for the investigated one
                if bpy.data.objects[str(part_name)].data.vertices[j].groups[k].group == i:  # and if there is a match,
                    buf.append(j)
    a.write("! number of supports = " + str(len(buf)) + "\n")
    for j in range(len(buf)):
        a.write("D," + str(nodes[buf[j]]+1) + ",UX,0,,,,UY\n")
a.write("\n")

for i in range(len(bpy.data.objects[str(part_name)].data.edges)):   # goes through all the edges
    if bpy.data.objects[str(part_name)].data.edges[i].is_loose:
        forces = forces + 1
a.write("! number of forces = " + str(forces) + "\n")

for i in range(len(bpy.data.objects[str(part_name)].data.edges)):   # goes through all edges
    index_buf = 0   # reset the buffer
    if bpy.data.objects[str(part_name)].data.edges[i].is_loose:
        if bpy.data.objects[str(part_name)].data.edges[i].vertices[0] in nodes: # if the first edge vertex is a node
            for j in range(len(nodes)): # finds the index of the given node
                if bpy.data.objects[str(part_name)].data.edges[i].vertices[0] == nodes[j]:  # if it finds it
                    index_buf = j   # it stores it in the buffer
            xcor = bpy.data.objects[str(part_name)].data.vertices[bpy.data.objects[str(part_name)].data.edges[i].vertices[1]].co.x - bpy.data.objects[str(part_name)].data.vertices[bpy.data.objects[str(part_name)].data.edges[i].vertices[0]].co.x
            ycor = bpy.data.objects[str(part_name)].data.vertices[bpy.data.objects[str(part_name)].data.edges[i].vertices[1]].co.y - bpy.data.objects[str(part_name)].data.vertices[bpy.data.objects[str(part_name)].data.edges[i].vertices[0]].co.y
            if xcor != 0:
                a.write("F," + str(index_buf+1) + ",FX,{0:.6f}\n".format(xcor * fm))
            if ycor != 0:
                a.write("F," + str(index_buf+1) + ",FY,{0:.6f}\n".format(ycor * fm))
        elif bpy.data.objects[str(part_name)].data.edges[i].vertices[1] in nodes:   # if the second edge vertex is a node
            for j in range(len(nodes)): # finds the index of the given node
                if bpy.data.objects[str(part_name)].data.edges[i].vertices[1] == nodes[j]:  # if it finds it
                    index_buf = j   # it stores it in the buffer
            xcor = bpy.data.objects[str(part_name)].data.vertices[bpy.data.objects[str(part_name)].data.edges[i].vertices[0]].co.x - bpy.data.objects[str(part_name)].data.vertices[bpy.data.objects[str(part_name)].data.edges[i].vertices[1]].co.x
            ycor = bpy.data.objects[str(part_name)].data.vertices[bpy.data.objects[str(part_name)].data.edges[i].vertices[0]].co.y - bpy.data.objects[str(part_name)].data.vertices[bpy.data.objects[str(part_name)].data.edges[i].vertices[1]].co.y
            if xcor != 0:
                a.write("F," + str(index_buf+1) + ",FX,{0:.6f}\n".format(xcor * fm))
            if ycor != 0:
                a.write("F," + str(index_buf+1) + ",FY,{0:.6f}\n".format(ycor * fm))

a.write("\n")

a.write("/SOLU\n")
a.write("SOLVE\n")

a.close()