UsmanGoraya commited on
Commit
bfaec4e
·
verified ·
1 Parent(s): 807a6cf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -46
app.py CHANGED
@@ -1,12 +1,6 @@
1
- Room: 15x12x10 ft
2
- Wall Thickness: 0.75 ft
3
- Openings:
4
- - Door: 3x7 ft
5
- - Window: 4x4 ft
6
- Beams: Yes
7
  import streamlit as st
8
- import fitz # PyMuPDF
9
- import re
10
 
11
  # Constants
12
  BRICK_VOLUME_CFT = (9/12) * (4.5/12) * (3/12) # in cft
@@ -15,44 +9,57 @@ SAND_RATIO = 5 / 6
15
  CEMENT_DENSITY_KG_PER_CFT = 1440 / 35.3147
16
  CEMENT_BAG_WEIGHT_KG = 50
17
 
18
- st.set_page_config(page_title="Smart Estimator", page_icon="📐")
19
- st.title("📐 Smart Quantity Estimator from Building Layout PDF")
20
-
21
- uploaded_pdf = st.file_uploader("Upload your house layout PDF", type=["pdf"])
22
-
23
- def extract_text_from_pdf(file):
24
- doc = fitz.open(stream=file.read(), filetype="pdf")
25
- text = ""
26
- for page in doc:
27
- text += page.get_text()
28
- return text
29
-
30
- def parse_dimensions(text):
31
- rooms = re.findall(r'Room:\s*(\d+\.?\d*)x(\d+\.?\d*)x(\d+\.?\d*)\s*ft', text)
32
- wall_thickness = re.search(r'Wall Thickness:\s*(\d+\.?\d*)\s*ft', text)
33
- openings = re.findall(r'(Door|Window|Opening):\s*(\d+\.?\d*)x(\d+\.?\d*)\s*ft', text)
34
- beams = 'Beams: Yes' in text
35
-
36
- return {
37
- "rooms": [(float(l), float(w), float(h)) for l, w, h in rooms],
38
- "wall_thickness": float(wall_thickness.group(1)) if wall_thickness else 0.75,
39
- "openings": [(typ, float(l), float(h)) for typ, l, h in openings],
40
- "has_beams": beams
41
- }
42
-
43
- def estimate(rooms, wall_thickness, openings, has_beams):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  wall_volume = 0
45
  for length, width, height in rooms:
46
  wall_area = 2 * (length + width) * height
47
  wall_volume += wall_area * wall_thickness
48
 
49
  opening_volume = sum(l * h * wall_thickness for _, l, h in openings)
50
-
51
  beam_volume = 0
52
- if has_beams:
53
- for _, l, _ in openings:
54
- beam_len = l + 1 # add 1ft
55
- beam_volume += beam_len * 0.75 * 0.75
56
 
57
  net_volume = wall_volume - opening_volume - beam_volume
58
 
@@ -66,18 +73,24 @@ def estimate(rooms, wall_thickness, openings, has_beams):
66
 
67
  return number_of_bricks, sand_volume, cement_bags
68
 
69
- if uploaded_pdf:
70
- text = extract_text_from_pdf(uploaded_pdf)
71
- st.text_area("📄 Extracted Text", text, height=300)
72
 
73
- data = parse_dimensions(text)
 
 
 
74
 
75
- if data["rooms"]:
76
- bricks, sand, cement = estimate(data["rooms"], data["wall_thickness"], data["openings"], data["has_beams"])
 
 
77
 
78
  st.subheader("📊 Estimated Quantities:")
79
  st.write(f"🧱 **Bricks Needed:** {bricks:,} bricks")
80
  st.write(f"🏖️ **Sand Needed:** {sand:.2f} cft")
81
  st.write(f"🪣 **Cement Needed:** {cement} bags (50kg each)")
82
  else:
83
- st.warning("No room dimensions found in the PDF. Please make sure your format is correct.")
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ import ezdxf
3
+ import io
4
 
5
  # Constants
6
  BRICK_VOLUME_CFT = (9/12) * (4.5/12) * (3/12) # in cft
 
9
  CEMENT_DENSITY_KG_PER_CFT = 1440 / 35.3147
10
  CEMENT_BAG_WEIGHT_KG = 50
11
 
12
+ st.set_page_config(page_title="CAD-based Quantity Estimator", page_icon="📐")
13
+ st.title("📐 Brick, Cement & Sand Estimation from AutoCAD (.dxf)")
14
+
15
+ uploaded_file = st.file_uploader("Upload your .dxf AutoCAD file", type=["dxf"])
16
+
17
+ def extract_from_dxf(file):
18
+ doc = ezdxf.read(file)
19
+ msp = doc.modelspace()
20
+
21
+ rooms = []
22
+ wall_thickness = 0.75 # Default
23
+ openings = []
24
+
25
+ for entity in msp:
26
+ if entity.dxftype() == "TEXT":
27
+ content = entity.dxf.text.lower()
28
+ if "room" in content and "x" in content:
29
+ try:
30
+ dims = content.split(":")[1].strip().split("x")
31
+ l, w, h = map(float, dims)
32
+ rooms.append((l, w, h))
33
+ except:
34
+ continue
35
+ elif "wall thickness" in content:
36
+ try:
37
+ wt = float(content.split(":")[1].strip())
38
+ wall_thickness = wt
39
+ except:
40
+ continue
41
+ elif any(x in content for x in ["door", "window", "opening"]):
42
+ try:
43
+ dims = content.split(":")[1].strip().split("x")
44
+ l, h = map(float, dims)
45
+ openings.append(("opening", l, h))
46
+ except:
47
+ continue
48
+
49
+ return rooms, wall_thickness, openings
50
+
51
+ def estimate(rooms, wall_thickness, openings):
52
  wall_volume = 0
53
  for length, width, height in rooms:
54
  wall_area = 2 * (length + width) * height
55
  wall_volume += wall_area * wall_thickness
56
 
57
  opening_volume = sum(l * h * wall_thickness for _, l, h in openings)
58
+
59
  beam_volume = 0
60
+ for _, l, _ in openings:
61
+ beam_len = l + 1 # add 1ft
62
+ beam_volume += beam_len * 0.75 * 0.75
 
63
 
64
  net_volume = wall_volume - opening_volume - beam_volume
65
 
 
73
 
74
  return number_of_bricks, sand_volume, cement_bags
75
 
76
+ if uploaded_file:
77
+ st.success("✅ File uploaded. Parsing...")
78
+ rooms, wall_thickness, openings = extract_from_dxf(io.BytesIO(uploaded_file.read()))
79
 
80
+ if rooms:
81
+ st.write(f"🧱 Rooms Detected: {len(rooms)}")
82
+ for i, r in enumerate(rooms, 1):
83
+ st.write(f"Room {i}: {r[0]}x{r[1]}x{r[2]} ft")
84
 
85
+ st.write(f"📏 Wall Thickness: {wall_thickness} ft")
86
+ st.write(f"🚪 Openings Detected: {len(openings)}")
87
+
88
+ bricks, sand, cement = estimate(rooms, wall_thickness, openings)
89
 
90
  st.subheader("📊 Estimated Quantities:")
91
  st.write(f"🧱 **Bricks Needed:** {bricks:,} bricks")
92
  st.write(f"🏖️ **Sand Needed:** {sand:.2f} cft")
93
  st.write(f"🪣 **Cement Needed:** {cement} bags (50kg each)")
94
  else:
95
+ st.warning("No room data found. Please check the .dxf text format.")
96
+