@itwin/core-backend
Version:
iTwin.js backend components
296 lines • 18.6 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 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