Spaces:
Sleeping
Sleeping
Update app/materials_library.py
Browse files- app/materials_library.py +118 -106
app/materials_library.py
CHANGED
@@ -56,7 +56,7 @@ DEFAULT_MATERIALS = {
|
|
56 |
"density": 1920.0,
|
57 |
"specific_heat": 840.0,
|
58 |
"default_thickness": 0.1,
|
59 |
-
"embodied_carbon": 240,
|
60 |
"cost": 180.0,
|
61 |
"absorptivity": 0.65,
|
62 |
"emissivity": 0.90,
|
@@ -350,9 +350,67 @@ def display_materials_page():
|
|
350 |
Display the material library page.
|
351 |
This is the main function called by main.py when the Material Library page is selected.
|
352 |
"""
|
353 |
-
# Initialize
|
354 |
-
if "
|
355 |
-
st.session_state.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
356 |
|
357 |
st.title("Material Library")
|
358 |
|
@@ -377,16 +435,24 @@ def display_materials_page():
|
|
377 |
with col1:
|
378 |
if st.button("Back to Climate Data", key="back_to_climate"):
|
379 |
st.session_state.current_page = "Climate Data"
|
380 |
-
st.session_state.
|
|
|
|
|
|
|
381 |
|
382 |
with col2:
|
383 |
if st.button("Continue to Construction", key="continue_to_construction"):
|
384 |
st.session_state.current_page = "Construction"
|
385 |
-
st.session_state.
|
|
|
|
|
|
|
386 |
|
387 |
-
# Trigger rerun if
|
388 |
-
if st.session_state.
|
389 |
-
st.session_state.
|
|
|
|
|
390 |
st.rerun()
|
391 |
|
392 |
def display_materials_tab():
|
@@ -430,35 +496,20 @@ def display_materials_tab():
|
|
430 |
cols[2].write(f"{u_value:.3f}")
|
431 |
unique_id = str(uuid.uuid4())
|
432 |
if cols[3].button("Preview", key=f"preview_lib_mat_{name}_{unique_id}"):
|
433 |
-
st.session_state.
|
|
|
434 |
"name": name,
|
435 |
-
"
|
436 |
-
"thermal_conductivity": material["thermal_conductivity"],
|
437 |
-
"density": material["density"],
|
438 |
-
"specific_heat": material["specific_heat"],
|
439 |
-
"default_thickness": material["default_thickness"],
|
440 |
-
"embodied_carbon": material["embodied_carbon"],
|
441 |
-
"cost": material["cost"],
|
442 |
-
"absorptivity": material["absorptivity"],
|
443 |
-
"emissivity": material["emissivity"],
|
444 |
-
"colour": material["colour"],
|
445 |
-
"edit_mode": False,
|
446 |
-
"original_name": name,
|
447 |
"is_library": True
|
448 |
}
|
449 |
-
st.session_state.active_tab = "Materials"
|
450 |
-
st.success(f"Previewing material '{name}'")
|
451 |
unique_id = str(uuid.uuid4())
|
452 |
if cols[4].button("Copy", key=f"copy_lib_mat_{name}_{unique_id}"):
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
st.success(f"Material '{new_name}' copied to project.")
|
460 |
-
logger.info(f"Copied library material '{name}' as '{new_name}' to project")
|
461 |
-
st.session_state.needs_rerun = True
|
462 |
else:
|
463 |
st.info("No materials found in the selected category.")
|
464 |
|
@@ -492,34 +543,20 @@ def display_materials_tab():
|
|
492 |
cols[2].write(f"{u_value:.3f}")
|
493 |
unique_id = str(uuid.uuid4())
|
494 |
if cols[3].button("Edit", key=f"edit_proj_mat_{name}_{unique_id}"):
|
495 |
-
st.session_state.
|
|
|
496 |
"name": name,
|
497 |
-
"
|
498 |
-
"thermal_conductivity": material["thermal_conductivity"],
|
499 |
-
"density": material["density"],
|
500 |
-
"specific_heat": material["specific_heat"],
|
501 |
-
"default_thickness": material["default_thickness"],
|
502 |
-
"embodied_carbon": material["embodied_carbon"],
|
503 |
-
"cost": material["cost"],
|
504 |
-
"absorptivity": material["absorptivity"],
|
505 |
-
"emissivity": material["emissivity"],
|
506 |
-
"colour": material["colour"],
|
507 |
-
"edit_mode": True,
|
508 |
-
"original_name": name,
|
509 |
"is_library": False
|
510 |
}
|
511 |
-
st.session_state.active_tab = "Materials"
|
512 |
-
st.success(f"Editing material '{name}'")
|
513 |
unique_id = str(uuid.uuid4())
|
514 |
if cols[4].button("Delete", key=f"delete_proj_mat_{name}_{unique_id}"):
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
logger.info(f"Deleted material '{name}' from project")
|
522 |
-
st.session_state.needs_rerun = True
|
523 |
else:
|
524 |
st.info("No project materials in the selected category.")
|
525 |
|
@@ -590,40 +627,26 @@ def display_fenestrations_tab():
|
|
590 |
|
591 |
for fenestration in filtered_fenestrations:
|
592 |
cols = st.columns([2, 1, 1, 1, 1])
|
593 |
-
name = [k for k
|
594 |
-
|
595 |
-
, v in library_fenestrations.items() if v == fenestration][0]
|
596 |
cols[0].write(name)
|
597 |
cols[1].write(fenestration["type"])
|
598 |
cols[2].write(f"{fenestration['u_value']:.2f}")
|
599 |
unique_id = str(uuid.uuid4())
|
600 |
if cols[3].button("Preview", key=f"preview_lib_fen_{name}_{unique_id}"):
|
601 |
-
st.session_state.
|
|
|
602 |
"name": name,
|
603 |
-
"
|
604 |
-
"u_value": fenestration["u_value"],
|
605 |
-
"shgc": fenestration["shgc"],
|
606 |
-
"visible_transmittance": fenestration["visible_transmittance"],
|
607 |
-
"thickness": fenestration["thickness"],
|
608 |
-
"embodied_carbon": fenestration["embodied_carbon"],
|
609 |
-
"cost": fenestration["cost"],
|
610 |
-
"edit_mode": False,
|
611 |
-
"original_name": name,
|
612 |
"is_library": True
|
613 |
}
|
614 |
-
st.session_state.active_tab = "Fenestrations"
|
615 |
-
st.success(f"Previewing fenestration '{name}'")
|
616 |
unique_id = str(uuid.uuid4())
|
617 |
if cols[4].button("Copy", key=f"copy_lib_fen_{name}_{unique_id}"):
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
st.success(f"Fenestration '{new_name}' copied to project.")
|
625 |
-
logger.info(f"Copied library fenestration '{name}' as '{new_name}' to project")
|
626 |
-
st.session_state.needs_rerun = True
|
627 |
else:
|
628 |
st.info("No fenestrations found in the selected type.")
|
629 |
|
@@ -654,31 +677,20 @@ def display_fenestrations_tab():
|
|
654 |
cols[2].write(f"{fenestration['u_value']:.2f}")
|
655 |
unique_id = str(uuid.uuid4())
|
656 |
if cols[3].button("Edit", key=f"edit_proj_fen_{name}_{unique_id}"):
|
657 |
-
st.session_state.
|
|
|
658 |
"name": name,
|
659 |
-
"
|
660 |
-
"u_value": fenestration["u_value"],
|
661 |
-
"shgc": fenestration["shgc"],
|
662 |
-
"visible_transmittance": fenestration["visible_transmittance"],
|
663 |
-
"thickness": fenestration["thickness"],
|
664 |
-
"embodied_carbon": fenestration["embodied_carbon"],
|
665 |
-
"cost": fenestration["cost"],
|
666 |
-
"edit_mode": True,
|
667 |
-
"original_name": name,
|
668 |
"is_library": False
|
669 |
}
|
670 |
-
st.session_state.active_tab = "Fenestrations"
|
671 |
-
st.success(f"Editing fenestration '{name}'")
|
672 |
unique_id = str(uuid.uuid4())
|
673 |
if cols[4].button("Delete", key=f"delete_proj_fen_{name}_{unique_id}"):
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
logger.info(f"Deleted fenestration '{name}' from project")
|
681 |
-
st.session_state.needs_rerun = True
|
682 |
else:
|
683 |
st.info("No project fenestrations in the selected type.")
|
684 |
|
@@ -955,14 +967,14 @@ def display_material_editor():
|
|
955 |
st.success(f"Material '{name}' added to your project.")
|
956 |
logger.info(f"Added new material '{name}' to project")
|
957 |
|
958 |
-
# Reset editor and flag
|
959 |
reset_material_editor()
|
960 |
-
st.session_state.
|
961 |
|
962 |
# Handle clear button
|
963 |
if clear_button:
|
964 |
reset_material_editor()
|
965 |
-
st.session_state.
|
966 |
|
967 |
def display_fenestration_editor():
|
968 |
"""Display the fenestration editor form."""
|
@@ -1109,14 +1121,14 @@ def display_fenestration_editor():
|
|
1109 |
st.success(f"Fenestration '{name}' added to your project.")
|
1110 |
logger.info(f"Added new fenestration '{name}' to project")
|
1111 |
|
1112 |
-
# Reset editor and flag
|
1113 |
reset_fenestration_editor()
|
1114 |
-
st.session_state.
|
1115 |
|
1116 |
# Handle clear button
|
1117 |
if clear_button:
|
1118 |
reset_fenestration_editor()
|
1119 |
-
st.session_state.
|
1120 |
|
1121 |
def validate_material(
|
1122 |
name: str, category: str, thermal_conductivity: float, density: float,
|
|
|
56 |
"density": 1920.0,
|
57 |
"specific_heat": 840.0,
|
58 |
"default_thickness": 0.1,
|
59 |
+
"embodied_carbon": 240.0,
|
60 |
"cost": 180.0,
|
61 |
"absorptivity": 0.65,
|
62 |
"emissivity": 0.90,
|
|
|
350 |
Display the material library page.
|
351 |
This is the main function called by main.py when the Material Library page is selected.
|
352 |
"""
|
353 |
+
# Initialize session state flags
|
354 |
+
if "material_form_action" not in st.session_state:
|
355 |
+
st.session_state.material_form_action = None
|
356 |
+
if "fenestration_form_action" not in st.session_state:
|
357 |
+
st.session_state.fenestration_form_action = None
|
358 |
+
if "table_action" not in st.session_state:
|
359 |
+
st.session_state.table_action = None
|
360 |
+
|
361 |
+
# Process table actions before rendering UI
|
362 |
+
if st.session_state.table_action:
|
363 |
+
action = st.session_state.table_action
|
364 |
+
action_type = action.get("type")
|
365 |
+
name = action.get("name")
|
366 |
+
is_material = action.get("is_material", True)
|
367 |
+
|
368 |
+
if action_type == "preview":
|
369 |
+
editor_key = "material_editor" if is_material else "fenestration_editor"
|
370 |
+
data = (st.session_state.project_data["materials" if is_material else "fenestrations"]
|
371 |
+
["library" if action["is_library"] else "project"][name])
|
372 |
+
st.session_state[editor_key] = {
|
373 |
+
**data,
|
374 |
+
"name": name,
|
375 |
+
"edit_mode": False,
|
376 |
+
"original_name": name,
|
377 |
+
"is_library": action["is_library"]
|
378 |
+
}
|
379 |
+
st.session_state.active_tab = "Materials" if is_material else "Fenestrations"
|
380 |
+
st.session_state.table_action = None
|
381 |
+
|
382 |
+
elif action_type == "copy":
|
383 |
+
library_data = st.session_state.project_data["materials" if is_material else "fenestrations"]["library"]
|
384 |
+
project_data = st.session_state.project_data["materials" if is_material else "fenestrations"]["project"]
|
385 |
+
new_name = f"{name}_Project"
|
386 |
+
counter = 1
|
387 |
+
while new_name in project_data or new_name in library_data:
|
388 |
+
new_name = f"{name}_Project_{counter}"
|
389 |
+
counter += 1
|
390 |
+
project_data[new_name] = library_data[name].copy()
|
391 |
+
logger.info(f"Copied library {'material' if is_material else 'fenestration'} '{name}' as '{new_name}' to project")
|
392 |
+
st.session_state.table_action = None
|
393 |
+
|
394 |
+
elif action_type == "edit":
|
395 |
+
st.session_state.material_editor = {
|
396 |
+
**st.session_state.project_data["materials"]["project"][name],
|
397 |
+
"name": name,
|
398 |
+
"edit_mode": True,
|
399 |
+
"original_name": name,
|
400 |
+
"is_library": False
|
401 |
+
}
|
402 |
+
st.session_state.active_tab = "Materials" if is_material else "Fenestrations"
|
403 |
+
st.session_state.table_action = None
|
404 |
+
|
405 |
+
elif action_type == "delete":
|
406 |
+
check_fn = check_material_in_use if is_material else check_fenestration_in_use
|
407 |
+
project_data = st.session_state.project_data["materials" if is_material else "fenestrations"]["project"]
|
408 |
+
if check_fn(name):
|
409 |
+
st.error(f"Cannot delete {'material' if is_material else 'fenestration'} '{name}' because it is in use.")
|
410 |
+
else:
|
411 |
+
del project_data[name]
|
412 |
+
logger.info(f"Deleted {'material' if is_material else 'fenestration'} '{name}' from project")
|
413 |
+
st.session_state.table_action = None
|
414 |
|
415 |
st.title("Material Library")
|
416 |
|
|
|
435 |
with col1:
|
436 |
if st.button("Back to Climate Data", key="back_to_climate"):
|
437 |
st.session_state.current_page = "Climate Data"
|
438 |
+
st.session_state.material_form_action = None
|
439 |
+
st.session_state.fenestration_form_action = None
|
440 |
+
st.session_state.table_action = None
|
441 |
+
st.rerun()
|
442 |
|
443 |
with col2:
|
444 |
if st.button("Continue to Construction", key="continue_to_construction"):
|
445 |
st.session_state.current_page = "Construction"
|
446 |
+
st.session_state.material_form_action = None
|
447 |
+
st.session_state.fenestration_form_action = None
|
448 |
+
st.session_state.table_action = None
|
449 |
+
st.rerun()
|
450 |
|
451 |
+
# Trigger rerun if form actions are pending
|
452 |
+
if st.session_state.material_form_action or st.session_state.fenestration_form_action or st.session_state.table_action:
|
453 |
+
st.session_state.material_form_action = None
|
454 |
+
st.session_state.fenestration_form_action = None
|
455 |
+
st.session_state.table_action = None
|
456 |
st.rerun()
|
457 |
|
458 |
def display_materials_tab():
|
|
|
496 |
cols[2].write(f"{u_value:.3f}")
|
497 |
unique_id = str(uuid.uuid4())
|
498 |
if cols[3].button("Preview", key=f"preview_lib_mat_{name}_{unique_id}"):
|
499 |
+
st.session_state.table_action = {
|
500 |
+
"type": "preview",
|
501 |
"name": name,
|
502 |
+
"is_material": True,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
503 |
"is_library": True
|
504 |
}
|
|
|
|
|
505 |
unique_id = str(uuid.uuid4())
|
506 |
if cols[4].button("Copy", key=f"copy_lib_mat_{name}_{unique_id}"):
|
507 |
+
st.session_state.table_action = {
|
508 |
+
"type": "copy",
|
509 |
+
"name": name,
|
510 |
+
"is_material": True,
|
511 |
+
"is_library": True
|
512 |
+
}
|
|
|
|
|
|
|
513 |
else:
|
514 |
st.info("No materials found in the selected category.")
|
515 |
|
|
|
543 |
cols[2].write(f"{u_value:.3f}")
|
544 |
unique_id = str(uuid.uuid4())
|
545 |
if cols[3].button("Edit", key=f"edit_proj_mat_{name}_{unique_id}"):
|
546 |
+
st.session_state.table_action = {
|
547 |
+
"type": "edit",
|
548 |
"name": name,
|
549 |
+
"is_material": True,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
550 |
"is_library": False
|
551 |
}
|
|
|
|
|
552 |
unique_id = str(uuid.uuid4())
|
553 |
if cols[4].button("Delete", key=f"delete_proj_mat_{name}_{unique_id}"):
|
554 |
+
st.session_state.table_action = {
|
555 |
+
"type": "delete",
|
556 |
+
"name": name,
|
557 |
+
"is_material": True,
|
558 |
+
"is_library": False
|
559 |
+
}
|
|
|
|
|
560 |
else:
|
561 |
st.info("No project materials in the selected category.")
|
562 |
|
|
|
627 |
|
628 |
for fenestration in filtered_fenestrations:
|
629 |
cols = st.columns([2, 1, 1, 1, 1])
|
630 |
+
name = [k for k, v in library_fenestrations.items() if v == fenestration][0]
|
|
|
|
|
631 |
cols[0].write(name)
|
632 |
cols[1].write(fenestration["type"])
|
633 |
cols[2].write(f"{fenestration['u_value']:.2f}")
|
634 |
unique_id = str(uuid.uuid4())
|
635 |
if cols[3].button("Preview", key=f"preview_lib_fen_{name}_{unique_id}"):
|
636 |
+
st.session_state.table_action = {
|
637 |
+
"type": "preview",
|
638 |
"name": name,
|
639 |
+
"is_material": False,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
640 |
"is_library": True
|
641 |
}
|
|
|
|
|
642 |
unique_id = str(uuid.uuid4())
|
643 |
if cols[4].button("Copy", key=f"copy_lib_fen_{name}_{unique_id}"):
|
644 |
+
st.session_state.table_action = {
|
645 |
+
"type": "copy",
|
646 |
+
"name": name,
|
647 |
+
"is_material": False,
|
648 |
+
"is_library": True
|
649 |
+
}
|
|
|
|
|
|
|
650 |
else:
|
651 |
st.info("No fenestrations found in the selected type.")
|
652 |
|
|
|
677 |
cols[2].write(f"{fenestration['u_value']:.2f}")
|
678 |
unique_id = str(uuid.uuid4())
|
679 |
if cols[3].button("Edit", key=f"edit_proj_fen_{name}_{unique_id}"):
|
680 |
+
st.session_state.table_action = {
|
681 |
+
"type": "edit",
|
682 |
"name": name,
|
683 |
+
"is_material": False,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
684 |
"is_library": False
|
685 |
}
|
|
|
|
|
686 |
unique_id = str(uuid.uuid4())
|
687 |
if cols[4].button("Delete", key=f"delete_proj_fen_{name}_{unique_id}"):
|
688 |
+
st.session_state.table_action = {
|
689 |
+
"type": "delete",
|
690 |
+
"name": name,
|
691 |
+
"is_material": False,
|
692 |
+
"is_library": False
|
693 |
+
}
|
|
|
|
|
694 |
else:
|
695 |
st.info("No project fenestrations in the selected type.")
|
696 |
|
|
|
967 |
st.success(f"Material '{name}' added to your project.")
|
968 |
logger.info(f"Added new material '{name}' to project")
|
969 |
|
970 |
+
# Reset editor and flag action
|
971 |
reset_material_editor()
|
972 |
+
st.session_state.material_form_action = "save"
|
973 |
|
974 |
# Handle clear button
|
975 |
if clear_button:
|
976 |
reset_material_editor()
|
977 |
+
st.session_state.material_form_action = "clear"
|
978 |
|
979 |
def display_fenestration_editor():
|
980 |
"""Display the fenestration editor form."""
|
|
|
1121 |
st.success(f"Fenestration '{name}' added to your project.")
|
1122 |
logger.info(f"Added new fenestration '{name}' to project")
|
1123 |
|
1124 |
+
# Reset editor and flag action
|
1125 |
reset_fenestration_editor()
|
1126 |
+
st.session_state.fenestration_form_action = "save"
|
1127 |
|
1128 |
# Handle clear button
|
1129 |
if clear_button:
|
1130 |
reset_fenestration_editor()
|
1131 |
+
st.session_state.fenestration_form_action = "clear"
|
1132 |
|
1133 |
def validate_material(
|
1134 |
name: str, category: str, thermal_conductivity: float, density: float,
|