Skip to content

Commit

Permalink
feat: smart measurement tools (#284)
Browse files Browse the repository at this point in the history
* Implement volume measurement

* Start working on edge measurement

* Progress with face measurement

* Choose right face for measuring

* Implement face selection delete

* Make visibility toggleable

* Make area measure persistable

* Make volume area marker

* Fix face measure materials

* Start tool to create edge measures

* Finish first version of edge measurements

* Implement disposal

* Rebuild examples

* Fix example grid color

* Update examples

* Fix face index 0 raycast bug
  • Loading branch information
agviegas authored Jan 30, 2024
1 parent bac8bfd commit ae100d0
Show file tree
Hide file tree
Showing 18 changed files with 5,239 additions and 2,929 deletions.
6,639 changes: 3,736 additions & 2,903 deletions resources/openbim-components.js

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion src/fragments/FragmentBoundingBox/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,15 @@ export class FragmentBoundingBox extends Component<void> implements Disposable {

const indices = Array.from(mesh.geometry.index.array);

for (const index of indices) {
for (let i = 0; i < indices.length; i++) {
if (i % 3 === 0) {
if (indices[i] === 0 && indices[i + 1] === 0 && indices[i + 2] === 0) {
i += 2;
continue;
}
}

const index = indices[i];
const x = position.getX(index);
const y = position.getY(index);
const z = position.getZ(index);
Expand Down
4 changes: 3 additions & 1 deletion src/fragments/FragmentHighlighter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ export class FragmentHighlighter
for (let i = 0; i < keys.length; i++) {
const fragKey = keys[i];
const fragID = group.keyFragments[fragKey];
if (fragID === mesh.uuid) continue;
const fragment = fragments.list[fragID];
fragList.push(fragment);
if (!this.selection[name][fragID]) {
Expand Down Expand Up @@ -343,6 +344,7 @@ export class FragmentHighlighter
}

readonly onSetup = new Event<FragmentHighlighter>();

async setup(config?: Partial<FragmentHighlighterConfig>) {
if (config?.selectionMaterial) {
this.config.selectionMaterial.dispose();
Expand All @@ -357,7 +359,7 @@ export class FragmentHighlighter
await this.add(this.config.hoverName, [this.config.hoverMaterial]);
this.setupEvents(true);
this.enabled = true;
this.onSetup.trigger(this);
await this.onSetup.trigger(this);
}

private async regenerate(name: string, fragID: string) {
Expand Down
2 changes: 1 addition & 1 deletion src/measurement/AngleMeasurement/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { LineMaterial } from "three/examples/jsm/lines/LineMaterial";
import { Line2 } from "three/examples/jsm/lines/Line2";
import { Simple2DMarker, Components } from "../../../core";
import { Hideable, Event, Disposable, Component } from "../../../base-types";
import { DimensionLabelClassName } from "../../LengthMeasurement";
import { DimensionLabelClassName } from "../../SimpleDimensionLine";

interface Angle {
points: THREE.Vector3[];
Expand Down
4 changes: 2 additions & 2 deletions src/measurement/AreaMeasurement/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Hideable, Event, Disposable, Component } from "../../../base-types";
import {
DimensionLabelClassName,
SimpleDimensionLine,
} from "../../LengthMeasurement";
} from "../../SimpleDimensionLine";

interface Area {
points: THREE.Vector3[];
Expand Down Expand Up @@ -78,7 +78,7 @@ export class AreaMeasureElement
if (this.points.length === 3) return;
this.points.splice(index, 1);
const { previousLine, nextLine } = this.getLinesBetweenIndex(index);
if (nextLine) previousLine.endPoint = nextLine.end;
if (nextLine) previousLine.endPoint = nextLine.endPoint;
nextLine?.dispose();
this._dimensionLines.splice(index, 1);
this.onPointRemoved.trigger();
Expand Down
131 changes: 131 additions & 0 deletions src/measurement/EdgeMeasurement/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="../../../resources/styles.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="icon" type="image/x-icon" href="../../../resources/favicon.ico">
<title>Tools Component</title>
<style>
.ifcjs-dimension-label {
background-color: black;
font-family: sans-serif;
color: white;
padding: 8px;
border-radius: 8px;
pointer-events: all;
transition: background-color 200ms ease-in-out;
}

.ifcjs-dimension-label:hover {
background-color: grey;
}

.ifcjs-dimension-preview {
pointer-events: none;
background-color: #ffffff;
width: 2rem;
height: 2rem;
opacity: 0.3;
padding: 8px;
border-radius: 100%;
}

body {
margin: 0;
padding: 0;
}

.full-screen {
width: 100vw;
height: 100vh;
position: relative;
overflow: hidden;
}
</style>
</head>
<body>
<div class="full-screen" id="container"></div>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/[email protected]/build/three.module.js",
"stats.js/src/Stats.js": "https://unpkg.com/[email protected]/src/Stats.js",
"three/examples/jsm/libs/lil-gui.module.min": "https://unpkg.com/[email protected]/examples/jsm/libs/lil-gui.module.min.js",
"openbim-components": "../../../resources/openbim-components.js"
}
}

</script>
<script type="module">

// Set up scene (see SimpleScene tutorial)

import * as THREE from 'three';
import * as OBC from 'openbim-components';
import Stats from 'stats.js/src/Stats.js';

const container = document.getElementById('container');

const components = new OBC.Components();

components.scene = new OBC.SimpleScene(components);
components.renderer = new OBC.PostproductionRenderer(components, container);
components.camera = new OBC.SimpleCamera(components);
components.raycaster = new OBC.SimpleRaycaster(components);

components.init();

components.renderer.postproduction.enabled = true;

const scene = components.scene.get();

components.camera.controls.setLookAt(10, 10, 10, 0, 0, 0);
components.scene.setup();

const grid = new OBC.SimpleGrid(components, new THREE.Color(0x666666));
const effects = components.renderer.postproduction.customEffects;
effects.excludedMeshes.push(grid.get());

const dimensions = new OBC.EdgeMeasurement(components);

let fragments = new OBC.FragmentManager(components);
const file = await fetch('../../../resources/small.frag');
const data = await file.arrayBuffer();
const buffer = new Uint8Array(data);
fragments.load(buffer);

let saved;
window.addEventListener('keydown', (event) => {
if (event.code === 'KeyO') {
dimensions.delete();
} else if (event.code === 'KeyS') {
saved = dimensions.get();
dimensions.deleteAll();
} else if (event.code === 'KeyL') {
if (saved) {
dimensions.set(saved);
}
}
});

const mainToolbar = new OBC.Toolbar(components, { name: 'Main Toolbar', position: 'bottom' });
mainToolbar.addChild(dimensions.uiElement.get('main'));
components.ui.addToolbar(mainToolbar);

// Set up stats

const stats = new Stats();
stats.showPanel(2);
document.body.append(stats.dom);
stats.dom.style.left = '0px';
const renderer = components.renderer;
renderer.onBeforeUpdate.add(() => stats.begin());
renderer.onAfterUpdate.add(() => stats.end());

</script>
</body>
</html>
Loading

0 comments on commit ae100d0

Please sign in to comment.