agerhund commited on
Commit
5222b98
·
verified ·
1 Parent(s): a58ce0e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -42
app.py CHANGED
@@ -72,8 +72,6 @@ if 'is_example' not in st.session_state: st.session_state.is_example = False
72
  @st.cache_resource
73
  def download_models():
74
  """Descarga ambos modelos grandes desde el Model Repository y devuelve las rutas locales temporales."""
75
- st.info("Descargando modelos grandes desde Hugging Face Hub (¡Solo la primera vez!)...")
76
-
77
  bert_path = hf_hub_download(repo_id=MODEL_REPO_ID, filename=MODEL_FILE_BERT)
78
  horizon_path = hf_hub_download(repo_id=MODEL_REPO_ID, filename=MODEL_FILE_HORIZON)
79
 
@@ -86,12 +84,18 @@ def init_backend(csv, cache, bert_model_path):
86
  df = dm.cargar_datos()
87
  return dm, df
88
 
89
- # --- 1. CARGA DE DATOS Y MODELOS (Cacheado) ---
90
  try:
91
  if st.session_state.data_manager is None:
92
 
 
 
 
 
93
  bert_path_downloaded, horizon_path_downloaded = download_models()
94
 
 
 
95
  with st.spinner("Cargando base de datos de muebles y modelos IA..."):
96
 
97
  dm, df = init_backend(csv_path, cache_path, bert_path_downloaded)
@@ -100,6 +104,8 @@ try:
100
  st.session_state.muebles_df = df
101
  st.session_state.horizon_model_path = horizon_path_downloaded
102
 
 
 
103
  st.sidebar.success(f"Base de datos cargada: {len(st.session_state.muebles_df)} items")
104
 
105
  except Exception as e:
@@ -140,41 +146,33 @@ st.header("1. Escaneo de Habitación")
140
 
141
  # --- LÓGICA DE SELECCIÓN DE EJEMPLOS EN EL CUERPO PRINCIPAL ---
142
  examples_dir = os.path.join(os.path.dirname(__file__), "examples")
143
- source_file = None
144
- file_caption = None
145
 
146
  if os.path.exists(examples_dir):
147
  example_files = [f for f in os.listdir(examples_dir) if f.endswith(('.jpg', '.png'))]
148
  example_files.sort()
149
 
150
- # 1. Creamos el selector de ejemplos
151
- display_files = ["--- Cargar imagen manualmente (prioridad) ---"] + example_files
152
-
153
- # Usamos st.empty para evitar re-render innecesario al mostrar la imagen
154
  col_select, col_download = st.columns([3, 1])
155
 
156
  with col_select:
 
 
 
157
  selected_example_name = st.selectbox(
158
  "O usa una imagen de ejemplo:",
159
  display_files,
160
- key='example_select_box',
161
- # El on_change es clave para forzar la actualización solo cuando el valor cambia
162
- on_change=lambda: st.session_state.update(
163
- # Forzar el re-render solo si el valor ha cambiado
164
- source_file_path=os.path.join(examples_dir, st.session_state.example_select_box) if st.session_state.example_select_box != display_files[0] else None,
165
- is_example=st.session_state.example_select_box != display_files[0]
166
- )
167
  )
168
 
169
- # 2. Manejo de la selección del ejemplo
170
- is_example_selected = st.session_state.get('is_example', False)
171
- source_file_path = st.session_state.get('source_file_path', None)
 
 
172
 
173
- if is_example_selected and source_file_path:
174
  with col_download:
175
- # Poner el botón de descarga en la columna derecha
176
  st.markdown(" ")
177
- with open(source_file_path, "rb") as file:
178
  st.download_button(
179
  label=f"⬇️ Descargar: {selected_example_name}",
180
  data=file,
@@ -182,24 +180,34 @@ if os.path.exists(examples_dir):
182
  mime="image/jpeg"
183
  )
184
 
185
- # Mostrar miniatura del ejemplo
186
- st.image(source_file_path, caption="Vista previa del ejemplo", use_container_width=True)
 
 
 
 
 
 
 
 
187
 
188
- # 2. Selector de carga manual (Se mantiene aquí, pero solo para subir el archivo)
189
- uploaded_file = st.file_uploader("Sube tu imagen panorámica (360)", type=['jpg', 'png', 'jpeg'])
 
190
 
191
  # Determinar qué archivo usar (la carga manual tiene prioridad)
