
Empty room
Stable Diffusion 1.5 with stacked ControlNets furnishes an empty room without moving its walls.
A graduation project, graded A+. I built its AI: the ComfyUI workflows that edit room photos, a furniture search over a catalogue I generated and annotated, and a workflow that turns a product photo into a 3D model.

IntelliRoom is a web platform where you upload a room, change it with AI and buy what you see. Drag the slider: an empty hall on the left, the same hall furnished by my edit workflow on the right. The arches, the doorway, the cornice and the herringbone floor stay exactly where they were.
I built every AI workflow behind it. Below are all of them, from the 72-node graph that switches between jobs to the eleven exports that run on the platform.


In the first semester each job was its own ComfyUI workflow: furnish an empty room, replace an object, transfer a style, render a sketch, upscale. I merged them into one graph, which the thesis calls the universal workflow, so the platform could change job by flipping switches instead of reloading files.
Image data runs along a rail with the control signals beside it. When a switch is off, Fast Muter and Any Switch nodes bypass that whole block, so a mode only pays for the nodes it uses. Scroll to fly through it.

The universal workflow 72 nodes, 116 links. Five blocks, left to right.
01 Serves: Every mode
Nine switches on the far left set the whole graph: generation mode (text-to-image, image-to-image or inpaint), manual or automatic masks, the IP-Adapter, each ControlNet, the Canny source, the denoise strength and M-LSD lines. Changing a job means flipping switches, not loading another file.

02 Serves: Replace one object
Florence-2 reads a word such as “carpet” and returns a box; SAM2 turns the box into a pixel mask. When the switch says manual, or the job needs no mask, the whole block is bypassed and costs nothing.

03 Serves: Shop the look
An IP-Adapter encodes a reference product, such as a rug from the catalogue, and injects it into the generation. With no reference, the switch opens and the prompt alone drives the result.

04 Serves: Empty room, sketch, restyle
A rail of logic gates picks which ControlNets guide the image: Canny edges for structure, depth for volume, M-LSD for straight walls, and sets their strengths for the current mode. This is what keeps walls and windows from bending.

05 Serves: Every mode
Whatever path the image took, everything meets at a single KSampler. A last switch either saves the result or sends it to Ultimate SD Upscale for a high-resolution export. The comparer on the right shows a real run.

The universal graph is one of eleven workflows I exported for the platform. Here is each graph as it looks in ComfyUI, with the size of its export. Open any of them at full size to read the nodes. The universal graph is above; the two Flux 2 Klein edit exports share one card, and the Flux text-to-image graph that made several of the empty test rooms has nine nodes.

Stable Diffusion 1.5 with stacked ControlNets furnishes an empty room without moving its walls.

Florence-2 finds the object by name, SAM2 masks it and an inpaint pass replaces only that region.

The same masking, plus an IP-Adapter that copies a reference product into the masked region.

A line drawing is turned into a photographic render under Canny, M-LSD and depth control.

A tiled upscaler that regenerates the image in tiles at a low denoise to add detail.

The source image, a prompt and up to three reference images go straight into an image-edit model. No masks, no ControlNets.

Restores the whole frame at once, replacing the tiled upscaler and its seams.

Background removal, Hunyuan3D 2.0 mesh, de-lighting, six painted views and a textured .glb.
First semester: Stable Diffusion 1.5 and ControlNet. To furnish a room without bending its walls, I stacked ControlNets (Canny edges, M-LSD lines and depth) on Stable Diffusion 1.5. To replace one object I chained Florence-2 to find it, SAM2 to mask it and an IP-Adapter to copy a reference texture. Each task was its own workflow.
Then I merged them into the universal graph above, 72 nodes behind nine switches. It worked, and it is the graph you just flew through, but every feature added another place for the routing to break.
Second semester: Flux 2 Klein. Flux 2 Klein 4B is an image-edit model: it takes the source image and a prompt, and optionally reference images, directly. Its graph needs no mask, ControlNet or preprocessing branch, so the whole edit fits in 11 nodes. I chose the 4B model partly for its Apache 2.0 licence. The 9B model's licence limits commercial use, and the thesis notes it also needs about 22 GB of VRAM against about 12 GB for the 4B.


One 11-node graph, many jobs. Each result below was made with the Flux 2 Klein edit workflow; the image metadata records it. Several input rooms were themselves generated with Flux text-to-image, so the starting point is known exactly. Drag every slider, and switch between examples where there are several.


01
An empty room becomes a furnished one in one pass. Then references stack: a floor material, then a wallpaper, each added on top of the last result while the window and the walls hold still.






