Context menu options for cuboids (#1554)

main
Dmitry Kalinin 6 years ago committed by GitHub
parent d1b2960b3d
commit c4e769d5cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,4 @@
<svg width="1em" height="1em" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M213 32L240 64H220V192H240L212.5 224L185 192H205V64H185L213 32Z" fill="black"/>
<path d="M32 64L33.1578 56.5899L24.5 55.2371V64H32ZM32 192H24.5V200.628L33.0444 199.427L32 192ZM160 174L161.044 181.427L167.5 180.519V174H160ZM160 84H167.5V77.5809L161.158 76.5899L160 84ZM24.5 64V192H39.5V64H24.5ZM33.0444 199.427L161.044 181.427L158.956 166.573L30.9556 184.573L33.0444 199.427ZM161.158 76.5899L33.1578 56.5899L30.8422 71.4101L158.842 91.4101L161.158 76.5899ZM167.5 174V84H152.5V174H167.5Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 658 B

@ -29,6 +29,7 @@ import {
NextIcon,
BackgroundIcon,
ForegroundIcon,
ResetPerspectiveIcon,
} from 'icons';
import { ObjectType, ShapeType } from 'reducers/interfaces';
import { clamp } from 'utils/math';
@ -38,6 +39,7 @@ function ItemMenu(
serverID: number | undefined,
locked: boolean,
objectType: ObjectType,
shapeType: ShapeType,
copyShortcut: string,
pasteShortcut: string,
propagateShortcut: string,
@ -50,6 +52,8 @@ function ItemMenu(
createURL: (() => void),
toBackground: (() => void),
toForeground: (() => void),
switchCuboidOrientation: (() => void),
resetCuboidPerspective: (() => void),
): JSX.Element {
return (
<Menu className='cvat-object-item-menu'>
@ -72,7 +76,22 @@ function ItemMenu(
</Button>
</Tooltip>
</Menu.Item>
{ objectType !== ObjectType.TAG && (
{shapeType === ShapeType.CUBOID && (
<Menu.Item>
<Button type='link' icon='retweet' onClick={switchCuboidOrientation}>
Switch orientation
</Button>
</Menu.Item>
)}
{shapeType === ShapeType.CUBOID && (
<Menu.Item>
<Button type='link' onClick={resetCuboidPerspective}>
<Icon component={ResetPerspectiveIcon}/>
Reset perspective
</Button>
</Menu.Item>
)}
{objectType !== ObjectType.TAG && (
<Menu.Item>
<Tooltip title={`${toBackgroundShortcut}`}>
<Button type='link' onClick={toBackground}>
@ -82,7 +101,7 @@ function ItemMenu(
</Tooltip>
</Menu.Item>
)}
{ objectType !== ObjectType.TAG && (
{objectType !== ObjectType.TAG && (
<Menu.Item>
<Tooltip title={`${toForegroundShortcut}`}>
<Button type='link' onClick={toForeground}>
@ -125,6 +144,7 @@ interface ItemTopComponentProps {
labelID: number;
labels: any[];
objectType: ObjectType;
shapeType: ShapeType;
type: string;
locked: boolean;
copyShortcut: string;
@ -140,6 +160,8 @@ interface ItemTopComponentProps {
createURL(): void;
toBackground(): void;
toForeground(): void;
switchCuboidOrientation(): void;
resetCuboidPerspective(): void;
}
function ItemTopComponent(props: ItemTopComponentProps): JSX.Element {
@ -149,6 +171,7 @@ function ItemTopComponent(props: ItemTopComponentProps): JSX.Element {
labelID,
labels,
objectType,
shapeType,
type,
locked,
copyShortcut,
@ -164,6 +187,8 @@ function ItemTopComponent(props: ItemTopComponentProps): JSX.Element {
createURL,
toBackground,
toForeground,
switchCuboidOrientation,
resetCuboidPerspective,
} = props;
return (
@ -191,6 +216,7 @@ function ItemTopComponent(props: ItemTopComponentProps): JSX.Element {
serverID,
locked,
objectType,
shapeType,
copyShortcut,
pasteShortcut,
propagateShortcut,
@ -203,6 +229,8 @@ function ItemTopComponent(props: ItemTopComponentProps): JSX.Element {
createURL,
toBackground,
toForeground,
switchCuboidOrientation,
resetCuboidPerspective,
)}
>
<Icon type='more' />
@ -727,6 +755,8 @@ interface Props {
changeAttribute(attrID: number, value: string): void;
changeColor(color: string): void;
collapse(): void;
switchCuboidOrientation(): void;
resetCuboidPerspective(): void;
}
function objectItemsAreEqual(prevProps: Props, nextProps: Props): boolean {
@ -804,6 +834,8 @@ function ObjectItemComponent(props: Props): JSX.Element {
changeAttribute,
changeColor,
collapse,
switchCuboidOrientation,
resetCuboidPerspective,
} = props;
const type = objectType === ObjectType.TAG ? ObjectType.TAG.toUpperCase()
@ -842,6 +874,7 @@ function ObjectItemComponent(props: Props): JSX.Element {
labels={labels}
objectType={objectType}
type={type}
shapeType={shapeType}
locked={locked}
copyShortcut={normalizedKeyMap.COPY_SHAPE}
pasteShortcut={normalizedKeyMap.PASTE_SHAPE}
@ -856,6 +889,8 @@ function ObjectItemComponent(props: Props): JSX.Element {
createURL={createURL}
toBackground={toBackground}
toForeground={toForeground}
switchCuboidOrientation={switchCuboidOrientation}
resetCuboidPerspective={resetCuboidPerspective}
/>
<ItemButtons
shapeType={shapeType}

@ -25,6 +25,8 @@ import {
import ObjectStateItemComponent from 'components/annotation-page/standard-workspace/objects-side-bar/object-item';
import {shift} from 'utils/math';
interface OwnProps {
clientID: number;
}
@ -404,6 +406,53 @@ class ObjectItemContainer extends React.PureComponent<Props> {
}
}
private switchCuboidOrientation = (): void => {
function cuboidOrientationIsLeft(points: number[]): boolean {
return points[12] > points[0];
}
const {objectState} = this.props;
this.resetCuboidPerspective(false);
objectState.points = shift(objectState.points,
cuboidOrientationIsLeft(objectState.points) ? 4 : -4);
this.commit();
}
private resetCuboidPerspective = (commit: boolean = true): void => {
function cuboidOrientationIsLeft(points: number[]): boolean {
return points[12] > points[0];
}
const {objectState} = this.props;
const {points} = objectState;
const minD = {
x: (points[6] - points[2])*0.001,
y: (points[3] - points[1])*0.001,
}
if (cuboidOrientationIsLeft(points)) {
points[14] = points[10] + points[2] - points[6] + minD.x;
points[15] = points[11] + points[3] - points[7];
points[8] = points[10] + points[4] - points[6];
points[9] = points[11] + points[5] - points[7] + minD.y;
points[12] = points[14] + points[0] - points[2];
points[13] = points[15] + points[1] - points[3] + minD.y;
} else {
points[10] = points[14] + points[6] - points[2] - minD.x;
points[11] = points[15] + points[7] - points[3];
points[12] = points[14] + points[0] - points[2];
points[13] = points[15] + points[1] - points[3] + minD.y;
points[8] = points[12] + points[4] - points[0] - minD.x;
points[9] = points[13] + points[5] - points[1];
}
objectState.points = points;
if (commit) this.commit();
}
private commit(): void {
const {
objectState,
@ -507,6 +556,8 @@ class ObjectItemContainer extends React.PureComponent<Props> {
changeLabel={this.changeLabel}
changeAttribute={this.changeAttribute}
collapse={this.collapse}
switchCuboidOrientation={this.switchCuboidOrientation}
resetCuboidPerspective={() => this.resetCuboidPerspective()}
/>
);
}

@ -40,6 +40,7 @@ import SVGObjectInsideIcon from './assets/object-inside-icon.svg';
import SVGBackgroundIcon from './assets/background-icon.svg';
import SVGForegroundIcon from './assets/foreground-icon.svg';
import SVGCubeIcon from './assets/cube-icon.svg';
import SVGResetPerspectiveIcon from './assets/reset-perspective.svg';
export const CVATLogo = React.memo(
(): JSX.Element => <SVGCVATLogo />,
@ -149,3 +150,6 @@ export const ForegroundIcon = React.memo(
export const CubeIcon = React.memo(
(): JSX.Element => <SVGCubeIcon />,
);
export const ResetPerspectiveIcon = React.memo(
(): JSX.Element => <SVGResetPerspectiveIcon />,
);

@ -2,3 +2,11 @@
export function clamp(value: number, min: number, max: number): number {
return Math.max(Math.min(value, max), min);
}
export function shift<T>(array: Array<T>, k: number): Array<T> {
if (k % array.length !== 0) {
return array.slice(k % array.length).concat(array.slice(0,k % array.length));
} else {
return array;
}
}
Loading…
Cancel
Save