SVG Detailed PathLength
SVG path lengths without leaving ComfyUI — the laser cutter's cost-estimate node
- total_length
- detailed_report
- element_count
If you've ever priced a laser-cut job, you know the number that actually matters isn't the image resolution - it's how many millimeters of line the head has to travel. SVG Detailed PathLength (SVGPathLengthDetailed) is the ComfyUI node that hands you that number: paste in an SVG, and it returns the total drawn length, a per-element breakdown, and a count of how many shapes it found.
It ships in mikemojen/ComfyUI-HappNodeSet, a pack that's clearly built around a fabrication workflow. Look at its sibling nodes - LaserPathTracer, HoleCounter, ContourGapCloser, DashedToSolidLine, RasterToUniformSVG - and the picture is obvious: this is a laser-cutting/CNC toolkit that happens to live inside ComfyUI because that's where the author does their prep work. The __init__.py even says it's "comfyUI nodes for Happrecision." If you're not cutting or engraving anything, this node is probably not for you. If you are, it's quietly the most useful node in the pack.
How it works
The node takes SVG text, not an image - the whole thing is geometry math, no model involved, so it runs in milliseconds. It parses the XML with Python's ElementTree, walks every element, and measures:
<path>elements via a full path-dparser coveringM,L,H,V,C,S,Q,T,A, andZin both relative and absolute forms. Straight segments are exact Euclidean distance; Beziers are approximated by sampling the curve at 100 steps and summing the chord lengths; arcs use a chord-based estimate.rect,circle,ellipse,line,polyline,polygonvia their perimeters - including rounded-corner rects, with ellipse arcs measured through Ramanujan's approximation formula rather than some lazy 2πr guess.
Crucially, it ignores stroke-width. You get the centerline length, which is exactly the distance a laser head or plotter pen travels - not the ink coverage. It also reads transform scale attributes (and the scale components of matrix(...)) and inherits them down through nested groups, so a <g> that scales its children 5x gets counted correctly.
The inputs and outputs
Only two inputs, and only one you'll touch:
svg_content(multiline text) - paste the raw SVG XML here. Required. Grab it from Inkscape, Illustrator, or any node upstream that outputs SVG.decimal_places(int, 0–10, default 4) - just rounding for the outputs.
The outputs wire into text/preview nodes or just display in the UI:
total_length(float) - the sum in SVG user units.detailed_report(string) - one line per element (path (id='leaf'): 123.4567 units) plus totals.element_count(int) - how many measurable elements it found.
The node is flagged as an output node, so the report renders directly on the graph like a ShowText node - no wiring needed to see it.
Installation
ComfyUI Manager: search for "HappNodeSet" and hit install. Or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/mikemojen/ComfyUI-HappNodeSet.git
Then restart ComfyUI. The pack's requirements.txt pulls in numpy, opencv-python, scipy, scikit-image, svgwrite, Pillow, torch, and cairosvg - most of those are already in a stock ComfyUI install, but cairosvg often isn't and will get pulled in. It's only used for SVG preview rendering, so a missing one won't break this node specifically, but let the install finish anyway.
Where people get burned
The most common gotcha is feeding it the wrong thing. This node does not measure raster images - if you drop a PNG in, you get an XML parse error in the report and a 0 back. Convert to SVG first (this same pack's RasterToUniformSVG or a vectorizer is the bridge). Second: <text> elements are silently skipped, which is the classic trap for laser engravers with lettering. Text in an SVG is not a path - convert it to outlines in Inkscape (Path → Object to Path) before measuring, or your "estimate" will be missing every letter. Third: the numbers are SVG user units, not millimeters, so multiply by your machine's scale factor (and check your viewBox vs width/height).
One honest caveat: curves are approximations. 100-segment Bezier sampling is plenty accurate for cutting-time and cost estimates, but don't quote a precision machining job off the last decimal. If a bad input slips in, the node returns an error string in the report instead of crashing the graph - a friendly failure mode worth copying.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| svg_content | STRING | — | |
| decimal_placesopt | INT | 40–10 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| total_length | FLOAT | — |
| detailed_report | STRING | — |
| element_count | INT | — |