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

part_name = 'Specimen'
filename = "model.mkp"

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

f = open(filename, "w")

f.write("% " + str(filename) + " generated from Blender 2.76\n")
f.write("% " + bpy.path.basename(bpy.context.blend_data.filepath) + "\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()

f.write(".<number_of_nodes>={" + str(len(nodes)) + "}\n") # total number of nodes

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
    f.write(".{0:d}=".format(i))
    f.write("{")
    f.write("{0:.6f};{1:.6f}".format(xcor, ycor))  # prints x and y coordinates of given node
    f.write("}\n")
f.write(".!\n\n")   # symbol for the end of nodes

f.write("#<number_of_elements>={" + str(len(bpy.data.objects[str(part_name)].data.polygons)) + "}\n")  # total number of elements

for i in range(len(bpy.data.objects[str(part_name)].data.polygons)):    # goes through all the elements
    f.write("#" + str(i) + "={")
    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)):
#            f.write(str(bpy.data.objects[str(part_name)].data.polygons[i].vertices[j]))
#            f.write(str(nodes[k]) + "\n")
            if str(bpy.data.objects[str(part_name)].data.polygons[i].vertices[j]) == str(nodes[k]): # error
                f.write(str(k)) # prints all the nodes one by one
                if j == 0:
                    f.write(",")
                elif j == 1:
                    f.write(":")
                elif j == 2:
                    f.write(";")
    f.write("}\n")
f.write("#!\n\n")   # symbol for the end of elements

f.write("_<number_of_substructures>={" + str(len(bpy.data.objects[str(part_name)].data.materials)) + "}\n")    # number of substructures the problem will be divided into

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
    f.write("_<" + str(i) + ">={" + str(len(buf)) + "}\n")   # starts off the list by substructure index and the number of elements it contains
    for j in range(len(buf)):
        f.write("_" + str(i) + "={" + str(buf[j]) + "}")
        if j == len(buf) - 1:    # if it is the last one
            f.write(";")
        f.write("\n")
f.write("_!\n\n")   # symbol for the end of substructures

sups = len(bpy.data.objects[str(part_name)].vertex_groups)  # number of support types
f.write("^<number_of_support_types>={" + str(sups) + "}\n") # number of different types of supports used

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)
    f.write("^\"" + str(bpy.data.objects[str(part_name)].vertex_groups[i].name + "\'<" + str(i) + ">={" + str(len(buf)) + "}\n"))
    for j in range(len(buf)):
        f.write("^" + str(i) + "={" + str(buf[j]) + "}") # it gets printed out
        if j == len(buf) - 1:   # if it is the last one
            f.write(";")    # indicate the end
        f.write("\n")
f.write("^!\n\n")  # symbol for the end of supports

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
f.write("$<number_of_forces>={" + str(forces) + "}")

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:
        f.write("\n")
        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
            f.write("$" + str(index_buf) + "={")   # it prints out the vertex index
            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
            f.write("{0:.6f};{1:.6f}".format(xcor, ycor))
            f.write("}")
        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
            f.write("$" + str(index_buf) + "={")   # it prints out the vertex index
            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
            f.write("{0:.6f};{1:.6f}".format(xcor, ycor))
            f.write("}")
f.write(";\n$!\n\n")   # symbol for the end of forces

f.write("!*")
f.close()
