@itwin/core-frontend
Version:
iTwin.js frontend components
209 lines • 9.06 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* 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 { assert } from "@itwin/core-bentley";
import { PolyfaceBuilder, PolyfaceQuery, StrokeOptions, SweepContour, } from "@itwin/core-geometry";
import { DisplayParams } from "./DisplayParams";
import { PolyfacePrimitive, PolyfacePrimitiveList } from "./Polyface";
import { StrokesPrimitive, StrokesPrimitiveList, StrokesPrimitivePointList, StrokesPrimitivePointLists } from "./Strokes";
/** @internal */
export class Geometry {
transform;
tileRange;
displayParams;
feature;
constructor(transform, tileRange, displayParams, feature) {
this.transform = transform;
this.tileRange = tileRange;
this.displayParams = displayParams;
this.feature = feature;
}
static createFromPointString(pts, tf, tileRange, params, feature) {
return new PrimitivePointStringGeometry(pts, tf, tileRange, params, feature);
}
static createFromLineString(pts, tf, tileRange, params, feature) {
return new PrimitiveLineStringGeometry(pts, tf, tileRange, params, feature);
}
static createFromLoop(loop, tf, tileRange, params, disjoint, feature) {
return new PrimitiveLoopGeometry(loop, tf, tileRange, params, disjoint, feature);
}
static createFromSolidPrimitive(primitive, tf, tileRange, params, feature) {
return new SolidPrimitiveGeometry(primitive, tf, tileRange, params, feature);
}
static createFromPath(path, tf, tileRange, params, disjoint, feature) {
return new PrimitivePathGeometry(path, tf, tileRange, params, disjoint, feature);
}
static createFromPolyface(ipf, tf, tileRange, params, feature) {
return new PrimitivePolyfaceGeometry(ipf, tf, tileRange, params, feature);
}
getPolyfaces(tolerance) {
const facetOptions = StrokeOptions.createForFacets();
facetOptions.chordTol = tolerance;
if (this.displayParams.isTextured)
facetOptions.needParams = true;
if (!this.displayParams.ignoreLighting) // ###TODO don't generate normals for 2d views.
facetOptions.needNormals = true;
return this._getPolyfaces(facetOptions);
}
getStrokes(tolerance) {
const strokeOptions = StrokeOptions.createForCurves();
strokeOptions.chordTol = tolerance;
return this._getStrokes(strokeOptions);
}
get hasTexture() { return this.displayParams.isTextured; }
doDecimate() { return false; }
doVertexCluster() { return true; }
part() { return undefined; }
}
/** @internal */
export class PrimitivePathGeometry extends Geometry {
path;
isDisjoint;
constructor(path, tf, range, params, isDisjoint, feature) {
super(tf, range, params, feature);
this.path = path;
this.isDisjoint = isDisjoint;
}
_getPolyfaces(_facetOptions) { return undefined; }
_getStrokes(facetOptions) {
return PrimitivePathGeometry.getStrokesForLoopOrPath(this.path, facetOptions, this.displayParams, this.isDisjoint, this.transform);
}
static getStrokesForLoopOrPath(loopOrPath, facetOptions, params, isDisjoint, transform) {
const strksList = new StrokesPrimitiveList();
if (!loopOrPath.isAnyRegionType || params.wantRegionOutline) {
const strksPts = new StrokesPrimitivePointLists();
PrimitivePathGeometry.collectCurveStrokes(strksPts, loopOrPath, facetOptions, transform);
if (strksPts.length > 0) {
const isPlanar = loopOrPath.isAnyRegionType;
assert(isPlanar === params.wantRegionOutline);
const strksPrim = StrokesPrimitive.create(params, isDisjoint, isPlanar);
strksPrim.strokes = strksPts;
strksList.push(strksPrim);
}
}
return strksList;
}
static collectCurveStrokes(strksPts, loopOrPath, facetOptions, trans) {
const strokes = loopOrPath.getPackedStrokes(facetOptions);
if (undefined !== strokes) {
const pts = strokes.getPoint3dArray();
trans.multiplyPoint3dArrayInPlace(pts);
strksPts.push(new StrokesPrimitivePointList(pts));
}
}
}
/** @internal */
export class PrimitivePointStringGeometry extends Geometry {
pts;
constructor(pts, tf, range, params, feature) {
super(tf, range, params, feature);
this.pts = pts;
}
_getPolyfaces(_facetOptions) {
return undefined;
}
_getStrokes(_facetOptions) {
const strksList = new StrokesPrimitiveList();
const strksPts = new StrokesPrimitivePointLists(new StrokesPrimitivePointList(this.pts));
const strksPrim = StrokesPrimitive.create(this.displayParams, true, false);
strksPrim.strokes = strksPts;
strksPrim.transform(this.transform);
strksList.push(strksPrim);
return strksList;
}
}
/** @internal */
export class PrimitiveLineStringGeometry extends Geometry {
pts;
constructor(pts, tf, range, params, feature) {
super(tf, range, params, feature);
this.pts = pts;
}
_getPolyfaces(_facetOptions) {
return undefined;
}
_getStrokes(_facetOptions) {
const strksList = new StrokesPrimitiveList();
const strksPts = new StrokesPrimitivePointLists(new StrokesPrimitivePointList(this.pts));
const strksPrim = StrokesPrimitive.create(this.displayParams, false, false);
strksPrim.strokes = strksPts;
strksPrim.transform(this.transform);
strksList.push(strksPrim);
return strksList;
}
}
/** @internal */
export class PrimitiveLoopGeometry extends Geometry {
loop;
isDisjoint;
constructor(loop, tf, range, params, isDisjoint, feature) {
super(tf, range, params, feature);
this.loop = loop;
this.isDisjoint = isDisjoint;
}
_getPolyfaces(facetOptions) {
if (!this.loop.isAnyRegionType) {
return undefined;
}
// The following is good for single loop things according to Earlin.
const contour = SweepContour.createForLinearSweep(this.loop);
if (contour !== undefined) {
const pfBuilder = PolyfaceBuilder.create(facetOptions);
contour.emitFacets(pfBuilder, false, this.transform); // build facets and emit them to the builder
const polyface = pfBuilder.claimPolyface();
const wantEdges = DisplayParams.RegionEdgeType.Default === this.displayParams.regionEdgeType;
const isPlanar = true;
return new PolyfacePrimitiveList(PolyfacePrimitive.create(this.displayParams, polyface, wantEdges, isPlanar));
} // ###TODO: this approach might not work with holes
return undefined;
}
_getStrokes(facetOptions) {
return PrimitivePathGeometry.getStrokesForLoopOrPath(this.loop, facetOptions, this.displayParams, this.isDisjoint, this.transform);
}
}
/** @internal */
export class PrimitivePolyfaceGeometry extends Geometry {
polyface;
constructor(polyface, tf, range, params, feature) {
super(tf, range, params, feature);
this.polyface = tf.isIdentity ? polyface : polyface.cloneTransformed(tf);
}
_getPolyfaces(facetOptions) {
if (!this.hasTexture) {
if (this.polyface.data.param)
this.polyface.data.param.clear();
if (this.polyface.data.paramIndex)
this.polyface.data.paramIndex = [];
}
if (!facetOptions.needNormals) {
if (this.polyface.data.normal)
this.polyface.data.normal.clear();
if (this.polyface.data.normalIndex)
this.polyface.data.normalIndex = [];
}
else if (!this.polyface.data.normal || 0 === this.polyface.data.normal.length) {
PolyfaceQuery.buildAverageNormals(this.polyface);
}
return new PolyfacePrimitiveList(PolyfacePrimitive.create(this.displayParams, this.polyface));
}
_getStrokes(_facetOptions) { return undefined; }
}
class SolidPrimitiveGeometry extends Geometry {
_primitive;
constructor(primitive, tf, range, params, feature) {
super(tf, range, params, feature);
const xformPrim = tf.isIdentity ? primitive : primitive.cloneTransformed(tf);
this._primitive = xformPrim !== undefined ? xformPrim : primitive;
}
_getStrokes() { return undefined; }
_getPolyfaces(opts) {
const builder = PolyfaceBuilder.create(opts);
builder.addGeometryQuery(this._primitive);
return new PolyfacePrimitiveList(PolyfacePrimitive.create(this.displayParams, builder.claimPolyface()));
}
}
//# sourceMappingURL=GeometryPrimitives.js.map