diff --git a/common/api/core-common.api.md b/common/api/core-common.api.md index 9b77483afcff..201fe659d47a 100644 --- a/common/api/core-common.api.md +++ b/common/api/core-common.api.md @@ -7638,8 +7638,24 @@ export interface RealityDataSourceProps { sourceKey: RealityDataSourceKey; } +// @beta +export interface RealityMeshDisplayProps { + bgMapDrape?: boolean; +} + +// @beta +export class RealityMeshDisplaySettings { + readonly bgMapDrape: boolean; + clone(changedProps: RealityMeshDisplayProps): RealityMeshDisplaySettings; + static defaults: RealityMeshDisplaySettings; + equals(other: RealityMeshDisplaySettings): boolean; + static fromJSON(props?: RealityMeshDisplayProps): RealityMeshDisplaySettings; + toJSON(): RealityMeshDisplayProps | undefined; +} + // @beta export interface RealityModelDisplayProps { + mesh?: RealityMeshDisplayProps; overrideColorRatio?: number; pointCloud?: PointCloudDisplayProps; } @@ -7650,6 +7666,7 @@ export class RealityModelDisplaySettings { static defaults: RealityModelDisplaySettings; equals(other: RealityModelDisplaySettings): boolean; static fromJSON(props?: RealityModelDisplayProps): RealityModelDisplaySettings; + readonly mesh: RealityMeshDisplaySettings; readonly overrideColorRatio: number; readonly pointCloud: PointCloudDisplaySettings; toJSON(): RealityModelDisplayProps | undefined; diff --git a/common/api/frontend-devtools.api.md b/common/api/frontend-devtools.api.md index 06195128bc8b..77101ad8bb53 100644 --- a/common/api/frontend-devtools.api.md +++ b/common/api/frontend-devtools.api.md @@ -1926,6 +1926,20 @@ export class SetModelTransparencyTool extends Tool { static toolId: string; } +// @beta +export class SetRealityModelBackgroundDrapeTool extends Tool { + // (undocumented) + static get maxArgs(): number; + // (undocumented) + static get minArgs(): number; + // (undocumented) + parseAndRun(...args: string[]): Promise; + // (undocumented) + run(bgDrape: boolean, index: number): Promise; + // (undocumented) + static toolId: string; +} + // @beta export class SetRealityModelColorTool extends Tool { // (undocumented) diff --git a/common/api/summary/core-common.exports.csv b/common/api/summary/core-common.exports.csv index bdf553480ae3..4a7629d8639b 100644 --- a/common/api/summary/core-common.exports.csv +++ b/common/api/summary/core-common.exports.csv @@ -666,6 +666,8 @@ beta;enum;RealityDataProvider beta;interface;RealityDataSourceKey beta;namespace;RealityDataSourceKey beta;interface;RealityDataSourceProps +beta;interface;RealityMeshDisplayProps +beta;class;RealityMeshDisplaySettings beta;interface;RealityModelDisplayProps beta;class;RealityModelDisplaySettings internal;const;REGISTRY diff --git a/common/api/summary/frontend-devtools.exports.csv b/common/api/summary/frontend-devtools.exports.csv index 201666b409d9..e3f35028e280 100644 --- a/common/api/summary/frontend-devtools.exports.csv +++ b/common/api/summary/frontend-devtools.exports.csv @@ -169,6 +169,7 @@ beta;class;SetModelLineCodeTool beta;class;SetModelLineWeightTool beta;class;SetModelLocateTool beta;class;SetModelTransparencyTool +beta;class;SetRealityModelBackgroundDrapeTool beta;class;SetRealityModelColorTool beta;class;SetRealityModelEmphasizedTool beta;class;SetRealityModelLocateTool diff --git a/common/changes/@itwin/core-common/man-drape-bgmap-onto-realitymesh_2024-11-19-19-11.json b/common/changes/@itwin/core-common/man-drape-bgmap-onto-realitymesh_2024-11-19-19-11.json new file mode 100644 index 000000000000..443810308183 --- /dev/null +++ b/common/changes/@itwin/core-common/man-drape-bgmap-onto-realitymesh_2024-11-19-19-11.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@itwin/core-common", + "comment": "Added ability to drape the background map onto a reality mesh.", + "type": "none" + } + ], + "packageName": "@itwin/core-common" +} \ No newline at end of file diff --git a/common/changes/@itwin/core-frontend/man-drape-bgmap-onto-realitymesh_2024-11-19-19-11.json b/common/changes/@itwin/core-frontend/man-drape-bgmap-onto-realitymesh_2024-11-19-19-11.json new file mode 100644 index 000000000000..8b5ad55856c2 --- /dev/null +++ b/common/changes/@itwin/core-frontend/man-drape-bgmap-onto-realitymesh_2024-11-19-19-11.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@itwin/core-frontend", + "comment": "Added ability to drape the background map onto a reality mesh.", + "type": "none" + } + ], + "packageName": "@itwin/core-frontend" +} \ No newline at end of file diff --git a/common/changes/@itwin/frontend-devtools/man-drape-bgmap-onto-realitymesh_2024-11-19-19-11.json b/common/changes/@itwin/frontend-devtools/man-drape-bgmap-onto-realitymesh_2024-11-19-19-11.json new file mode 100644 index 000000000000..ff69da5c18be --- /dev/null +++ b/common/changes/@itwin/frontend-devtools/man-drape-bgmap-onto-realitymesh_2024-11-19-19-11.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@itwin/frontend-devtools", + "comment": "Added ability to drape the background map onto a reality mesh.", + "type": "none" + } + ], + "packageName": "@itwin/frontend-devtools" +} \ No newline at end of file diff --git a/core/common/src/RealityModelDisplaySettings.ts b/core/common/src/RealityModelDisplaySettings.ts index 0a3386e5594e..25ba4b9fbb99 100644 --- a/core/common/src/RealityModelDisplaySettings.ts +++ b/core/common/src/RealityModelDisplaySettings.ts @@ -63,6 +63,14 @@ export interface PointCloudDisplayProps { edlMixWts4?: number; } +/** The JSON representation of [[RealityMeshDisplaySettings]]. + * @beta + */ +export interface RealityMeshDisplayProps { + /** See [[RealityMeshDisplaySettings.bgMapDrape]]. */ + bgMapDrape?: boolean; +} + /** The JSON representation of [[RealityModelDisplaySettings]]. * @beta */ @@ -71,7 +79,8 @@ export interface RealityModelDisplayProps { pointCloud?: PointCloudDisplayProps; /** See [[RealityModelDisplaySettings.overrideColorRatio]]. */ overrideColorRatio?: number; - // ###TODO when we need it: mesh?: RealityMeshDisplayProps; + /** See [[RealityModelDisplaySettings.mesh]]. */ + mesh?: RealityMeshDisplayProps; } /** Settings that control how a point cloud reality model is displayed within a [Viewport]($frontend). @@ -249,6 +258,59 @@ export class PointCloudDisplaySettings { } } +/** Settings that control how a reality mesh model is displayed within a [Viewport]($frontend). + * @note This is an immutable type - to modify its properties, use [[clone]]. + * @see [[RealityModelDisplaySettings.mesh]]. + * @beta + */ +export class RealityMeshDisplaySettings { + /** When true will drape the background map onto the reality mesh. + * Default: "false". + */ + public readonly bgMapDrape: boolean; + + /** Settings with all properties initialized to their default values. */ + public static defaults = new RealityMeshDisplaySettings(); + + private constructor(props?: RealityMeshDisplayProps) { + this.bgMapDrape = props?.bgMapDrape ?? false; + } + + /** Create display settings from their JSON representation. If `props` is `undefined`, the default settings are returned. */ + public static fromJSON(props?: RealityMeshDisplayProps): RealityMeshDisplaySettings { + return props ? new RealityMeshDisplaySettings(props) : this.defaults; + } + + /** Convert these settings to their JSON representation. */ + public toJSON(): RealityMeshDisplayProps | undefined { + const defs = RealityMeshDisplaySettings.defaults; + if (this.equals(defs)) + return undefined; + + const props: RealityMeshDisplayProps = { }; + if (this.bgMapDrape !== defs.bgMapDrape) + props.bgMapDrape = this.bgMapDrape; + + return props; + } + + /** Create a copy of these settings, identical except for any properties explicitly specified by `changedProps`. */ + public clone(changedProps: RealityMeshDisplayProps): RealityMeshDisplaySettings { + return RealityMeshDisplaySettings.fromJSON({ + ...this.toJSON(), + ...changedProps, + }); + } + + /** Returns true if these settings are identical to `other`. */ + public equals(other: RealityMeshDisplaySettings): boolean { + if (this === other) + return true; + + return this.bgMapDrape === other.bgMapDrape; + } +} + /** Settings that control how a reality model - whether a [[ContextRealityModel]] or a persistent reality [Model]($backend) - is displayed within a [Viewport]($frontend). * @see [[ContextRealityModel.displaySettings]] to apply these settings to a context reality model. * @see [[DisplayStyleSettings.setRealityModelDisplaySettings]] to apply these settings to a persistent reality model. @@ -266,13 +328,18 @@ export class RealityModelDisplaySettings { * Default: [[PointCloudDisplaySettings.defaults]]. */ public readonly pointCloud: PointCloudDisplaySettings; + /** Settings that apply specifically to mesh reality models. + * Default: [[RealityMeshDisplaySettings.defaults]]. + */ + public readonly mesh: RealityMeshDisplaySettings; /** Settings with all properties initialized to their default values. */ - public static defaults = new RealityModelDisplaySettings(undefined, PointCloudDisplaySettings.defaults); + public static defaults = new RealityModelDisplaySettings(undefined, PointCloudDisplaySettings.defaults, RealityMeshDisplaySettings.defaults); - private constructor(overrideColorRatio: number | undefined, pointCloud: PointCloudDisplaySettings) { + private constructor(overrideColorRatio: number | undefined, pointCloud: PointCloudDisplaySettings, mesh?: RealityMeshDisplaySettings) { this.overrideColorRatio = overrideColorRatio ?? 0.5; this.pointCloud = pointCloud; + this.mesh = mesh ?? RealityMeshDisplaySettings.defaults; } /** Create display settings from their JSON representation. If `props` is `undefined`, the default settings are returned. */ @@ -280,21 +347,25 @@ export class RealityModelDisplaySettings { if (!props) return this.defaults; - return new RealityModelDisplaySettings(props.overrideColorRatio, PointCloudDisplaySettings.fromJSON(props.pointCloud)); + return new RealityModelDisplaySettings(props.overrideColorRatio, PointCloudDisplaySettings.fromJSON(props.pointCloud), RealityMeshDisplaySettings.fromJSON(props.mesh)); } /** Convert these settings to their JSON representation, which is `undefined` if all of their properties match the default settings. */ public toJSON(): RealityModelDisplayProps | undefined { const pointCloud = this.pointCloud.toJSON(); + const mesh = this.mesh.toJSON(); const overrideColorRatio = this.overrideColorRatio === RealityModelDisplaySettings.defaults.overrideColorRatio ? undefined : this.overrideColorRatio; - if (undefined === pointCloud && undefined === overrideColorRatio) + if (undefined === pointCloud && undefined === mesh && undefined === overrideColorRatio) return undefined; const props: RealityModelDisplayProps = { }; if (undefined !== pointCloud) props.pointCloud = pointCloud; + if (undefined !== mesh) + props.mesh = mesh; + if (undefined !== overrideColorRatio) props.overrideColorRatio = overrideColorRatio; @@ -306,13 +377,14 @@ export class RealityModelDisplaySettings { if (this === other) return true; - return this.overrideColorRatio === other.overrideColorRatio && this.pointCloud.equals(other.pointCloud); + return this.overrideColorRatio === other.overrideColorRatio && this.pointCloud.equals(other.pointCloud) && this.mesh.equals(other.mesh); } /** Create a copy of these settings, identical except for any properties explicitly specified by `changedProps`. */ public clone(changedProps: RealityModelDisplayProps): RealityModelDisplaySettings { const pointCloud = changedProps.pointCloud ? this.pointCloud.clone(changedProps.pointCloud) : this.pointCloud; + const mesh = changedProps.mesh ? this.mesh.clone(changedProps.mesh) : this.mesh; const colorRatio = changedProps.hasOwnProperty("overrideColorRatio") ? changedProps.overrideColorRatio : this.overrideColorRatio; - return new RealityModelDisplaySettings(colorRatio, pointCloud); + return new RealityModelDisplaySettings(colorRatio, pointCloud, mesh); } } diff --git a/core/common/src/test/RealityModelDisplaySettings.test.ts b/core/common/src/test/RealityModelDisplaySettings.test.ts index 1a3c0cecd243..442a413d1600 100644 --- a/core/common/src/test/RealityModelDisplaySettings.test.ts +++ b/core/common/src/test/RealityModelDisplaySettings.test.ts @@ -5,7 +5,7 @@ import { describe, expect, it } from "vitest"; import { - PointCloudDisplayProps, PointCloudDisplaySettings, RealityModelDisplayProps, RealityModelDisplaySettings, + PointCloudDisplayProps, PointCloudDisplaySettings, RealityMeshDisplayProps, RealityMeshDisplaySettings, RealityModelDisplayProps, RealityModelDisplaySettings, } from "../RealityModelDisplaySettings"; describe("PointCloudDisplaySettings", () => { @@ -60,6 +60,46 @@ describe("PointCloudDisplaySettings", () => { }); }); +describe("RealityMeshDisplaySettings", () => { + it("round-trips through JSON", () => { + const roundTrip = (props: RealityMeshDisplayProps | undefined, expected: RealityMeshDisplayProps | undefined | "input") => { + if ("input" === expected) + expected = props; + + const settings = RealityMeshDisplaySettings.fromJSON(props); + const actual = settings.toJSON(); + expect(actual).to.deep.equal(expected); + + const actualSettings = RealityMeshDisplaySettings.fromJSON(actual); + expect(actualSettings.equals(settings)).to.be.true; + expect(actualSettings === RealityMeshDisplaySettings.defaults).to.equal(settings.equals(RealityMeshDisplaySettings.defaults)); + expect(actualSettings === RealityMeshDisplaySettings.defaults).to.equal(undefined === actual); + }; + + roundTrip(undefined, undefined); + roundTrip({ bgMapDrape: false }, undefined); + roundTrip({ bgMapDrape: true }, "input"); + roundTrip({ bgMapDrape: true }, { bgMapDrape: true }); + }); + + it("clones", () => { + const test = (baseProps: RealityMeshDisplayProps | undefined, changedProps: RealityMeshDisplayProps, expected: RealityMeshDisplayProps | undefined | "input") => { + if (expected === "input") + expected = baseProps; + + const baseSettings = RealityMeshDisplaySettings.fromJSON(baseProps); + const clone = baseSettings.clone(changedProps); + const actual = clone.toJSON(); + expect(actual).to.deep.equal(expected); + }; + + test(undefined, { bgMapDrape: false }, "input"); + test({ bgMapDrape: false }, { bgMapDrape: true }, { bgMapDrape: true }); + test({ bgMapDrape: true }, { bgMapDrape: false }, undefined); + test({ bgMapDrape: true }, { bgMapDrape: undefined }, undefined ); + }); +}); + describe("RealityModelDisplaySettings", () => { it("round-trips through JSON", () => { const roundTrip = (props: RealityModelDisplayProps | undefined, expected: RealityModelDisplayProps | undefined | "input") => { @@ -79,7 +119,10 @@ describe("RealityModelDisplaySettings", () => { roundTrip(undefined, undefined); roundTrip({ overrideColorRatio: 0.5 }, undefined); roundTrip({ overrideColorRatio: 0.5, pointCloud: undefined }, undefined); + roundTrip({ overrideColorRatio: 0.5, pointCloud: undefined, mesh: undefined }, undefined); roundTrip({ overrideColorRatio: 0.5, pointCloud: { sizeMode: "voxel", voxelScale: 1, minPixelsPerVoxel: 2, maxPixelsPerVoxel: 20, pixelSize: 1, shape: "round" } }, undefined); + roundTrip({ overrideColorRatio: 0.5, pointCloud: undefined, mesh: { bgMapDrape: false } }, undefined); + roundTrip({ overrideColorRatio: 0.5, pointCloud: { sizeMode: "voxel", voxelScale: 1, minPixelsPerVoxel: 2, maxPixelsPerVoxel: 20, pixelSize: 1, shape: "round" }, mesh: { bgMapDrape: false } }, undefined); roundTrip({ overrideColorRatio: 0.1 }, "input"); roundTrip({ overrideColorRatio: 0 }, "input"); @@ -87,7 +130,8 @@ describe("RealityModelDisplaySettings", () => { roundTrip({ overrideColorRatio: -12.5 }, "input"); roundTrip({ pointCloud: { sizeMode: "pixel", pixelSize: 1, shape: "square" } }, { pointCloud: { sizeMode: "pixel", shape: "square" } }); - roundTrip({ overrideColorRatio: 12.5, pointCloud: { voxelScale: 2 } }, "input"); + roundTrip({ mesh: { bgMapDrape: true } }, { mesh: { bgMapDrape: true } }); + roundTrip({ overrideColorRatio: 12.5, pointCloud: { voxelScale: 2 }, mesh: { bgMapDrape: true } }, "input"); }); it("clones", () => { @@ -108,5 +152,11 @@ describe("RealityModelDisplaySettings", () => { test({ pointCloud: { sizeMode: "pixel" } }, { pointCloud: { pixelSize: 2 } }, { pointCloud: { sizeMode: "pixel", pixelSize: 2 } }); test({ pointCloud: { sizeMode: "pixel" }, overrideColorRatio: 2 }, { pointCloud: { sizeMode: undefined} }, { overrideColorRatio: 2 }); test({ pointCloud: { sizeMode: "pixel" }, overrideColorRatio: 2 }, { pointCloud: { } }, { overrideColorRatio: 2, pointCloud: { sizeMode: "pixel" } }); + test({ mesh: { bgMapDrape: true } }, { mesh: { bgMapDrape: false } }, undefined); + test({ mesh: { bgMapDrape: false } }, { mesh: { bgMapDrape: true } }, { mesh: { bgMapDrape: true } }); + test({ mesh: { bgMapDrape: true } }, { mesh: { } }, "input"); + test({ overrideColorRatio: 2 }, { mesh: { bgMapDrape: true } }, { overrideColorRatio: 2, mesh: { bgMapDrape: true } }); + test({ overrideColorRatio: 2, pointCloud: { sizeMode: "pixel" }, mesh: { bgMapDrape: true } }, { overrideColorRatio: 0.5, pointCloud: { sizeMode: "voxel" }, mesh: { bgMapDrape: false } }, undefined); + test({ overrideColorRatio: 2, pointCloud: { sizeMode: "pixel" }, mesh: { bgMapDrape: false } }, { overrideColorRatio: 1, pointCloud: { sizeMode: "voxel" } }, { overrideColorRatio: 1 }); }); }); diff --git a/core/frontend-devtools/README.md b/core/frontend-devtools/README.md index 5ba5514bb981..082d9f15a1ce 100644 --- a/core/frontend-devtools/README.md +++ b/core/frontend-devtools/README.md @@ -175,6 +175,7 @@ Reality models can be attached to a display style to provide context when that d * `fdt set reality model locatable` - Set the whether a (contextual) reality model can be located. The first argument must be `true`, `false`, `on` or `off`. Second argument if supplied is the reality model index, if not supplied then the the tool applies to all reality models. * `fdt set reality model emphasized` - Set the whether a (contextual) reality model is emphasized. The first argument must be `true`, `false`, `on` or `off`. Second argument if supplied is the reality model index, if not supplied then the the tool applies to all reality models. * `fdt set reality model color` - Set the reality model color. The first three arguments are red, green and blue components in [0,255]. Second argument if supplied is the reality model index, if not supplied then the the tool applies to all reality models. +* `fdt set reality model bgdrape` - Turn on or off draping of the background map onto the reality model (only for meshes). The first argument must be `true`, `false`, `on` or `off`. Second argument if supplied is the reality model index, if not supplied then the the tool applies to all reality models. Note that unlike other commands in this section, if no context reality models exist this command will apply to reality models that are attached to the project as spatial models. * `fdt clear reality model overrides`. Clears the appearance overrides for a (contextual) reality model. First argument if supplied is the reality model index, if not supplied then the the tool applies to all reality models. * `fdt attach reality properties` - Attach a "context" reality model from properties JSON (generally saved from `fdt save reality properties`) * the json properties representing a reality model. These can be created by using the `fdt save reality modelproperties` keyin. diff --git a/core/frontend-devtools/public/locales/en/FrontendDevTools.json b/core/frontend-devtools/public/locales/en/FrontendDevTools.json index e297165a40c1..1fabefc6f5f4 100644 --- a/core/frontend-devtools/public/locales/en/FrontendDevTools.json +++ b/core/frontend-devtools/public/locales/en/FrontendDevTools.json @@ -271,6 +271,9 @@ "SaveRealityModelTool": { "keyin": "fdt save reality properties" }, + "SetRealityModelBackgroundDrapeTool": { + "keyin": "fdt set reality model bgdrape" + }, "SetRealityModelColorTool": { "keyin": "fdt set reality model color" }, diff --git a/core/frontend-devtools/src/FrontEndDevTools.ts b/core/frontend-devtools/src/FrontEndDevTools.ts index de1fa8390764..1bf13aa156df 100644 --- a/core/frontend-devtools/src/FrontEndDevTools.ts +++ b/core/frontend-devtools/src/FrontEndDevTools.ts @@ -53,7 +53,7 @@ import { ChangePlanProjectionSettingsTool, DumpPlanProjectionSettingsTool, Overr import { ToggleProjectExtentsTool } from "./tools/ProjectExtents"; import { AttachCesiumAssetTool, AttachRealityModelTool, ClearRealityModelAppearanceOverrides, DetachRealityModelTool, SaveRealityModelTool, - SetRealityModelColorTool, SetRealityModelEmphasizedTool, SetRealityModelLocateTool, SetRealityModelTransparencyTool, ToggleOSMBuildingDisplay, + SetRealityModelBackgroundDrapeTool, SetRealityModelColorTool, SetRealityModelEmphasizedTool, SetRealityModelLocateTool, SetRealityModelTransparencyTool, ToggleOSMBuildingDisplay, } from "./tools/RealityModelTools"; import { RealityTransitionTool } from "./tools/RealityTransitionTool"; import { CompileShadersTool, LoseWebGLContextTool, ToggleDPIForLODTool } from "./tools/RenderSystemTools"; @@ -217,6 +217,8 @@ export class FrontendDevTools { SetRealityModelLocateTool, SetRealityModelEmphasizedTool, SetRealityModelTransparencyTool, + SetRealityModelTransparencyTool, + SetRealityModelBackgroundDrapeTool, SetRealityModelColorTool, SetModelLocateTool, SetModelEmphasizedTool, diff --git a/core/frontend-devtools/src/tools/RealityModelTools.ts b/core/frontend-devtools/src/tools/RealityModelTools.ts index 6aafa8b528cc..e009950a146c 100644 --- a/core/frontend-devtools/src/tools/RealityModelTools.ts +++ b/core/frontend-devtools/src/tools/RealityModelTools.ts @@ -7,8 +7,8 @@ * @module Tools */ -import { FeatureAppearance, FeatureAppearanceProps, RgbColorProps } from "@itwin/core-common"; -import { getCesiumAssetUrl, IModelApp, NotifyMessageDetails, OutputMessagePriority, Tool, Viewport } from "@itwin/core-frontend"; +import { FeatureAppearance, FeatureAppearanceProps, RealityModelDisplaySettings, RgbColorProps } from "@itwin/core-common"; +import { getCesiumAssetUrl, IModelApp, NotifyMessageDetails, OutputMessagePriority, RealityTreeReference, Tool, Viewport } from "@itwin/core-frontend"; import { copyStringToClipboard } from "../ClipboardUtilities"; import { parseBoolean } from "./parseBoolean"; import { parseToggle } from "./parseToggle"; @@ -211,6 +211,59 @@ export class DetachRealityModelTool extends Tool { } } +/** Set reality model background drape flag. + * @beta + */ +export class SetRealityModelBackgroundDrapeTool extends Tool { + public static override toolId = "SetRealityModelBackgroundDrapeTool"; + public static override get minArgs() { return 1; } + public static override get maxArgs() { return 2; } + + public override async run(bgDrape: boolean, index: number): Promise { + const vp = IModelApp.viewManager.selectedView; + if (vp === undefined) + return false; + + if (vp.displayStyle.settings.contextRealityModels.models.length > 0) { + if (index < 0) { + vp.displayStyle.settings.contextRealityModels.models.forEach((model) => { + model.displaySettings = model.displaySettings.clone({ mesh: {bgMapDrape: bgDrape} }); + }); + } else { + const model = vp.displayStyle.settings.contextRealityModels.models[index]; + if (!model) + return false; + model.displaySettings = model.displaySettings.clone({ mesh: {bgMapDrape: bgDrape} }); + } + } else { + // If there are no context reality models, apply to reality tree references instead. + let count = 0; + vp.forEachTileTreeRef((tree) => { + if (tree instanceof RealityTreeReference) { + if (index < 0 || index >= 0 && index === count) { + const ds = vp.displayStyle.settings.getRealityModelDisplaySettings(tree.modelId); + if (undefined !== ds) { + vp.displayStyle.settings.setRealityModelDisplaySettings(tree.modelId, ds.clone({ mesh: {bgMapDrape: bgDrape} })); + } else { + vp.displayStyle.settings.setRealityModelDisplaySettings(tree.modelId, RealityModelDisplaySettings.defaults.clone({ mesh: {bgMapDrape: bgDrape} })); + } + } + ++count; + } + }); + } + + IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Info, `${appearanceChangedString(index)} set to bgMapDrape: ${bgDrape}`)); + + return true; + } + + public override async parseAndRun(...args: string[]): Promise { + const bgDrape = parseBoolean(args[0]); + return bgDrape === undefined ? false : this.run(bgDrape, args.length > 1 ? parseInt(args[1], 10) : -1); + } +} + /** Set reality model appearance override for color in display style. * @beta */ @@ -250,11 +303,17 @@ export class ClearRealityModelAppearanceOverrides extends Tool { if (!vp) return false; - const model = vp.displayStyle.settings.contextRealityModels.models[index]; - if (!model) - return false; + if (index < 0) { + vp.displayStyle.settings.contextRealityModels.models.forEach((model) => { + model.appearanceOverrides = undefined; + }); + } else { + const model = vp.displayStyle.settings.contextRealityModels.models[index]; + if (!model) + return false; + model.appearanceOverrides = undefined; + } - model.appearanceOverrides = undefined; return true; } diff --git a/core/frontend/src/render/webgl/glsl/PlanarClassification.ts b/core/frontend/src/render/webgl/glsl/PlanarClassification.ts index 3e27919ac290..d8adf69d120f 100644 --- a/core/frontend/src/render/webgl/glsl/PlanarClassification.ts +++ b/core/frontend/src/render/webgl/glsl/PlanarClassification.ts @@ -105,9 +105,8 @@ if (doMask) { if (kClassifierDisplay_Off == param) { discard; return vec4(0); -} -` - ; + } +`; // Currently we discard if classifier is pure black (acts as clipping mask). // These could be more efficiently handled with masks. diff --git a/core/frontend/src/render/webgl/glsl/RealityMesh.ts b/core/frontend/src/render/webgl/glsl/RealityMesh.ts index c8fb953d1d29..1177add63b6f 100644 --- a/core/frontend/src/render/webgl/glsl/RealityMesh.ts +++ b/core/frontend/src/render/webgl/glsl/RealityMesh.ts @@ -201,7 +201,7 @@ function baseColorFromTextures(textureCount: number, applyFeatureColor: string) const applyTextureStrings = []; for (let i = 0; i < textureCount; i++) - applyTextureStrings.push(`if (applyTexture(col, s_texture${i}, u_texParams${i}, u_texMatrix${i})) doDiscard = false; `); + applyTextureStrings.push(`if (applyTexture(col, s_texture${i}, u_texParams${i}, u_texMatrix${i})) doDiscard = false;`); return ` if (!u_texturesPresent) { @@ -215,9 +215,7 @@ function baseColorFromTextures(textureCount: number, applyFeatureColor: string) ${applyTextureStrings.join("\n ")} if (doDiscard) discard; - ${applyFeatureColor} - return col; `; } @@ -227,7 +225,7 @@ function baseColorFromTextures(textureCount: number, applyFeatureColor: string) const mixFeatureColor = ` col.rgb = mix(col.rgb, mix(col.rgb, v_color.rgb, u_overrideColorMix), step(0.0, v_color.r)); col.a = mix(col.a, v_color.a, step(0.0, v_color.a)); - `; +`; function addThematicToRealityMesh(builder: ProgramBuilder, gradientTextureUnit: TextureUnit) { addNormalMatrix(builder.vert); diff --git a/core/frontend/src/tile/RealityModelTileTree.ts b/core/frontend/src/tile/RealityModelTileTree.ts index 89fcc29e0d3c..17395702eec7 100644 --- a/core/frontend/src/tile/RealityModelTileTree.ts +++ b/core/frontend/src/tile/RealityModelTileTree.ts @@ -865,7 +865,8 @@ export class RealityTreeReference extends RealityModelTileTree.Reference { public override addToScene(context: SceneContext): void { const tree = this.treeOwner.tileTree as RealityTileTree; - if (undefined !== tree && context.viewport.iModel.isGeoLocated && (tree.loader as RealityModelTileLoader).doDrapeBackgroundMap) { + const displaySettings = this._getDisplaySettings(); + if (undefined !== tree && context.viewport.iModel.isGeoLocated && ((tree.loader as RealityModelTileLoader).doDrapeBackgroundMap || displaySettings.mesh.bgMapDrape)) { // NB: We save this off strictly so that discloseTileTrees() can find it...better option? this._mapDrapeTree = context.viewport.backgroundDrapeMap; context.addBackgroundDrapedModel(this, undefined);