Skip to content

feat: add OFFSET command with dynamic distance input and open polyline support#283

Closed
son-urban wants to merge 14 commits into
mlightcad:mainfrom
son-urban:feat/offset
Closed

feat: add OFFSET command with dynamic distance input and open polyline support#283
son-urban wants to merge 14 commits into
mlightcad:mainfrom
son-urban:feat/offset

Conversation

@son-urban
Copy link
Copy Markdown
Contributor

Summary

  • Adds OFFSET command (AcApOffsetCmd) supporting Line, Arc, Circle, Ellipse, Polyline, and Spline entities
  • Supports two modes: fixed distance and Through-point (cursor picks the offset distance dynamically)
  • Live preview jig updates in real-time as the cursor moves
  • Open polyline offset via per-segment parallel translation with intersection joining
  • Erase source (E) and Layer (L) keyword toggles with status echo
  • Ribbon button with SVG icon wired to the Home → Modify panel
  • EN/ZH i18n strings
  • Uses Clipper2 (clipper2-ts) for closed polyline offset

Infrastructure changes

  • AcEdFloatingInput: new distanceInput mode — shows a single floating input box that displays the perpendicular distance from cursor to the selected entity and accepts a typed override
  • AcEdFloatingInputBox/Boxes/Types: extracted shared types and multi-box layout helpers
  • AcEdPromptPointOptions: added distanceInput option for distance-anchored point prompts
  • OSNAP guard: skip OSNAP processing when osnapModes === 0 (pre-existing bug fixed during this work)
  • Click-suppression fix: entity-pick click no longer leaks into the subsequent side-pick prompt

Test plan

  • Unit tests: 17 geometry tests covering Line, Arc, Circle, Ellipse, closed Polyline, open Polyline (2-vertex, 3-vertex, degenerate), and pickSide
  • All tests pass: npx jest packages/cad-simple-viewer/__tests__/AcApOffsetGeometry.spec.ts

Notes

  • Ellipse offset is a known approximation (adds scalar distance to both radii). Rotated ellipses are not supported — this is a limitation of the current data model API which does not expose the axis vector for write. Ellipse is included in OFFSETTABLE_TYPES for axis-aligned cases which are the common case.
  • Spline offset returns null (not supported) — control points are not accessible via the public API.

son-urban and others added 12 commits May 20, 2026 03:03
- Remove dead code (rectangleDimensions, polarDistanceAngle) from AcEdInputManager
- Remove AcApOffsetGeometry from public modify index
- Echo state when Erase/Layer keywords are toggled
- Add open polyline test coverage (2-vertex, 3-vertex, degenerate)
- Fix duplicate i18n keys in offset section
- Add trailing newline to offset.svg
- Remove agent planning docs
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@son-urban
Copy link
Copy Markdown
Contributor Author

Note on ellipse offset limitation

The ellipse offset (offsetEllipse) and side-pick (pickSide ellipse branch) are both limited to axis-aligned ellipses. Here's why:

AcDbEllipse accepts a majorAxis: AcGeVector3dLike direction vector in its constructor, but the class does not expose a majorAxis getter. The value is stored in the private _geo: AcGeEllipseArc3d field — which does have get majorAxis(): AcGeVector3d — but it is never surfaced on AcDbEllipse itself.

Without the axis direction, we cannot:

  • Reconstruct the offset ellipse with the correct orientation (we fall back to (1, 0, 0))
  • Transform the cursor point into the ellipse's local frame to determine inside/outside

Fix needed in data-model: add a getter to AcDbEllipse:

get majorAxis(): AcGeVector3d {
  return this._geo.majorAxis
}

Once that's available, both functions can be corrected. Happy to follow up in a separate PR once the getter is exposed.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Owner

@mlightcad mlightcad May 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@son-urban The correct way is to add method getOffsetCurves in class AcDbCurve as what AutoCAD ObjectARX does.

https://help.autodesk.com/view/OARX/2024/ENU/?guid=OARX-RefGuide-AcDbCurve__getOffsetCurves_double_AcDbVoidPtrArray__const

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@son-urban You needs to change code in realdwg-web repo to add this method.

Copy link
Copy Markdown
Owner

@mlightcad mlightcad May 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@son-urban You should add one new class AcDbPromptDistanceOptions as the corresponding class in .NET

https://help.autodesk.com/view/OARX/2024/ENU/?guid=OARX-ManagedRefGuide-Autodesk_AutoCAD_EditorInput_PromptDistanceOptions

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that makes sense. I’ll refactor toward this direction before marking the PR ready for review again.

@son-urban son-urban marked this pull request as draft May 22, 2026 09:32
@mlightcad
Copy link
Copy Markdown
Owner

mlightcad commented May 24, 2026

@son-urban I added offset command in this PR. You can continue to refine offset command based on it if you are interested in it. For example, algorithm to compute offset for spline is still incorrect in certain case.

…7.40

Replace standalone offset geometry functions with AcDbCurve#getOffsetSideAtPoint() and AcDbCurve#getOffsetCurves() from @mlightcad/data-model@1.7.40. Remove viewer-local AcApOffsetGeometry.ts + old tests. Bump deps, drop clipper2-ts. Add 58 unit tests covering all entity types and UX modes.
@son-urban
Copy link
Copy Markdown
Contributor Author

Closing this PR since mlightcad's OFFSET implementation (#290) has been merged into main. The refactor to use AcDbCurve.getOffsetCurves() is already covered there. Thanks!

@son-urban son-urban closed this May 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants