dxflib from RibbonSoft adds DFX support to OpenFrameworks
README
ofxDxf
Load, display, and save 2D DXF geometry for openFrameworks plotting and conversion workflows.
Built on dxflib. Geometry uses a dual storage model:
ofPath— exact commands where openFrameworks supports them: lines, circular arcs, circles, bulge arcs (path.arc/path.circle).- Metadata —
DxfArcInfo,DxfEllipseInfo,DxfSplineInfowhen DXF needs extra fields. Ellipse/spline entities keeppathempty; preview tessellates from metadata at draw time.
ofPath. Display tessellation follows ofGetStyle() and view zoom.Load is lossless and non-destructive — no heuristic curve fitting runs automatically. Optional
promoteCurves() can recover bulge arcs or (if you opt in) faceted circles later.Examples
| Example | Description |
|---|---|
example-simple | Minimal DXF viewer (drag & drop) |
example-dxftosvg | DXF ↔ SVG converter with layer UI and export |
Basic usage
#include "ofxDxf.h"
DxfDocument doc = ofxDxf::load("drawing.dxf");
if (doc.empty()) return;
for (auto& err : doc.errors) // includes skip summary when present
ofLogWarning("ofxDxf") << err;
DxfViewContext view;
view.center = viewCenter; // world-space pan
view.viewportW = ofGetWidth();
view.viewportH = ofGetHeight();
for (auto& layer : doc.layers) {
for (auto& entity : layer.entities) {
entity.draw(zoom, -1, &view); // preview — local arc tessellation
// entity.exportPath(); // plot / SVG — exact where possible
}
}
ofxDxf::save(doc, "out.dxf"); // R2000 ASCII DXF
doc.flipY(); // DXF Y-up ↔ screen Y-downSupported on load
| Feature | Status | Notes |
|---|---|---|
| LINE | ✅ | Native ofPath |
| ARC | ✅ | Exact arc commands + DxfArcInfo |
| CIRCLE | ✅ | Exact arc / circle + DxfArcInfo |
| LWPOLYLINE | ✅ | Lines + bulge arcs |
| POLYLINE | ✅ | Legacy polyline + vertices |
| ELLIPSE | ✅ | Metadata preserved; display via tessellation |
| SPLINE | ✅ | NURBS metadata preserved; display via tessellation |
| POINT | ✅ | Loaded; not drawn by default |
| INSERT / BLOCK | ✅ | Blocks collected; INSERT expanded (scale, rotation, arrays); block entity layers preserved |
| Deferred INSERT | ✅ | INSERT before block definition — resolved after load |
| HATCH | ✅ | Boundary edges as typed entities (line / arc / ellipse / spline / bulge polyline); fill pattern ignored |
| SOLID / TRACE / 3DFACE | ✅ | Closed polylines (≤4 corners) |
| Layers | ✅ | LAYER table + entity layer attribute |
| Colors | ✅ | ACI palette + 24-bit color24 |
| Empty layers | ✅ | Layers from table appear even with 0 entities |
| Skip diagnostics | ✅ | Counts ignored types; logged + appended to doc.errors |
Export / save (ofxDxf::save)
| Entity | Write format |
|---|---|
| Line, arc, circle | Native DXF entities (from arcInfo when present) |
| Ellipse, spline | Native DXF when metadata present |
| Hatch / solid / trace | Native types when metadata present; else LWPOLYLINE |
| Other / fallback | LWPOLYLINE at export quality (exportPath()) |
Preview rendering
Circles and arcs tessellate at arc center in local coordinates (avoids jitter on large sheet coordinates). Rules:
| Source | Preview path |
|---|---|
Native CIRCLE / ARC (arcInfo) | Local tessellation from DxfArcInfo |
ELLIPSE (ellipseInfo) | Local tessellation at ellipse center (zoom-adaptive) |
SPLINE (splineInfo) | Local NURBS tessellation at spline centroid (zoom-adaptive) |
Bulge polylines (ofPath arc commands) | Each arc drawn locally; elliptical arcs when radiusX ≠ radiusY |
Chord-faceted polylines (many lineTo) | Drawn as stored — call promoteCurves() to recover arcs/circles |
DxfViewContext to entity.draw() so full circles only stroke the viewport-visible arc span at high zoom.Optional curve promotion
Heuristic fitting never runs on load. Call explicitly when you want polylines replaced by native CIRCLE / ARC metadata:
DxfCurvePromotionSettings settings;
settings.promoteBulgeArcCircles = true; // exact: arc commands spanning 360°
settings.promoteBulgeArcs = true; // exact: single bulge arc
settings.promoteFacetedCircles = false; // off by default — avoids hexagon → circle
settings.promoteFacetedArcs = false; // off by default — open chord arc → ARC
auto result = ofxDxf::promoteCurves(doc, settings);
// result.circlesPromoted, result.arcsPromoted, result.entitiesExamined| Setting | Default | Meaning |
|---|---|---|
promoteBulgeArcCircles | true | Closed loop of exact arc commands → CIRCLE |
promoteBulgeArcs | true | moveTo + one arc (bulge) → ARC |
promoteFacetedCircles | false | Chord-fit closed polyline → CIRCLE (heuristic) |
promoteFacetedArcs | false | Chord-fit open polyline → ARC (heuristic) |
facetedCircleMinVertices | 16 | Minimum facet count for closed circle fit |
facetedArcMinVertices | 8 | Minimum facet count for open arc fit |
facetedCircleMaxRelativeError | 0.01 | Max radius fit error |
facetedCircleMaxEdgeVariance | 0.05 | Rejects uneven edge lengths (circles only) |
arcInfo are never changed.INSERT transforms
- Uniform block scale:
arcInfoandpathstay in sync after INSERT (CIRCLE/ARC). - Non-uniform scale on circles/arcs: converted to
DxfEllipseInfo(Type::Ellipse) so export writes native DXF ELLIPSE, not a false circle or tessellated polyline fallback.
Not supported (counted & logged)
These are parsed by dxflib but not converted to geometry. Counts appear in the console and in
doc.errors (e.g. Skipped/unresolved: TEXT=12 DIMENSION=4):| Type | Common in |
|---|---|
| TEXT / MTEXT | Labels, part numbers |
| DIMENSION (+ variants) | AutoCAD dimensions |
| HATCH fill pattern | Pattern fill (boundaries are loaded) |
| XLINE / RAY | Construction geometry |
| ATTRIB | Block attribute text |
| IMAGE | Raster references |
| LEADER | Annotation leaders |
| Paper space layouts | Layout tabs (model space only) |
| Linetypes / lineweights | Stored in DXF; not applied on draw |
| Unknown INSERT | Block name not found after deferred retry |
ofxDxf: Load summary line or doc.errors.Geometry API
| Method | Use |
|---|---|
entity.path | Exact ofPath when geometry allows (lines, arcs, bulge); empty for ellipse/spline |
entity.arcInfo | Native circle/arc parameters (export source of truth) |
entity.exportPath() | Export / plot — exact paths; arcInfo rebuilt into ofPath |
entity.resolvedPath() | Display — uses ofGetStyle() segment count |
entity.getOutline() | Tessellated polylines (local arc tessellation when arcInfo present) |
entity.draw(zoom, segs, &view) | Preview with zoom-adaptive local arcs |
ofxDxf::promoteCurves(doc, settings) | Optional in-place CIRCLE/ARC recovery |
ofGetStyle(), zoom), except export which uses world-space quality automatically for splines/ellipses.Roadmap (next improvements)
| Item | Effort | Notes |
|---|---|---|
| Linetype on draw | medium | Dashed layer styles |
| DIMENSION → lines/arcs | ~1 day | Explode dimension primitives |
| TEXT outline / bbox | ~1–2 days | Optional labels for reference |
| Paper space | medium | Layout tab support |
| INSERT/BLOCK on save | medium | Preserve block structure round-trip |
| Full HATCH fill | high | Pattern rendering, not just boundaries |
Dependencies
- openFrameworks (
ofPath,ofPolyline, …) - dxflib (included under
libs/dxflib)
ofxSvg, ofxImGui, ofxImGuiStyle.License
See addon and dxflib license files.
ofxAddons