({ x: p.x * DISPLAY_SCALE, y: p.y * DISPLAY_SCALE }))}
+ holes={interiorRings?.map(ring => ring.map(p => ({ x: p.x * DISPLAY_SCALE, y: p.y * DISPLAY_SCALE })))}
+ mmPerUnit={1 / DISPLAY_SCALE}
+ uiScale={zvbW / 800}
+ />
+ )}
+
{/* per-ring hit areas for fill-ring mode */}
{editMode === 'fill-ring' && interiorRings?.map((ring, idx) => {
const d = ring.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x * DISPLAY_SCALE} ${p.y * DISPLAY_SCALE}`).join(' ') + ' Z'
diff --git a/frontend/src/components/ToolEditorToolbar.tsx b/frontend/src/components/ToolEditorToolbar.tsx
index c24fa06..19972f1 100644
--- a/frontend/src/components/ToolEditorToolbar.tsx
+++ b/frontend/src/components/ToolEditorToolbar.tsx
@@ -1,7 +1,7 @@
'use client'
import { ReactNode } from 'react'
-import { MousePointer2, Plus, Minus, Undo2, Redo2, Trash2, Circle, Disc, Square, RectangleHorizontal, Fingerprint, Magnet, RotateCw, RotateCcw, FlipHorizontal2, FlipVertical2, ChevronDown, PaintBucket } from 'lucide-react'
+import { MousePointer2, Plus, Minus, Undo2, Redo2, Trash2, Circle, Disc, Square, RectangleHorizontal, Fingerprint, Magnet, RotateCw, RotateCcw, FlipHorizontal2, FlipVertical2, ChevronDown, PaintBucket, Ruler } from 'lucide-react'
import type { FingerHole } from '@/types'
import { SNAP_GRID } from '@/lib/constants'
@@ -21,6 +21,8 @@ interface Props {
onSmoothLevelChange: (level: number) => void
snapEnabled: boolean
setSnapEnabled: (enabled: boolean) => void
+ showMeasurements: boolean
+ setShowMeasurements: (show: boolean) => void
canUndo: boolean
canRedo: boolean
handleUndo: () => void
@@ -43,6 +45,7 @@ export function ToolEditorToolbar({
editMode, setEditMode,
smoothed, smoothLevel, onSmoothedChange, onSmoothLevelChange,
snapEnabled, setSnapEnabled,
+ showMeasurements, setShowMeasurements,
canUndo, canRedo, handleUndo, handleRedo,
cutoutOpen, setCutoutOpen,
isCutoutMode, cutoutModeIcon, cutoutModeLabel,
@@ -184,6 +187,16 @@ export function ToolEditorToolbar({
Snap
+