Help merging curves

Hi there. Im working on a script that merges beziers points.

Its working but im a crappy programmer and the code isnt so fine.

It works merging splines inside the same curve if the points are close enough defined by a limit.

I had problems iterating through splines and the script fails if one spline isnt about to be merged.

if u can think any easier way to do this please tell me.

heres the blendand the code:


#mergue points
import bpy
print("----------------------------")
limit = 0.1

def setcursor(pos):
    bpy.data.scenes[0].cursor_location = pos

#distance between 2 points
def dist(p1, p2):
    distance = abs((p1-p2).magnitude)
    return distance

#gets the curve
if bpy.context.edit_object==None:
    c1obj = bpy.context.selected_objects[0]
else:
    c1obj = bpy.context.edit_object
        
#curve matrix 
mat = c1obj.matrix_world


splines = []
for sp in c1obj.data.splines:
    splines.append(sp)

#merge 2 splines and returns the new spline
def merge(spl1, spl2):
    newc = []
    #first and ending points of eeach spline
    p0i = spl1.bezier_points[0]
    p0f = spl1.bezier_points[-1]
    p1i = spl2.bezier_points[0]
    p1f = spl2.bezier_points[-1]
    col = [p0i, p0f, p1i, p1f]
    
    #domerge
    dom=0
    
    #compares all the points in col
    for i in range(0, len(col)):
        p1 = col[i]
        for j in range(0, len(col)):
            p2 = col[j]
            if p1!=p2 and dist(p1.co, p2.co)<=limit:
                dom=1
                print(i, j)
                break
        if dom: break
    if dom:
        
        co1 = mat * p1.co
        co2 = mat * p2.co
        
        #midpoint between closest points
        con = co1 + (co2-co1)*0.5
        
        #how to fill the points
        if i==0:
            #spl1 goes forward
            
            if j==2:
                union = [col[j].handle2, con, col[i].handle2]
                #spl2 goes backwards
                for k in range(0, len(spl2.bezier_points)):
                    x = (len(spl2.bezier_points)-1)-k
                    if k==len(spl2.bezier_points)-1:
                        newc.append([union, 'FREE', 'FREE'])
                    else:
                        p10 = mat * spl2.bezier_points[x].handle1
                        p11 = mat * spl2.bezier_points[x].co
                        p12 = mat * spl2.bezier_points[x].handle2
                        h1type = spl2.bezier_points[x].handle1_type
                        h2type = spl2.bezier_points[x].handle2_type
                        newc.append([[p12, p11, p10], h2type, h1type])
                        
                for l in range(0, len(spl1.bezier_points)):
                    if l!=0:
                        p20 = mat * spl1.bezier_points[l].handle1
                        p21 = mat * spl1.bezier_points[l].co
                        p22 = mat * spl1.bezier_points[l].handle2
                        h1type = spl1.bezier_points[l].handle1_type
                        h2type = spl1.bezier_points[l].handle2_type
                        newc.append([[p20, p21, p22], h1type, h2type])    
                        
            else:
                union = [col[j].handle1, con, col[i].handle2]    
                
                #spl2 goes forward
                for k in range(0, len(spl2.bezier_points)):
                    if k==len(spl2.bezier_points)-1:
                        newc.append([union, 'FREE', 'FREE'])
                    else:
                        p10 = mat * spl2.bezier_points[k].handle1
                        p11 = mat * spl2.bezier_points[k].co
                        p12 = mat * spl2.bezier_points[k].handle2
                        h1type = spl2.bezier_points[k].handle1_type
                        h2type = spl2.bezier_points[k].handle2_type
                        newc.append([[p10, p11, p12], h1type, h2type])
                        
                for l in range(0, len(spl1.bezier_points)):
                    if l!=0:
                        p20 = mat * spl1.bezier_points[l].handle1
                        p21 = mat * spl1.bezier_points[l].co
                        p22 = mat * spl1.bezier_points[l].handle2
                        h1type = spl1.bezier_points[l].handle1_type
                        h2type = spl1.bezier_points[l].handle2_type
                        newc.append([[p20, p21, p22], h1type, h2type])
                
        else:
            #spl1 goes forward
            if j==2:
                
                union = [col[i].handle1, con, col[j].handle2]
    
                for k in range(0, len(spl1.bezier_points)):
                    if k==len(spl1.bezier_points)-1:
                        newc.append([union, 'FREE', 'FREE'])
                    else:
                        p10 = mat * spl1.bezier_points[k].handle1
                        p11 = mat * spl1.bezier_points[k].co
                        p12 = mat * spl1.bezier_points[k].handle2
                        h1type = spl1.bezier_points[k].handle1_type
                        h2type = spl1.bezier_points[k].handle2_type
                        
                        newc.append([[p10, p11, p12], h1type, h2type] )
                #spl2 forward
                for l in range(0, len(spl2.bezier_points)):
                    if l!=0:
                        p20 = mat * spl2.bezier_points[l].handle1
                        p21 = mat * spl2.bezier_points[l].co
                        p22 = mat * spl2.bezier_points[l].handle2
                        h1type = spl1.bezier_points[l].handle1_type
                        h2type = spl1.bezier_points[l].handle2_type
                        newc.append([[p20, p21, p22], h1type, h2type])
                
            else:
                #spl2 backward
                union = [col[i].handle1, con, col[j].handle1]
                for k in range(0, len(spl1.bezier_points)):
                    if k==len(spl1.bezier_points)-1:
                        newc.append([union, 'FREE', 'FREE'])
                    else:
                        p10 = mat * spl1.bezier_points[k].handle1
                        p11 = mat * spl1.bezier_points[k].co
                        p12 = mat * spl1.bezier_points[k].handle2
                        h1type = spl1.bezier_points[k].handle1_type
                        h2type = spl1.bezier_points[k].handle2_type
                        newc.append([[p10, p11, p12], h1type, h2type])
                for l in range(0, len(spl2.bezier_points)):
                    x = (len(spl2.bezier_points)-1)-l
                    if l!=0:
                        p20 = mat * spl2.bezier_points[x].handle1
                        p21 = mat * spl2.bezier_points[x].co
                        p22 = mat * spl2.bezier_points[x].handle2
                        h1type = spl2.bezier_points[x].handle1_type
                        h2type = spl2.bezier_points[x].handle2_type
                        newc.append([[p20, p21, p22], h1type, h2type])
        #create spline
        
        j=0
        cu = bpy.data.curves.new(c1obj.name+"."+str(j), "CURVE")
        cu.splines.new('BEZIER')
        
        for p in newc:
            
            if j!=0:
                cu.splines[0].bezier_points.add()
            
            cu.splines[0].bezier_points[j].handle1 = p[0][0]
            cu.splines[0].bezier_points[j].co = p[0][1]
            cu.splines[0].bezier_points[j].handle2 = p[0][2]
            cu.splines[0].bezier_points[j].handle1_type = p[1]
            cu.splines[0].bezier_points[j].handle2_type = p[2]
            
            j+=1        
        
        #we are not creating the curve here,
        #just return the spline at the moment
        
        #curve = bpy.data.objects.new(c1obj.name+"."+str(j), cu)
        #bpy.context.scene.objects.link(curve)
        return cu.splines[0]
    else:
        return None
    
