Skip to content

Daedalus WebCAD 現状分析・リファクタリング計画レポート

作成日: 2026-06-16 対象: frontend/src(Vue3 + TypeScript)の Daedalus / CAD Core


0. エグゼクティブサマリ

  • CAD Core は想像以上に成熟している。 frontend/src/cad-core は 222 個の TS ファイルを持ち、Entity モデル・Geometry・Snap・Selection・History・Dimensions・Layers・DXF I/O・Constraints がモジュール分割で実装済み。
  • 最大の問題は UI 層の肥大化。 D_Daedalus.vue48,124 行 の巨大モノリスで、CAD ロジック(描画プレビュー・グリップ・スナップ・寸法計算)が大量に混在している。
  • CAD Core の独立性に重大な「漏れ」がある。 汎用変換のうち Move のみが CAD Core にあり、Copy / Rotate / Scale / Mirror は Drafting 層(D_cadPointCommandExecutor.ts)に、しかも設備(equipment)モデル(eq.x, eq.width)に結合した形で実装されている。これにより汎用 CadEntity に対する回転・拡縮・ミラーが CAD Core に存在しない。
  • 結論: 新規実装よりも「既存資産の昇格・集約」が最優先。 破壊せず、Drafting に散らばったロジックを CAD Core に引き上げ、薄い UI へ近づける。

1. 現状分析レポート

1.1 ディレクトリ構成(CAD 関連の中核)

frontend/src/
├── cad-core/                    ← CAD Core(222 TS ファイル)
│   ├── models/                  entities.ts / document.ts / editorState.ts / productStructure.ts
│   ├── geometry/                math / intersections / bounds / distance / projection / fillet / rect ...
│   ├── snaps/ + snapping.ts     snapEngine / line・circle・arc・polylineSnap
│   ├── selection/ + selection.ts selectionEngine / selectionBox
│   ├── history/ + history.ts    historyEngine / transactions
│   ├── commands/                lineEditCommands(Trim/Extend/Break/Join/Fillet/Chamfer/Offset)
│   ├── transform/               moveTransform / transformEngine / gripTransform ← Move のみ
│   ├── constraints/             constraintEngine(H/V/Coincident/EqualLength/FixedPoint)
│   ├── dimensions/              linear / aligned / styles / labelFormatter
│   ├── document/                operations / spaceTypes / operationHistoryAdapter
│   ├── adapters/dxf/            dxfIO / dxfAdapter / dimension・annotation・hatchAdapter
│   ├── exporters/               svg / pdf / raster(未) / exportEngine
│   ├── renderers/               2d(svgRendererAdapter, viewportTransform) / 3d(threeSceneAdapter)
│   ├── hitTest/ grips/ hatches/ blocks/ annotations/ layouts/ interaction/
│   ├── spatialIndex/ versioning/ diff/ collaboration/ parametric/ pid/ plugins/
│   └── analysis/                analysisMesh / vtkAdapter / meshingService

├── stores/                      cadDocumentStore.ts / cadHistoryStore.ts(Pinia)

└── components/Daedalus/Drafting/
    ├── D_Daedalus.vue           ← 48,124 行のメイン(モノリス)
    ├── D_DaedalusRibbon.vue     ← 7,043 行(リボン)
    ├── D_Daedalus{MenuBar,LeftSidebar,RightSidebar,Footer}.vue
    ├── D_cadPointCommandExecutor.ts  ← Move/Copy/Rotate/Scale/Mirror(設備結合)
    ├── D_cadAliasCommandExecutor.ts  ← AutoCAD 風エイリアス(L→LINE 等)
    ├── D_useLineEditCommandRunner.ts ← Trim/Extend... の UI ランナー
    ├── D_use*.ts (多数の composable)
    └── SymbolRenderer/           D_sr.*.ts(Canvas 2D・適切に分離された良い例)

1.2 各機能の実装状況(調査結果)

