@itwin/core-frontend
Version:
iTwin.js frontend components
317 lines • 17.6 kB
JavaScript
"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 Views
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuxCoordSystemSpatialState = exports.AuxCoordSystem3dState = exports.AuxCoordSystem2dState = exports.AuxCoordSystemState = exports.ACSDisplayOptions = exports.ACSType = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const core_geometry_1 = require("@itwin/core-geometry");
const core_common_1 = require("@itwin/core-common");
const EntityState_1 = require("./EntityState");
const CoordSystem_1 = require("./CoordSystem");
const GraphicType_1 = require("./common/render/GraphicType");
/**
* @public
* @extensions
*/
var ACSType;
(function (ACSType) {
ACSType[ACSType["None"] = 0] = "None";
ACSType[ACSType["Rectangular"] = 1] = "Rectangular";
ACSType[ACSType["Cylindrical"] = 2] = "Cylindrical";
ACSType[ACSType["Spherical"] = 3] = "Spherical";
})(ACSType || (exports.ACSType = ACSType = {}));
/**
* @public
* @extensions
*/
var ACSDisplayOptions;
(function (ACSDisplayOptions) {
ACSDisplayOptions[ACSDisplayOptions["None"] = 0] = "None";
ACSDisplayOptions[ACSDisplayOptions["Active"] = 1] = "Active";
ACSDisplayOptions[ACSDisplayOptions["Deemphasized"] = 2] = "Deemphasized";
ACSDisplayOptions[ACSDisplayOptions["Hilite"] = 4] = "Hilite";
ACSDisplayOptions[ACSDisplayOptions["CheckVisible"] = 8] = "CheckVisible";
ACSDisplayOptions[ACSDisplayOptions["Dynamics"] = 16] = "Dynamics";
})(ACSDisplayOptions || (exports.ACSDisplayOptions = ACSDisplayOptions = {}));
/** The state of an AuxCoordSystem element in the frontend
* @public
* @extensions
*/
class AuxCoordSystemState extends EntityState_1.ElementState {
static get className() { return "AuxCoordSystem"; }
type;
description;
static fromProps(props, iModel) {
const name = props.classFullName.toLowerCase();
if (name.endsWith("system2d"))
return new AuxCoordSystem2dState(props, iModel);
if (name.endsWith("system3d"))
return new AuxCoordSystem3dState(props, iModel);
return new AuxCoordSystemSpatialState(props, iModel);
}
/** Create a new AuxCoordSystemState.
* @param acsName the name for the new AuxCoordSystem
* @param iModel the iModel for which the ACS applies.
* @note call this method with the appropriate subclass (e.g. AuxCoordSystemSpatialState, AuxCoordSystem2dState, etc), not on AuxCoordSystemState directly
*/
static createNew(acsName, iModel) {
const myCode = new core_common_1.Code({ spec: core_common_1.BisCodeSpec.auxCoordSystemSpatial, scope: core_common_1.IModel.dictionaryId.toString(), value: acsName });
return new AuxCoordSystemSpatialState({ model: core_common_1.IModel.dictionaryId, code: myCode, classFullName: this.classFullName }, iModel);
}
constructor(props, iModel) {
super(props, iModel);
this.type = core_bentley_1.JsonUtils.asInt(props.type, ACSType.None);
this.description = props.description;
}
toJSON() {
const val = super.toJSON();
val.type = this.type;
val.description = this.description;
return val;
}
isValidForView(view) {
if (view.isSpatialView())
return this instanceof AuxCoordSystemSpatialState;
return (view.is3d() === this.is3d);
}
get is3d() { return this instanceof AuxCoordSystem3dState; }
drawGrid(context) {
// Called for active ACS when grid orientation is GridOrientationType::ACS.
const view = context.viewport.view;
const fixedRepsAuto = core_geometry_1.Point2d.create(); // limit grid to project extents
context.drawStandardGrid(this.getOrigin(), this.getRotation(), view.getGridSpacing(), view.getGridsPerRef(), false, fixedRepsAuto);
}
/** Returns the value, clamped to the supplied range. */
static limitRange(min, max, val) { return Math.max(min, Math.min(max, val)); }
/**
* Given an origin point, returns whether the point falls within the view or not. If adjustOrigin is set to true, a point outside
* the view will be modified to fall within the appropriate range.
*/
static isOriginInView(drawOrigin, viewport, adjustOrigin) {
const testPtView = viewport.worldToView(drawOrigin);
const frustum = viewport.getFrustum(CoordSystem_1.CoordSystem.View);
const screenRange = core_geometry_1.Point3d.create();
screenRange.x = frustum.points[core_common_1.Npc._000].distance(frustum.points[core_common_1.Npc._100]);
screenRange.y = frustum.points[core_common_1.Npc._000].distance(frustum.points[core_common_1.Npc._010]);
screenRange.z = frustum.points[core_common_1.Npc._000].distance(frustum.points[core_common_1.Npc._001]);
// Check if current acs origin is outside view...
const inView = (!((testPtView.x < 0 || testPtView.x > screenRange.x) || (testPtView.y < 0 || testPtView.y > screenRange.y)));
if (!adjustOrigin)
return inView;
if (!inView) {
const offset = viewport.pixelsFromInches(0.6 /* ACSDisplaySizes.TriadSizeInches */);
testPtView.x = AuxCoordSystemState.limitRange(offset, screenRange.x - offset, testPtView.x);
testPtView.y = AuxCoordSystemState.limitRange(offset, screenRange.y - offset, testPtView.y);
}
// Limit point to NPC box to prevent triad from being clipped from display...
const originPtNpc = viewport.viewToNpc(testPtView);
originPtNpc.x = AuxCoordSystemState.limitRange(0, 1, originPtNpc.x);
originPtNpc.y = AuxCoordSystemState.limitRange(0, 1, originPtNpc.y);
originPtNpc.z = AuxCoordSystemState.limitRange(0, 1, originPtNpc.z);
viewport.npcToView(originPtNpc, testPtView);
viewport.viewToWorld(testPtView, drawOrigin);
return inView;
}
getAdjustedColor(inColor, isFill, viewport, options) {
let color;
if ((options & ACSDisplayOptions.Hilite) !== ACSDisplayOptions.None) {
color = viewport.hilite.color;
}
else if ((options & ACSDisplayOptions.Active) !== ACSDisplayOptions.None) {
color = inColor.equals(core_common_1.ColorDef.white) ? viewport.getContrastToBackgroundColor() : inColor;
}
else {
color = core_common_1.ColorDef.from(150, 150, 150, 0);
}
color = color.adjustedForContrast(viewport.view.backgroundColor);
if (isFill)
color = color.withTransparency((options & (ACSDisplayOptions.Deemphasized | ACSDisplayOptions.Dynamics)) !== ACSDisplayOptions.None ? 225 : 200);
else
color = color.withTransparency((options & ACSDisplayOptions.Deemphasized) !== ACSDisplayOptions.None ? 150 : 75);
return color;
}
addAxisLabel(builder, axis, options, vp) {
const color = core_common_1.ColorDef.white;
const lineColor = this.getAdjustedColor(color, false, vp, options);
builder.setSymbology(lineColor, lineColor, 2);
const linePts1 = [];
if (0 === axis) {
linePts1[0] = core_geometry_1.Point3d.create(0.4 /* ACSDisplaySizes.LabelStart */, -0.15 /* ACSDisplaySizes.LabelWidth */);
linePts1[1] = core_geometry_1.Point3d.create(0.8 /* ACSDisplaySizes.LabelEnd */, 0.15 /* ACSDisplaySizes.LabelWidth */);
}
else {
linePts1[0] = core_geometry_1.Point3d.create(0.0, 0.4 /* ACSDisplaySizes.LabelStart */);
linePts1[1] = core_geometry_1.Point3d.create(0.0, (0.4 /* ACSDisplaySizes.LabelStart */ + 0.8 /* ACSDisplaySizes.LabelEnd */) * 0.5);
}
builder.addLineString(linePts1);
const linePts2 = []; // NOTE: Don't use same point array, addPointString/addLineString don't deep copy...
if (0 === axis) {
linePts2[0] = core_geometry_1.Point3d.create(0.4 /* ACSDisplaySizes.LabelStart */, 0.15 /* ACSDisplaySizes.LabelWidth */);
linePts2[1] = core_geometry_1.Point3d.create(0.8 /* ACSDisplaySizes.LabelEnd */, -0.15 /* ACSDisplaySizes.LabelWidth */);
}
else {
linePts2[0] = core_geometry_1.Point3d.create(0.15 /* ACSDisplaySizes.LabelWidth */, 0.8 /* ACSDisplaySizes.LabelEnd */);
linePts2[1] = core_geometry_1.Point3d.create(0.0, (0.4 /* ACSDisplaySizes.LabelStart */ + 0.8 /* ACSDisplaySizes.LabelEnd */) * 0.5);
linePts2[2] = core_geometry_1.Point3d.create(-0.15 /* ACSDisplaySizes.LabelWidth */, 0.8 /* ACSDisplaySizes.LabelEnd */);
}
builder.addLineString(linePts2);
}
addAxis(builder, axis, options, vp) {
const color = (0 === axis ? core_common_1.ColorDef.red : (1 === axis ? core_common_1.ColorDef.green : core_common_1.ColorDef.blue));
const lineColor = this.getAdjustedColor(color, false, vp, options);
const fillColor = this.getAdjustedColor(color, true, vp, options);
if (axis === 2) {
builder.setSymbology(lineColor, lineColor, 6);
builder.addPointString([core_geometry_1.Point3d.create(0.0, 0.0, 0.65 /* ACSDisplaySizes.ZAxisLength */)]); // NOTE: ACS origin point will be drawn separately as a pickable world decoration...
const linePts2 = [core_geometry_1.Point3d.create(), core_geometry_1.Point3d.create()]; // NOTE: Don't use same point array, addPointString/addLineString don't deep copy...
linePts2[1].z = 0.65 /* ACSDisplaySizes.ZAxisLength */;
builder.setSymbology(lineColor, lineColor, 1, (options & ACSDisplayOptions.Dynamics) === ACSDisplayOptions.None ? core_common_1.LinePixels.Solid : core_common_1.LinePixels.Code2);
builder.addLineString(linePts2);
const scale = 0.4 /* ACSDisplaySizes.ArrowTipWidth */ / 2;
const center = core_geometry_1.Point3d.create();
const viewRMatrix = vp.rotation;
const xVec = viewRMatrix.getRow(0);
const yVec = viewRMatrix.getRow(1);
builder.placement.matrix.multiplyTransposeVectorInPlace(xVec);
builder.placement.matrix.multiplyTransposeVectorInPlace(yVec);
xVec.normalize(xVec);
yVec.normalize(yVec);
const ellipse = core_geometry_1.Arc3d.createScaledXYColumns(center, core_geometry_1.Matrix3d.createColumns(xVec, yVec, core_geometry_1.Vector3d.create()), scale, scale, core_geometry_1.AngleSweep.createStartEnd(core_geometry_1.Angle.createRadians(0), core_geometry_1.Angle.createRadians(Math.PI * 2)));
builder.addArc(ellipse, false, false);
builder.setBlankingFill(fillColor);
builder.addArc(ellipse, true, true);
return;
}
const shapePts = [];
shapePts[0] = core_geometry_1.Point3d.create(1.25 /* ACSDisplaySizes.ArrowTipEnd */, 0.0);
shapePts[1] = core_geometry_1.Point3d.create(0.75 /* ACSDisplaySizes.ArrowTipFlange */, 0.4 /* ACSDisplaySizes.ArrowTipWidth */);
shapePts[2] = core_geometry_1.Point3d.create(0.85 /* ACSDisplaySizes.ArrowTipStart */, 0.2 /* ACSDisplaySizes.ArrowBaseWidth */);
shapePts[3] = core_geometry_1.Point3d.create(0.3 /* ACSDisplaySizes.ArrowBaseStart */, 0.2 /* ACSDisplaySizes.ArrowBaseWidth */);
shapePts[4] = core_geometry_1.Point3d.create(0.3 /* ACSDisplaySizes.ArrowBaseStart */, -0.2 /* ACSDisplaySizes.ArrowBaseWidth */);
shapePts[5] = core_geometry_1.Point3d.create(0.85 /* ACSDisplaySizes.ArrowTipStart */, -0.2 /* ACSDisplaySizes.ArrowBaseWidth */);
shapePts[6] = core_geometry_1.Point3d.create(0.75 /* ACSDisplaySizes.ArrowTipFlange */, -0.4 /* ACSDisplaySizes.ArrowTipWidth */);
shapePts[7] = shapePts[0].clone();
if (1 === axis)
shapePts.forEach((tmpPt) => tmpPt.set(tmpPt.y, tmpPt.x));
builder.setSymbology(lineColor, lineColor, 1, (options & ACSDisplayOptions.Dynamics) === ACSDisplayOptions.None ? core_common_1.LinePixels.Solid : core_common_1.LinePixels.Code2);
builder.addLineString(shapePts);
this.addAxisLabel(builder, axis, options, vp);
builder.setBlankingFill(fillColor);
builder.addShape(shapePts);
}
/** Returns a GraphicBuilder for this AuxCoordSystemState. */
createGraphicBuilder(context, options) {
const checkOutOfView = (options & ACSDisplayOptions.CheckVisible) !== ACSDisplayOptions.None;
const drawOrigin = this.getOrigin();
if (checkOutOfView && !AuxCoordSystemState.isOriginInView(drawOrigin, context.viewport, true))
options = options | ACSDisplayOptions.Deemphasized;
let pixelSize = context.viewport.pixelsFromInches(0.6 /* ACSDisplaySizes.TriadSizeInches */);
if ((options & ACSDisplayOptions.Deemphasized) !== ACSDisplayOptions.None)
pixelSize *= 0.8;
else if ((options & ACSDisplayOptions.Active) !== ACSDisplayOptions.None)
pixelSize *= 0.9;
const exaggerate = context.viewport.view.getAspectRatioSkew();
const scale = context.getPixelSizeAtPoint(drawOrigin) * pixelSize;
const rMatrix = this.getRotation();
rMatrix.transposeInPlace();
rMatrix.scaleColumns(scale, scale / exaggerate, scale, rMatrix);
const transform = core_geometry_1.Transform.createRefs(drawOrigin, rMatrix);
const builder = context.createGraphicBuilder(GraphicType_1.GraphicType.WorldOverlay, transform);
const vp = context.viewport;
this.addAxis(builder, 0, options, vp);
this.addAxis(builder, 1, options, vp);
this.addAxis(builder, 2, options, vp);
return builder;
}
display(context, options) {
const builder = this.createGraphicBuilder(context, options);
if (undefined !== builder)
context.addDecorationFromBuilder(builder);
}
}
exports.AuxCoordSystemState = AuxCoordSystemState;
/** The state of an AuxCoordSystem2d element in the frontend
* @public
* @extensions
*/
class AuxCoordSystem2dState extends AuxCoordSystemState {
static get className() { return "AuxCoordSystem2d"; }
origin;
angle; // in degrees
_rMatrix;
constructor(props, iModel) {
super(props, iModel);
this.origin = core_geometry_1.Point2d.fromJSON(props.origin);
this.angle = core_bentley_1.JsonUtils.asDouble(props.angle);
this._rMatrix = core_geometry_1.Matrix3d.createRotationAroundVector(core_geometry_1.Vector3d.unitZ(), core_geometry_1.Angle.createDegrees(this.angle)) ?? core_geometry_1.Matrix3d.createIdentity();
}
toJSON() {
const val = super.toJSON();
val.origin = this.origin;
val.angle = this.angle;
return val;
}
getOrigin(result) { return core_geometry_1.Point3d.createFrom(this.origin, result); }
setOrigin(val) { this.origin.setFrom(val); }
getRotation(result) { return this._rMatrix.clone(result); }
setRotation(val) {
this._rMatrix.setFrom(val);
const angle = core_geometry_1.YawPitchRollAngles.createFromMatrix3d(val);
this.angle = (undefined !== angle ? angle.yaw.degrees : 0.0);
}
}
exports.AuxCoordSystem2dState = AuxCoordSystem2dState;
/** The state of an AuxCoordSystem3d element in the frontend
* @public
* @extensions
*/
class AuxCoordSystem3dState extends AuxCoordSystemState {
static get className() { return "AuxCoordSystem3d"; }
origin;
yaw; // in degrees
pitch; // in degrees
roll; // in degrees
_rMatrix;
constructor(props, iModel) {
super(props, iModel);
this.origin = core_geometry_1.Point3d.fromJSON(props.origin);
this.yaw = core_bentley_1.JsonUtils.asDouble(props.yaw);
this.pitch = core_bentley_1.JsonUtils.asDouble(props.pitch);
this.roll = core_bentley_1.JsonUtils.asDouble(props.roll);
const angles = new core_geometry_1.YawPitchRollAngles(core_geometry_1.Angle.createDegrees(this.yaw), core_geometry_1.Angle.createDegrees(this.pitch), core_geometry_1.Angle.createDegrees(this.roll));
this._rMatrix = angles.toMatrix3d();
}
toJSON() {
const val = super.toJSON();
val.origin = this.origin;
val.yaw = this.yaw;
val.pitch = this.pitch;
val.roll = this.roll;
return val;
}
getOrigin(result) { return core_geometry_1.Point3d.createFrom(this.origin, result); }
setOrigin(val) { this.origin.setFrom(val); }
getRotation(result) { return this._rMatrix.clone(result); }
setRotation(rMatrix) {
this._rMatrix.setFrom(rMatrix);
const angles = core_geometry_1.YawPitchRollAngles.createFromMatrix3d(rMatrix);
this.yaw = (undefined !== angles ? angles.yaw.degrees : 0.0);
this.pitch = (undefined !== angles ? angles.pitch.degrees : 0.0);
this.roll = (undefined !== angles ? angles.roll.degrees : 0.0);
}
}
exports.AuxCoordSystem3dState = AuxCoordSystem3dState;
/** The state of an AuxCoordSystemSpatial element in the frontend
* @public
* @extensions
*/
class AuxCoordSystemSpatialState extends AuxCoordSystem3dState {
static get className() { return "AuxCoordSystemSpatial"; }
}
exports.AuxCoordSystemSpatialState = AuxCoordSystemSpatialState;
//# sourceMappingURL=AuxCoordSys.js.map