Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to drape the background map onto reality meshes. #7401

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions common/api/core-common.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
Expand Down
14 changes: 14 additions & 0 deletions common/api/frontend-devtools.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<boolean>;
// (undocumented)
run(bgDrape: boolean, index: number): Promise<boolean>;
// (undocumented)
static toolId: string;
}

// @beta
export class SetRealityModelColorTool extends Tool {
// (undocumented)
Expand Down
2 changes: 2 additions & 0 deletions common/api/summary/core-common.exports.csv
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions common/api/summary/frontend-devtools.exports.csv
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
}
Original file line number Diff line number Diff line change
@@ -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"
}
Original file line number Diff line number Diff line change
@@ -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"
}
86 changes: 79 additions & 7 deletions core/common/src/RealityModelDisplaySettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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).
Expand Down Expand Up @@ -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.
Expand All @@ -266,35 +328,44 @@ 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. */
public static fromJSON(props?: RealityModelDisplayProps): 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;

Expand All @@ -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);
}
}
54 changes: 52 additions & 2 deletions core/common/src/test/RealityModelDisplaySettings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand Down Expand Up @@ -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") => {
Expand All @@ -79,15 +119,19 @@ 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");
roundTrip({ overrideColorRatio: 1 }, "input");
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", () => {
Expand All @@ -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 });
});
});
1 change: 1 addition & 0 deletions core/frontend-devtools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@
"SaveRealityModelTool": {
"keyin": "fdt save reality properties"
},
"SetRealityModelBackgroundDrapeTool": {
"keyin": "fdt set reality model bgdrape"
},
"SetRealityModelColorTool": {
"keyin": "fdt set reality model color"
},
Expand Down
4 changes: 3 additions & 1 deletion core/frontend-devtools/src/FrontEndDevTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -217,6 +217,8 @@ export class FrontendDevTools {
SetRealityModelLocateTool,
SetRealityModelEmphasizedTool,
SetRealityModelTransparencyTool,
SetRealityModelTransparencyTool,
SetRealityModelBackgroundDrapeTool,
SetRealityModelColorTool,
SetModelLocateTool,
SetModelEmphasizedTool,
Expand Down
Loading
Loading