#!/usr/bin/env python3
"""Spirale de nivellement : une seule couche, du centre au bord, sans slicer.

    ./make-spiral.py > gcodes/spiral_pla.gcode

Une ligne continue posee en spirale d'Archimede : chaque spire est a PITCH mm
de la precedente, jusqu'au rayon R_MAX. Imprimee, elle montre d'un coup d'oeil
ou la buse est trop pres (cordon plat, translucide, ecrase) et ou elle est
trop loin (cordon rond, mal colle). C'est le test de premiere couche le plus
lisible sur un plateau rond. 12 minutes sur une FLSun QQ-S.

Le debut (M140/M104 puis START_PRINT) suppose la macro START_PRINT de
printer.cfg ; adapter si besoin.
"""
import math

BED, HOTEND = 60, 210          # PLA
R_MAX = 120.0                  # rayon de la derniere spire (plateau de 130)
PITCH = 2.5                    # ecart entre deux spires
LAYER, WIDTH = 0.20, 0.45      # hauteur de couche, largeur de cordon
FILAMENT = 1.75
SPEED, TRAVEL = 25 * 60, 150 * 60
SEG = 1.0                      # longueur d'un segment (mm)
R0 = 2.0                       # rayon de depart

e_per_mm = LAYER * WIDTH / (math.pi * (FILAMENT / 2) ** 2)


def point(theta):
    r = PITCH * theta / (2 * math.pi)
    return r * math.cos(theta), r * math.sin(theta), r


def main():
    print("; spirale de nivellement - 1 couche %.1f, spires tous les %.1f mm, r max %g" % (LAYER, PITCH, R_MAX))
    print("; generee par make-spiral.py (pas de slicer)")
    print("M140 S%d\nM104 S%d\nSTART_PRINT BED=%d HOTEND=%d" % (BED, HOTEND, BED, HOTEND))
    print("M82\nG92 E0\nM106 S0")
    theta = R0 * 2 * math.pi / PITCH
    x, y, r = point(theta)
    print("G1 Z5 F%d\nG1 X%.3f Y%.3f F%d\nG1 Z%.2f F%d\nG1 F%d" % (TRAVEL, x, y, TRAVEL, LAYER, TRAVEL, SPEED))
    e = 0.0
    while True:
        theta += min(SEG / max(r, 1.0), 0.4)
        nx, ny, r = point(theta)
        if r > R_MAX:
            break
        e += math.hypot(nx - x, ny - y) * e_per_mm
        print("G1 X%.3f Y%.3f E%.4f" % (nx, ny, e))
        x, y = nx, ny
    print("G1 E%.4f F1800" % (e - 4))          # retraction
    print("G1 Z5 F%d" % TRAVEL)
    print("END_PRINT")


if __name__ == "__main__":
    main()
