UNPKG

@inweb/viewer-visualize

Version:

JavaScript library for rendering CAD and BIM files in a browser using VisualizeJS

183 lines (152 loc) 5.92 kB
/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a // license agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// import { Point2d } from "../Common/Geometry"; export function createHtmlElementIfNeed( element: HTMLElement, targetElement: HTMLElement, dataTestId: string ): HTMLElement { if (!element) { element = document.createElement("div"); element.setAttribute("data-testid", dataTestId); targetElement.appendChild(element); } return element; } export function destroyHtmlElement(element: HTMLElement, targetElement: HTMLElement) { if (element) { targetElement.removeChild(element); } return null; } export function worldToScreen(gePoint: number[], moduleInstance, viewer): Point2d { const worldPoint = moduleInstance.Point3d.createFromArray(gePoint); const avp = viewer.activeView; const mtx = avp.worldToDeviceMatrix; const devicePoint = worldPoint.transformBy(mtx); const res = { x: devicePoint.x / window.devicePixelRatio, y: devicePoint.y / window.devicePixelRatio }; mtx.delete(); worldPoint.delete(); devicePoint.delete(); avp.delete(); return res; } export function getDistance(gePoint1: number[], gePoint2: number[], moduleInstance: any) { const tvPoint1 = moduleInstance.Point3d.createFromArray(gePoint1); const tvPoint2 = moduleInstance.Point3d.createFromArray(gePoint2); const distance = tvPoint1.distanceTo(tvPoint2).toFixed(2); tvPoint1.delete(); tvPoint2.delete(); return distance; } export function getAngle(geStart: number[], geOrigin: number[], geEnd: number[], moduleInstance: any): number { const tvStart = moduleInstance.Point3d.createFromArray(geStart); const tvOrigin = moduleInstance.Point3d.createFromArray(geOrigin); const tvEnd = moduleInstance.Point3d.createFromArray(geEnd); const s1 = tvStart.sub(tvOrigin); const s2 = tvEnd.sub(tvOrigin); const v1 = s1.asVector(); const v2 = s2.asVector(); const angle = (180 * v1.angleTo(v2)) / Math.PI; return angle; } export function getDataForDrawLine(p1: Point2d, p2: Point2d) { const dx = p2.x - p1.x; const dy = p2.y - p1.y; let angle = (180 * Math.atan(dy / dx)) / Math.PI; if (dx < 0) { angle -= 180; } const width = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); return { angle, width }; } function normalizeFloat(value: number): number { return value < 0 ? Math.ceil(value) : Math.floor(value); } const lineSegmentsIntersect = (p1: Point2d, p2: Point2d, p3: Point2d, p4: Point2d): false | Point2d => { const a_dx = p2.x - p1.x; const a_dy = p2.y - p1.y; const b_dx = p4.x - p3.x; const b_dy = p4.y - p3.y; const s = (-a_dy * (p1.x - p3.x) + a_dx * (p1.y - p3.y)) / (-b_dx * a_dy + a_dx * b_dy); const t = (+b_dx * (p1.y - p3.y) - b_dy * (p1.x - p3.x)) / (-b_dx * a_dy + a_dx * b_dy); return s >= 0 && s <= 1 && t >= 0 && t <= 1 ? { x: normalizeFloat(p1.x + t * a_dx), y: normalizeFloat(p1.y + t * a_dy), } : false; }; function checkSegmentsIntersect(p1: Point2d, p2: Point2d, p3: Point2d, p4: Point2d, res: Point2d[]): void { const r = lineSegmentsIntersect(p1, p2, p3, p4); if (r) { res.push(r); } } export function isInsideRect(p: Point2d, width: number, height: number): boolean { return p.x <= width && p.x >= 0 && p.y <= height && p.y >= 0; } export function getDataForDrawLineWithFixed(p1: Point2d, p2: Point2d, width: number, height: number) { const pLU = { x: 0, y: 0 }; const pRU = { x: width, y: 0 }; const pLB = { x: 0, y: height }; const pRB = { x: width, y: height }; const intersects: Point2d[] = []; checkSegmentsIntersect(p1, p2, pLU, pRU, intersects); checkSegmentsIntersect(p1, p2, pLU, pLB, intersects); checkSegmentsIntersect(p1, p2, pLB, pRB, intersects); checkSegmentsIntersect(p1, p2, pRB, pRU, intersects); let fixedP1: Point2d = null; let fixedP2: Point2d = null; if (intersects.length === 0) { fixedP1 = p1; fixedP2 = p2; } else if (intersects.length === 1) { if (isInsideRect(p1, width, height)) { fixedP1 = p1; fixedP2 = intersects[0]; } else { fixedP1 = intersects[0]; fixedP2 = p2; } } else { fixedP1 = intersects[0]; fixedP2 = intersects[1]; } const dx = fixedP2.x - fixedP1.x; const dy = fixedP2.y - fixedP1.y; let angle = (180 * Math.atan(dy / dx)) / Math.PI; if (dx < 0) { angle -= 180; } const size = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); return { angle, width: size, p1: fixedP1, p2: fixedP2 }; } export function onSetCallback(element: HTMLElement, cb: () => void): void { if (element) { element.onclick = cb ? () => cb() : () => {}; } } export function onSetSelectivity(element: HTMLElement, enable: boolean): void { element.style.pointerEvents = enable ? "auto" : "none"; }