Skip to content

Commit b22028d

Browse files
committed
Clipping updates
1 parent c74e9d5 commit b22028d

5 files changed

Lines changed: 99 additions & 32 deletions

File tree

src/apps/permits/index.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ import '../../plugins/cesium/ngv-plugin-cesium-slicing';
1818
import '../../plugins/cesium/ngv-plugin-cesium-measure';
1919
import '../../plugins/cesium/ngv-plugin-cesium-navigation';
2020
import '../../plugins/cesium/ngv-plugin-cesium-click-info';
21-
import type {CesiumWidget, DataSourceCollection} from '@cesium/engine';
21+
import type {NgvPluginCesiumSlicing} from '../../plugins/cesium/ngv-plugin-cesium-slicing.js';
2222

23+
import type {CesiumWidget, DataSourceCollection} from '@cesium/engine';
2324
import {PrimitiveCollection} from '@cesium/engine';
25+
import type {Cartesian3} from '@cesium/engine';
2426
import type {ViewerInitializedDetails} from '../../plugins/cesium/ngv-plugin-cesium-widget.js';
2527
import type {INGVCesiumModel} from '../../interfaces/cesium/ingv-layers.js';
2628

@@ -31,6 +33,8 @@ export class NgvAppPermits extends ABaseApp<IPermitsConfig> {
3133
private viewer: CesiumWidget;
3234
@query('.ngv-vertical-menu')
3335
private verticalMenu: {show: () => void};
36+
@query('ngv-plugin-cesium-slicing')
37+
private slicingPlugin: NgvPluginCesiumSlicing;
3438
private uploadedModelsCollection: PrimitiveCollection =
3539
new PrimitiveCollection();
3640
private dataSourceCollection: DataSourceCollection;
@@ -92,12 +96,15 @@ export class NgvAppPermits extends ABaseApp<IPermitsConfig> {
9296
.primitiveCollection="${this.uploadedModelsCollection}"
9397
.tiles3dCollection="${this.collections.tiles3d}"
9498
.storeOptions="${this.storeOptions}"
95-
.options="${{listTitle: 'Uploaded models'}}"
99+
.options="${{listTitle: 'Uploaded models', showEditBtns: true}}"
96100
@chosenModelChanged=${(evt: {detail: INGVCesiumModel}) => {
97101
if (evt.detail) {
98102
this.verticalMenu.show();
99103
}
100104
}}
105+
@modelAddClipping=${(evt: {detail: {positions: Cartesian3[], name: string}}) => {
106+
this.slicingPlugin?.addClippingFromPositions(evt.detail.positions, evt.detail.name);
107+
}}
101108
></ngv-plugin-cesium-model-interact>
102109
103110
<ngv-plugin-cesium-navigation

src/plugins/cesium/interactionHelpers.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,15 +205,18 @@ export function getDimensions(model: Model): {
205205
}
206206
}
207207

208-
export function getClippingPolygon(model: INGVCesiumModel): ClippingPolygon {
209-
const positions = LOCAL_EDGES.map((edge) => {
208+
export function getModelFootprintPositions(model: INGVCesiumModel): Cartesian3[] {
209+
return LOCAL_EDGES.map((edge) => {
210210
const position = new Cartesian3();
211211
const matrix = getTranslationRotationDimensionsMatrix(model);
212212
Matrix4.multiplyByPoint(matrix, edge[0], position);
213213
return position;
214214
});
215+
}
216+
217+
export function getClippingPolygon(model: INGVCesiumModel): ClippingPolygon {
215218
return new ClippingPolygon({
216-
positions,
219+
positions: getModelFootprintPositions(model),
217220
});
218221
}
219222

src/plugins/cesium/ngv-plugin-cesium-model-interact.ts

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,15 @@ import '../ui/ngv-layer-details.js';
3131
import '../ui/ngv-layers-list.js';
3232
import {
3333
applyClippingTo3dTileset,
34+
getModelFootprintPositions,
3435
removeClippingFrom3dTilesets,
3536
updateModelClipping,
3637
} from './interactionHelpers.js';
3738
import type {ControlType} from './controlsHelpers.js';
3839
import type {DragState} from './controlsDragMath.js';
3940
import {applyDrag, startDrag} from './controlsDragMath.js';
4041
import type {INGVCesiumModel} from '../../interfaces/cesium/ingv-layers.js';
41-
import type {ClippingChangeDetail, PositionChangeDetail} from '../ui/ngv-layer-details.js';
42+
import type {PositionChangeDetail} from '../ui/ngv-layer-details.js';
4243
import {Task} from '@lit/task';
4344
import {ControlAxis} from './controlAxis.js';
4445
import type {ControlPickId} from './controlAxis.js';
@@ -50,9 +51,10 @@ export class NgvPluginCesiumModelInteract extends LitElement {
5051
@property({type: Object}) tiles3dCollection: PrimitiveCollection;
5152
@property({type: Object}) dataSourceCollection: DataSourceCollection;
5253
@property({type: Object}) storeOptions?: {localStoreKey: string; indexDbName: string};
53-
@property({type: Object}) options?: {listTitle: string};
54+
@property({type: Object}) options?: {listTitle: string; showEditBtns?: boolean};
5455

5556
@state() private chosenModel: INGVCesiumModel | undefined;
57+
@state() private savedMatrix: Matrix4 | undefined;
5658
@state() private modelPosition: {
5759
longitude: number; latitude: number; height: number;
5860
heading: number; pitch: number; roll: number; scale: number;
@@ -255,19 +257,29 @@ export class NgvPluginCesiumModelInteract extends LitElement {
255257
const model = this.pickModel(evt.position);
256258
if (model) {
257259
if (model !== this.chosenModel) {
258-
this.chosenModel = model;
259-
this.modelPosition = this.extractModelPosition(model);
260-
this.control?.show(model);
261-
this._startContinuousRender();
260+
this.selectModel(model);
262261
}
263262
} else {
264-
this.chosenModel = undefined;
265-
this.modelPosition = undefined;
266-
this.control?.hide();
267-
this._stopContinuousRender();
263+
this.deselectModel();
268264
}
269265
}
270266

267+
private selectModel(model: INGVCesiumModel): void {
268+
this.chosenModel = model;
269+
this.savedMatrix = Matrix4.clone(model.modelMatrix, new Matrix4());
270+
this.modelPosition = this.extractModelPosition(model);
271+
this.control?.show(model);
272+
this._startContinuousRender();
273+
}
274+
275+
private deselectModel(): void {
276+
this.chosenModel = undefined;
277+
this.savedMatrix = undefined;
278+
this.modelPosition = undefined;
279+
this.control?.hide();
280+
this._stopContinuousRender();
281+
}
282+
271283
private _unlistenPostRender: Event.RemoveCallback | undefined;
272284
private _startContinuousRender(): void {
273285
if (this._unlistenPostRender) return;
@@ -338,20 +350,10 @@ export class NgvPluginCesiumModelInteract extends LitElement {
338350
<ngv-layer-details
339351
.layer="${{
340352
name: this.chosenModel.id.name,
341-
clippingOptions: {
342-
terrainClipping: this.chosenModel.id.terrainClipping,
343-
tilesClipping: this.chosenModel.id.tilesClipping,
344-
},
345353
position: this.modelPosition,
346354
}}"
347355
.showDone=${true}
348-
@clippingChange=${(evt: {detail: ClippingChangeDetail}) => {
349-
if (typeof evt.detail.terrainClipping === 'boolean')
350-
this.chosenModel.id.terrainClipping = evt.detail.terrainClipping;
351-
if (typeof evt.detail.tilesClipping === 'boolean')
352-
this.chosenModel.id.tilesClipping = evt.detail.tilesClipping;
353-
updateModelClipping(this.chosenModel, this.tiles3dCollection, this.viewer.scene.globe);
354-
}}
356+
.showCancel=${true}
355357
@positionChange=${(evt: {detail: PositionChangeDetail}) => {
356358
if (!this.chosenModel || !this.modelPosition) return;
357359
const updated = {...this.modelPosition, ...evt.detail};
@@ -378,10 +380,18 @@ export class NgvPluginCesiumModelInteract extends LitElement {
378380
this.viewer.scene.requestRender();
379381
}}
380382
@done="${() => {
381-
this.control?.hide();
382-
this._stopContinuousRender();
383-
this.chosenModel = undefined;
384-
this.modelPosition = undefined;
383+
this.deselectModel();
384+
this.onPrimitivesChanged();
385+
}}"
386+
@cancel="${() => {
387+
if (this.chosenModel && this.savedMatrix) {
388+
Matrix4.clone(this.savedMatrix, this.chosenModel.modelMatrix);
389+
if (this.chosenModel.id.tilesClipping || this.chosenModel.id.terrainClipping) {
390+
updateModelClipping(this.chosenModel, this.tiles3dCollection, this.viewer.scene.globe);
391+
}
392+
this.viewer.scene.requestRender();
393+
}
394+
this.deselectModel();
385395
this.onPrimitivesChanged();
386396
}}"
387397
>
@@ -406,8 +416,21 @@ export class NgvPluginCesiumModelInteract extends LitElement {
406416
${this.options?.listTitle}
407417
</div>
408418
<ngv-layers-list
409-
.options="${{showDeleteBtns: true, showZoomBtns: true}}"
419+
.options="${{showDeleteBtns: true, showZoomBtns: true, showEditBtns: this.options?.showEditBtns, showAddClippingBtns: this.options?.showEditBtns}}"
410420
.layers=${this.models.map((m) => ({name: m.id.name}))}
421+
@addClipping="${(evt: {detail: number}) => {
422+
const model = this.primitiveCollection.get(evt.detail) as INGVCesiumModel;
423+
if (!model) return;
424+
const positions = getModelFootprintPositions(model);
425+
this.dispatchEvent(new CustomEvent('modelAddClipping', {
426+
detail: {positions, name: model.id.name},
427+
bubbles: true, composed: true,
428+
}));
429+
}}"
430+
@edit="${(evt: {detail: number}) => {
431+
const model = this.primitiveCollection.get(evt.detail) as INGVCesiumModel;
432+
if (model) this.selectModel(model);
433+
}}"
411434
@remove="${(evt: {detail: number}) => {
412435
const model = this.primitiveCollection.get(evt.detail) as INGVCesiumModel;
413436
if (model) this.primitiveCollection.remove(model);

