import oc from "../opencascade/initializer";
import {Face} from "../modeling";
import {Vector, Axis} from "./index";
import cachedGetters from "../utils/cache";
/**
* Represents a mathematical plane in 3D space.
* @memberof math
* @alias Plane
*/
export class Plane {
#wrapped;
#forwardTransformation;
#inverseTransformation;
constructor({origin, normal, xDirection}) {
const originPoint = new oc.gp_Pnt_3(origin.x, origin.y, origin.z);
const normalDir = new oc.gp_Dir_4(normal.x, normal.y, normal.z);
const xDir = new oc.gp_Dir_4(xDirection.x, xDirection.y, xDirection.z);
const ax3 = new oc.gp_Ax3_3(originPoint, normalDir, xDir);
this.#wrapped = new oc.gp_Pln_2(ax3);
const globalCoordinateSystem = new oc.gp_Ax3_1();
this.#forwardTransformation = new oc.gp_Trsf_1();
this.#forwardTransformation.SetTransformation_1(globalCoordinateSystem, this.#wrapped.Position());
this.#inverseTransformation = new oc.gp_Trsf_1();
this.#inverseTransformation.SetTransformation_1(this.#wrapped.Position(), globalCoordinateSystem);
}
/**
* Returns the wrapped OpenCascade object.
* @private
*/
get wrapped() {
return this.#wrapped;
}
/**
* Returns the origin of the plane.
* @returns {Vector} The origin of the plane.
*/
get origin() {
const axis = this.#wrapped.Axis();
const origin = axis.Location();
return new Vector({x: origin.X(), y: origin.Y(), z: origin.Z()});
}
/**
* Returns the normal vector of the plane.
* @returns {Vector} The normal vector of the plane.
*/
get normal() {
const axis = this.#wrapped.Axis();
const direction = axis.Direction();
return new Vector({x: direction.X(), y: direction.Y(), z: direction.Z()});
}
/**
* Returns the x-direction vector of the plane.
* @returns {Vector} The x-direction vector of the plane.
*/
get xDirection() {
const direction = this.#wrapped.XAxis().Direction();
return new Vector({x: direction.X(), y: direction.Y(), z: direction.Z()});
}
/**
* Returns the axis of the plane.
* @returns {Axis} An `Axis` object representing the plane's axis.
*/
get axis() {
return new Axis({
origin: this.origin,
direction: this.normal,
});
}
/**
* Transforms the given OpenCascade object to local coordinates of this plane.
* @private
* @param {*} transformable - An OpenCascade object that can be transformed.
* @returns The transformed opencascade object.
*/
toLocalCoordinates(transformable) {
return transformable.Transformed(this.#forwardTransformation);
}
/**
* Transforms the given OpenCascade object to world coordinates from local coordinates of this plane.
* @private
* @param {*} transformable - An OpenCascade object that can be transformed.
* @returns The transformed opencascade object.
*/
toWorldCoordinates(transformable) {
return transformable.Transformed(this.#inverseTransformation);
}
/**
* Offsets the plane by a given vector.
* @param {Vector} offset - The offset vector to apply to the plane's origin.
* @returns {Plane} A new `Plane` object with the origin offset by the given vector.
*/
offset(offset) {
return new Plane({
origin: this.origin.add(offset),
normal: this.normal,
xDirection: this.xDirection,
});
}
/**
* Creates a `Plane` object from a given `Face` object.
* @param {Face} face - The face from which to create a `Plane` object.
* @returns {Plane|undefined} A new `Plane` object if the face is a plane, otherwise `undefined`.
*/
static fromFace(face) {
if (!(face.type === Face.TYPE.Plane)) {
return undefined;
}
return new Plane({
origin: face.centerOfMass,
normal: face.normal,
xDirection: face.xDirection,
});
}
/**
* Creates a `Plane` object representing the XY plane.
* @returns {Plane} A new `Plane` object representing the XY plane.
*/
static XY = new Plane({
origin: Vector.ZERO,
xDirection: Vector.X,
normal: Vector.Z,
});
/**
* Creates a `Plane` object representing the YX plane.
* @returns {Plane} A new `Plane` object representing the YX plane.
*/
static YX = new Plane({
origin: Vector.ZERO,
xDirection: Vector.Y,
normal: Vector.NEGATIVE_Z,
});
/**
* Creates a `Plane` object representing the YZ plane.
* @returns {Plane} A new `Plane` object representing the YZ plane.
*/
static YZ = new Plane({
origin: Vector.ZERO,
xDirection: Vector.Y,
normal: Vector.X,
});
/**
* Creates a `Plane` object representing the ZY plane.
* @returns {Plane} A new `Plane` object representing the ZY plane.
*/
static ZY = new Plane({
origin: Vector.ZERO,
xDirection: Vector.Z,
normal: Vector.NEGATIVE_X,
});
/**
* Creates a `Plane` object representing the XZ plane.
* @returns {Plane} A new `Plane` object representing the XZ plane.
*/
static XZ = new Plane({
origin: Vector.ZERO,
xDirection: Vector.X,
normal: Vector.NEGATIVE_Y,
});
/**
* Creates a `Plane` object representing the ZX plane.
* @returns {Plane} A new `Plane` object representing the ZX plane.
*/
static ZX = new Plane({
origin: Vector.ZERO,
xDirection: Vector.Z,
normal: Vector.Y,
});
}
cachedGetters({
object: Plane,
properties: ["origin", "normal", "xDirection", "axis"],
});