import bpy   
from mathutils import Vector
from math import sin,cos,acos
# creer un cercle qui servira de section
sectionData=bpy.data.curves.new(name='Section',type='CURVE')
# definir quelque variables
w = 1 # weight  
n_points=64
pi=3.1416
two_pi=2*pi
div= two_pi/(n_points-1)
global compteur
compteur=0
global cList 
cList = [Vector((0,0,0))] 
global z,zInc
# interplolation  (Python utilise les indents pour definir les blocs) (C utilise les accolades)
def myRange(i,from0,to0):
    from1=from0+3
    to1=to0-3
    return from1+(i-from0)*(to1-from1)/(to0-from0)
# ---------------PREPARER UN ETAGE
def plot(afrom,ato):
    global z,zInc,start
    o2=100
    zInc=  .1  # increment vertical 
    afrom=afrom*scale
    ato=ato*scale
    plotter(afrom,ato,o2)
    print ("nombre de points cumulés",len(cList)) 
# ----------------CREER LA LISTE DES POINTS D UN ETAGE
def plotter(afrom,ato,o2): 
    global compteur
    global rot0,rot1
    global cList
    global z,zInc
    rot0=0
    rot1=0
#   Balayage de 360 degrés divisés en n_points
    for i in range(1,n_points): # de 0 a 64  
    # courbes horlogiques      
        if(afrom<50):
           radius=afrom + i*(ato-afrom)/(n_points-1)
           x=radius*cos (i*div)  #pas d'offset car le centre est à gauche          
        # Etablissement de la correction d angle rot
           # seconds et avant derniers points
           if (i==1):
                rot0=2*(pi/2-acos((x-afrom)/afrom))
           if (i==n_points-2):
                rot0=-2*(pi/2-acos((x-ato)/ato))
         # premiers et derniers points
           if(i==0):
               rot1=0
               print("--------courbe centre O ",afrom)
           if (i==n_points-1):
                rot1=0
         # interploation à partir de rot0 et rot1
           rot=rot0*(i/n_points) + rot1*(1-i/n_points)
         # calcul des coordonnées 3D
           x=radius*cos (i*div +rot) 
           y=radius*sin(i*div)
           z+=zInc
           cList.append (Vector((x,y,z)))
     #courbes anti-horlogiques
        if(afrom > 50):
           irev=n_points-i-1
           iloc=myRange(irev,0,n_points)
           radius=o2-ato+ irev*(ato-afrom)/(n_points-1)
           x=o2+radius*cos (irev*div+pi)
           if (i==1):
                print("--------courbe centre O2 ",afrom," to ", ato)
                rot0=2*(pi/2-acos((o2-x)/radius))
                print("o2-x = ",o2-x ,"radius = ",radius,"rot0 = ",rot0)
           if (i==n_points-2):
                rot1=-2*(pi/2-acos((x-ato)/radius))
                print("x-ato = ",x-ato,"radius = ",radius,"rot1 = ",rot1)
           if(i==0):
               rot0=0
           if (i==n_points-1):
                rot1=0
           rot=0
           if (correctionGlobale):
                rot=rot0*(i/n_points) + rot1*(1-i/n_points)
           y=radius*sin(irev*div+pi+ rot)
           z+=zInc
           cList.append (Vector((x,y,z)))
def extrudeList():
#   DESSINER LA LISTE ET EXTRUDER
    global cList 
# Tronc commun traduire les listes de points en courbes  
    curvedata = bpy.data.curves.new(name='Curve', type='CURVE')
    curvedata.dimensions = '3D'  
    nom= "courbe"
    objectdata = bpy.data.objects.new(nom, curvedata)   
    objectdata.location = (0,0,0) #object origin  
    bpy.context.scene.objects.link(objectdata)   
    polyline = curvedata.splines.new('POLY')   
    polyline.points.add(len(cList)-1)   
    for num in range(len(cList)):   
        x, y, z = cList[num]   
        polyline.points[num].co = (x, y, z, w)                               
#  créer le cercle de section et l'appliquer
    bpy.data.objects["Section"].select=False
    dum=bpy.data.objects["Section"]
    bpy.data.objects[nom].data.bevel_object=dum
    bpy.data.objects[nom].data.use_fill_caps=True
#   finalisation du rendu
    bpy.data.objects[nom].scale=(scaleRendu,scaleRendu,scaleRendu)
    bpy.data.objects[nom].select=True
# MAIN 
print("==============================================")
scale=1  #  jusqu'a 2 , décale les deux attracteurs et provoque des inversions
z=0
scaleRendu=.4  # la taille globale de l'objet
scaleSection=16*scaleRendu   # l'épaiseur du spaghetto
correctionGlobale=False 
bpy.ops.curve.primitive_bezier_circle_add(radius=.5,location=(0,0,0))
bpy.data.objects["BezierCircle"].name= "Section"
bpy.data.objects["Section"].scale=Vector((scaleSection,scaleSection,scaleSection))
start=94
cList = [Vector((start,0,0))] # ajout pour demarrer
cTest=[start]
for loop in range(1,25):  # Le ressort n'a jamais plus de 25 etages
    end = 2* start # LA FORMULE 
    if(end>100):
        end=end-100
    cTest.append(end)
    plot(start,end)
    print ("bbbbbbbb",loop,start,end)
# Est ce la fin ?   et ou boucle t on ?
    if (loop>3 and end ==cTest[0]):
        print ("break at first",end, "loops : ",loop)
        break
    if (loop>3 and end ==cTest[1]):
        print ("break at second",end, "loops : ",loop)
        break
    if (loop>3 and end ==cTest[2]):
        print ("break at third",end, "loops : ",loop)
        break
    if (loop>3 and end ==cTest[3]):
        print ("break at fourth",end, "loops : ",loop)
        break
    start=end
print(" ================make =======================")
extrudeList()

 
	
						
								
						
							 
	
						
								
						
							 
	
						
								
						
							 
	
						
								
						
							 
	
						
								
						
							