192
- source_file_path_session = st.session_state.get('source_file_path', None)
193
- is_example_session = st.session_state.get('is_example', False)
194
 
195
  if uploaded_file is not None:
196
  source_file = uploaded_file
197
  file_caption = 'Imagen subida'
198
  is_example = False
199
- elif source_file_path_session and is_example_session:
200
- source_file = source_file_path_session
201
- file_caption = f'Imagen de ejemplo: {source_file_path_session.split(os.sep)[-1]}'
202
- is_example = True
 
203
  else:
204
  source_file = None
205
 
@@ -213,7 +221,8 @@ if source_file is not None:
213
 
214
  # Mostrar la imagen subida (solo si es subida, ya que el ejemplo se mostró arriba)
215
  if uploaded_file is not None:
216
- st.image(image, caption=file_caption, use_container_width=True)
 
217
 
218
  if st.button("Analizar la habitación"):
219
  with st.spinner("Detectando la geometría..."):
@@ -241,7 +250,8 @@ if source_file is not None:
241
  else:
242
  st.session_state.room_data = room_data
243
  st.session_state.stage = 1
244
- st.success("Análisis completado")
 
245
 
246
  # Mostrar resultado de la detección de HorizonNet
247
  st.header("Resultado del análisis visual")
@@ -359,14 +369,14 @@ if st.session_state.stage >= 2:
359
  presupuesto = st.number_input("Presupuesto Máximo (€)", min_value=100.0, value=1000.0, step=100.0)
360
 
361
  if st.button("Generar diseño"):
362
- # Convertir dimensiones de m a cm para el LayoutEngine
363
- w_cm = st.session_state.room_data.get('width', 0.0) * 100
364
- l_cm = st.session_state.room_data.get('length', 0.0) * 100
365
-
366
- if w_cm < 200 or l_cm < 200:
367
- st.error("Las dimensiones de la habitación son demasiado pequeñas (mínimo 2x2m) o no fueron capturadas correctamente.")
368
- else:
369
- with st.spinner("Calculando distribución óptima y seleccionando muebles..."):
370
  # 1. Inicializar motores
371
  layout_engine = logic.LayoutEngine(st.session_state.data_manager.dimensiones_promedio)
372
  recommender = logic.Recommender(st.session_state.muebles_df)
 
72
  @st.cache_resource
73
  def download_models():
74
  """Descarga ambos modelos grandes desde el Model Repository y devuelve las rutas locales temporales."""
 
 
75
  bert_path = hf_hub_download(repo_id=MODEL_REPO_ID, filename=MODEL_FILE_BERT)
76
  horizon_path = hf_hub_download(repo_id=MODEL_REPO_ID, filename=MODEL_FILE_HORIZON)
77
 
 
84
  df = dm.cargar_datos()
85
  return dm, df
86
 
87
+ # --- 1. CARGA DE DATOS Y MODELOS (Cacheado y estabilizado) ---
88
  try:
89
  if st.session_state.data_manager is None:
90
 
91
+ # 1. Usar contenedor para el mensaje de descarga (Estabiliza el salto)
92
+ status_message = st.empty()
93
+ status_message.info("Descargando modelos grandes desde Hugging Face Hub (¡Solo la primera vez!)...")
94
+
95
  bert_path_downloaded, horizon_path_downloaded = download_models()
96
 
97
+ # 2. Limpiar el placeholder de descarga y mostrar el spinner de carga de datos
98
+ status_message.empty()
99
  with st.spinner("Cargando base de datos de muebles y modelos IA..."):
100
 
101
  dm, df = init_backend(csv_path, cache_path, bert_path_downloaded)
 
104
  st.session_state.muebles_df = df
105
  st.session_state.horizon_model_path = horizon_path_downloaded
106
 
107
+ st.toast("Modelos y datos cargados con éxito.", icon="✅")
108
+
109
  st.sidebar.success(f"Base de datos cargada: {len(st.session_state.muebles_df)} items")
110
 
111
  except Exception as e:
 
146
 
147
  # --- LÓGICA DE SELECCIÓN DE EJEMPLOS EN EL CUERPO PRINCIPAL ---
148
  examples_dir = os.path.join(os.path.dirname(__file__), "examples")
149
+ image_placeholder = st.empty() # Placeholder para la imagen (Estabiliza el temblor)
 
150
 
151
  if os.path.exists(examples_dir):
