UNPKG

@itwin/core-frontend

Version:
128 lines 6.34 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Rendering */ import { Point3d, Range3d, Transform } from "@itwin/core-geometry"; import { MeshBuilderMap } from "./MeshBuilderMap"; import { MeshList } from "./MeshPrimitives"; import { GeometryList } from "./GeometryList"; import { Geometry } from "./GeometryPrimitives"; /** @internal */ export class GeometryAccumulator { _transform; _surfacesOnly; _analysisDisplacement; tileRange; geometries = new GeometryList(); currentFeature; get surfacesOnly() { return this._surfacesOnly; } get transform() { return this._transform; } get isEmpty() { return this.geometries.isEmpty; } get haveTransform() { return !this._transform.isIdentity; } constructor(options) { this.tileRange = options?.tileRange ?? Range3d.createNull(); this._surfacesOnly = true === options?.surfacesOnly; this._transform = options?.transform ?? Transform.createIdentity(); this._analysisDisplacement = options?.analysisStyleDisplacement; this.currentFeature = options?.feature; } getPrimitiveRange(geom) { const range = new Range3d(); geom.range(undefined, range); return range.isNull ? undefined : range; } calculateTransform(transform, range) { if (this.haveTransform) transform = this._transform.multiplyTransformTransform(transform); transform.multiplyRange(range, range); return transform; } addLoop(loop, displayParams, transform, disjoint) { const range = this.getPrimitiveRange(loop); if (!range) return false; const xform = this.calculateTransform(transform, range); return this.addGeometry(Geometry.createFromLoop(loop, xform, range, displayParams, disjoint, this.currentFeature)); } addLineString(pts, displayParams, transform) { // Do this.getPrimitiveRange() manually, so there is no need to create a PointString3d object just to find the range const range = Range3d.createNull(); range.extendArray(pts, undefined); if (range.isNull) return false; const xform = this.calculateTransform(transform, range); return this.addGeometry(Geometry.createFromLineString(pts, xform, range, displayParams, this.currentFeature)); } addPointString(pts, displayParams, transform) { // Do this.getPrimitiveRange() manually, so there is no need to create a PointString3d object just to find the range const range = Range3d.createNull(); range.extendArray(pts, undefined); if (range.isNull) return false; const xform = this.calculateTransform(transform, range); return this.addGeometry(Geometry.createFromPointString(pts, xform, range, displayParams, this.currentFeature)); } addPath(path, displayParams, transform, disjoint) { const range = this.getPrimitiveRange(path); if (!range) return false; const xform = this.calculateTransform(transform, range); return this.addGeometry(Geometry.createFromPath(path, xform, range, displayParams, disjoint, this.currentFeature)); } addPolyface(pf, displayParams, transform) { // Adjust the mesh range based on displacements applied to vertices by analysis style, if applicable. let range; const analysisDisplacement = this._analysisDisplacement; if (analysisDisplacement) { const channel = pf.data.auxData?.channels.find((x) => x.name === analysisDisplacement.channelName); const displacementRange = channel?.computeDisplacementRange(analysisDisplacement.scale); if (displacementRange && !displacementRange.isNull) { range = Range3d.createNull(); const pt = new Point3d(); for (let i = 0; i < pf.data.point.length; i++) { pf.data.point.getPoint3dAtUncheckedPointIndex(i, pt); range.extendXYZ(pt.x + displacementRange.low.x, pt.y + displacementRange.low.y, pt.z + displacementRange.low.z); range.extendXYZ(pt.x + displacementRange.high.x, pt.y + displacementRange.high.y, pt.z + displacementRange.high.z); } } } if (!range && !(range = this.getPrimitiveRange(pf))) return false; const xform = this.calculateTransform(transform, range); return this.addGeometry(Geometry.createFromPolyface(pf, xform, range, displayParams, this.currentFeature)); } addSolidPrimitive(primitive, displayParams, transform) { const range = this.getPrimitiveRange(primitive); if (!range) return false; const xform = this.calculateTransform(transform, range); return this.addGeometry(Geometry.createFromSolidPrimitive(primitive, xform, range, displayParams, this.currentFeature)); } addGeometry(geom) { this.geometries.push(geom); return true; } clear() { this.geometries.clear(); } /** * Generates a MeshBuilderMap * native: GeometryAccumulator::ToMeshBuilderMap(GeometryOptionsCR options, double tolerance, FeatureTableP featureTable, ViewContextR context) const * note : removed featureTable, ViewContext * @param tolerance should derive from Viewport.getPixelSizeAtPoint */ toMeshBuilderMap(options, tolerance, pickable) { const { geometries } = this; // declare internal dependencies const range = geometries.computeRange(); const is2d = !range.isNull && range.isAlmostZeroZ; return MeshBuilderMap.createFromGeometries(geometries, tolerance, range, is2d, options, pickable); } toMeshes(options, tolerance, pickable) { if (this.geometries.isEmpty) return new MeshList(); const builderMap = this.toMeshBuilderMap(options, tolerance, pickable); return builderMap.toMeshes(); } } //# sourceMappingURL=GeometryAccumulator.js.map