src/plugins/cesium/ngv-plugin-cesium-slicing.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import {
2020
} from '@cesium/engine';
2121
import '../ui/ngv-layer-details.js';
2222
import '../ui/ngv-layers-list.js';
23-
import type {ClippingChangeDetail} from '../ui/ngv-layer-details.js';
2423
import type {DrawEndDetails} from './draw.js';
2524
import {CesiumDraw} from './draw.js';
2625
import {msg} from '@lit/localize';
@@ -29,6 +28,7 @@ import {getStoredClipping, updateClippingInLocalStore} from './localStore.js';
2928
import type {IngvCesiumContext} from '../../interfaces/cesium/ingv-cesium-context.js';
3029
import {Task} from '@lit/task';
3130
import {classMap} from 'lit/directives/class-map.js';
31+
import type {ClippingChangeDetail} from '../ui/ngv-layer-details.js';
3232

3333
export type ClippingData = {
3434
clipping: ClippingPolygon;
@@ -184,6 +184,7 @@ export class NgvPluginCesiumSlicing extends LitElement {
184184
`Polygon ${date.toLocaleDateString()} ${date.toLocaleTimeString()}`,
185185
show: false,
186186
polygon: {
187+
perPositionHeight: true,
187188
hierarchy: positions || [],
188189
material: Color.RED.withAlpha(0.7),
189190
},
@@ -199,6 +200,26 @@ export class NgvPluginCesiumSlicing extends LitElement {
199200
this.activePolygon = this.drawPolygon();
200201
}
201202

203+
addClippingFromPositions(positions: Cartesian3[], name: string): void {
204+
const entity = this.drawPolygon(positions, name);
205+
entity.polygon.hierarchy = new ConstantProperty(new PolygonHierarchy(positions));
206+
const clippingPolygon = new ClippingPolygon({positions});
207+
const clippingData: ClippingData = {clipping: clippingPolygon, entity};
208+
this.clippingPolygons = [...this.clippingPolygons, clippingData];
209+
this.saveToLocalStore();
210+
// open in edit mode
211+
this.editingClipping = clippingData;
212+
this.removeClipping(clippingData.clipping);
213+
this.draw.type = 'polygon';
214+
this.activePolygon = clippingData.entity;
215+
this.draw.entityForEdit = this.drawDataSource.entities.add(
216+
new Entity({polygon: clippingData.entity.polygon.clone()}),
217+
);
218+
this.draw.active = true;
219+
this.active = true;
220+
this.requestUpdate();
221+
}
222+
202223
applyClipping(clippingData: ClippingData): void {
203224
if (!this.viewer.scene.globe.clippingPolygons) {
204225
this.viewer.scene.globe.clippingPolygons =
@@ -353,8 +374,10 @@ export class NgvPluginCesiumSlicing extends LitElement {
353374
});
354375
this.applyClipping(this.editingClipping);
355376
this.activePolygon = undefined;
377+
this.editingClipping = undefined;
356378
this.draw.active = false;
357379
this.draw.clear();
380+
this.draw.entityForEdit = undefined;
358381
this.requestUpdate();
359382
this.saveToLocalStore();
360383
} else {

src/plugins/ui/ngv-layers-list.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export type LayerListOptions = {
1212
showDeleteBtnCallback?: (index: number) => boolean;
1313
showZoomBtns?: boolean;
1414
showEditBtns?: boolean;
15+
showAddClippingBtns?: boolean;
1516
};
1617

1718
@customElement('ngv-layers-list')
@@ -48,6 +49,16 @@ export class NgvLayersList extends LitElement {
4849
: ''}
4950
<span class="ngv-layers-list-title">${l.name}</span>
5051
<div class="ngv-layers-list-item-actions">
52+
${this.options?.showAddClippingBtns
53+
? html`<wa-icon-button
54+
src="../../../icons/slice.svg"
55+
size="small"
56+
title="Add clipping"
57+
@click=${() => {
58+
this.dispatchEvent(new CustomEvent('addClipping', {detail: i}));
59+
}}
60+
></wa-icon-button>`
61+
: ''}
5162
${this.options?.showEditBtns
5263
? html`<wa-icon-button
5364
name="pencil"

0 commit comments

Comments
 (0)