152
  example_files = [f for f in os.listdir(examples_dir) if f.endswith(('.jpg', '.png'))]
153
  example_files.sort()
154
 
 
 
 
 
155
  col_select, col_download = st.columns([3, 1])
156
 
157
  with col_select:
158
+ # Añadimos la opción de carga manual como la principal
159
+ display_files = ["--- Cargar imagen manualmente (prioridad) ---"] + example_files
160
+
161
  selected_example_name = st.selectbox(
162
  "O usa una imagen de ejemplo:",
163
  display_files,
164
+ key='example_select_box'
 
 
 
 
 
 
165
  )
166
 
167
+ # Manejo de la selección del ejemplo
168
+ if selected_example_name != display_files[0]:
169
+ file_path = os.path.join(examples_dir, selected_example_name)
170
+ st.session_state.source_file_path = file_path
171
+ st.session_state.is_example = True
172
 
 
173
  with col_download:
 
174
  st.markdown(" ")
175
+ with open(file_path, "rb") as file:
176
  st.download_button(
177
  label=f"⬇️ Descargar: {selected_example_name}",
178
  data=file,
 
180
  mime="image/jpeg"
181
  )
182
 
183
+ # Mostrar miniatura del ejemplo en el placeholder
184
+ with image_placeholder.container():
185
+ st.image(file_path, caption="Vista previa del ejemplo", use_container_width=True)
186
+
187
+ else:
188
+ # Limpiar las variables si se selecciona la opción nula
189
+ if 'source_file_path' in st.session_state:
190
+ del st.session_state.source_file_path
191
+ st.session_state.is_example = False
192
+ image_placeholder.empty() # Limpiar el placeholder si no hay selección de ejemplo
193
 
194
+
195
+ # 1. Selector de carga manual (Se mantiene aquí, pero solo para subir el archivo)
196
+ uploaded_file = st.file_uploader("Sube tu imagen panorámica (360)", type=['jpg', 'png', 'jpeg'], key='main_file_uploader')
197
 
198
  # Determinar qué archivo usar (la carga manual tiene prioridad)
199
+ source_file_path = st.session_state.get('source_file_path', None)
200
+ is_example = st.session_state.get('is_example', False)
201
 
202
  if uploaded_file is not None:
203
  source_file = uploaded_file
204
  file_caption = 'Imagen subida'
205
  is_example = False
206
+ st.session_state.is_example = False # Resetear por seguridad
207
+ image_placeholder.empty() # Limpiar el placeholder si hay una subida manual
208
+ elif source_file_path is not None and is_example == True:
209
+ source_file = source_file_path
210
+ file_caption = f'Imagen de ejemplo: {source_file_path.split(os.sep)[-1]}'
211
  else:
212
  source_file = None
213
 
 
221
 
222
  # Mostrar la imagen subida (solo si es subida, ya que el ejemplo se mostró arriba)
223
  if uploaded_file is not None:
224
+ with image_placeholder.container():
225
+ st.image(image, caption=file_caption, use_container_width=True)
226
 
227
  if st.button("Analizar la habitación"):
228
  with st.spinner("Detectando la geometría..."):
 
250
  else:
251
  st.session_state.room_data = room_data
252
  st.session_state.stage = 1
253
+
254
+ st.toast("Análisis completado", icon="✅")
255
 
256
  # Mostrar resultado de la detección de HorizonNet
257
  st.header("Resultado del análisis visual")
 
369
  presupuesto = st.number_input("Presupuesto Máximo (€)", min_value=100.0, value=1000.0, step=100.0)
370
 
371
  if st.button("Generar diseño"):
372
+ with st.spinner("Calculando distribución óptima y seleccionando muebles..."):
373
+ # Convertir dimensiones de m a cm para el LayoutEngine
374
+ w_cm = st.session_state.room_data.get('width', 0.0) * 100
375
+ l_cm = st.session_state.room_data.get('length', 0.0) * 100
376
+
377
+ if w_cm < 200 or l_cm < 200:
378
+ st.error("Las dimensiones de la habitación son demasiado pequeñas (mínimo 2x2m) o no fueron capturadas correctamente.")
379
+ else:
380
  # 1. Inicializar motores
381
  layout_engine = logic.LayoutEngine(st.session_state.data_manager.dimensiones_promedio)
382
  recommender = logic.Recommender(st.session_state.muebles_df)