2D DXF Cutting Plan Renderer — End-to-End Pipeline

End-to-end DXF-to-canvas pipeline: ASP.NET ingestion, Azure Service Bus messaging, Functions processing, CosmosDB persistence, Canvas rendering.

The problem

Customers were uploading DXF files (CAD cutting plans) and waiting for someone on the team to open them in AutoCAD, review the geometry, and reply. Hours of turnaround, manual bottleneck, no scaling.

The goal: ingest a DXF, parse the geometry server-side, render it interactively in the browser within seconds.

The architecture

Browser  →  ASP.NET API  →  Azure Service Bus  →  Azure Function  →  CosmosDB

                                                              Angular  ←  REST

                                                            Canvas / SVG

Why each piece earned its place:

ASP.NET ingestion

Handles upload, validates the file, drops the parse job on the queue. Returns instantly — the user doesn’t wait for parsing.

Azure Service Bus

Decouples upload from parse. Bursty traffic (someone uploads 50 files at once) doesn’t take down the API. Built-in retries handle parse failures without losing data.

Azure Function

Pure parse worker. Receives a message, reads the DXF from blob storage, walks the entity tree, normalises geometry into a coordinate system the renderer understands, writes the result to Cosmos.

CosmosDB

Stores the parsed geometry as JSON. Indexed by file ID. Fast point reads when the browser fetches the result.

Angular + Canvas

Receives the geometry, renders it on a <canvas> for performance with pan/zoom, falls back to SVG for export and accessibility.

Trade-offs I’d make again

Async by default. The temptation was to parse inline in the API request — simpler, fewer moving parts. But a single 10MB DXF would block a request thread for seconds. Async with Service Bus added two components but kept the API responsive under any load.

Canvas over pure SVG. SVG was tempting for accessibility, but DXFs can contain thousands of entities. The DOM cost of SVG at that scale tanked frame rate. Canvas renders smoothly with 50,000 lines; SVG started chugging at 2,000.

CosmosDB over relational. Geometry is a graph. Forcing it into rows and joins would have meant either denormalising into a JSON blob anyway, or building a join layer that no one would want to maintain. Document-native was the right shape.

What I’d do differently

WebGL for rendering, when I revisit. Canvas held up but I can see the ceiling — interactive plans with thousands of cuts start to feel sluggish on pan. WebGL via something like PixiJS would push that ceiling much higher without changing the data layer at all.