UNPKG

@itwin/core-frontend

Version:
187 lines • 9.51 kB
"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 Rendering */ Object.defineProperty(exports, "__esModule", { value: true }); exports.PrimitiveBuilder = void 0; const core_geometry_1 = require("@itwin/core-geometry"); const core_common_1 = require("@itwin/core-common"); const GraphicBuilder_1 = require("../../render/GraphicBuilder"); const GraphicBranch_1 = require("../../render/GraphicBranch"); const core_bentley_1 = require("@itwin/core-bentley"); const Symbols_1 = require("../../common/internal/Symbols"); const GraphicTemplateImpl_1 = require("../../internal/render/GraphicTemplateImpl"); class PrimitiveBuilder extends GraphicBuilder_1.GraphicBuilder { [Symbols_1._implementationProhibited] = undefined; system; primitives = []; _options; _viewIndependentOrigin; constructor(system, options) { super(options); this.system = system; this._options = options; this._viewIndependentOrigin = options.viewIndependentOrigin?.clone(); } finish() { const template = this.toTemplate(false); const graphic = this.system.createGraphicFromTemplate({ template }); return graphic ?? this.system.createGraphicList([]); } finishTemplate() { return this.toTemplate(true); } toTemplate(noDispose) { const accum = this[Symbols_1._accumulator]; const tolerance = this.computeTolerance(accum); const result = this.saveToTemplate(this, tolerance, this.pickable, noDispose); accum.clear(); return result ?? (0, GraphicTemplateImpl_1.createGraphicTemplate)({ nodes: [], noDispose }); } computeTolerance(accum) { return this._computeChordTolerance({ graphic: this, computeRange: () => accum.geometries.computeRange(), }); } resolveGradient(gradient) { return this.system.getGradientTexture(gradient, this.iModel); } /** * Populate a list of Graphic objects from the accumulated Geometry objects. * removed ViewContext */ saveToGraphicList(graphics, options, tolerance, pickable) { const meshes = this[Symbols_1._accumulator].toMeshes(options, tolerance, pickable); if (0 === meshes.length) return undefined; // If the meshes contain quantized positions, they are all quantized to the same range. If that range is small relative to the distance // from the origin, quantization errors can produce display artifacts. Remove the translation from the quantization parameters and apply // it in the transform instead. // // If the positions are not quantized, they have already been transformed to be relative to the center of the meshes' range. // Apply the inverse translation to put them back into model space. const branch = new GraphicBranch_1.GraphicBranch(true); let transformOrigin; let meshesRangeOffset = false; for (const mesh of meshes) { const verts = mesh.points; if (branch.isEmpty) { if (verts instanceof core_common_1.QPoint3dList) { transformOrigin = verts.params.origin.clone(); verts.params.origin.setZero(); } else { transformOrigin = verts.range.center; // In this case we need to modify the qOrigin of the graphic that will get created later since we have translated the origin. // We can't modify it directly, but if we temporarily modify the range of the mesh used to create it the qOrigin will get created properly. // Range is shared (not cloned) by all meshes and the mesh list itself, so modifying the range of the meshlist will modify it for all meshes. // We will then later add this offset back to the range once all of the graphics have been created because it is needed unmodified for locate. if (!meshesRangeOffset) { meshes.range?.low.subtractInPlace(transformOrigin); meshes.range?.high.subtractInPlace(transformOrigin); meshesRangeOffset = true; } } } else { (0, core_bentley_1.assert)(undefined !== transformOrigin); if (verts instanceof core_common_1.QPoint3dList) { (0, core_bentley_1.assert)(transformOrigin.isAlmostEqual(verts.params.origin)); verts.params.origin.setZero(); } else { (0, core_bentley_1.assert)(verts.range.center.isAlmostZero); } } const graphic = this.system.createMeshGraphics(mesh, this._viewIndependentOrigin); if (graphic) branch.add(graphic); } if (!branch.isEmpty) { (0, core_bentley_1.assert)(undefined !== transformOrigin); const transform = core_geometry_1.Transform.createTranslation(transformOrigin); graphics.push(this.system.createBranch(branch, transform)); if (meshesRangeOffset) { // restore the meshes range that we modified earlier. meshes.range?.low.addInPlace(transformOrigin); meshes.range?.high.addInPlace(transformOrigin); } } return meshes; } saveToTemplate(options, tolerance, pickable, noDispose) { const meshes = this[Symbols_1._accumulator].toMeshes(options, tolerance, pickable); if (0 === meshes.length) return undefined; // If the meshes contain quantized positions, they are all quantized to the same range. If that range is small relative to the distance // from the origin, quantization errors can produce display artifacts. Remove the translation from the quantization parameters and apply // it in the transform instead. // // If the positions are not quantized, they have already been transformed to be relative to the center of the meshes' range. // Apply the inverse translation to put them back into model space. let transformOrigin; let meshesRangeOffset = false; const geometry = []; for (const mesh of meshes) { const verts = mesh.points; if (!transformOrigin) { if (verts instanceof core_common_1.QPoint3dList) { transformOrigin = verts.params.origin.clone(); verts.params.origin.setZero(); } else { transformOrigin = verts.range.center; // In this case we need to modify the qOrigin of the graphic that will get created later since we have translated the origin. // We can't modify it directly, but if we temporarily modify the range of the mesh used to create it the qOrigin will get created properly. // Range is shared (not cloned) by all meshes and the mesh list itself, so modifying the range of the meshlist will modify it for all meshes. // We will then later add this offset back to the range once all of the graphics have been created because it is needed unmodified for locate. if (!meshesRangeOffset) { meshes.range?.low.subtractInPlace(transformOrigin); meshes.range?.high.subtractInPlace(transformOrigin); meshesRangeOffset = true; } } } else { if (verts instanceof core_common_1.QPoint3dList) { (0, core_bentley_1.assert)(transformOrigin.isAlmostEqual(verts.params.origin)); verts.params.origin.setZero(); } else { (0, core_bentley_1.assert)(verts.range.center.isAlmostZero); } } const geom = this.system.createGeometryFromMesh(mesh, this._viewIndependentOrigin); if (geom) { geometry.push(geom); } } let transform; if (transformOrigin) { transform = core_geometry_1.Transform.createTranslation(transformOrigin); if (meshesRangeOffset) { // restore the meshes range that we modified earlier. meshes.range?.low.addInPlace(transformOrigin); meshes.range?.high.addInPlace(transformOrigin); } } let batch; if (meshes.features?.anyDefined) { batch = { featureTable: core_common_1.PackedFeatureTable.pack(meshes.features), range: meshes.range ?? new core_geometry_1.Range3d(), options: this._options.pickable, }; } return (0, GraphicTemplateImpl_1.createGraphicTemplate)({ batch, nodes: [{ geometry, transform }], noDispose, }); } } exports.PrimitiveBuilder = PrimitiveBuilder; //# sourceMappingURL=PrimitiveBuilder.js.map