@itwin/core-frontend
Version:
iTwin.js frontend components
183 lines • 7.9 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 Rendering
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.MeshBuilderMap = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const core_common_1 = require("@itwin/core-common");
const MeshPrimitive_1 = require("./MeshPrimitive");
const Primitives_1 = require("./Primitives");
const MeshBuilder_1 = require("./MeshBuilder");
const MeshPrimitives_1 = require("./MeshPrimitives");
/** @internal */
class MeshBuilderMap extends core_bentley_1.Dictionary {
range;
vertexTolerance;
facetAreaTolerance;
tolerance;
is2d;
features;
options;
_isVolumeClassifier;
_keyOrder = 0;
constructor(tolerance, range, is2d, options, pickable) {
super((lhs, rhs) => lhs.compare(rhs));
this.tolerance = tolerance;
this.vertexTolerance = tolerance * Primitives_1.ToleranceRatio.vertex;
this.facetAreaTolerance = tolerance * Primitives_1.ToleranceRatio.facetArea;
this.range = range;
this.is2d = is2d;
this.options = options;
this._isVolumeClassifier = pickable?.isVolumeClassifier ?? false;
if (pickable)
this.features = new core_common_1.FeatureTable(2048 * 1024, pickable.modelId);
}
static createFromGeometries(geometries, tolerance, range, is2d, options, pickable) {
const map = new MeshBuilderMap(tolerance, range, is2d, options, pickable);
for (const geom of geometries)
map.loadGeometry(geom);
return map;
}
toMeshes() {
const meshes = new MeshPrimitives_1.MeshList(this.features, this.range);
for (const builder of this._values) {
if (builder.mesh.points.length > 0)
meshes.push(builder.mesh);
}
return meshes;
}
/**
* extract polyfaces and strokes from geometry into MeshBuilder stored in builderMap
* @param geom Geometry instance to extract polyfaces and strokes from
*/
loadGeometry(geom) {
this.loadPolyfacePrimitiveList(geom);
this.loadStrokePrimitiveList(geom);
}
/**
* extract polyface primitives from geometry in meshBuilder stored in builderMap
* @param geom Geometry instance to extract polyfaces from
*/
loadPolyfacePrimitiveList(geom) {
const polyfaces = geom.getPolyfaces(this.tolerance);
if (polyfaces !== undefined)
for (const polyface of polyfaces)
this.loadIndexedPolyface(polyface, geom.feature);
}
/**
* extract indexed polyfaces into meshBuilder stored in builderMap
* @param polyface PolyfacePrimitive to extract indexed polyfaces from
*/
loadIndexedPolyface(polyface, feature) {
const { indexedPolyface, displayParams, isPlanar } = polyface;
const { pointCount, normalCount } = indexedPolyface;
const { fillColor, isTextured } = displayParams;
const textureMapping = displayParams.textureMapping;
if (pointCount === 0)
return;
const builder = this.getBuilder(displayParams, MeshPrimitive_1.MeshPrimitiveType.Mesh, normalCount > 0, isPlanar);
const edgeOptions = new MeshBuilder_1.MeshEdgeCreationOptions(polyface.displayEdges && this.options.wantEdges ? MeshBuilder_1.MeshEdgeCreationOptions.Type.DefaultEdges : MeshBuilder_1.MeshEdgeCreationOptions.Type.NoEdges);
builder.addFromPolyface(indexedPolyface, { edgeOptions, includeParams: isTextured, fillColor: fillColor.tbgr, mappedTexture: textureMapping }, feature);
}
/**
* extract stroke primitives from geometry in meshBuilder stored in builderMap
* @param geom Geometry instance to extract strokes from
*/
loadStrokePrimitiveList(geom) {
const strokes = geom.getStrokes(this.tolerance);
if (undefined !== strokes)
for (const stroke of strokes)
this.loadStrokesPrimitive(stroke, geom.feature);
}
/**
* extract strokes primitive into meshBuilder stored in builderMap
* @param strokePrimitive StrokesPrimitive instance to extractfrom
*/
loadStrokesPrimitive(strokePrimitive, feature) {
const { displayParams, isDisjoint, isPlanar, strokes } = strokePrimitive;
const type = isDisjoint ? MeshPrimitive_1.MeshPrimitiveType.Point : MeshPrimitive_1.MeshPrimitiveType.Polyline;
const builder = this.getBuilder(displayParams, type, false, isPlanar);
builder.addStrokePointLists(strokes, isDisjoint, displayParams.lineColor.tbgr, feature);
}
getBuilder(displayParams, type, hasNormals, isPlanar) {
const { facetAreaTolerance, tolerance, is2d, range } = this;
const key = this.getKey(displayParams, type, hasNormals, isPlanar);
const quantizePositions = false; // ###TODO should this be configurable?
return this.getBuilderFromKey(key, {
displayParams,
type,
range,
quantizePositions,
is2d,
isPlanar,
tolerance,
areaTolerance: facetAreaTolerance,
features: this.features,
isVolumeClassifier: this._isVolumeClassifier,
});
}
getKey(displayParams, type, hasNormals, isPlanar) {
const key = new MeshBuilderMap.Key(displayParams, type, hasNormals, isPlanar);
if (this.options.preserveOrder)
key.order = ++this._keyOrder;
return key;
}
/**
* gets builder associated with key if defined, otherwise creates a new builder and sets that with key
* @param key MeshBuilderMap.Key to associate with builder
* @param props MeshBuilder.Props required to create builder if it does not already exist
* @returns builder reference, changes will update instance stored in builderMap
*/
getBuilderFromKey(key, props) {
let builder = this.get(key);
if (undefined === builder) {
builder = MeshBuilder_1.MeshBuilder.create(props);
this.set(key, builder);
}
return builder;
}
}
exports.MeshBuilderMap = MeshBuilderMap;
/** @internal */
(function (MeshBuilderMap) {
class Key {
order = 0;
params;
type;
hasNormals;
isPlanar;
constructor(params, type, hasNormals, isPlanar) {
this.params = params;
this.type = type;
this.hasNormals = hasNormals;
this.isPlanar = isPlanar;
}
static createFromMesh(mesh) {
return new Key(mesh.displayParams, mesh.type, mesh.normals.length !== 0, mesh.isPlanar);
}
compare(rhs) {
let diff = (0, core_bentley_1.compareNumbers)(this.order, rhs.order);
if (0 === diff) {
diff = (0, core_bentley_1.compareNumbers)(this.type, rhs.type);
if (0 === diff) {
diff = (0, core_bentley_1.compareBooleans)(this.isPlanar, rhs.isPlanar);
if (0 === diff) {
diff = (0, core_bentley_1.compareBooleans)(this.hasNormals, rhs.hasNormals);
if (0 === diff) {
diff = this.params.compareForMerge(rhs.params);
}
}
}
}
return diff;
}
equals(rhs) { return 0 === this.compare(rhs); }
}
MeshBuilderMap.Key = Key;
})(MeshBuilderMap || (exports.MeshBuilderMap = MeshBuilderMap = {}));
//# sourceMappingURL=MeshBuilderMap.js.map