UNPKG

@itwin/core-backend

Version:
384 lines • 17.8 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. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); exports.generateGeometrySummaries = generateGeometrySummaries; const core_bentley_1 = require("@itwin/core-bentley"); const core_geometry_1 = require("@itwin/core-geometry"); const core_common_1 = require("@itwin/core-common"); const Element_1 = require("./Element"); const Symbols_1 = require("./internal/Symbols"); // cspell:ignore earlin /** Generates an array of GeometryStreamResponseProps. */ class ResponseGenerator { verbosity = core_common_1.GeometrySummaryVerbosity.Basic; includePlacement = false; includePartReferences; verboseSymbology = false; elementIds; iModel; get wantSquish() { return core_common_1.GeometrySummaryVerbosity.Full !== this.verbosity; } constructor(request, iModel) { this.elementIds = request.elementIds; this.iModel = iModel; const opts = request.options; if (undefined !== opts) { this.verbosity = undefined !== opts.geometryVerbosity ? opts.geometryVerbosity : core_common_1.GeometrySummaryVerbosity.Basic; this.includePlacement = true === opts.includePlacement; this.includePartReferences = opts.includePartReferences; this.verboseSymbology = true === opts.verboseSymbology; } } generateSummaries() { const summaries = []; for (const elementId of this.elementIds) summaries.push(this.generateSummary(elementId)); return summaries.join("\n"); } generateSummary(id) { let lines = [`[Geometry Summary for Element ${id}]`]; try { const geom = this.getElementGeom(id); if (undefined === geom) throw new core_common_1.IModelError(core_bentley_1.IModelStatus.NoGeometry, "Element is neither a geometric element nor a geometry part"); if (undefined !== geom.geometricElement) lines.push(this.summarizeElement(geom.geometricElement)); else if (undefined !== this.includePartReferences) lines.push(this.summarizePartReferences(id, "2d" === this.includePartReferences)); // NB: Hideously inefficient if more than one element's summary was requested. let curGeomParams; let curLocalRange; for (const entry of geom.iterator) { if (this.verboseSymbology && (undefined === curGeomParams || !curGeomParams.isEquivalent(entry.geomParams))) { lines.push(`Symbology: ${this.stringify(entry.geomParams)}`); curGeomParams = entry.geomParams.clone(); } if (undefined !== entry.localRange && (undefined === curLocalRange || !curLocalRange.isAlmostEqual(entry.localRange))) { lines.push(this.summarizeRange3d(entry.localRange)); curLocalRange = entry.localRange; } const prim = entry.primitive; switch (prim.type) { case "textString": case "image": this.summarizePrimitive(lines, prim); break; case "brep": this.summarizeBRep(lines, prim.brep); break; case "geometryQuery": this.summarizeGeometryQuery(lines, prim.geometry); break; case "partReference": lines.push(this.summarizePartReference(prim.part.id, prim.part.toLocal)); break; } } } catch (err) { lines = lines.slice(0, 1); lines.push(`ERROR: ${core_bentley_1.BentleyError.getErrorMessage(err)}`); } return lines.filter((line) => line !== "").join("\n"); } summarizeElement(elem) { const lines = []; lines.push(`(${elem.is2d() ? "2D" : "3D"}) Category: ${elem.category}`); lines.push(`Model: ${elem.model}`); if (this.includePlacement) { lines.push(`Range: ${this.stringify(elem.calculateRange3d())}`); lines.push(`Transform: ${this.stringify(elem.getPlacementTransform())}`); } return lines.join("\n"); } summarizePartReferences(id, is2d) { const refIds = this.iModel[Symbols_1._nativeDb].findGeometryPartReferences([id], is2d); return `Part references (${refIds.length}): ${refIds.join()}`; } getElementGeom(id) { const elem = this.iModel.elements.getElement({ id, wantGeometry: true }); let iterator; let geometricElement; if (elem instanceof Element_1.GeometricElement) { geometricElement = elem; if (geometricElement.is2d()) { iterator = core_common_1.GeometryStreamIterator.fromGeometricElement2d(geometricElement); } else { (0, core_bentley_1.assert)(geometricElement.is3d()); iterator = core_common_1.GeometryStreamIterator.fromGeometricElement3d(geometricElement); } } else if (elem instanceof Element_1.GeometryPart) { iterator = core_common_1.GeometryStreamIterator.fromGeometryPart(elem); } return undefined !== iterator ? { iterator, geometricElement } : undefined; } summarizeRange3d(range) { return `SubGraphicRange: ${this.stringify(range)}`; } summarizePrimitive(lines, primitive) { const summary = primitive.type; if (core_common_1.GeometrySummaryVerbosity.Basic >= this.verbosity) { lines.push(summary); return; } const json = this.stringify(primitive.type === "textString" ? primitive.textString : primitive.image); if (core_common_1.GeometrySummaryVerbosity.Detailed >= this.verbosity) { lines.push(`${summary}: ${json}`); return; } lines.push(`${summary}:`); lines.push(json); } summarizeBRep(lines, brep) { const summary = "brep"; if (core_common_1.GeometrySummaryVerbosity.Basic >= this.verbosity) { lines.push(summary); return; } const json = this.stringify({ type: brep.type, transform: brep.transform, faceSymbology: brep.faceSymbology }); if (core_common_1.GeometrySummaryVerbosity.Detailed >= this.verbosity) { lines.push(`${summary}: ${json}`); return; } lines.push(`${summary}:`); lines.push(json); } summarizePartReference(partId, partToLocal) { let line = `part id: ${partId}`; if (undefined !== partToLocal) line = `${line} transform: ${this.stringify(partToLocal)}`; return line; } summarizeGeometryQuery(lines, query) { switch (this.verbosity) { case core_common_1.GeometrySummaryVerbosity.Detailed: lines.push(this.summarizeGeometryQueryDetailed(query)); break; case core_common_1.GeometrySummaryVerbosity.Full: lines.push(this.summarizeGeometryQueryFull(query)); break; default: lines.push(this.summarizeGeometryQueryBasic(query)); break; } } summarizeGeometryQueryBasic(query) { switch (query.geometryCategory) { case "solid": return query.solidPrimitiveType; case "curvePrimitive": return query.curvePrimitiveType; case "curveCollection": return query.curveCollectionType; default: return query.geometryCategory; } } summarizeGeometryQueryFull(query) { return this.geometryQueryToJson(query); } geometryQueryToJson(query) { try { const json = core_geometry_1.IModelJson.Writer.toIModelJson(query); const str = JSON.stringify(json); return this.wantSquish ? this.squish(str) : str; } catch (err) { return core_bentley_1.BentleyError.getErrorMessage(err); } } // Earlin likes to put tons of whitespace + newlines into his JSON. Remove it. squish(str) { return str.replace(/\s+/g, ""); } stringify(obj) { const json = JSON.stringify(obj); return this.wantSquish ? this.squish(json) : json; } summarizeGeometryQueryDetailed(query) { let summary = `${this.summarizeGeometryQueryBasic(query)}: `; switch (query.geometryCategory) { case "solid": return summary + this.summarizeSolidPrimitive(query); case "curvePrimitive": return summary + this.summarizeCurvePrimitive(query); case "curveCollection": return summary + this.summarizeCurveCollection(query); case "pointCollection": return `${summary} numPoints: ${query.points.length}`; case "bsurf": return `${summary}' ' poleDimension: ${query.poleDimension}' ' numPolesTotal: ${query.numPolesTotal()}' ' degree[U,V]: ${JSON.stringify([query.degreeUV(core_geometry_1.UVSelect.uDirection), query.degreeUV(core_geometry_1.UVSelect.vDirection)])}' ' order[U,V]: ${JSON.stringify([query.orderUV(core_geometry_1.UVSelect.uDirection), query.orderUV(core_geometry_1.UVSelect.vDirection)])}' ' numSpan[U,V]: ${JSON.stringify([query.numSpanUV(core_geometry_1.UVSelect.uDirection), query.numSpanUV(core_geometry_1.UVSelect.vDirection)])}' ' numPoles[U,V]: ${JSON.stringify([query.numPolesUV(core_geometry_1.UVSelect.uDirection), query.numPolesUV(core_geometry_1.UVSelect.vDirection)])}' ' poleStep[U,V]: ${JSON.stringify([query.poleStepUV(core_geometry_1.UVSelect.uDirection), query.poleStepUV(core_geometry_1.UVSelect.vDirection)])}`; case "polyface": { const data = query.data; summary = `${summary} pointCount: ${data.point.length}' ' pointIndexCount: ${data.pointIndex.length}`; if (query.twoSided) summary = `${summary} (two-sided)`; if (undefined !== data.normal) summary = `${summary} normalCount: ${data.normal.length}`; if (undefined !== data.param) summary = `${summary} paramCount: ${data.param.length}`; if (undefined !== data.color) summary = `${summary} colorCount: ${data.color.length}`; return summary; } case "point": return summary + this.geometryQueryToJson(query); } } summarizeSolidPrimitive(solid) { const summary = solid.capped ? " capped" : " uncapped"; switch (solid.solidPrimitiveType) { case "box": const box = solid; return `${summary}' ' origin: ${JSON.stringify(box.getBaseOrigin().toJSON())}' ' topOrigin: ${JSON.stringify(box.getTopOrigin().toJSON())}' ' baseX: ${box.getBaseX()}' ' baseY: ${box.getBaseY()}`; case "cone": const cone = solid; return `${summary}' ' baseCenterPoint: ${JSON.stringify(cone.getCenterA())}' ' topCenterPoint: ${JSON.stringify(cone.getCenterB())}' ' baseCenterRadius: ${JSON.stringify(cone.getRadiusA())}' ' topCenterRadius: ${JSON.stringify(cone.getRadiusB())}`; case "sphere": const sphere = solid; return `${summary}' ' centerPoint: ${JSON.stringify(sphere.cloneCenter().toJSON())}' ' radius: ${JSON.stringify(sphere.trueSphereRadius())}`; case "linearSweep": const linearSweep = solid; return `${summary}' ' vector: ${JSON.stringify(linearSweep.cloneSweepVector().toJSON())}' ' curves${this.summarizeCurveCollection(linearSweep.getCurvesRef())}`; case "rotationalSweep": const rotationalSweep = solid; const axis = rotationalSweep.cloneAxisRay(); return `${summary}' ' center: ${JSON.stringify(axis.origin.toJSON())}' ' axis: ${JSON.stringify(axis.direction.toJSON())}' ' sweepAngle: ${rotationalSweep.getSweep().degrees}`; case "ruledSweep": const ruledSweep = solid; const summarizedCollection = ruledSweep.cloneContours().map((curveCollection) => this.summarizeCurveCollection(curveCollection)); return `${summary}' ' isClosedVolume${ruledSweep.isClosedVolume}' ' contours: ${JSON.stringify(summarizedCollection)}`; case "torusPipe": const torusPipe = solid; const vectorX = torusPipe.cloneVectorX(); const vectorY = torusPipe.cloneVectorY(); const sweep = torusPipe.getSweepAngle(); if (torusPipe.getIsReversed()) { vectorY.scaleInPlace(-1.0); sweep.setRadians(-sweep.radians); } return `${summary}' ' center: ${JSON.stringify(torusPipe.cloneCenter().toJSON())}' ' xyVectors: ${JSON.stringify([vectorX.toJSON(), vectorY.toJSON()])}' ' majorRadius: ${torusPipe.getMajorRadius()}' ' minorRadius: ${torusPipe.getMinorRadius()}' ' sweepAngle: ${sweep.degrees}`; } } summarizeCurvePrimitive(curve) { let summary = ""; const writer = new core_geometry_1.IModelJson.Writer(); switch (curve.curvePrimitiveType) { case "arc": const arc = curve; summary = `${summary} center: ${JSON.stringify(arc.center.toJSON())}`; if (undefined !== arc.circularRadius) summary = `${summary} radius: ${arc.circularRadius()}`; summary = `${summary}' ' vectorX:${JSON.stringify(arc.vector0.toJSON())}' ' vectorY:${JSON.stringify(arc.vector90.toJSON())}' ' sweepStartEnd [${arc.sweep.startDegrees}, ${arc.sweep.endDegrees}]` + ` curveLength: ${curve.curveLength()}`; return summary; case "lineSegment": const lineSegment = curve; summary = `${summary} points: ${JSON.stringify(lineSegment.toJSON())}`; summary = `${summary} curveLength: ${curve.curveLength()}`; return summary; case "lineString": const lineString = curve; summary = `${summary} pointCount: ${lineString.numPoints()}' ' curveLength: ${curve.curveLength()}`; return summary; case "bsplineCurve": const bsplineCurve = curve; summary = `${summary}' ' curveOrder: ${bsplineCurve.order}' ' controlPointsCount: ${bsplineCurve.numPoles}' ' curveLength: ${curve.curveLength()}`; return summary; case "interpolationCurve": const interpolationCurve = curve; const interpolationProps = interpolationCurve.cloneProps(); summary = `${summary}' ' curveOrder: ${interpolationProps.order}' ' controlPointsCount: ${interpolationProps.fitPoints.length}`; return summary; case "akimaCurve": const akimaCurve = curve; const akimaProps = akimaCurve.cloneProps(); summary = `${summary}' ' controlPointsCount: ${akimaProps.fitPoints.length}`; return summary; case "bezierCurve": const bezierCurve = curve; summary = `${summary}' ' curveOrder: ${bezierCurve.order}' ' controlPointsCount: ${bezierCurve.numPoles}' ' curveLength: ${curve.curveLength()}`; return summary; case "transitionSpiral": const transitionSpiral = curve; const json = writer.handleTransitionSpiral(transitionSpiral); summary = summary + JSON.stringify(json); return summary; case "curveChainWithDistanceIndex": const curveChainWithDistanceIndex = curve; const path = curveChainWithDistanceIndex.path; summary = `${summary}' ' curveLength: ${curve.curveLength()}' ' isOpen: ${path.isOpenPath}`; return summary; } } summarizeCurveCollection(curves) { let summary = ""; switch (curves.curveCollectionType) { case "loop": const loop = curves; summary = `${summary} isInner: ${loop.isInner}`; break; case "path": const path = curves; summary = `${summary} isOpen: ${path.isOpenPath}`; break; } return `${summary}' ' numCurves: ${curves.collectCurvePrimitives().length}' ' boundary: ${curves.dgnBoundaryType()}`; } } /** @internal */ function generateGeometrySummaries(request, iModel) { const generator = new ResponseGenerator(request, iModel); return generator.generateSummaries(); } //# sourceMappingURL=GeometrySummary.js.map