#looks if the splines can be joined
def compare(spl1, spl2):
    p0i = spl1.bezier_points[0]
    p0f = spl1.bezier_points[-1]
    p1i = spl2.bezier_points[0]
    p1f = spl2.bezier_points[-1]
    col = [p0i, p0f, p1i, p1f]
    
    for i in range(0, len(col)):
        dom=0
        p1 = col[i]
        for j in range(0, len(col)):
            p2 = col[j]
            if p1!=p2 and dist(p1.co, p2.co)<=limit:
                dom=1
                #print(i, j)
                break
        if dom: break
    if dom:
        return True
    else:
        return False

#curve object
c1obj = bpy.data.objects['Curve']

#splines collection    
splines = []
for spl in c1obj.data.splines:
    splines.append(spl)

#splines comparison
i=0
for spl1 in splines:
    j=0
    for spl2 in splines:
        if spl1!=spl2:
            x = compare(spl1, spl2)
            print(i, j, x)
            if x:
                spln = merge(spl1, spl2)
                splines.remove(spl1)
                splines.remove(spl2)
                splines.append(spln)
        j+=1
    i+=1


#creating the merged curve
cu = bpy.data.curves.new(c1obj.name+"."+str(j), "CURVE")

cu.splines.new('BEZIER')
j=0    
for p in spln.bezier_points:
    
    if j!=0:
        cu.splines[0].bezier_points.add()

    cu.splines[0].bezier_points[j].handle1 = p.handle1
    cu.splines[0].bezier_points[j].co = p.co
    cu.splines[0].bezier_points[j].handle2 = p.handle2
    cu.splines[0].bezier_points[j].handle1_type = p.handle1_type
    cu.splines[0].bezier_points[j].handle2_type = p.handle2_type
    
    j+=1        
        
curve = bpy.data.objects.new(c1obj.name+"."+str(j), cu)
bpy.context.scene.objects.link(curve)


Ok heres the deal:
Let me make the problem easier:
Lets say we got an array like:

arr = [7, 10, 5, 11, 6, 14]

we have to sort the array but those numbers represents splines so we cannot order them like comparing if they are greater or less than.

what we can do is knowing if one number is forward or behind another.
like:


def compare(n1, n2):
    if n1==n2-1:
        return "forward"
    if n1==n2+1:
        return "behind"
    else:
        return "isolated"

the function im looking for should return:
solution = [[5, 6, 7], [10, 11], [14]]

any idea for the function that can sort the array like that?

thank you so much.