x2XcarleX2x commited on
Commit
3c5146f
·
verified ·
1 Parent(s): 09f64ca

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -7
app.py CHANGED
@@ -37,7 +37,6 @@ def gerar_sequencia_completa(angulo_camera: int, progress=gr.Progress(track_tqdm
37
  NUM_CICLOS = 10
38
  clipes_de_video = []
39
 
40
- # Estado inicial da simulação
41
  estado = {
42
  "ponto_b": np.array([-40., 20., 10.]),
43
  "vetor_inercia": np.array([30., 10., -20.])
@@ -46,17 +45,99 @@ def gerar_sequencia_completa(angulo_camera: int, progress=gr.Progress(track_tqdm
46
  for ciclo_atual in range(NUM_CICLOS):
47
  progress(ciclo_atual / NUM_CICLOS, desc=f"Processando Ciclo {ciclo_atual + 1}/{NUM_CICLOS}")
48
 
49
- # 1. Atualiza o estado para o novo ciclo
50
  ponto_a = estado["ponto_b"]
51
  vetor_inercia_anterior = estado["vetor_inercia"]
52
  ponto_b = np.random.rand(3) * 120 - 60
53
 
54
- # 2. Calcula a trajetória
55
  ponto_controle = ponto_a + vetor_inercia_anterior
56
  pontos_curva = [ponto_a, ponto_controle, ponto_b]
57
- x_traj, y_traj, z_traj = bezier_curve_3d(pontos_curva) # 60 vetores
58
  total_frames = len(x_traj)
59
 
60
- # 3. Aprende o eco para o próximo ciclo
61
- tamanho_eco = 20 # Eco menor para trajetórias mais curtas
62
- pontos_eco = list(zip(x_traj[-tamanho
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  NUM_CICLOS = 10
38
  clipes_de_video = []
39
 
 
40
  estado = {
41
  "ponto_b": np.array([-40., 20., 10.]),
42
  "vetor_inercia": np.array([30., 10., -20.])
 
45
  for ciclo_atual in range(NUM_CICLOS):
46
  progress(ciclo_atual / NUM_CICLOS, desc=f"Processando Ciclo {ciclo_atual + 1}/{NUM_CICLOS}")
47
 
 
48
  ponto_a = estado["ponto_b"]
49
  vetor_inercia_anterior = estado["vetor_inercia"]
50
  ponto_b = np.random.rand(3) * 120 - 60
51
 
 
52
  ponto_controle = ponto_a + vetor_inercia_anterior
53
  pontos_curva = [ponto_a, ponto_controle, ponto_b]
54
+ x_traj, y_traj, z_traj = bezier_curve_3d(pontos_curva)
55
  total_frames = len(x_traj)
56
 
57
+ tamanho_eco = 20
58
+ # --- CORREÇÃO DO SYNTAXERROR AQUI ---
59
+ pontos_eco = list(zip(x_traj[-tamanho_eco:], y_traj[-tamanho_eco:], z_traj[-tamanho_eco:]))
60
+ # ------------------------------------
61
+ vetor_inercia_novo = aprender_com_o_eco_3d(pontos_eco)["velocity_vector"]
62
+
63
+ estado = {"ponto_b": ponto_b, "vetor_inercia": vetor_inercia_novo}
64
+
65
+ fig = plt.figure(figsize=(8, 8)); ax = fig.add_subplot(111, projection='3d')
66
+
67
+ cor_fundo = '#0a0a0a'; fig.patch.set_facecolor(cor_fundo); ax.set_facecolor(cor_fundo)
68
+ ax.xaxis.pane.fill = False; ax.yaxis.pane.fill = False; ax.zaxis.pane.fill = False
69
+ ax.grid(color='#222222', linestyle='--')
70
+
71
+ ax.plot(x_traj, y_traj, z_traj, color='cyan', linewidth=1.5, alpha=0.2) # Trajetória completa mais sutil
72
+ ax.scatter(*ponto_a, s=150, c='lime', alpha=0.9, edgecolors='w', linewidth=0.5)
73
+ ax.scatter(*ponto_b, s=150, c='yellow', marker='X', alpha=0.9, edgecolors='w', linewidth=0.5)
74
+ ax.view_init(elev=30., azim=angulo_camera)
75
+ ax.set_xlim(-70, 70); ax.set_ylim(-70, 70); ax.set_zlim(-70, 70)
76
+ ax.set_xticklabels([]); ax.set_yticklabels([]); ax.set_zticklabels([])
77
+
78
+ bola, = ax.plot([], [], [], 'o', color='#ff4500', markersize=8, markeredgecolor='white', linewidth=2)
79
+
80
+ # --- AJUSTE ESTÉTICO: RASTRO DA BOLA ---
81
+ rastro, = ax.plot([], [], [], '-', color='#ff4500', linewidth=4, alpha=0.6)
82
+ tamanho_rastro = 25 # O rastro terá 25 vetores de comprimento
83
+ # ------------------------------------
84
+
85
+ def update(frame):
86
+ bola.set_data_3d([x_traj[frame]], [y_traj[frame]], [z_traj[frame]])
87
+
88
+ # Atualiza o rastro para mostrar os últimos 'tamanho_rastro' pontos
89
+ start_index = max(0, frame - tamanho_rastro)
90
+ rastro.set_data_3d(x_traj[start_index:frame+1], y_traj[start_index:frame+1], z_traj[start_index:frame+1])
91
+
92
+ return bola, rastro,
93
+
94
+ ani = FuncAnimation(fig, update, frames=total_frames, interval=33, blit=True)
95
+ clip_filename = f"clip_{ciclo_atual}.mp4"
96
+ ani.save(clip_filename, writer='ffmpeg', fps=30, dpi=120)
97
+ plt.close(fig)
98
+ clipes_de_video.append(clip_filename)
99
+
100
+ progress(0.95, desc="Concatenando 10 clipes em um vídeo final...")
101
+
102
+ with open("lista_de_clipes.txt", "w") as f:
103
+ for clip in clipes_de_video:
104
+ f.write(f"file '{os.path.abspath(clip)}'\n")
105
+
106
+ video_final = "sequencia_convergencia_final.mp4"
107
+ comando = f"ffmpeg -y -f concat -safe 0 -i lista_de_clipes.txt -c copy {video_final}"
108
+ subprocess.run(comando, shell=True, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
109
+
110
+ for clip in clipes_de_video: os.remove(clip)
111
+ os.remove("lista_de_clipes.txt")
112
+
113
+ return video_final
114
+
115
+ # --- Interface Gradio (Inalterada) ---
116
+
117
+ with gr.Blocks(theme=gr.themes.Base(primary_hue="blue")) as demo:
118
+ gr.Markdown(
119
+ """
120
+ # 🎬 Estúdio de Animação de Convergência 3D
121
+ Clique no botão para gerar uma sequência contínua de **10 ciclos**. Cada ciclo tem **60 vetores**.
122
+ O sistema irá renderizar cada ciclo e concatenar todos em um único vídeo de demonstração.
123
+ """
124
+ )
125
+
126
+ with gr.Row():
127
+ with gr.Column(scale=1):
128
+ gr.Markdown("### 🎮 Controles")
129
+ angulo_camera_slider = gr.Slider(-180, 180, value=45, label="Ângulo da Câmera (Fixo)")
130
+ generate_btn = gr.Button("🚀 Gerar Sequência Completa (10 Ciclos)", variant="primary")
131
+
132
+ with gr.Column(scale=2):
133
+ gr.Markdown("### 📽️ Vídeo Final")
134
+ video_output = gr.Video(label="Animação da Sequência Completa", autoplay=True)
135
+
136
+ generate_btn.click(
137
+ fn=gerar_sequencia_completa,
138
+ inputs=[angulo_camera_slider],
139
+ outputs=[video_output]
140
+ )
141
+
142
+ if __name__ == "__main__":
143
+ demo.launch()