@itwin/core-common
Version:
iTwin.js components common to frontend and backend
141 lines • 6.91 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 Geometry
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Placement2d = exports.Placement3d = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const core_geometry_1 = require("@itwin/core-geometry");
const Frustum_1 = require("../Frustum");
const IModelError_1 = require("../IModelError");
/** The placement of a GeometricElement3d. This includes the origin, orientation, and size (bounding box) of the element.
* All geometry of a GeometricElement are relative to its placement.
* @public
*/
class Placement3d {
origin;
angles;
bbox;
constructor(origin, angles, bbox) {
this.origin = origin;
this.angles = angles;
this.bbox = bbox;
}
/** Get the rotation from local coordinates of this placement to world coordinates. */
get rotation() { return this.angles.toMatrix3d(); }
/** Get the transform from local coordinates of this placement to world coordinates. */
get transform() { return core_geometry_1.Transform.createOriginAndMatrix(this.origin, this.rotation); }
/** determine if this is 3d placement */
get is3d() { return true; }
/** Create a new Placement3d from a Placement3dProps. */
static fromJSON(json) {
const props = json ? json : {};
return new Placement3d(core_geometry_1.Point3d.fromJSON(props.origin), core_geometry_1.YawPitchRollAngles.fromJSON(props.angles), core_geometry_1.Range3d.fromJSON(props.bbox));
}
/** Get the 8 corners, in world coordinates, of this placement. */
getWorldCorners(out) {
const frust = Frustum_1.Frustum.fromRange(this.bbox, out);
frust.multiply(this.transform);
return frust;
}
/** Set the contents of this Placement3d from another Placement3d */
setFrom(other) {
this.origin.setFrom(other.origin);
this.angles.setFrom(other.angles);
this.bbox.setFrom(other.bbox);
}
/** Determine whether this Placement3d is valid. */
get isValid() { return !this.bbox.isNull && Math.max(this.origin.maxAbs(), this.bbox.maxAbs()) < core_geometry_1.Constant.circumferenceOfEarth; }
/** Calculate the axis-aligned bounding box for this placement. */
calculateRange() {
const range = new core_geometry_1.Range3d();
if (!this.isValid)
return range;
this.transform.multiplyRange(this.bbox, range);
// low and high are not allowed to be equal
range.ensureMinLengths();
return range;
}
/** Multiply the Transform of this Placement3d by the specified *other* Transform.
* * Specifically `this.angles` is set to the rotation specified by `other.matrix * this.transform.matrix`
* and `this.origin` is set to the origin of `other * this.transform`.
* * Since the placement transform is local-to-world, this means `other` is a world-to-world transform.
* @throws [[IModelError]] if the Transform is invalid for a GeometricElement3d.
*/
multiplyTransform(other) {
const transform = other.multiplyTransformTransform(this.transform);
const angles = core_geometry_1.YawPitchRollAngles.createFromMatrix3d(transform.matrix);
if (undefined === angles)
throw new IModelError_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Invalid Transform");
this.angles = angles;
this.origin.setFrom(transform.origin);
}
}
exports.Placement3d = Placement3d;
/** The placement of a GeometricElement2d. This includes the origin, rotation, and size (bounding box) of the element.
* @public
*/
class Placement2d {
origin;
angle;
bbox;
constructor(origin, angle, bbox) {
this.origin = origin;
this.angle = angle;
this.bbox = bbox;
}
/** Get the rotation from local coordinates of this placement to world coordinates. */
get rotation() { return core_geometry_1.Matrix3d.createRotationAroundVector(core_geometry_1.Vector3d.unitZ(), this.angle); }
/** Get the transform from local coordinates of this placement to world coordinates. */
get transform() { return core_geometry_1.Transform.createOriginAndMatrix(core_geometry_1.Point3d.createFrom(this.origin), this.rotation); }
/** Create a new Placement2d from a Placement2dProps. */
static fromJSON(json) {
const props = json ? json : {};
return new Placement2d(core_geometry_1.Point2d.fromJSON(props.origin), core_geometry_1.Angle.fromJSON(props.angle), core_geometry_1.Range2d.fromJSON(props.bbox));
}
/** determine if this is 3d placement */
get is3d() { return false; }
/** Get the 8 corners, in world coordinates, of this placement. */
getWorldCorners(out) {
const frust = Frustum_1.Frustum.fromRange(this.bbox, out);
frust.multiply(this.transform);
return frust;
}
/** Determine whether this Placement2d is valid. */
get isValid() { return !this.bbox.isNull && Math.max(this.origin.maxAbs(), this.bbox.maxAbs()) < core_geometry_1.Constant.circumferenceOfEarth; }
/** Set the contents of this Placement2d from another Placement2d */
setFrom(other) {
this.origin.setFrom(other.origin);
this.angle.setFrom(other.angle);
this.bbox.setFrom(other.bbox);
}
/** Calculate the axis-aligned bounding box for this placement. */
calculateRange() {
const range = new core_geometry_1.Range3d();
if (!this.isValid)
return range;
this.transform.multiplyRange(core_geometry_1.Range3d.createRange2d(this.bbox, 0), range);
// low and high are not allowed to be equal
range.ensureMinLengths();
range.low.z = -1.0; // is the 2dFrustumDepth, which === 1 meter
range.high.z = 1.0;
return range;
}
/** Multiply the Transform of this Placement2d by the specified *other* Transform.
* @throws [[IModelError]] if the Transform is invalid for a GeometricElement2d.
*/
multiplyTransform(other) {
const transform = other.multiplyTransformTransform(this.transform);
const angles = core_geometry_1.YawPitchRollAngles.createFromMatrix3d(transform.matrix);
if ((undefined === angles) || !angles.pitch.isAlmostZero || !angles.roll.isAlmostZero)
throw new IModelError_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Invalid Transform");
this.angle = angles.yaw;
this.origin.setFrom(transform.origin);
}
}
exports.Placement2d = Placement2d;
//# sourceMappingURL=Placement.js.map