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

feat(react-components): Add NextClippingCommand to the clip tool #4641

Merged
merged 5 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { type VisualDomainObject } from '../../base/domainObjects/VisualDomainOb
import { SetClipTypeCommand } from './commands/SetClipTypeCommand';
import { PlaneCreator } from '../primitives/plane/PlaneCreator';
import { SliceDomainObject } from './SliceDomainObject';
import { NextClippingCommand } from './commands/NextClippingCommand';

export class ClipTool extends PrimitiveEditTool {
// ==================================================
Expand Down Expand Up @@ -47,6 +48,7 @@ export class ClipTool extends PrimitiveEditTool {
new SetClipTypeCommand(PrimitiveType.Box),
undefined, // Separator
new ApplyClipCommand(),
new NextClippingCommand(),
new ShowClippingOnTopCommand(),
new ShowAllClippingCommand()
];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*!
* Copyright 2024 Cognite AS
*/

import { RenderTargetCommand } from '../../../base/commands/RenderTargetCommand';
import { type DomainObject } from '../../../base/domainObjects/DomainObject';
import { type TranslateKey } from '../../../base/utilities/TranslateKey';
import { CropBoxDomainObject } from '../CropBoxDomainObject';
import { SliceDomainObject } from '../SliceDomainObject';
import { ApplyClipCommand } from './ApplyClipCommand';

export class NextClippingCommand extends RenderTargetCommand {
// ==================================================
// OVERRIDES
// ==================================================

public override get tooltip(): TranslateKey {
return {
key: 'CLIP_NEXT',
fallback: 'Set the next crop box or slicing plane as global clipping'
};
}

public override get icon(): string {
return 'ArrowRight';
}

public override get isEnabled(): boolean {
if (!this.renderTarget.isGlobalClippingActive) {
return false;
}
// Require at least two crop boxes or one crop box and one slice
let count = 0;
for (const domainObject of this.rootDomainObject.getDescendants()) {
if (domainObject instanceof CropBoxDomainObject) {
count++;
}
}
if (this.rootDomainObject.getDescendantByType(SliceDomainObject) !== undefined) {
count++;
}
return count >= 2;
}

protected override invokeCore(): boolean {
nilscognite marked this conversation as resolved.
Show resolved Hide resolved
// This code treat the slicing planes as one single group, along with all the crop boxes.
// The next selected crop box or slicing planes will be used as clipping.
const { renderTarget } = this;

const selectedSlice = this.rootDomainObject.getSelectedDescendantByType(SliceDomainObject);
if (selectedSlice !== undefined) {
// If any slice is selected, use the first crop box as clipping
selectedSlice.setSelectedInteractive(false);
const cropBox = this.rootDomainObject.getDescendantByType(CropBoxDomainObject);
if (cropBox !== undefined) {
cropBox.setSelectedInteractive(true);
cropBox.setThisAsGlobalCropBox();
renderTarget.fitView();
return true;
}
}
// Build the array of crop boxes and at least one slice
const array: DomainObject[] = [];
let haveSlice = false;
let selectedIndex: number | undefined;
for (const domainObject of this.rootDomainObject.getDescendants()) {
if (domainObject instanceof CropBoxDomainObject) {
if (domainObject.isSelected) {
selectedIndex = array.length;
}
array.push(domainObject);
} else if (!haveSlice && domainObject instanceof SliceDomainObject) {
if (domainObject.isSelected) {
selectedIndex = array.length;
}
array.push(domainObject);
haveSlice = true;
}
}
if (array.length <= 1 || selectedIndex === undefined) {
return false;
}
// Turn all selection off
for (let i = 0; i < array.length; i++) {
const domainObject = array[i];
domainObject.setSelectedInteractive(false);
}
// Select the next crop box or slicing planes and use it as clipping
selectedIndex = (selectedIndex + 1) % array.length;
for (let i = 0; i < array.length; i++) {
const domainObject = array[i];
if (i !== selectedIndex) {
continue;
}
domainObject.setSelectedInteractive(true);
if (domainObject instanceof CropBoxDomainObject) {
domainObject.setThisAsGlobalCropBox();
} else {
ApplyClipCommand.setClippingPlanes(this.rootDomainObject);
}
renderTarget.fitView();
break;
}
return true;
}
}
Loading