UNPKG

@itwin/core-backend

Version:
296 lines • 18.6 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 ElementGeometry */ Object.defineProperty(exports, "__esModule", { value: true }); exports.LineStyleDefinition = void 0; const core_bentley_1 = require("@itwin/core-bentley"); const core_common_1 = require("@itwin/core-common"); const Element_1 = require("./Element"); /** A line style definition is a uniquely named pattern that repeats as it is displayed along a curve path. In the absence of a line style, curve display is limited to solid lines with a width in pixels. * There are three varieties of line styles: * - A style described by a stroke pattern (series of dashes and gaps) that may also include symbol graphics. * - A style using pre-defined pixel bit patterns [[LinePixels]] for dashed display (Code1-Code7). * - A style that uses a texture. * * A definition is defined by one or more components. A component is saved as a "file property" and can be referenced by other components. The line style definition references a component * by file property id and type and is saved as a dictionary element. * @public */ var LineStyleDefinition; (function (LineStyleDefinition) { /** Line style component type identifiers */ let ComponentType; (function (ComponentType) { /** Component type for [[LineStyleDefinition.PointSymbolProps]] */ ComponentType[ComponentType["PointSymbol"] = 1] = "PointSymbol"; /** Component type for [[LineStyleDefinition.CompoundProps]] */ ComponentType[ComponentType["Compound"] = 2] = "Compound"; /** Component type for [[LineStyleDefinition.StrokePatternProps]] */ ComponentType[ComponentType["StrokePattern"] = 3] = "StrokePattern"; /** Component type for [[LineStyleDefinition.StrokePointProps]] */ ComponentType[ComponentType["StrokePoint"] = 4] = "StrokePoint"; /** Component type for [[LinePixels]], never saved as a file property */ ComponentType[ComponentType["Internal"] = 6] = "Internal"; /** Component type for [[LineStyleDefinition.RasterImageProps]] */ ComponentType[ComponentType["RasterImage"] = 7] = "RasterImage"; })(ComponentType = LineStyleDefinition.ComponentType || (LineStyleDefinition.ComponentType = {})); /** Mask of values for StrokeMode */ let StrokeMode; (function (StrokeMode) { /** Stroke represents a blank space */ StrokeMode[StrokeMode["Gap"] = 0] = "Gap"; /** Stroke represents a solid dash */ StrokeMode[StrokeMode["Dash"] = 1] = "Dash"; /** Treat stroke as rigid and continue past a corner to complete the stroke as opposed to breaking at the corner */ StrokeMode[StrokeMode["Ray"] = 2] = "Ray"; /** Stroke length can be stretched when [[LineStyleDefinition.StrokePatternOptions.Iteration]] and [[LineStyleDefinition.StrokePatternOptions.AutoPhase]] options are set, applicable to both Gap and Dash strokes */ StrokeMode[StrokeMode["Scale"] = 4] = "Scale"; /** Invert stroke in first stroke pattern */ StrokeMode[StrokeMode["FirstInvert"] = 8] = "FirstInvert"; /** Invert stroke in last stroke pattern */ StrokeMode[StrokeMode["LastInvert"] = 16] = "LastInvert"; })(StrokeMode = LineStyleDefinition.StrokeMode || (LineStyleDefinition.StrokeMode = {})); /** Define constant width or tapered strokes with distance specified in meters */ let StrokeWidth; (function (StrokeWidth) { /** Stroke draws as one pixel wide line */ StrokeWidth[StrokeWidth["None"] = 0] = "None"; /** Half [[LineStyleDefinition.StrokeProps.orgWidth]] and [[LineStyleDefinition.StrokeProps.endWidth]] applied to left side of stroke */ StrokeWidth[StrokeWidth["Left"] = 1] = "Left"; /** Half [[LineStyleDefinition.StrokeProps.orgWidth]] and [[LineStyleDefinition.StrokeProps.endWidth]] applied to right side of stroke */ StrokeWidth[StrokeWidth["Right"] = 2] = "Right"; /** Half [[LineStyleDefinition.StrokeProps.orgWidth]] and [[LineStyleDefinition.StrokeProps.endWidth]] applied to both sides of stroke */ StrokeWidth[StrokeWidth["Full"] = 3] = "Full"; })(StrokeWidth = LineStyleDefinition.StrokeWidth || (LineStyleDefinition.StrokeWidth = {})); /** Controls appearance of stroke end caps. If StrokeCap is >= Hexagon, the end cap is stroked as an arc and the value of * StrokeCap indicates the number of vectors in the arc. */ let StrokeCap; (function (StrokeCap) { /** Stroke displays as a closed polygon */ StrokeCap[StrokeCap["Closed"] = 0] = "Closed"; /** Stroke displays lines at specified width instead of a polygon */ StrokeCap[StrokeCap["Open"] = 1] = "Open"; /** Stroke length extended by half the stroke width */ StrokeCap[StrokeCap["Extended"] = 2] = "Extended"; /** Stroke end cap is a hexagon */ StrokeCap[StrokeCap["Hexagon"] = 3] = "Hexagon"; /** Stroke end cap is an octagon */ StrokeCap[StrokeCap["Octagon"] = 4] = "Octagon"; /** Stroke end cap is a decagon */ StrokeCap[StrokeCap["Decagon"] = 5] = "Decagon"; /** Stroke end cap is an arc */ StrokeCap[StrokeCap["Arc"] = 30] = "Arc"; })(StrokeCap = LineStyleDefinition.StrokeCap || (LineStyleDefinition.StrokeCap = {})); /** Options to control how stroke pattern is applied to underlying curve */ let StrokePatternOptions; (function (StrokePatternOptions) { /** Use default stroke behavior */ StrokePatternOptions[StrokePatternOptions["None"] = 0] = "None"; /** [[LineStyleDefinition.StrokePatternProps.phase]] represents fractional distance into first stroke of pattern */ StrokePatternOptions[StrokePatternOptions["AutoPhase"] = 1] = "AutoPhase"; /** Use [[LineStyleDefinition.StrokePatternProps.maxIter]] to limit the number of iterations of the stroke pattern */ StrokePatternOptions[StrokePatternOptions["Iteration"] = 8] = "Iteration"; /** Single segment mode restarts the stroke pattern at corners instead of continuing around corners */ StrokePatternOptions[StrokePatternOptions["Segment"] = 16] = "Segment"; /** Center the line style and stretch the ends */ StrokePatternOptions[StrokePatternOptions["CenterStretch"] = 32] = "CenterStretch"; })(StrokePatternOptions = LineStyleDefinition.StrokePatternOptions || (LineStyleDefinition.StrokePatternOptions = {})); /** Flags to identify point symbol behavior */ let PointSymbolFlags; (function (PointSymbolFlags) { /** Default symbol behavior */ PointSymbolFlags[PointSymbolFlags["None"] = 0] = "None"; /** Symbol includes 3d geometry */ PointSymbolFlags[PointSymbolFlags["Is3d"] = 1] = "Is3d"; /** Symbol does not allow scaling */ PointSymbolFlags[PointSymbolFlags["NoScale"] = 2] = "NoScale"; })(PointSymbolFlags = LineStyleDefinition.PointSymbolFlags || (LineStyleDefinition.PointSymbolFlags = {})); /** Symbol options for location, orientation, and behavior */ let SymbolOptions; (function (SymbolOptions) { /** No point symbol */ SymbolOptions[SymbolOptions["None"] = 0] = "None"; /** Symbol at origin of stroke */ SymbolOptions[SymbolOptions["Origin"] = 1] = "Origin"; /** Symbol at end of stroke */ SymbolOptions[SymbolOptions["End"] = 2] = "End"; /** symbol at center of stroke */ SymbolOptions[SymbolOptions["Center"] = 3] = "Center"; /** Symbol at curve start point */ SymbolOptions[SymbolOptions["CurveOrigin"] = 4] = "CurveOrigin"; /** Symbol at curve end point */ SymbolOptions[SymbolOptions["CurveEnd"] = 8] = "CurveEnd"; /** Symbol at each vertex */ SymbolOptions[SymbolOptions["CurveVertex"] = 16] = "CurveVertex"; /** Adjust symbol rotation left->right */ SymbolOptions[SymbolOptions["AdjustRotation"] = 32] = "AdjustRotation"; /** Angle of symbol not relative to stroke direction */ SymbolOptions[SymbolOptions["AbsoluteRotation"] = 64] = "AbsoluteRotation"; /** No scale on variable strokes */ SymbolOptions[SymbolOptions["NoScale"] = 256] = "NoScale"; /** No clip on partial strokes */ SymbolOptions[SymbolOptions["NoClip"] = 512] = "NoClip"; /** No partial strokes */ SymbolOptions[SymbolOptions["NoPartial"] = 1024] = "NoPartial"; /** Project partial origin */ SymbolOptions[SymbolOptions["ProjectOrigin"] = 2048] = "ProjectOrigin"; /** Use color from symbol instead of inheriting curve color */ SymbolOptions[SymbolOptions["UseColor"] = 16384] = "UseColor"; /** Use weight from symbol instead of inheriting curve weight */ SymbolOptions[SymbolOptions["UseWeight"] = 32768] = "UseWeight"; })(SymbolOptions = LineStyleDefinition.SymbolOptions || (LineStyleDefinition.SymbolOptions = {})); /** Flags to describe a style or control style behavior */ let StyleFlags; (function (StyleFlags) { /** Use defaults */ StyleFlags[StyleFlags["None"] = 0] = "None"; /** Only snap to center line and not individual strokes and symbols of line style */ StyleFlags[StyleFlags["NoSnap"] = 4] = "NoSnap"; /** Style represents a continuous line with width (determined by looking at components if not set) */ StyleFlags[StyleFlags["Continuous"] = 8] = "Continuous"; /** Style represents physical geometry and should be scaled as such */ StyleFlags[StyleFlags["Physical"] = 128] = "Physical"; })(StyleFlags = LineStyleDefinition.StyleFlags || (LineStyleDefinition.StyleFlags = {})); /** Helper methods for creating and querying line styles */ class Utils { /** Create a file property for a new stroke pattern component. */ static createStrokePatternComponent(iModel, props) { const fileProps = { name: "LineCodeV1", namespace: "dgn_LStyle" }; fileProps.id = iModel.queryNextAvailableFileProperty(fileProps); iModel.saveFileProperty(fileProps, JSON.stringify(props)); return { compId: fileProps.id, compType: ComponentType.StrokePattern }; } /** Create a file property for a new point symbol component. * If base and size parameters are not supplied, queries GeometryPart by id to set them. */ static createPointSymbolComponent(iModel, props) { // if part extents weren't supplied, set them up now. if (!props.baseX && !props.baseY && !props.baseZ && !props.sizeX && !props.sizeY && !props.sizeZ) { const geomPart = iModel.elements.getElement(props.geomPartId); if (!geomPart) return undefined; props.baseX = geomPart.bbox.low.x; props.baseY = geomPart.bbox.low.y; props.baseZ = geomPart.bbox.low.z; props.sizeX = geomPart.bbox.high.x; props.sizeY = geomPart.bbox.high.y; props.sizeZ = geomPart.bbox.high.z; } const fileProps = { name: "PointSymV1", namespace: "dgn_LStyle" }; fileProps.id = iModel.queryNextAvailableFileProperty(fileProps); iModel.saveFileProperty(fileProps, JSON.stringify(props)); return { compId: fileProps.id, compType: ComponentType.PointSymbol }; } /** Create a file property for a new stroke point component. */ static createStrokePointComponent(iModel, props) { const fileProps = { name: "LinePointV1", namespace: "dgn_LStyle" }; fileProps.id = iModel.queryNextAvailableFileProperty(fileProps); iModel.saveFileProperty(fileProps, JSON.stringify(props)); return { compId: fileProps.id, compType: ComponentType.StrokePoint }; } /** Create a file property for a new compound component. */ static createCompoundComponent(iModel, props) { const fileProps = { name: "CompoundV1", namespace: "dgn_LStyle" }; fileProps.id = iModel.queryNextAvailableFileProperty(fileProps); iModel.saveFileProperty(fileProps, JSON.stringify(props)); return { compId: fileProps.id, compType: ComponentType.Compound }; } /** Create a file property for a new raster image component. */ static createRasterComponent(iModel, props, image) { const rasterFileProps = { name: "RasterImageV1", namespace: "dgn_LStyle" }; rasterFileProps.id = iModel.queryNextAvailableFileProperty(rasterFileProps); iModel.saveFileProperty(rasterFileProps, undefined, image); props.imageId = rasterFileProps.id; const fileProps = { name: "RasterComponentV1", namespace: "dgn_LStyle" }; fileProps.id = iModel.queryNextAvailableFileProperty(fileProps); iModel.saveFileProperty(fileProps, JSON.stringify(props)); return { compId: fileProps.id, compType: ComponentType.RasterImage }; } /** Query for an existing line style with the supplied name. */ static queryStyle(imodel, scopeModelId, name) { return imodel.elements.queryElementIdByCode(Element_1.LineStyle.createCode(imodel, scopeModelId, name)); } /** Insert a new line style with the supplied name. * @throws [[IModelError]] if unable to insert the line style definition element. */ static createStyle(imodel, scopeModelId, name, props) { if (undefined === props.flags) props.flags = StyleFlags.NoSnap; // If flags weren't supplied, default to not snapping to stroke geometry. const lsProps = { classFullName: "BisCore:LineStyle", model: scopeModelId, code: Element_1.LineStyle.createCode(imodel, scopeModelId, name), data: JSON.stringify(props), }; return imodel.elements.insertElement(lsProps); } /** Query for a continuous line style that can be used to create curves with physical width instead of weight in pixels and create one if it does not already exist. * There are 2 ways to define a continuous line style: * - Width is not specified in the style itself and instead will be supplied as an override for each curve that is drawn. * - Defined using [[LineStyleDefinition.ComponentType.Internal]] with component id 0 [[LinePixels.Solid]] which has special behavior of being affected by width overrides. * - Width is specified in the style. * - Defined using a single stroke component that is a long dash. * * @throws [[IModelError]] if unable to insert the line style definition element. */ static getOrCreateContinuousStyle(imodel, scopeModelId, width) { if (width === undefined) { const name0 = "Continuous"; const lsId0 = this.queryStyle(imodel, scopeModelId, name0); return (undefined === lsId0 ? this.createStyle(imodel, scopeModelId, name0, { compId: 0, compType: ComponentType.Internal, flags: StyleFlags.Continuous | StyleFlags.NoSnap }) : lsId0); } const name = `Continuous-${width}`; const lsId = this.queryStyle(imodel, scopeModelId, name); if (undefined !== lsId) return lsId; const strokePatternData = this.createStrokePatternComponent(imodel, { descr: name, strokes: [{ length: 1e37, orgWidth: width, strokeMode: StrokeMode.Dash, widthMode: StrokeWidth.Full }] }); if (undefined === strokePatternData) throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadArg, "Unable to insert stroke component"); return this.createStyle(imodel, scopeModelId, name, { compId: strokePatternData.compId, compType: strokePatternData.compType, flags: StyleFlags.Continuous | StyleFlags.NoSnap }); } /** Query for a line style using the supplied [[LinePixels]] value (Code1-Code7) and create one if it does not already exist. * Most applications should instead use [[createStrokePatternComponent]] to define a style with physical dash and gap lengths. * Unlike other components, [[LineStyleDefinition.ComponentType.Internal]] uses the line code as the compId instead of a file property id. * @throws [[IModelError]] if supplied an invalid [[LinePixels]] value or if unable to insert the line style definition element. */ static getOrCreateLinePixelsStyle(imodel, scopeModelId, linePixels) { let lineCode; switch (linePixels) { case core_common_1.LinePixels.Code1: lineCode = 1; break; case core_common_1.LinePixels.Code2: lineCode = 2; break; case core_common_1.LinePixels.Code3: lineCode = 3; break; case core_common_1.LinePixels.Code4: lineCode = 4; break; case core_common_1.LinePixels.Code5: lineCode = 5; break; case core_common_1.LinePixels.Code6: lineCode = 6; break; case core_common_1.LinePixels.Code7: lineCode = 7; break; default: throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadArg, "Invalid LinePixels"); } const name = `LinePixelsCodeNumber-${lineCode}`; const lsId = this.queryStyle(imodel, scopeModelId, name); return (undefined === lsId ? this.createStyle(imodel, scopeModelId, name, { compId: lineCode, compType: ComponentType.Internal }) : lsId); } } LineStyleDefinition.Utils = Utils; })(LineStyleDefinition || (exports.LineStyleDefinition = LineStyleDefinition = {})); //# sourceMappingURL=LineStyle.js.map