02
The edit does not need an empty room. Given a lived-in room it swaps the furniture and the styling and leaves the architecture alone.


03
This is the shop-the-look step. I gave the edit this bedroom and a product photo of one bed. The bed in the room becomes that bed, with its fabric and colour, and the window, the light and the sea view stay.




04
The same reference edit on a smaller object: the rug on the floor is replaced by a patterned rug from a product photo, and nothing else in the living room moves.








05
The same graph can move a room into a different world: an anime illustration by day and by night, a Minecraft build, a coastal beach house. Pick an example, then drag.






06
Light is an edit too. One teenage bedroom, three results: recoloured in daylight, at night with the lamps on, and at night with the curtains drawn.










07
It works on exteriors as well. One street of white houses, five results: two cartoon versions, an orange sunset, a purple twilight and rain on wet asphalt.


08
Clothes and rubbish are removed and the floor under them is filled in, while the bed, the chest and the window stay where they were.




09
A pen sketch or a black-and-white block-out becomes a photographic interior. The drawn proportions and openings are what the render keeps.


10
A monochrome room gets its colours back: wood, plaster and fabric, with the cracks in the walls and the furniture kept as they were.


11
Diffusion output can leave noise on smooth surfaces. SeedVR2 restores the whole frame at once; here it took an 813 by 512 image to 1706 by 1080. Drag across the sunflowers to see the difference.


A separate ComfyUI workflow turns one photo of a piece of furniture into a textured 3D model. It removes the background, builds the shape with Hunyuan3D 2.0, removes baked-in shadows from the photo, paints the unseen sides from six rendered views, patches texture seams and exports a .glb file with a 2048 px texture.
To run on a cloud GPU notebook it needed extra work: patching the Hunyuan3D nodes and compiling a custom CUDA rasterizer. The graph has 44 nodes.
A generated room is not much use if you cannot buy what is in it. The search service takes a room image, finds a piece of furniture and looks for similar products in a catalog.
RT-DETR detects furniture and I keep the most confident detection. Two models read that crop in parallel. SigLIP2 turns it into an embedding for visual similarity, and Qwen3-VL describes it as JSON: colour, material, style and room fit. The service filters the catalog by colour, material and style, then ranks what is left by embedding similarity. If the filter returns nothing, it ranks without the filter, so a search always returns results.
The vision-language model invents words such as "cream", "charcoal black" or "mid-century". A catalog filter needs a fixed list. A small snapper maps known synonyms first ("cream" becomes "beige"), then picks the nearest allowed word by character n-gram similarity. That keeps the filters working. It cannot fix a description that is wrong.
I picked RT-DETR over YOLO because many YOLO versions carry GPL or AGPL terms and RT-DETR is Apache 2.0. Flux 2 Klein 4B was chosen on licence too, as above.
I tried three sizes on two furniture images, a wicker sofa and a gold classic sofa, and recorded the time for each.
IntelliRoom was built by a team of seven. My teammates built the web app, the backend, the marketplace and the 2D and 3D planner. Those products needed furniture to sell and to place, so I made the data they run on.
I generated every product with a ComfyUI workflow, running it through permutations of furniture type, colour and material: sofas, armchairs, beds, tables, shelves, lamps, rugs and curtains on a clean white ground. Then a vision-language model annotated each product to a strict format and a fixed taxonomy, so the marketplace filters and the furniture search all speak the same words.

Qwen3-VL receives each product with a system prompt that allows one answer shape only: raw JSON, no explanation, no markdown, and every value taken from the allowed lists. If it is unsure it must pick the closest allowed value, never a new one.
{
"color": one of 14,
"material": one of 13,
"style": one of 13,
"room_fit": a list from 8,
"complementary_styles": a list from 11,
"description": one sentence
}
When a model still drifts, a snapper maps known synonyms first (“cream” becomes beige) and then the nearest allowed word, so nothing outside the taxonomy reaches the database.
Style new classicmodernscandinavianindustrialbohemianminimalistjapandicoastalrusticart decotraditionalheritage fusiondesert modern
Material solid woodengineered woodmetalglassleatherfaux leatherfabricvelvetlinenrattanmarbletravertineplastic
Colour blackwhitegraybrownbeigebluenavygreenredorangeyellowpinkpurplegold
Room salonliving roombedroomdining roomofficeoutdoorkids roombathroom



The thesis covers the whole platform, graded A+. The presentation is 72 slides on the image edits and the furniture search, with before and after examples; the 3D workflow is not in it.