-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
190 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { demo } from "../../demo"; | ||
import { MeasureDemoHost } from "../../hosts/measure"; | ||
|
||
/** Here goes code demo code that you can see in the playground */ | ||
import parametricMeasure from "./parametric_measure.ts?raw"; | ||
|
||
export const measure = { | ||
...demo("measure", "parametric_measure", "Parametric Measure", parametricMeasure, MeasureDemoHost, {}, "Measure API can be used to fetch parametric data based on real world position, and calculate measurements between 2 objects."), | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { View } from "@novorender/api"; | ||
// import { type MeasureEntity } from "@novorender/api/types/measure"; | ||
|
||
// we export this function to our react component which will then execute it once the demo started running. | ||
export function showTip() { | ||
return openAlert( | ||
"Click to select parametric object, parametric data will be shown in an alert dialog. Select another object and the measurement data between the objects will be shown in the alert dialog. Clicking further objects will alternate between first and second selected and show measure values within an alert dialog." | ||
); | ||
} | ||
|
||
export async function main(view: View, canvas: HTMLCanvasElement) { | ||
const measureView = await view.measure; | ||
|
||
// Parametric entities used to measure between | ||
// @todo - implement interface `MeasureEntity` | ||
let measureEntity1: any | undefined = undefined; | ||
let measureEntity2: any | undefined = undefined; | ||
|
||
// number to alternate between selected entities. | ||
let selectEntity: 1 | 2 = 1; | ||
|
||
canvas.onclick = async (e: MouseEvent) => { | ||
const result = await view.pick(e.offsetX, e.offsetY); | ||
if (result) { | ||
const { objectId, position } = result; | ||
|
||
if (selectEntity === 1) { | ||
// Find measure entity at pick location | ||
measureEntity1 = (await measureView.core.pickMeasureEntity(objectId, position)).entity; | ||
selectEntity = 2; | ||
} else { | ||
// Find measure entity at pick location | ||
measureEntity2 = (await measureView.core.pickMeasureEntity(objectId, position)).entity; | ||
selectEntity = 1; | ||
} | ||
// As long as one object is selected log out the values | ||
// Note that if measureEntity2 is undefined then the result will be the parametric values of measureEntity1 | ||
if (measureEntity1) { | ||
const _log = await measureView.core.measure(measureEntity1, measureEntity2); | ||
openInfoPane(_log); | ||
} | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { createAPI, type SceneData } from "@novorender/data-js-api"; | ||
import { View } from "@novorender/api"; | ||
import { IDemoContext, IDemoHost, IModule } from "../demo"; | ||
|
||
type Args = [View: View, canvas: HTMLCanvasElement]; | ||
type Ret = void; | ||
type Module = IModule<Ret, Args>; | ||
|
||
export class MeasureDemoHost implements IDemoHost<Module> { | ||
private readonly view: View; | ||
private sceneData!: SceneData; | ||
|
||
constructor(readonly context: IDemoContext) { | ||
const { | ||
canvasElements: { primaryCanvas: canvas }, | ||
deviceProfile, | ||
imports, | ||
} = this.context; | ||
this.view = new View(canvas, deviceProfile, imports); | ||
} | ||
|
||
async run(): Promise<void> { | ||
const { view } = this; | ||
await this.loadScene(); | ||
await view.run(); | ||
view.dispose(); | ||
} | ||
|
||
async loadScene() { | ||
const { view } = this; | ||
|
||
// Initialize the data API with the Novorender data server service | ||
const dataApi = createAPI({ | ||
serviceUrl: "https://data.novorender.com/api", | ||
}); | ||
|
||
try { | ||
// Load scene metadata | ||
// Condos scene ID, but can be changed to any public scene ID | ||
const sceneData = await dataApi.loadScene("95a89d20dd084d9486e383e131242c4c"); | ||
|
||
console.log("sceneData ", sceneData); | ||
|
||
this.sceneData = sceneData as SceneData; | ||
|
||
// Destructure relevant properties into variables | ||
const { url, db } = sceneData as SceneData; | ||
// load the scene using URL gotten from `sceneData` | ||
const config = await view.loadSceneFromURL(new URL(url)); | ||
const { center, radius } = config.boundingSphere; | ||
view.activeController.autoFit(center, radius); | ||
} catch (error) { | ||
console.log("Error while loading scene from URL ", error); | ||
} | ||
} | ||
|
||
updateModule(module: Module) { | ||
// TODO: verify module shape first | ||
module.main(this.view, this.context.canvasElements.primaryCanvas); | ||
} | ||
|
||
exit(): void { | ||
this.view?.exit(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
--- | ||
title: "Parametric measure" | ||
description: "Fetch parametric data based on real world position, and calculate measurements between 2 objects using Web API's Measure module." | ||
keywords: ["novorender api docs", "web api", "measure module", "parametric measure"] | ||
--- | ||
|
||
import { snippets } from "@site/demo-snippets/index"; | ||
|
||
TODO - add correct links to mentioned functions | ||
|
||
Web API's Measure module can be used to fetch parametric data based on real world position, and calculate measurements between 2 objects | ||
|
||
### Measure entity | ||
|
||
A measure entity refers to a part of a parametric object, for example the inner or outer cylinder of a pipe. | ||
A measure entity can also be a single point, this is usually used if no parametric object exists at a clicked location. | ||
|
||
The normal way of getting measure entities is to used the <code>[pickMeasureEntity()](/docs/web_api/Classes/class.View#pickmeasureentity)</code> function on the <code>[measure view](/docs/web_api/Classes/class.View#measure)</code> object. This will use world coordinates and <code>[objectId](/docs/web_api/Interfaces/interface.PickSample#objectid)</code> to find the closest edge surface or point. It will return the picked point if no parametric data is found near the input point. <code>[objectId](/docs/web_api/Interfaces/interface.PickSample#objectid)</code> and <code>[position](/docs/web_api/Interfaces/interface.PickSample#position)</code> can be used from the <code>[pick](/docs/web_api/Classes/class.View#pick)</code> function on <code>[view](/docs/web_api/Classes/class.View)</code> | ||
|
||
```typescript | ||
const view = new View(canvas, deviceProfile, imports); | ||
const result = await view.pick(x, y); | ||
|
||
if (result) { | ||
const entity = await measureView.core.pickMeasureEntity(objectId, position); | ||
} | ||
``` | ||
|
||
### Parametric values on entity | ||
|
||
To get the parametric values such as the the radius, and centerline of a cylinder the <code>[measure()](#)</code> | ||
function can be used. This function be be used to get values from a single object by leaving the second argument as undefined. | ||
|
||
```typescript | ||
const measureView = await view.measure; | ||
const measureValues = await measureView.core.measure(entity); | ||
|
||
if (measureValues.kind === "cylinder") { | ||
console.log(`Radius of cylinder is: ${measureValues.radius}`); | ||
} | ||
``` | ||
|
||
### Measure against another entity | ||
|
||
A measure between two entities is done by using the <code>[core.measure()](#)</code> function on scene with 2 arguments. | ||
What property the resulting object has will depend on the input arguments. There is also an option parameter | ||
to support additional options such as where a cylinder should measure from | ||
|
||
```typescript | ||
const view = new View(canvas, deviceProfile, imports); | ||
const result1 = await view.pick(x1, y1); | ||
const result2 = await view.pick(x2, y2); | ||
|
||
if (result1 && result2) { | ||
const entity1 = await measureView.core.pickMeasureEntity(result1.objectId, result1.position); | ||
const entity2 = await measureView.core.pickMeasureEntity(result2.objectId, result2.position); | ||
|
||
const measureValues = await measureView.core.measure(entity1, entity1); | ||
|
||
if (measureValues && measureValues.distance) { | ||
console.log(`Distance between objects is: ${measureValues.distance}`); | ||
} | ||
} | ||
``` | ||
|
||
### Demo | ||
|
||
Click to select parametric object, parametric data will be shown in an alert dialog. Select another object and the measurement data between the objects will be shown in the alert dialog. | ||
Clicking further objects will alternate between first and second selected and show measure values within an alert dialog. | ||
|
||
<PlaygroundComponent {...snippets.measure.parametric_measure}></PlaygroundComponent> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.