UNPKG

@itwin/core-frontend

Version:
1,132 lines • 55.7 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Tools */ Object.defineProperty(exports, "__esModule", { value: true }); exports.DefineACSByPointsTool = exports.DefineACSByElementTool = exports.AccuDrawRotateElementTool = exports.AccuDrawRotateAxesTool = exports.AccuDrawRotate90AboutZTool = exports.AccuDrawRotate90AboutYTool = exports.AccuDrawRotate90AboutXTool = exports.AccuDrawRotateViewTool = exports.AccuDrawRotateSideTool = exports.AccuDrawRotateFrontTool = exports.AccuDrawRotateTopTool = exports.AccuDrawRotateCycleTool = exports.AccuDrawChangeModeTool = exports.AccuDrawSetLockAngleTool = exports.AccuDrawSetLockDistanceTool = exports.AccuDrawSetLockZTool = exports.AccuDrawSetLockYTool = exports.AccuDrawSetLockXTool = exports.AccuDrawSetLockIndexTool = exports.AccuDrawSetLockSmartTool = exports.AccuDrawSetOriginTool = exports.AccuDrawSuspendToggleTool = exports.AccuDrawSessionToggleTool = exports.AccuDrawShortcuts = void 0; const core_bentley_1 = require("@itwin/core-bentley"); const core_geometry_1 = require("@itwin/core-geometry"); const AccuDraw_1 = require("../AccuDraw"); const AccuSnap_1 = require("../AccuSnap"); const AuxCoordSys_1 = require("../AuxCoordSys"); const IModelApp_1 = require("../IModelApp"); const Tool_1 = require("./Tool"); // cSpell:ignore dont unlockedz function normalizedDifference(point1, point2, out) { return point2.vectorTo(point1).normalizeWithLength(out).mag; } function normalizedCrossProduct(vec1, vec2, out) { return vec1.crossProduct(vec2, out).normalizeWithLength(out).mag; } /** * A shortcut may require no user input (immediate) or it may install a tool to collect the needed input. AccuDrawShortcuts are how users control AccuDraw. * A tool implementor should not use this class to setup AccuDraw, instead use AccuDrawHintBuilder to provide hints. * @beta */ class AccuDrawShortcuts { /** Disable/Enable AccuDraw for the session */ static sessionToggle() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (accudraw.isEnabled) accudraw.disableForSession(); else accudraw.enableForSession(); } /** Suspend/Unsuspend AccuDraw for the active tool */ static suspendToggle() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; if (accudraw.isActive) accudraw.deactivate(); else accudraw.activate(); accudraw.refreshDecorationsAndDynamics(); } static rotateAxesByPoint(isSnapped, aboutCurrentZ) { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return false; const vp = accudraw.currentView; if (!vp) return false; const point = accudraw.point; if (!vp.view.is3d()) point.z = 0.0; if (aboutCurrentZ) accudraw.hardConstructionPlane(point, point, accudraw.planePt, accudraw.axes.z, vp, isSnapped); else accudraw.softConstructionPlane(point, point, accudraw.planePt, accudraw.axes.z, vp, isSnapped); // Snap point and compass origin coincide... const xVec = new core_geometry_1.Vector3d(); if (normalizedDifference(point, accudraw.planePt, xVec) < core_geometry_1.Geometry.smallAngleRadians) return false; accudraw.axes.x.setFrom(xVec); if (AccuDraw_1.RotationMode.Context !== accudraw.rotationMode) accudraw.setRotationMode(AccuDraw_1.RotationMode.Context); accudraw.flags.contextRotMode = AccuDraw_1.ContextMode.XAxis; accudraw.flags.lockedRotation = false; accudraw.updateRotation(); // Always want index line to display for x-Axis...changing rotation clears this...so it flashes... accudraw.indexed |= AccuDraw_1.LockedStates.X_BM; return true; } static updateACSByPoints(acs, vp, points, isDynamics) { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return false; let accept = false; const vec = [new core_geometry_1.Vector3d(), new core_geometry_1.Vector3d(), new core_geometry_1.Vector3d()]; acs.setOrigin(points[0]); switch (points.length) { case 1: acs.setRotation(vp.rotation); if (!isDynamics) { accudraw.published.origin.setFrom(points[0]); accudraw.published.flags = AccuDraw_1.AccuDrawFlags.SetOrigin; accudraw.flags.fixedOrg = true; } break; case 2: if (normalizedDifference(points[1], points[0], vec[0]) < 0.00001) { accept = true; break; } if (vp.view.is3d()) { if (normalizedCrossProduct(accudraw.axes.y, vec[0], vec[1]) < 0.00001) { vec[2].set(0.0, 0.0, 1.0); if (normalizedCrossProduct(vec[2], vec[0], vec[1]) < 0.00001) { vec[2].set(0.0, 1.0, 0.0); normalizedCrossProduct(vec[2], vec[0], vec[1]); } } normalizedCrossProduct(vec[0], vec[1], vec[2]); acs.setRotation(core_geometry_1.Matrix3d.createRows(vec[0], vec[1], vec[2])); if (!isDynamics) { accudraw.published.origin.setFrom(points[0]); accudraw.published.flags = AccuDraw_1.AccuDrawFlags.SetOrigin | AccuDraw_1.AccuDrawFlags.SetNormal; accudraw.published.vector.setFrom(vec[0]); } break; } vec[2].set(0.0, 0.0, 1.0); normalizedCrossProduct(vec[2], vec[0], vec[1]); acs.setRotation(core_geometry_1.Matrix3d.createRows(vec[0], vec[1], vec[2])); accept = true; break; case 3: if (normalizedDifference(points[1], points[0], vec[0]) < 0.00001 || normalizedDifference(points[2], points[0], vec[1]) < 0.00001 || normalizedCrossProduct(vec[0], vec[1], vec[2]) < 0.00001) { accept = true; break; } normalizedCrossProduct(vec[2], vec[0], vec[1]); acs.setRotation(core_geometry_1.Matrix3d.createRows(vec[0], vec[1], vec[2])); accept = true; break; } return accept; } static processPendingHints() { IModelApp_1.IModelApp.accuDraw.processHints(); } static requestInputFocus() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; accudraw.grabInputFocus(); accudraw.refreshDecorationsAndDynamics(); } // Helper method for GUI implementation... static async itemFieldNavigate(index, str, forward) { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; if (accudraw.getFieldLock(index)) accudraw.saveCoordinate(index, accudraw.getValueByIndex(index)); if (!accudraw.isActive && AccuDraw_1.KeyinStatus.Partial === accudraw.getKeyinStatus(index)) { await accudraw.processFieldInput(index, str, true); } else { accudraw.setKeyinStatus(index, AccuDraw_1.KeyinStatus.Dynamic); accudraw.onFieldValueChange(index); } const vp = accudraw.currentView; const is3d = vp ? accudraw.is3dCompass(vp) : false; const isPolar = (AccuDraw_1.CompassMode.Polar === accudraw.compassMode); switch (index) { case AccuDraw_1.ItemField.DIST_Item: index = ((is3d && !forward) ? AccuDraw_1.ItemField.Z_Item : AccuDraw_1.ItemField.ANGLE_Item); break; case AccuDraw_1.ItemField.ANGLE_Item: index = ((is3d && forward) ? AccuDraw_1.ItemField.Z_Item : AccuDraw_1.ItemField.DIST_Item); break; case AccuDraw_1.ItemField.X_Item: index = ((is3d && !forward) ? AccuDraw_1.ItemField.Z_Item : AccuDraw_1.ItemField.Y_Item); break; case AccuDraw_1.ItemField.Y_Item: index = ((is3d && forward) ? AccuDraw_1.ItemField.Z_Item : AccuDraw_1.ItemField.X_Item); break; case AccuDraw_1.ItemField.Z_Item: index = (forward ? (isPolar ? AccuDraw_1.ItemField.DIST_Item : AccuDraw_1.ItemField.X_Item) : (isPolar ? AccuDraw_1.ItemField.ANGLE_Item : AccuDraw_1.ItemField.Y_Item)); break; } // Set focus to new item and disable automatic focus change based on cursor location in rectangular mode. accudraw.setFocusItem(index); accudraw.dontMoveFocus = true; } static itemFieldNewInput(index) { IModelApp_1.IModelApp.accuDraw.setKeyinStatus(index, AccuDraw_1.KeyinStatus.Partial); } static itemFieldCompletedInput(index) { IModelApp_1.IModelApp.accuDraw.setKeyinStatus(index, AccuDraw_1.KeyinStatus.Dynamic); } static async itemFieldAcceptInput(index, str) { const accudraw = IModelApp_1.IModelApp.accuDraw; await accudraw.processFieldInput(index, str, true); accudraw.setKeyinStatus(index, AccuDraw_1.KeyinStatus.Dynamic); if (accudraw.getFieldLock(index)) accudraw.saveCoordinate(index, accudraw.getValueByIndex(index)); const vp = accudraw.currentView; if (accudraw.isActive) { if (!vp) return; if (AccuDraw_1.CompassMode.Polar === accudraw.compassMode) accudraw.fixPointPolar(vp); else accudraw.fixPointRectangular(vp); accudraw.flags.dialogNeedsUpdate = true; return; } const is3d = vp ? vp.view.is3d() : false; const isPolar = (AccuDraw_1.CompassMode.Polar === accudraw.compassMode); switch (index) { case AccuDraw_1.ItemField.DIST_Item: index = AccuDraw_1.ItemField.ANGLE_Item; break; case AccuDraw_1.ItemField.ANGLE_Item: index = (is3d ? AccuDraw_1.ItemField.Z_Item : AccuDraw_1.ItemField.DIST_Item); break; case AccuDraw_1.ItemField.X_Item: index = AccuDraw_1.ItemField.Y_Item; break; case AccuDraw_1.ItemField.Y_Item: index = (is3d ? AccuDraw_1.ItemField.Z_Item : AccuDraw_1.ItemField.X_Item); break; case AccuDraw_1.ItemField.Z_Item: index = (isPolar ? AccuDraw_1.ItemField.DIST_Item : AccuDraw_1.ItemField.X_Item); break; } accudraw.setFocusItem(index); } static itemFieldLockToggle(index) { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; if (accudraw.getFieldLock(index)) { switch (index) { case AccuDraw_1.ItemField.DIST_Item: accudraw.distanceLock(true, false); break; case AccuDraw_1.ItemField.ANGLE_Item: accudraw.angleLock(); break; case AccuDraw_1.ItemField.X_Item: accudraw.clearTentative(); accudraw.locked |= AccuDraw_1.LockedStates.X_BM; break; case AccuDraw_1.ItemField.Y_Item: accudraw.clearTentative(); accudraw.locked |= AccuDraw_1.LockedStates.Y_BM; break; case AccuDraw_1.ItemField.Z_Item: accudraw.clearTentative(); break; } return; } switch (index) { case AccuDraw_1.ItemField.DIST_Item: accudraw.locked &= ~AccuDraw_1.LockedStates.DIST_BM; break; case AccuDraw_1.ItemField.ANGLE_Item: accudraw.locked &= ~AccuDraw_1.LockedStates.ANGLE_BM; break; case AccuDraw_1.ItemField.X_Item: accudraw.locked &= ~AccuDraw_1.LockedStates.X_BM; break; case AccuDraw_1.ItemField.Y_Item: accudraw.locked &= ~AccuDraw_1.LockedStates.Y_BM; break; case AccuDraw_1.ItemField.Z_Item: break; } accudraw.dontMoveFocus = false; accudraw.clearTentative(); } static choosePreviousValue(index) { const accudraw = IModelApp_1.IModelApp.accuDraw; accudraw.getSavedValue(index, false); accudraw.refreshDecorationsAndDynamics(); } static chooseNextValue(index) { const accudraw = IModelApp_1.IModelApp.accuDraw; accudraw.getSavedValue(index, true); accudraw.refreshDecorationsAndDynamics(); } static clearSavedValues() { const accudraw = IModelApp_1.IModelApp.accuDraw; accudraw.clearSavedValues(); } static itemRotationModeChange(rotation) { const accudraw = IModelApp_1.IModelApp.accuDraw; const vp = accudraw.currentView; const is3d = vp ? vp.view.is3d() : true; if (!is3d && (AccuDraw_1.RotationMode.Front === rotation || AccuDraw_1.RotationMode.Side === rotation)) accudraw.setRotationMode(AccuDraw_1.RotationMode.Top); accudraw.flags.baseRotation = rotation; accudraw.updateRotation(true); } // Shortcut implementations for GUI entry points... static setOrigin(explicitOrigin) { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; if (explicitOrigin) { accudraw.published.origin.setFrom(explicitOrigin); accudraw.flags.haveValidOrigin = true; } else if (accudraw.isInactive || accudraw.isDeactivated) { // If AccuSnap is active use adjusted snap point, otherwise use last data point... const snap = AccuSnap_1.TentativeOrAccuSnap.getCurrentSnap(false); if (undefined !== snap) { accudraw.published.origin.setFrom(snap.isPointAdjusted ? snap.adjustedPoint : snap.getPoint()); accudraw.flags.haveValidOrigin = true; } else { const ev = new Tool_1.BeButtonEvent(); IModelApp_1.IModelApp.toolAdmin.fillEventFromLastDataButton(ev); if (ev.viewport) { accudraw.published.origin.setFrom(ev.point); accudraw.flags.haveValidOrigin = true; } else { // NOTE: If current point isn't valid setDefaultOrigin will be called... accudraw.published.origin.setFrom(accudraw.point); } } } else { accudraw.published.origin.setFrom(accudraw.point); accudraw.flags.haveValidOrigin = true; accudraw.setLastPoint(accudraw.published.origin); } accudraw.clearTentative(); const vp = accudraw.currentView; // NOTE: _AdjustPoint should have been called to have setup currentView... if (vp && !vp.view.is3d()) accudraw.published.origin.z = 0.0; accudraw.origin.setFrom(accudraw.published.origin); accudraw.point.setFrom(accudraw.published.origin); accudraw.planePt.setFrom(accudraw.published.origin); accudraw.published.flags |= AccuDraw_1.AccuDrawFlags.SetOrigin; accudraw.activate(); accudraw.refreshDecorationsAndDynamics(); // NOTE: Will already grab input focus through processHints... } static changeCompassMode() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; let axisLockStatus = accudraw.locked & AccuDraw_1.LockedStates.XY_BM; if (axisLockStatus) { if (AccuDraw_1.CompassMode.Rectangular === accudraw.compassMode) { if (axisLockStatus & AccuDraw_1.LockedStates.X_BM && accudraw.delta.x !== 0.0) axisLockStatus &= ~AccuDraw_1.LockedStates.X_BM; if (axisLockStatus & AccuDraw_1.LockedStates.Y_BM && accudraw.delta.y !== 0.0) axisLockStatus &= ~AccuDraw_1.LockedStates.Y_BM; } } accudraw.changeCompassMode(true); if (axisLockStatus) { if (AccuDraw_1.CompassMode.Rectangular === accudraw.compassMode) { accudraw.delta.x = accudraw.delta.y = 0.0; if (axisLockStatus & AccuDraw_1.LockedStates.X_BM) accudraw.setFieldLock(AccuDraw_1.ItemField.X_Item, true); else if (axisLockStatus & AccuDraw_1.LockedStates.Y_BM) accudraw.setFieldLock(AccuDraw_1.ItemField.Y_Item, true); } else { accudraw.setFieldLock(AccuDraw_1.ItemField.ANGLE_Item, true); } accudraw.locked = axisLockStatus; } accudraw.flags.baseMode = accudraw.compassMode; this.requestInputFocus(); } static lockSmart() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; const accuSnap = IModelApp_1.IModelApp.accuSnap; // Don't want AccuSnap to influence axis or Z... if (accuSnap.isHot) { accuSnap.clear(); const vp = accudraw.currentView; if (vp) { if (AccuDraw_1.CompassMode.Polar === accudraw.compassMode) accudraw.fixPointPolar(vp); else accudraw.fixPointRectangular(vp); } } if (AccuDraw_1.CompassMode.Polar === accudraw.compassMode) { const isSnapped = accudraw.clearTentative(); if (accudraw.locked & AccuDraw_1.LockedStates.ANGLE_BM) { // angle locked (unlock it) accudraw.setFieldLock(AccuDraw_1.ItemField.ANGLE_Item, false); accudraw.locked &= ~AccuDraw_1.LockedStates.ANGLE_BM; } else if (accudraw.getFieldLock(AccuDraw_1.ItemField.DIST_Item)) { // distance locked (unlock it) accudraw.setFieldLock(AccuDraw_1.ItemField.DIST_Item, false); accudraw.locked &= ~AccuDraw_1.LockedStates.DIST_BM; } else if (isSnapped) { accudraw.doLockAngle(isSnapped); } else if (accudraw.indexed & AccuDraw_1.LockedStates.ANGLE_BM) { // angle indexed (lock it) accudraw.angleLock(); } else { if (Math.abs(accudraw.vector.dotProduct(accudraw.axes.x)) > Math.abs(accudraw.vector.dotProduct(accudraw.axes.y))) accudraw.indexed |= AccuDraw_1.LockedStates.Y_BM; else accudraw.indexed |= AccuDraw_1.LockedStates.X_BM; accudraw.angleLock(); } this.requestInputFocus(); return; } if (accudraw.locked) { // if locked, unlock accudraw.clearTentative(); accudraw.locked &= ~AccuDraw_1.LockedStates.XY_BM; accudraw.setFieldLock(AccuDraw_1.ItemField.X_Item, false); accudraw.setFieldLock(AccuDraw_1.ItemField.Y_Item, false); if (accudraw.getFieldLock(AccuDraw_1.ItemField.Z_Item) && accudraw.delta.z === 0.0 && !accudraw.stickyZLock) accudraw.setFieldLock(AccuDraw_1.ItemField.Z_Item, false); } else { // lock to nearest axis if (accudraw.clearTentative()) { if (Math.abs(accudraw.delta.x) >= core_geometry_1.Geometry.smallAngleRadians && Math.abs(accudraw.delta.y) >= core_geometry_1.Geometry.smallAngleRadians) { accudraw.doLockAngle(false); return; } } const vp = accudraw.currentView; if (Math.abs(accudraw.delta.x) > Math.abs(accudraw.delta.y)) { accudraw.delta.y = 0.0; accudraw.onFieldValueChange(AccuDraw_1.ItemField.Y_Item); accudraw.locked |= AccuDraw_1.LockedStates.Y_BM; accudraw.locked &= ~AccuDraw_1.LockedStates.X_BM; accudraw.setFieldLock(AccuDraw_1.ItemField.X_Item, false); accudraw.setFieldLock(AccuDraw_1.ItemField.Y_Item, true); accudraw.setFieldLock(AccuDraw_1.ItemField.Z_Item, vp ? vp.view.is3d() : false); } else { accudraw.delta.x = 0.0; accudraw.onFieldValueChange(AccuDraw_1.ItemField.X_Item); accudraw.locked |= AccuDraw_1.LockedStates.X_BM; accudraw.locked &= ~AccuDraw_1.LockedStates.Y_BM; accudraw.setFieldLock(AccuDraw_1.ItemField.Y_Item, false); accudraw.setFieldLock(AccuDraw_1.ItemField.X_Item, true); accudraw.setFieldLock(AccuDraw_1.ItemField.Z_Item, vp ? vp.view.is3d() : false); } if (!accudraw.flags.lockedRotation) { accudraw.flags.lockedRotation = true; accudraw.flags.contextRotMode = AccuDraw_1.ContextMode.Locked; accudraw.setRotationMode(AccuDraw_1.RotationMode.Context); } } this.requestInputFocus(); } /** Disable indexing when not currently indexed; if indexed, enable respective lock. */ static lockIndex() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; if (accudraw.flags.indexLocked) { if (accudraw.locked) this.lockSmart(); accudraw.flags.indexLocked = false; } else { if (AccuDraw_1.CompassMode.Polar === accudraw.compassMode) { if (accudraw.indexed & AccuDraw_1.LockedStates.XY_BM) { accudraw.setFieldLock(AccuDraw_1.ItemField.ANGLE_Item, true); accudraw.angleLock(); } if (accudraw.indexed & AccuDraw_1.LockedStates.DIST_BM) this.lockDistance(); } else { if (accudraw.indexed & AccuDraw_1.LockedStates.X_BM) { this.lockX(); if (accudraw.indexed & AccuDraw_1.LockedStates.DIST_BM) this.lockY(); } if (accudraw.indexed & AccuDraw_1.LockedStates.Y_BM) { this.lockY(); if (accudraw.indexed & AccuDraw_1.LockedStates.DIST_BM) this.lockX(); } if (accudraw.indexed & AccuDraw_1.LockedStates.DIST_BM && !(accudraw.indexed & AccuDraw_1.LockedStates.XY_BM)) { if (accudraw.locked & AccuDraw_1.LockedStates.X_BM) this.lockY(); else this.lockX(); } } accudraw.flags.indexLocked = true; } this.requestInputFocus(); } static lockX() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; accudraw.clearTentative(); if (AccuDraw_1.CompassMode.Rectangular !== accudraw.compassMode) { const vp = accudraw.currentView; if (!vp) return; accudraw.fixPointRectangular(vp); accudraw.changeCompassMode(true); } if (accudraw.getFieldLock(AccuDraw_1.ItemField.X_Item)) { accudraw.setFieldLock(AccuDraw_1.ItemField.X_Item, false); accudraw.locked = accudraw.locked & ~AccuDraw_1.LockedStates.X_BM; accudraw.setKeyinStatus(AccuDraw_1.ItemField.X_Item, AccuDraw_1.KeyinStatus.Dynamic); } else { accudraw.saveCoordinate(AccuDraw_1.ItemField.X_Item, accudraw.delta.x); accudraw.setFieldLock(AccuDraw_1.ItemField.X_Item, true); accudraw.locked = accudraw.locked | AccuDraw_1.LockedStates.X_BM; } this.requestInputFocus(); } static lockY() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; accudraw.clearTentative(); if (AccuDraw_1.CompassMode.Rectangular !== accudraw.compassMode) { const vp = accudraw.currentView; if (!vp) return; accudraw.fixPointRectangular(vp); accudraw.changeCompassMode(true); } if (accudraw.getFieldLock(AccuDraw_1.ItemField.Y_Item)) { accudraw.setFieldLock(AccuDraw_1.ItemField.Y_Item, false); accudraw.locked = accudraw.locked & ~AccuDraw_1.LockedStates.Y_BM; accudraw.setKeyinStatus(AccuDraw_1.ItemField.Y_Item, AccuDraw_1.KeyinStatus.Dynamic); } else { accudraw.saveCoordinate(AccuDraw_1.ItemField.Y_Item, accudraw.delta.y); accudraw.setFieldLock(AccuDraw_1.ItemField.Y_Item, true); accudraw.locked = accudraw.locked | AccuDraw_1.LockedStates.Y_BM; } this.requestInputFocus(); } static lockZ() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; const vp = accudraw.currentView; if (!vp || !vp.view.is3d()) return; const isSnapped = accudraw.clearTentative(); if (accudraw.getFieldLock(AccuDraw_1.ItemField.Z_Item)) { accudraw.setFieldLock(AccuDraw_1.ItemField.Z_Item, false); accudraw.setKeyinStatus(AccuDraw_1.ItemField.Z_Item, AccuDraw_1.KeyinStatus.Dynamic); } else { // Move focus to Z field... if (!isSnapped && accudraw.autoFocusFields) { accudraw.setFocusItem(AccuDraw_1.ItemField.Z_Item); accudraw.dontMoveFocus = true; } accudraw.setFieldLock(AccuDraw_1.ItemField.Z_Item, true); } this.requestInputFocus(); } static lockDistance() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; const isSnapped = accudraw.clearTentative(); if (AccuDraw_1.CompassMode.Polar !== accudraw.compassMode) { const vp = accudraw.currentView; if (!vp) return; accudraw.locked = 0; accudraw.fixPointPolar(vp); accudraw.changeCompassMode(true); } if (accudraw.getFieldLock(AccuDraw_1.ItemField.DIST_Item)) { accudraw.setFieldLock(AccuDraw_1.ItemField.DIST_Item, false); accudraw.locked &= ~AccuDraw_1.LockedStates.DIST_BM; accudraw.setKeyinStatus(AccuDraw_1.ItemField.DIST_Item, AccuDraw_1.KeyinStatus.Dynamic); } else { // Move focus to distance field... if (!isSnapped && accudraw.autoFocusFields) accudraw.setFocusItem(AccuDraw_1.ItemField.DIST_Item); accudraw.distanceLock(true, true); } this.requestInputFocus(); } static lockAngle() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; accudraw.doLockAngle(accudraw.clearTentative()); this.requestInputFocus(); } static setStandardRotation(rotation) { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; if (AccuDraw_1.RotationMode.Context === rotation) { const axes = accudraw.baseAxes.clone(); accudraw.accountForAuxRotationPlane(axes, accudraw.flags.auxRotationPlane); accudraw.setContextRotation(axes.toMatrix3d(), false, true); this.requestInputFocus(); return; } else { accudraw.flags.baseRotation = rotation; accudraw.setRotationMode(rotation); } accudraw.updateRotation(true); this.requestInputFocus(); } static alignView() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; const vp = accudraw.currentView; if (!vp) return; const newMatrix = accudraw.getRotation(); if (newMatrix.isExactEqual(vp.rotation)) return; const targetMatrix = newMatrix.multiplyMatrixMatrix(vp.rotation); const rotateTransform = core_geometry_1.Transform.createFixedPointAndMatrix(vp.view.getTargetPoint(), targetMatrix); const newFrustum = vp.getFrustum(); newFrustum.multiply(rotateTransform); vp.view.setupFromFrustum(newFrustum); vp.synchWithView(); vp.animateFrustumChange(); this.requestInputFocus(); } static rotateToBase() { this.setStandardRotation(IModelApp_1.IModelApp.accuDraw.flags.baseRotation); } static rotateToACS() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; // NOTE: Match current ACS orientation..reset auxRotationPlane to top! accudraw.flags.auxRotationPlane = AccuDraw_1.RotationMode.Top; this.setStandardRotation(AccuDraw_1.RotationMode.ACS); } static rotateCycle() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; const vp = accudraw.currentView; if (!vp || !vp.view.is3d()) return; let rotation; switch (accudraw.rotationMode) { case AccuDraw_1.RotationMode.View: case AccuDraw_1.RotationMode.Side: rotation = AccuDraw_1.RotationMode.Top; break; case AccuDraw_1.RotationMode.Top: rotation = AccuDraw_1.RotationMode.Front; break; case AccuDraw_1.RotationMode.Front: rotation = AccuDraw_1.RotationMode.Side; break; case AccuDraw_1.RotationMode.Context: rotation = AccuDraw_1.RotationMode.Context; if (rotation !== accudraw.flags.baseRotation) { accudraw.baseAxes.setFrom(accudraw.axes); accudraw.flags.auxRotationPlane = AccuDraw_1.RotationMode.Top; accudraw.flags.baseRotation = rotation; } else { const axes = accudraw.baseAxes.clone(); accudraw.accountForAuxRotationPlane(axes, accudraw.flags.auxRotationPlane); if (!accudraw.axes.equals(axes)) accudraw.changeBaseRotationMode(rotation); } switch (accudraw.flags.auxRotationPlane) { case AccuDraw_1.RotationMode.Front: accudraw.flags.auxRotationPlane = AccuDraw_1.RotationMode.Side; break; case AccuDraw_1.RotationMode.Side: accudraw.flags.auxRotationPlane = AccuDraw_1.RotationMode.Top; break; case AccuDraw_1.RotationMode.Top: accudraw.flags.auxRotationPlane = AccuDraw_1.RotationMode.Front; break; } break; case AccuDraw_1.RotationMode.ACS: rotation = AccuDraw_1.RotationMode.ACS; switch (accudraw.flags.auxRotationPlane) { case AccuDraw_1.RotationMode.Front: accudraw.flags.auxRotationPlane = AccuDraw_1.RotationMode.Side; break; case AccuDraw_1.RotationMode.Side: accudraw.flags.auxRotationPlane = AccuDraw_1.RotationMode.Top; break; case AccuDraw_1.RotationMode.Top: accudraw.flags.auxRotationPlane = AccuDraw_1.RotationMode.Front; break; } break; default: return; } this.setStandardRotation(rotation); } static rotate90(axis) { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return; const newRotation = new AccuDraw_1.ThreeAxes(); accudraw.locked = accudraw.indexed = 0; accudraw.unlockAllFields(); switch (axis) { case 0: newRotation.x.setFrom(accudraw.axes.x); newRotation.z.setFrom(accudraw.axes.y); newRotation.z.crossProduct(newRotation.x, newRotation.y); break; case 1: newRotation.x.setFrom(accudraw.axes.z); newRotation.y.setFrom(accudraw.axes.y); newRotation.x.crossProduct(newRotation.y, newRotation.z); break; case 2: newRotation.x.setFrom(accudraw.axes.y); newRotation.z.setFrom(accudraw.axes.z); newRotation.z.crossProduct(newRotation.x, newRotation.y); break; } accudraw.setContextRotation(newRotation.toMatrix3d(), true, true); this.requestInputFocus(); } static async rotateAxes(aboutCurrentZ) { return IModelApp_1.IModelApp.tools.run("AccuDraw.RotateAxes", aboutCurrentZ); } static async rotateToElement() { return IModelApp_1.IModelApp.tools.run("AccuDraw.RotateElement"); } static async defineACSByElement() { return IModelApp_1.IModelApp.tools.run("AccuDraw.DefineACSByElement"); } static async defineACSByPoints() { return IModelApp_1.IModelApp.tools.run("AccuDraw.DefineACSByPoints"); } static getACS(acsName, useOrigin, useRotation) { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return core_bentley_1.BentleyStatus.ERROR; const vp = accudraw.currentView; if (!vp) return core_bentley_1.BentleyStatus.ERROR; let currRotation = 0, currBaseRotation = 0; const axes = new AccuDraw_1.ThreeAxes(); if (!useRotation) { // Save current rotation, event listener on ACS change will orient AccuDraw to ACS... currRotation = accudraw.rotationMode; currBaseRotation = accudraw.flags.baseRotation; axes.setFrom(accudraw.axes); } if (acsName && "" !== acsName) { // // See if this ACS already exists... // DgnCode acsCode = AuxCoordSystem:: CreateCode(vp -> GetViewControllerR().GetViewDefinition(), acsName); // DgnElementId acsId = vp -> GetViewController().GetDgnDb().Elements().QueryElementIdByCode(acsCode); // if (!acsId.IsValid()) // return ERROR; // AuxCoordSystemCPtr auxElm = vp -> GetViewController().GetDgnDb().Elements().Get<AuxCoordSystem>(acsId); // if (!auxElm.IsValid()) // return ERROR; // AuxCoordSystemPtr acsPtr = auxElm -> MakeCopy<AuxCoordSystem>(); // if (!acsPtr.IsValid()) // return ERROR; // AuxCoordSystemCR oldACS = vp -> GetViewController().GetAuxCoordinateSystem(); // if (!useOrigin) // acsPtr -> SetOrigin(oldACS.GetOrigin()); // if (!useRotation) // acsPtr -> SetRotation(oldACS.GetRotation()); // AccuDraw:: UpdateAuxCoordinateSystem(* acsPtr, * vp); } const currentACS = vp.view.auxiliaryCoordinateSystem; if (useOrigin) { accudraw.origin.setFrom(currentACS.getOrigin()); accudraw.point.setFrom(accudraw.origin); accudraw.planePt.setFrom(accudraw.origin); } if (useRotation) { accudraw.flags.auxRotationPlane = AccuDraw_1.RotationMode.Top; this.setStandardRotation(AccuDraw_1.RotationMode.ACS); } else { this.itemFieldUnlockAll(); accudraw.setRotationMode(currRotation); accudraw.flags.baseRotation = currBaseRotation; accudraw.axes.setFrom(axes); if (AccuDraw_1.RotationMode.ACS === accudraw.flags.baseRotation) { const acs = currentACS.clone(); const rMatrix = accudraw.getRotation(); acs.setRotation(rMatrix); AccuDraw_1.AccuDraw.updateAuxCoordinateSystem(acs, vp); } accudraw.published.flags &= ~AccuDraw_1.AccuDrawFlags.OrientACS; } return core_bentley_1.BentleyStatus.SUCCESS; } static writeACS(_acsName) { const accudraw = IModelApp_1.IModelApp.accuDraw; if (!accudraw.isEnabled) return core_bentley_1.BentleyStatus.ERROR; const vp = accudraw.currentView; if (!vp) return core_bentley_1.BentleyStatus.ERROR; // const origin = accudraw.origin; // const rMatrix = accudraw.getRotation(); // AuxCoordSystemPtr acsPtr = AuxCoordSystem:: CreateFrom(vp -> GetViewController().GetAuxCoordinateSystem()); // acsPtr -> SetOrigin(origin); // acsPtr -> SetRotation(rMatrix); // acsPtr -> SetType(CompassMode.Polar == accudraw.getCompassMode() ? ACSType :: Cylindrical : ACSType:: Rectangular); // acsPtr -> SetCode(AuxCoordSystem:: CreateCode(vp -> GetViewControllerR().GetViewDefinition(), nullptr != acsName ? acsName : "")); // acsPtr -> SetDescription(""); // if (acsName && '\0' != acsName[0]) { // DgnDbStatus status; // acsPtr -> Insert(& status); // if (DgnDbStatus:: Success != status) // return BentleyStatus.ERROR; // } // AccuDraw:: UpdateAuxCoordinateSystem(* acsPtr, * vp); // accudraw.flags.baseRotation = RotationMode.ACS; // accudraw.SetRotationMode(RotationMode.ACS); return core_bentley_1.BentleyStatus.SUCCESS; } static itemFieldUnlockAll() { const accudraw = IModelApp_1.IModelApp.accuDraw; if (accudraw.isEnabled) accudraw.unlockAllFields(); } } exports.AccuDrawShortcuts = AccuDrawShortcuts; /** @beta */ class AccuDrawSessionToggleTool extends Tool_1.Tool { static toolId = "AccuDraw.SessionToggle"; async run() { AccuDrawShortcuts.sessionToggle(); return true; } } exports.AccuDrawSessionToggleTool = AccuDrawSessionToggleTool; /** @beta */ class AccuDrawSuspendToggleTool extends Tool_1.Tool { static toolId = "AccuDraw.SuspendToggle"; async run() { AccuDrawShortcuts.suspendToggle(); return true; } } exports.AccuDrawSuspendToggleTool = AccuDrawSuspendToggleTool; /** @beta */ class AccuDrawSetOriginTool extends Tool_1.Tool { static toolId = "AccuDraw.SetOrigin"; async run() { AccuDrawShortcuts.setOrigin(); return true; } } exports.AccuDrawSetOriginTool = AccuDrawSetOriginTool; /** @beta */ class AccuDrawSetLockSmartTool extends Tool_1.Tool { static toolId = "AccuDraw.LockSmart"; async run() { AccuDrawShortcuts.lockSmart(); return true; } } exports.AccuDrawSetLockSmartTool = AccuDrawSetLockSmartTool; /** @beta */ class AccuDrawSetLockIndexTool extends Tool_1.Tool { static toolId = "AccuDraw.LockIndex"; async run() { AccuDrawShortcuts.lockIndex(); return true; } } exports.AccuDrawSetLockIndexTool = AccuDrawSetLockIndexTool; /** @beta */ class AccuDrawSetLockXTool extends Tool_1.Tool { static toolId = "AccuDraw.LockX"; async run() { AccuDrawShortcuts.lockX(); return true; } } exports.AccuDrawSetLockXTool = AccuDrawSetLockXTool; /** @beta */ class AccuDrawSetLockYTool extends Tool_1.Tool { static toolId = "AccuDraw.LockY"; async run() { AccuDrawShortcuts.lockY(); return true; } } exports.AccuDrawSetLockYTool = AccuDrawSetLockYTool; /** @beta */ class AccuDrawSetLockZTool extends Tool_1.Tool { static toolId = "AccuDraw.LockZ"; async run() { AccuDrawShortcuts.lockZ(); return true; } } exports.AccuDrawSetLockZTool = AccuDrawSetLockZTool; /** @beta */ class AccuDrawSetLockDistanceTool extends Tool_1.Tool { static toolId = "AccuDraw.LockDistance"; async run() { AccuDrawShortcuts.lockDistance(); return true; } } exports.AccuDrawSetLockDistanceTool = AccuDrawSetLockDistanceTool; /** @beta */ class AccuDrawSetLockAngleTool extends Tool_1.Tool { static toolId = "AccuDraw.LockAngle"; async run() { AccuDrawShortcuts.lockAngle(); return true; } } exports.AccuDrawSetLockAngleTool = AccuDrawSetLockAngleTool; /** @beta */ class AccuDrawChangeModeTool extends Tool_1.Tool { static toolId = "AccuDraw.ChangeMode"; async run() { AccuDrawShortcuts.changeCompassMode(); return true; } } exports.AccuDrawChangeModeTool = AccuDrawChangeModeTool; /** @beta */ class AccuDrawRotateCycleTool extends Tool_1.Tool { static toolId = "AccuDraw.RotateCycle"; async run() { AccuDrawShortcuts.rotateCycle(); return true; } } exports.AccuDrawRotateCycleTool = AccuDrawRotateCycleTool; /** @beta */ class AccuDrawRotateTopTool extends Tool_1.Tool { static toolId = "AccuDraw.RotateTop"; async run() { AccuDrawShortcuts.setStandardRotation(AccuDraw_1.RotationMode.Top); return true; } } exports.AccuDrawRotateTopTool = AccuDrawRotateTopTool; /** @beta */ class AccuDrawRotateFrontTool extends Tool_1.Tool { static toolId = "AccuDraw.RotateFront"; async run() { AccuDrawShortcuts.setStandardRotation(AccuDraw_1.RotationMode.Front); return true; } } exports.AccuDrawRotateFrontTool = AccuDrawRotateFrontTool; /** @beta */ class AccuDrawRotateSideTool extends Tool_1.Tool { static toolId = "AccuDraw.RotateSide"; async run() { AccuDrawShortcuts.setStandardRotation(AccuDraw_1.RotationMode.Side); return true; } } exports.AccuDrawRotateSideTool = AccuDrawRotateSideTool; /** @beta */ class AccuDrawRotateViewTool extends Tool_1.Tool { static toolId = "AccuDraw.RotateView"; async run() { AccuDrawShortcuts.setStandardRotation(AccuDraw_1.RotationMode.View); return true; } } exports.AccuDrawRotateViewTool = AccuDrawRotateViewTool; /** @beta */ class AccuDrawRotate90AboutXTool extends Tool_1.Tool { static toolId = "AccuDraw.Rotate90AboutX"; async run() { AccuDrawShortcuts.rotate90(0); return true; } } exports.AccuDrawRotate90AboutXTool = AccuDrawRotate90AboutXTool; /** @beta */ class AccuDrawRotate90AboutYTool extends Tool_1.Tool { static toolId = "AccuDraw.Rotate90AboutY"; async run() { AccuDrawShortcuts.rotate90(1); return true; } } exports.AccuDrawRotate90AboutYTool = AccuDrawRotate90AboutYTool; /** @beta */ class AccuDrawRotate90AboutZTool extends Tool_1.Tool { static toolId = "AccuDraw.Rotate90AboutZ"; async run() { AccuDrawShortcuts.rotate90(2); return true; } } exports.AccuDrawRotate90AboutZTool = AccuDrawRotate90AboutZTool; /** @internal */ class AccuDrawShortcutsTool extends Tool_1.InputCollector { _complete = false; get allowShortcut() { return this.wantActivateOnStart ? IModelApp_1.IModelApp.accuDraw.isEnabled : true; } get wantActivateOnStart() { return false; } // Whether to automatically enable AccuDraw before the 1st data button... get wantClearSnapOnStart() { return false; } // Whether to preserve active Tentative/AccuSnap on install... get wantManipulationImmediate() { return false; } // Whether additional input is required to process on install... get wantExitOnDataButtonUp() { return false; } // Whether to exit on button up instead of down... async onInstall() { if (!this.allowShortcut) return false; return super.onInstall(); } async onPostInstall() { await super.onPostInstall(); if (this.wantActivateOnStart) IModelApp_1.IModelApp.accuDraw.activate(); this.onManipulationStart(); if (this.wantManipulationImmediate && this.doManipulation(undefined, false)) { this._complete = true; return this.exitTool(); } // NOTE: InputCollector inherits suspended primitive's state, set everything... if (this.wantClearSnapOnStart) { this.initLocateElements(false, true, undefined, Tool_1.CoordinateLockOverrides.None); // This clears the active Tentative/AccuSnap, some shortcuts have special behavior when invoked with an active snap... } else { IModelApp_1.IModelApp.locateManager.initLocateOptions(); this.changeLocateState(false, true, undefined, Tool_1.CoordinateLockOverrides.None); } this.doManipulation(undefined, true); ; } async onCleanup() { if (this._complete) IModelApp_1.IModelApp.accuDraw.savedStateInputCollector.ignoreFlags = this.onManipulationComplete(); } async exitTool() { await super.exitTool(); AccuDrawShortcuts.requestInputFocus(); // re-grab focus when auto-focus tool setting set... } async onDataButtonDown(ev) { if (this.doManipulation(ev, false)) { this._complete = true; if (!this.wantExitOnDataButtonUp) await this.exitTool(); } return Tool_1.EventHandled.No; } async onDataButtonUp(_ev) { if (this._complete && this.wantExitOnDataButtonUp) await this.exitTool(); return Tool_1.EventHandled.No; } async onMouseMotion(ev) { this.doManipulation(ev, true); } onManipulationStart() { } onManipulationComplete() { return AccuDraw_1.AccuDrawFlags.SetRMatrix; } } /** @beta */ class AccuDrawRotateAxesTool extends AccuDrawShortcutsTool { aboutCurrentZ; static toolId = "AccuDraw.RotateAxes"; static get maxArgs() { return 1; } constructor(aboutCurrentZ = true) { super(); this.aboutCurrentZ = aboutCurrentZ; } /** @internal */ get allowShortcut() { return IModelApp_1.IModelApp.accuDraw.isActive; } // Require compass to already be active for this shortcut... /** @internal */ get wantActivateOnStart() { return true; } // State is demoted to inactive when a tool install, still need this... /** @internal */ get wantManipulationImmediate() { if (AccuSnap_1.TentativeOrAccuSnap.isHot) return true; const accudraw = IModelApp_1.IModelApp.accuDraw; if (AccuDraw_1.CompassMode.Polar === accudraw.compassMode) return accudraw.getFieldLock(AccuDraw_1.ItemField.ANGLE_Item); return accudraw.getFieldLock(AccuDraw_1.ItemField.X_Item) && accudraw.getFieldLock(AccuDraw_1.ItemField.Y_Item); } /** @internal */ onManipulationStart() { if (this.aboutCurrentZ) IModelApp_1.IModelApp.accuDraw.changeBaseRotationMode(AccuDraw_1.RotationMode.Context); // Establish current orientation as base for when defining compass rotation by x axis... Tool_1.CoreTools.outputPromptByKey("AccuDraw.RotateAxes.Prompts.FirstPoint"); } /** @internal */ doManipulation(ev, isMotion) { const vp = ev ? ev.viewport : IModelApp_1.IModelApp.accuDraw.currentView; if (!vp) return false; if (!AccuDrawShortcuts.rotateAxesByPoint(AccuSnap_1.TentativeOrAccuSnap.isHot, this.aboutCurrentZ)) return false; vp.invalidateDecorations(); if (!isMotion) { AccuDrawShortcuts.itemFieldUnlockAll(); IModelApp_1.IModelApp.tentativePoint.clear(true); } return true; } async parseAndRun(...args) { for (const arg of args) { if (arg.toLowerCase() === "unlockedz") this.aboutCurrentZ = false; } return this.run(args); } } exports.AccuDrawRotateAxesTool = AccuDrawRotateAxesTool; /** @beta */ class AccuDrawRotateElementTool extends AccuDrawShortcutsTool { static toolId = "AccuDraw.RotateElement"; _moveOrigin = !IModelApp_1.IModelApp.accuDraw.isActive || IModelApp_1.IModelApp.tentativePoint.isActive; // Preserve current origin if AccuDraw already active and not tentative snap... /** @internal */ get wantActivateOnStart() { return true; } /** @internal */ get wantManipulationImmediate() { return IModelApp_1.IModelApp.tentativePoint.isSnapped; } /** @internal */ onManipulationStart() { IModelApp_1.IModelApp.accuDraw.setContext(AccuDraw_1.AccuDrawFlags.FixedOrigin); // Don't move compass when updateOrientation returns false... Tool_1.CoreTools.outputPromptByKey("AccuDraw.RotateElement.Prompts.FirstPoint"); } /** @internal */ onManipulationComplete() { let ignoreFlags = AccuDraw_1.AccuDrawFlags.SetRMatrix | AccuDraw_1.AccuDrawFlags.Disable; // If AccuDraw wasn't active when the shortcut started, let it remain active for suspended tool when shortcut completes... if (this._moveOrigin) i