Skip to content

Commit

Permalink
feat: add angle measurement
Browse files Browse the repository at this point in the history
  • Loading branch information
agviegas committed May 20, 2024
1 parent 5a96f9c commit 70a57c9
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 105 deletions.
20 changes: 2 additions & 18 deletions packages/core/src/utils/vertex-picker.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
import * as THREE from "three";
import {
Component,
Components,
Event,
Raycasters,
World,
Disposable,
} from "../core";
import { Component, Components, Event, Raycasters, World } from "../core";

export interface VertexPickerConfig {
showOnlyVertex: boolean;
snapDistance: number;
previewElement: HTMLElement;
}

export class VertexPicker extends Component implements Disposable {
export class VertexPicker extends Component {
onVertexFound = new Event<THREE.Vector3>();
onVertexLost = new Event<THREE.Vector3>();

Expand All @@ -28,9 +21,6 @@ export class VertexPicker extends Component implements Disposable {

private _workingPlane: THREE.Plane | null = null;

/** {@link Disposable.onDisposed} */
readonly onDisposed = new Event();

set enabled(value: boolean) {
this._enabled = value;
if (!value) {
Expand All @@ -53,10 +43,6 @@ export class VertexPicker extends Component implements Disposable {
this.enabled = false;
}

[Symbol.dispose](): void {
throw new Error("Method not implemented.");
}

set workingPlane(plane: THREE.Plane | null) {
this._workingPlane = plane;
}
Expand All @@ -77,8 +63,6 @@ export class VertexPicker extends Component implements Disposable {
this.onVertexFound.reset();
this.onVertexLost.reset();
(this.components as any) = null;
this.onDisposed.trigger();
this.onDisposed.reset();
}

get(world: World) {
Expand Down
5 changes: 3 additions & 2 deletions packages/front/src/core/Marker/src/mark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ export class Mark implements OBC.Hideable, OBC.Disposable {
marker = element;
} else {
marker = document.createElement("div");
marker.className =
"w-[15px] h-[15px] border-3 border-solid border-red-600";
marker.style.width = "15px";
marker.style.height = "15px";
marker.style.border = "5px solid red";
}

this.three = new CSS2DObject(marker);
Expand Down
2 changes: 0 additions & 2 deletions packages/front/src/fragments/Highlighter/example.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// Set up scene (see SimpleScene tutorial)

/* eslint import/no-extraneous-dependencies: 0 */

import Stats from "stats.js";
Expand Down
3 changes: 2 additions & 1 deletion packages/front/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./civil";
export * from "./core";
export * from "./measurement";
export * from "./fragments";
export * from "./civil";
export * from "./utils";
27 changes: 1 addition & 26 deletions packages/front/src/measurement/AngleMeasurement/example.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,9 @@
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>Angle Measurement</title>
<title>Fragment Highlighter</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;
Expand Down
84 changes: 35 additions & 49 deletions packages/front/src/measurement/AngleMeasurement/example.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,36 @@
// Set up scene (see SimpleScene tutorial)
/* eslint import/no-extraneous-dependencies: 0 */

import * as THREE from "three";
import Stats from "stats.js";
import * as OBC from "../..";
// @ts-ignore
import * as dat from "three/examples/jsm/libs/lil-gui.module.min";
import * as OBC from "@thatopen/components";
import * as THREE from "three";
import * as OBCF from "../..";

const container = document.getElementById("container")!;

const components = new OBC.Components();

const sceneComponent = new OBC.SimpleScene(components);
sceneComponent.setup();
components.scene = sceneComponent;

const rendererComponent = new OBC.PostproductionRenderer(components, container);
components.renderer = rendererComponent;
const worlds = components.get(OBC.Worlds);

const cameraComponent = new OBC.SimpleCamera(components);
components.camera = cameraComponent;
const world = worlds.create<
OBC.SimpleScene,
OBC.SimpleCamera,
OBCF.PostproductionRenderer
>();

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

components.init();

const scene = components.scene.get();
world.camera.controls.setLookAt(5, 5, 5, 0, 0, 0);

cameraComponent.controls.setLookAt(10, 10, 10, 0, 0, 0);
world.scene.setup();

const directionalLight = new THREE.DirectionalLight();
directionalLight.position.set(5, 10, 3);
directionalLight.intensity = 0.5;
scene.add(directionalLight);

const ambientLight = new THREE.AmbientLight();
ambientLight.intensity = 0.5;
scene.add(ambientLight);

// @ts-ignore
const grid = new OBC.SimpleGrid(components);
const grids = components.get(OBC.Grids);
grids.create(world);

/* MD
### 📏 Dimensions Tool
Expand Down Expand Up @@ -70,10 +64,10 @@ cube.position.set(0, 1.5, 0);
/* MD
Now, we will add the Cube to the `Scene`. We must also add the **cube** to `components.meshes`,
which is simply an array of all the meshes in the Scene.🗄️
*/
*/

scene.add(cube);
components.meshes.add(cube);
world.scene.three.add(cube);
world.meshes.add(cube);

/* MD
Expand All @@ -92,7 +86,8 @@ components.meshes.add(cube);
and you only need to write a few lines for creating the Dimension Tool.💪
*/

const dimensions = new OBC.AngleMeasurement(components);
const angles = components.get(OBCF.AngleMeasurement);
angles.world = world;

/* MD
We will build dimensions by supplying the `components` to **OBC.SimpleDimensions**.
Expand All @@ -109,7 +104,7 @@ const dimensions = new OBC.AngleMeasurement(components);
*/

dimensions.enabled = true;
angles.enabled = true;

/* MD
### 🖱️ Managing Events
Expand All @@ -125,7 +120,7 @@ dimensions.enabled = true;
*/

container.ondblclick = () => dimensions.create();
container.ondblclick = () => angles.create();

/* MD
Expand All @@ -146,25 +141,16 @@ container.ondblclick = () => dimensions.create();

window.onkeydown = (event) => {
if (event.code === "Delete" || event.code === "Backspace") {
dimensions.delete();
angles.delete();
}
};

/* MD
### ⏏️ Creating a Toolbar for the Dimensions
---
We'll make a **Toolbar Component** and set it at the bottom.
In addition, we will have a button that allows you to toggle the dimension tool.
*/

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

/* MD
Expand Down Expand Up @@ -216,8 +202,8 @@ const stats = new Stats();
stats.showPanel(2);
document.body.append(stats.dom);
stats.dom.style.left = "0px";
rendererComponent.onBeforeUpdate.add(() => stats.begin());
rendererComponent.onAfterUpdate.add(() => stats.end());
world.renderer.onBeforeUpdate.add(() => stats.begin());
world.renderer.onAfterUpdate.add(() => stats.end());

// Set up dat.gui menu

Expand Down
7 changes: 5 additions & 2 deletions packages/front/src/measurement/AngleMeasurement/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import * as THREE from "three";
import * as OBC from "@thatopen/components";
import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";
import { AngleMeasureElement } from "./src";
import { GraphicVertexPicker } from "../../utils";

// TODO: Make appearance customizable?

export class AngleMeasurement
extends OBC.Component
Expand All @@ -19,7 +22,7 @@ export class AngleMeasurement

private _enabled = false;

private _vertexPicker: OBC.VertexPicker;
private _vertexPicker: GraphicVertexPicker;

private _currentAngleElement: AngleMeasureElement | null = null;

Expand Down Expand Up @@ -59,7 +62,7 @@ export class AngleMeasurement
constructor(components: OBC.Components) {
super(components);
this.components.add(AngleMeasurement.uuid, this);
this._vertexPicker = new OBC.VertexPicker(components);
this._vertexPicker = new GraphicVertexPicker(components);
this._lineMaterial = new LineMaterial({
color: 0x6528d7,
linewidth: 2,
Expand Down
9 changes: 6 additions & 3 deletions packages/front/src/measurement/AngleMeasurement/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as OBC from "@thatopen/components";
import { LineGeometry } from "three/examples/jsm/lines/LineGeometry.js";
import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";
import { Line2 } from "three/examples/jsm/lines/Line2.js";
import { DimensionLabelClassName } from "../../SimpleDimensionLine";
import { Mark } from "../../../core";

interface Angle {
Expand Down Expand Up @@ -67,9 +66,13 @@ export class AngleMeasureElement implements OBC.Hideable, OBC.Disposable {
this.world = world;

const htmlText = document.createElement("div");
htmlText.className = DimensionLabelClassName;
htmlText.style.backgroundColor = "black";
htmlText.style.color = "white";
htmlText.style.padding = "8px";
htmlText.style.borderRadius = "8px";
htmlText.style.fontFamily = "sans-serif";
this._labelMarker = new Mark(world, htmlText);
this.labelMarker.visible = false;
this.labelMarker.visible = true;

this.onPointAdded.add(() => {
if (this.points.length === 1) world.scene.three.add(this._line);
Expand Down
3 changes: 1 addition & 2 deletions packages/front/src/measurement/SimpleDimensionLine/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as THREE from "three";

/** The name of the CSS class that styles the dimension label. */
export const DimensionLabelClassName =
"text-white text-sm bg-ifcjs-100 rounded-md px-3 py-1";
export const DimensionLabelClassName = "that-open-dimension-label";

/** The name of the CSS class that styles the dimension label. */
export const DimensionPreviewClassName =
Expand Down
44 changes: 44 additions & 0 deletions packages/front/src/utils/graphic-vertex-picker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as THREE from "three";
import * as OBC from "@thatopen/components";
import { Mark } from "../core";

// TODO: Make a component?

export class GraphicVertexPicker
extends OBC.VertexPicker
implements OBC.Disposable
{
/** {@link Disposable.onDisposed} */
readonly onDisposed = new OBC.Event();

marker: Mark | null = null;

dispose() {
if (this.marker) {
this.marker.dispose();
}
this.onDisposed.trigger();
this.onDisposed.reset();
}

get(world: OBC.World) {
const found = super.get(world) as THREE.Vector3 | null;

if (found) {
if (!this.marker) {
this.marker = new Mark(world);
}
if (this.marker.world !== world) {
this.marker.world = world;
this.marker.three.removeFromParent();
world.scene.three.add(this.marker.three);
}
this.marker.visible = true;
this.marker.three.position.copy(found);
} else if (this.marker) {
this.marker.visible = false;
}

return found;
}
}
1 change: 1 addition & 0 deletions packages/front/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./graphic-vertex-picker";

0 comments on commit 70a57c9

Please sign in to comment.