観点実装場所備考
Entity モデル✅ 完全cad-core/models/entities.ts10 型: LINE/POLYLINE/CIRCLE/ARC/TEXT/ELLIPSE/INSERT/DIMENSION/ANNOTATION/HATCH
Geometry✅ 完全cad-core/geometry/距離・交差・射影・bounds・Fillet 幾何
Snap✅ 完全cad-core/snaps/endpoint/midpoint/center/quadrant/intersection/nearest
Selection✅ 完全cad-core/selection/window/crossing, policy, modifier
Undo/Redo✅ 完全cad-core/history/ + cadHistoryStoreトランザクション対応、容量 80
線編集コマンド✅ 完全cad-core/commands/lineEditCommands.tsTrim/Extend/Break/Join/Fillet/Chamfer/Offset
Move✅ 完全cad-core/transform/moveTransform.ts全 Entity 型対応
Copy/Rotate/Scale/Mirror⚠️ 設備結合Drafting/D_cadPointCommandExecutor.tsCAD Core に汎用版が無い
Constraints⚠️ 部分cad-core/constraints/5 種のみ(Tangent/Perpendicular/Angle/Radius 無し)
Dimensions⚠️ 部分cad-core/dimensions/Linear/Aligned のみ(Angular/Radius/Diameter/Ordinate 無し)
Layers✅ 完全cad-core/models/document.tsvisible/locked/printable/colorIndex
DXF I/O✅ 完全cad-core/adapters/dxf/LINE/XLINE/TEXT/CIRCLE/ARC/ELLIPSE/POLYLINE/SPLINE/HATCH
Project Save/Load✅ ありapi/*AdapterDedicated.ts + backend snapshots複合キーで snapshot 保存
State 管理✅ Piniastores/cadDocumentStore.tsapplyOperation() で一元化、履歴連携

1.3 描画エンジン構成

技術用途場所
SVGモデル空間・レイアウトの寸法/注釈/ハッチ描画cad-core/renderers/2d/svgRendererAdapter.ts + D_Daedalus.vue テンプレート
Canvas 2DシンボルエディタSymbolRenderer/D_sr.draw.ts分離良好
Three.js3D Feature プレビューD_feature3dThree*.ts
vtk.jsFEA 解析結果AnalysisVtkViewer.vue

座標変換は cad-core/renderers/2d/viewportTransform.tsworldToScreen/screenToWorld)と Drafting 側 D_useCoordinateSystem.ts / D_ucsCoordinate.ts に二重に存在。


2. 問題点一覧

P1: アーキテクチャ(CAD Core 独立性の漏れ)

  1. 汎用変換の欠落 — Rotate/Scale/Mirror/Copy が CAD Core に無く、Drafting の設備モデル(eq.x/eq.width)に結合。CadEntity を回転できない。
  2. 座標変換の二重実装viewportTransform.ts(Core)と D_useCoordinateSystem.ts(UI)が並存。UCS は UI 側のみ。
  3. 描画ロジックの Vue 混在D_Daedalus.vue 内に cadLinearDimensionScreen(), resolveCadQuickLineScreen(), onDrawLineEndpointMouseDown() 等、幾何・グリップ・スナップ計算が直書き。

P2: 保守性

  1. D_Daedalus.vue 48,124 行のモノリス — レビュー・差分・HMR・型チェックすべてに悪影響。ユーザーメモリにも「巨大 SFC で apply_patch が隣接ブロックへ誤注入」の既知リスクあり。
  2. D_DaedalusRibbon.vue 7,043 行 — タブ別 CSS は分割済みだが本体は肥大。
  3. 責務の重複 — Trim 系は cad-core/commandsDrafting/D_useLineEditCommandRunner の二段構成で、UI ランナーにも幾何ロジックが滲む。

P3: 機能完成度(機械系 2D CAD として)

  1. 寸法不足 — 角度・半径・直径・座標(Ordinate)寸法が無い。機械図面では必須。
  2. 拘束不足 — Tangent/Perpendicular/Parallel/Angle/Radius 拘束が無い。
  3. Polygon/Rectangle が専用 Entity でない — POLYLINE で代替(DXF 往復で意味が失われ得る)。
  4. PNG エクスポート未実装rasterExporter.ts がスタブ。

P4: パフォーマンス

  1. 巨大 SFC の再描画D_Daedalus.vue の reactive 状態が多すぎ、SVG テンプレートの再評価コスト大。spatialIndex/ はあるが UI から十分活用されていない可能性。

3. 設計レビュー

観点評価所見
責務分離CAD Core 内部は良好。だが UI ↔ Core 境界が崩れ、変換・座標・描画が UI に漏出。
保守性48k 行 SFC が最大のボトルネック。
拡張性Core はモジュール分割され寸法/拘束追加は容易。Entity は discriminated union で型安全。
パフォーマンス巨大 reactive SFC が懸念。Core の spatialIndex 活用余地。
CAD Core 独立性Vue 非依存だが、変換ロジックの一部が UI に逃げており「Core だけで図形を編集できない」。

Vue へのロジック混在: 重度(D_Daedalus.vue)。 SymbolRenderer(D_sr.*)は分離の良い手本であり、これを横展開の指針とする。


4. リファクタリング計画(方針)

原則(ユーザー指定): ①既存を壊さない ②既存を再利用 ③重複削減 ④CAD Core 中心へ ⑤将来の WASM 移植を考慮(今回 Rust/WASM は実装しない)。

WASM 移植を見据え、CAD Core は 純粋関数 + プレーンデータ(Vue リアクティブ非依存) を維持する。structuredClone 依存は将来 Rust 置換しやすい純データ操作に限定する。

目標アーキテクチャ(再掲)

UI Layer        : Toolbar / Property / Layer / Command Input   ← Vue は薄く
Rendering Layer : Canvas / SVG / Three.js                       ← Core の frame を描くだけ
CAD Core        : Entities / Geometry / Snap / Selection /
                  Commands / Constraints / Dimensions / Layers / Transform
Data Layer      : DXF Import/Export / Project Save/Load

移行戦略(段階的・非破壊)

  • Strangler パターン: 既存の Drafting 関数はそのまま残し、内部実装を Core 呼び出しへ差し替える「委譲」方式で 1 つずつ移す。
  • 各ステップは 追加 → 委譲 → 旧実装削除 の 3 フェーズ。テストを伴わせる。

5. 優先順位付き改善ロードマップ

#項目内容破壊リスク効果
R1CAD Core 汎用変換モジュールcad-core/transform/entityTransforms.ts を新設し、rotateEntity / scaleEntity / mirrorEntity / copyEntity を全 CadEntity 型に対応で追加(applyMoveToEntity と対のパターン)。追加のみ・既存不変なし高(Core 独立性回復の核)
R2変換モジュールの単体テストVitest で各 Entity 型 × 各変換の不変条件(長さ・半径・角度)を検証。なし
R3Drafting の Copy/Rotate/Scale/Mirror を Core へ委譲D_cadPointCommandExecutor.ts の汎用図形分岐を R1 の関数呼び出しに置換(設備固有処理は残す)。
R4角度・半径・直径寸法cad-core/dimensions/angularDimension / radialDimension を追加。Entity 型へ dimensionType 拡張。中(機械系で必須)
R5追加スナップ(Perpendicular/Tangent)cad-core/snaps/ に perpendicular/tangent 候補を追加。
R6座標変換の一本化UI の D_useCoordinateSystem を Core の viewportTransform の薄いラッパへ。UCS を Core へ昇格。
R7D_Daedalus.vue の分割描画プレビュー/グリップ/寸法計算を composable + Core へ抽出し SFC を縮小。中〜高高(保守性)
R8Rectangle/Polygon Entity・PNG エクスポート不足図形と raster 出力の整備。低〜中

6. 今回の着手

ロードマップ R1(CAD Core 汎用変換モジュール)+ R2(テスト) から開始する。理由:

  • 完全に 追加のみ で既存挙動を一切変えない(最も安全)。
  • CAD Core 独立性という最重要課題の核心を埋める。
  • 後続 R3(委譲)の前提資産になる。

以降の R3〜R8 は本レポートの順で、各々レビュー可能な小さな単位で実施する。


7. 【重要】R3 着手で判明したアーキテクチャの核心: 2 つの並行データモデル

R3(変換ロジックの Core 委譲)に着手して、Daedalus 作図アプリの最重要構造が判明した。

7.1 2 モデル並存の事実

Daedalus は2 つの異なる CAD データモデルを並行して持っている:

A: Equipment モデルB: CadEntity モデル(cad-core)
フラットな AABB: { id, x, y, width, height, rotation, type, meta }。曲線・パスは meta.drawPathPoints 等に格納discriminated union(LINE/CIRCLE/ARC/...)、各型が固有 geometry を持つ
用途メイン作図データ。 D_Daedalus.vue の SVG テンプレートに直接描画され、保存される実体hitTest / snap / grips / selection / spatialIndex / DXF I/O / analysis など補助サブシステムで利用
変換D_cadPointCommandExecutor.ts(equipment 専用、eq.x/eq.width 直接操作)cad-core/transform(Move のみ存在 → R1 で Rotate/Scale/Mirror/Copy 追加済み)

→ つまり D_Daedalus.vue48k 行に肥大化した根本原因はこれ。equipment モデル上に変換・幾何・描画を再実装しており、成熟した cad-core の資産(Entity 変換・寸法・拘束)を直接は使えていない。R1 で追加した entityTransforms.ts は CadEntity 用であり、equipment 用変換をそのまま置換できない(モデル不一致)。

7.2 R3 で実際に行った安全な改善(実装済み)

モデル不一致のため「変換ロジック全体の委譲」は一段で不可。代わりに 両モデルで重複していた純粋幾何プリミティブを CAD Core に集約した(挙動不変・低リスク):

  • 新規: cad-core/geometry/pointTransforms.tsrotatePointAround / rotatePointAroundDeg / scalePointAround / reflectPointAcrossAxis(CAD Core を single source of truth 化)
  • cad-core/transform/entityTransforms.ts — 内部の重複プリミティブを上記へ委譲
  • Drafting/D_cadPointCommandExecutor.ts — ローカル複製の reflectPointAcrossAxis を削除し CAD Core 版を import(設備固有のミラー処理ロジックは温存
  • テスト追加: pointTransforms.test.ts(9 件)。entityTransforms.test.ts(13 件)と合わせ 22 件全パス

7.3 今後の収束方針(R3 の続き → R7 へ接続)

2 モデルは段階的に CadEntity へ収束させるのが本筋。一気の置換は破壊的なので Strangler で進める:

  1. 共有プリミティブ集約(R3 で着手済み)— 幾何演算を CAD Core に一本化。
  2. Equipment ⇄ CadEntity アダプタの明確化Phase 0 完了)— equipment を CadEntity に投影する変換層を 1 箇所に集約。
  3. 新規図形を CadEntity ネイティブに — 以降の新機能(角度寸法など)は CadEntity 側に実装し、equipment へは描画時のみ投影。
  4. 段階的移行 — 図形種別ごとに描画・編集を CadEntity 経由へ差し替え、equipment を最終的に「ビューモデル」へ降格。

Phase 0 実装内容(完了)

frontend/src/cad-core/adapters/equipment/ を新設し、2 モデルの境界を 1 箇所に集約(追加のみ・既存挙動は不変)。

  • equipmentGeometry.ts — equipment 座標規約(左上基準・y 上向き・中心まわり回転)を純粋関数化。equipmentCenterWorld / equipmentWorldFromLocal(y 反転 → 中心回転)/ equipmentLocalFromWorld(逆変換)/ 線・矩形・ポリゴン・パス・円弧・円・楕円のワールド幾何リゾルバ。線分は既存 resolveLineAxisWorldSegment を再利用。
  • equipmentToCadEntity.tsequipmentToCadEntity(eq){ok, entity} または {ok:false, reason, type} を返す。equipmentsToCadEntities(eqs) は一括変換+未対応を skipped[] に収集。3 点円弧の中心復元 resolveArcFromThreePoints(外接円算出、共線時 null)を実装(再利用可能な既存関数は無かった)。
  • 対応種別: drawLine→LINE / drawCircle→CIRCLE / drawEllipse→ELLIPSE / drawArc→ARC / drawRect→閉 POLYLINE(4頂点) / drawPolygon→閉 POLYLINE / drawPen→開 POLYLINE / drawText→TEXT
  • 後続フェーズへ繰り延べok:false): 寸法・引出線・中心線・雲マーク・表・スプライン・シンボル/レイアウト物。
  • テスト: equipmentToCadEntity.test.ts 14 件全パス(座標往復・3 点円弧・各図形変換・未対応スキップ)。

Phase 1 実装内容(完了)— 新機能を CadEntity ネイティブで実装

方針 3「新規図形を CadEntity ネイティブに」の最初の実装として、角度/半径/直径寸法を CAD Core ネイティブで追加し、描画時のみ equipment へ投影する経路を整備した(追加のみ・既存挙動不変)。

CAD Core 側(寸法モデル拡張):

  • models/entities.tsCadDimensionEntity.dimensionType'angular' | 'radial' | 'diameter' を追加。任意フィールド vertex?(角の頂点), centerPoint?(円中心)を追加(既存 linear/aligned はそのまま)。
  • dimensions/angularRadialDimension.ts(新規)— resolveAngularDimensionCore(vertex を頂点に 2 射線がなす角を円弧で表現。dimensionLinePoint で弧の半径・向き=劣角/優角を決定。measuredValue = 度)と resolveRadialDimensionCore(radial/diameter。measuredValue = 半径/直径)。
  • dimensions/types.tsResolvedDimensionGeometry に任意の arc?(角度寸法の円弧表現)を追加。DimensionKind も拡張。
  • dimensions/resolveDimension.tsresolveDimensionGeometry のディスパッチ、computeDimensionMeasurementformatDimensionText(角度=°、半径=R、直径= 接頭/接尾)を拡張。
  • dimensions/bounds.ts — 円弧をサンプリングして bounds に反映。
  • dimensions/dimensionFactory.ts(新規)— createAngularDimension / createRadialDimension / createDiameterDimension コンストラクタ。

描画投影(CadEntity → equipment):

  • adapters/equipment/cadEntityToEquipment.ts(新規・Phase 0 の逆方向)— cadEntityToEquipment(entity) で LINE→drawLine / CIRCLE→drawCircle / ELLIPSE→drawEllipse / ARC→drawArc / POLYLINE→drawPolygon・drawPen / TEXT→drawText に投影(rotation 0・meta にローカル点を明示)。
  • adapters/equipment/dimensionRenderProjection.ts(新規)— dimensionToRenderEntities(dim) が寸法を普遍プリミティブ(LINE/ARC/閉 POLYLINE 矢じり/TEXT)へ分解。dimensionToEquipmentPrimitives(dim) = 分解 → cadEntityToEquipment で equipment 群へ投影。CadEntity が source of truth、equipment は描画専用の派生物
  • テスト: angularRadialDimension.test.ts 9 件全パス(角度 90°/優角 270°・R/⌀ 表示・textOverride 優先・プリミティブ分解・equipment 投影と drawArc 往復)。cad-core 全体 45 件全パス

8. Rust / WASM 移植の判断(現時点の結論)

ユーザー目標「cad-core 完成後に Rust/WASM の要否を判断」に対する現時点の評価

8.1 結論: 現段階では WASM 不要。先に TS で構造的負債を解消すべき。

理由:

  • ボトルネックは計算性能ではなく構造。 現状の最大課題は 48k 行モノリスと 2 モデル並存であり、これは Rust では解決しない(むしろ FFI 境界が増えて悪化)。
  • CAD Core は既に純粋関数 + プレーンデータで書かれている。 Vue 非依存・structuredClone 中心で、将来 WASM 化する場合の「移植しやすさ」は既に確保されている。今は移植の前提づくりが整っていれば十分。
  • WASM のコストが効果を上回る局面ではない。 ビルド複雑化・デバッグ困難・バンドル増・JS↔WASM のデータマーシャリングコストは、現在の図形数規模では正当化されない。

8.2 WASM を検討すべき将来の閾値(トリガ条件)

以下が現実の問題になった時に初めて WASM/Rust を再評価する:

  • 単一図面の Entity 数が 数万〜数十万規模になり、ヒットテスト/スナップ/再描画が JS で 16ms/frame を超える。
  • 重い幾何カーネルが必要になる(ブーリアン演算・オフセット網羅・制約ソルバの大規模化・NURBS・メッシュブーリアン)。
  • DXF/STEP の大規模パースが CPU バウンドになる。

8.3 WASM 化する場合の準備(今 TS でやっておくべきこと = 移植容易性の担保)

  • 幾何プリミティブを cad-core/geometry に集約(R3 で前進)。
  • CAD Core を「純粋関数 + プレーン構造体(リアクティブ非依存)」に保つ(既に達成)。
  • 変換・交差・スナップなど CPU 集約カーネルを副作用フリーの関数境界に閉じ込める(Rust 置換時にそのまま 1:1 で移せる単位にする)。

方針: WASM は「いつでも移植できる状態」を TS で維持しつつ、当面は実装しない。 まず cad-core 収束(R3〜R7)と機械系機能拡充(R4〜R5)を TS で完了させる。

Last updated:

この記事の著者

MECHPHAISTOS | センサーを使わない保全

Yoshitaka Notoです。保全業務に携わり、AI時代の3Kと呼ばれるメンテナンス保全をもっと楽にしたい。 そういった保全ツール開発してます。