A small monorepo of AI-assisted BIM demonstrators built during Summer Semester 2026.
It contains:
- a Flask backend that exposes endpoints for IFC metadata extraction + Q&A, room photo classification, house price prediction, and (optional) Stable Diffusion layout generation
- a Next.js (App Router) frontend that provides a UI for the demonstrators
- IFC Explorer: upload an IFC file, extract basic building metadata + rooms, and ask questions about the model
- House Price Predictor: XGBoost-based price estimate from a small set of house features
- Layout Generator: text-to-image and sketch-to-image layout generation (Stable Diffusion; optional)
- Room Classifier: classify a room photo using a Hugging Face image classification model
The Flask backend provides:
- an LLM Q&A endpoint using an OpenAI-compatible API (optional; falls back to simple rule-based answers)
- ML inference endpoints for price prediction and room image classification
- Stable Diffusion generation endpoint (only enabled when the diffusion pipeline loads successfully)
.
├── backend/ # Flask API + ML inference code
│ ├── flask_app.py
│ ├── requirements.txt
│ ├── diffusion/ # Custom UNet checkpoints (if available)
│ ├── house_price_predict/ # XGBoost model + predictor
│ └── room_classifier/ # Hugging Face room classifier + training utilities
├── website/ # Next.js frontend
└── docs/ # Learning material (house price notebook + data)
- Python: 3.10 or 3.11 required (newer versions may fail to install TensorFlow/PyTorch dependencies)
- Node.js: 18+ recommended (Next.js 16)
- Optional for faster generation:
- NVIDIA GPU + CUDA (for Stable Diffusion)
Optional: Open website/.env.local and add your Supabase project keys (NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY). The Next.js frontend will crash if these are missing.
For the Layout Generator (Stable Diffusion) to work, you need the custom UNet checkpoint:
- Download the
unet_epoch_19folder (safetensors and config) from https://drive.google.com/drive/folders/1B5hX9o55sh_kYn8yhfQnvvEF_3hwLSPl?usp=sharing. - Place the folder inside the
backend/diffusion/directory so the path looks likebackend/diffusion/unet_epoch_19/.
Important: run from the backend/ folder so imports resolve correctly.
# Open Terminal 1
cd backend
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python flask_app.pyNote: The first time you run this, it will take several minutes to download gigabytes of base ML models (like Stable Diffusion).
Backend listens on http://127.0.0.1:5001.
Check:
curl http://127.0.0.1:5001/health# Open a NEW Terminal (Terminal 2)
cd website
npm install
npm run devFrontend is available at http://localhost:3000.
Tip: From the repo root you can also run
npm run dev, but you still neednpm installinsidewebsite/at least once.
The backend reads these variables from the process environment:
The Flask app does NOT auto-load
.env.example.
# Optional: enables IFC Q&A with an OpenAI-compatible endpoint
LLM_API_KEY=...
LLM_BASE_URL=...
LLM_MODEL=openai-gpt-oss-120bIf LLM_API_KEY is not set, the backend falls back to a small built-in answer function.
The frontend includes login/sign-up pages and expects a profiles table.
- Create a Supabase project
- Run the SQL in
website/scripts/001_create_profiles.sqlin the Supabase SQL editor - Set the
NEXT_PUBLIC_SUPABASE_URL+NEXT_PUBLIC_SUPABASE_ANON_KEYvariables
Base URL (default): http://127.0.0.1:5001
Returns service status and which models loaded.
curl http://127.0.0.1:5001/healthUpload an IFC file and extract basic metadata + room boxes.
- Content-Type:
multipart/form-data - Field name:
file
curl -F "file=@/path/to/model.ifc" \
http://127.0.0.1:5001/api/upload-ifcResponse includes a server-side filename token (used for queries) and data (rooms, storeys, summary).
Ask a natural language question about a previously uploaded IFC.
curl -X POST http://127.0.0.1:5001/api/query-ifc \
-H "Content-Type: application/json" \
-d '{"filename":"<from upload>","question":"How many rooms are there?"}'Predict a house price using a pre-trained XGBoost model.
curl -X POST http://127.0.0.1:5001/predict-price \
-H "Content-Type: application/json" \
-d '{
"GrLivArea": 1500,
"BedroomAbvGr": 3,
"FullBath": 2,
"YearBuilt": 2005,
"KitchenAbvGr": 1
}'Notes:
- The model expects feature keys matching the training columns stored in
backend/house_price_predict/columns_xgb.pkl. - To inspect available columns:
python - <<'PY'
import joblib
cols = joblib.load('backend/house_price_predict/columns_xgb.pkl')
print('n_columns =', len(cols))
print('sample =', cols[:25])
PYClassify an image of a room.
- Content-Type:
multipart/form-data - Field name:
image
curl -F "image=@/path/to/room.jpg" \
http://127.0.0.1:5001/api/classify-roomGenerate an architectural layout image.
curl -X POST http://127.0.0.1:5001/api/generate-layout \
-H "Content-Type: application/json" \
-d '{"prompt":"A modern house layout with 3 bedrooms and an open kitchen"}'Optional img2img (sketch-to-layout):
- Provide
imageas a base64 PNG (data URL is accepted) - Provide
strengthin[0.0, 1.0]
If the diffusion pipeline is not available, this endpoint returns 503.
- The backend extracts rooms (
IfcSpace) and derives approximate 3D boxes (x,z,width,depth,height). - The frontend renders these as colored
three.jsboxes (not full IFC geometry). - Extracted IFC data is stored in-memory in the backend; restarting the backend clears uploaded model context.
- The backend loads diffusion pipelines on startup (this can take time).
- It is configured to load Stable Diffusion v1.5 (
runwayml/stable-diffusion-v1-5) with a custom UNet checkpoint frombackend/diffusion/unet_epoch_19. - If the diffusion pipeline can’t be initialized (missing checkpoint files, incompatible weights, download/auth issues),
/healthreports diffusion asnot_loadedandPOST /api/generate-layoutreturns503. - Depending on your environment, you may need to authenticate with Hugging Face / accept model terms to download the base model.
From website/:
npm run devnpm run buildnpm run startnpm run lint
From repo root:
npm run dev(delegates towebsite)npm run build/start/lint
- Backend import errors: run
python flask_app.pyfrom insidebackend/. ifcopenshellissues: it can be platform-specific; ensure your Python version matches a supported wheel for your OS.- Layout generator returns 503: diffusion pipeline didn’t load (missing or incompatible checkpoint / model download issues).
- Slow first run: Hugging Face / Diffusers may download model weights on first use.
- Supabase errors in the UI: set
NEXT_PUBLIC_SUPABASE_URLandNEXT_PUBLIC_SUPABASE_ANON_KEY.
Built with:
- Flask +
flask-cors - IfcOpenShell (
ifcopenshell) - Hugging Face Transformers (
pipeline) - XGBoost + scikit-learn
- Diffusers (Stable Diffusion)
- Next.js + Tailwind CSS + Radix UI
- Supabase (Auth)