-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
CVAT-3D - Part1 #3738
CVAT-3D - Part1 #3738
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,11 +67,14 @@ export interface ShapeProperties { | |
outlineColor: string; | ||
selectedOpacity: number; | ||
colorBy: string; | ||
resetZoom: boolean; | ||
canvasBackgroundColor: string; | ||
} | ||
|
||
export enum UpdateReasons { | ||
IMAGE_CHANGED = 'image_changed', | ||
OBJECTS_UPDATED = 'objects_updated', | ||
UPDATE_CANVAS_BACKGROUND = 'update_canvas_background', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not see any notifications with |
||
DRAW = 'draw', | ||
SELECT = 'select', | ||
CANCEL = 'cancel', | ||
|
@@ -80,6 +83,7 @@ export enum UpdateReasons { | |
SHAPE_ACTIVATED = 'shape_activated', | ||
GROUP = 'group', | ||
FITTED_CANVAS = 'fitted_canvas', | ||
UPDATE_OPACITY = 'update_opacity', | ||
} | ||
|
||
export enum Mode { | ||
|
@@ -172,6 +176,8 @@ export class Canvas3dModelImpl extends MasterImpl implements Canvas3dModel { | |
outlineColor: '#000000', | ||
selectedOpacity: 60, | ||
colorBy: 'Label', | ||
resetZoom: true, | ||
canvasBackgroundColor: '#000000', | ||
}, | ||
}; | ||
} | ||
|
@@ -324,13 +330,18 @@ export class Canvas3dModelImpl extends MasterImpl implements Canvas3dModel { | |
} | ||
|
||
public configureShapes(shapeProperties: ShapeProperties): void { | ||
const { opacity, selectedOpacity } = this.data.shapeProperties; | ||
this.data.drawData.enabled = false; | ||
this.data.mode = Mode.IDLE; | ||
this.cancel(); | ||
this.data.shapeProperties = { | ||
...shapeProperties, | ||
}; | ||
this.notify(UpdateReasons.OBJECTS_UPDATED); | ||
if (opacity !== shapeProperties.opacity || selectedOpacity !== shapeProperties.selectedOpacity) { | ||
this.notify(UpdateReasons.UPDATE_OPACITY); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need separated notify for opacity? |
||
} else { | ||
this.notify(UpdateReasons.OBJECTS_UPDATED); | ||
} | ||
} | ||
|
||
public fit(): void { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -204,6 +204,16 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { | |
const canvasSideView = this.views.side.renderer.domElement; | ||
const canvasFrontView = this.views.front.renderer.domElement; | ||
|
||
canvasPerspectiveView.addEventListener('mouseleave', (event: MouseEvent): void => { | ||
if (this.mode === Mode.DRAW) { | ||
event.preventDefault(); | ||
this.cancelDraw(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need stop drawing when mouse gets out of the canvas? |
||
this.setHelperVisibility(false); | ||
this.mode = Mode.IDLE; | ||
this.dispatchEvent(new CustomEvent('canvas.canceled')); | ||
} | ||
}); | ||
|
||
canvasPerspectiveView.addEventListener('contextmenu', (e: MouseEvent): void => { | ||
if (this.controller.focused.clientID !== null) { | ||
this.dispatchEvent( | ||
|
@@ -448,12 +458,6 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { | |
viewType.controls.mouseButtons.right = CameraControls.ACTION.NONE; | ||
} else { | ||
viewType.controls = new CameraControls(viewType.camera, viewType.renderer.domElement); | ||
viewType.controls.mouseButtons.left = CameraControls.ACTION.NONE; | ||
viewType.controls.mouseButtons.right = CameraControls.ACTION.NONE; | ||
viewType.controls.mouseButtons.wheel = CameraControls.ACTION.NONE; | ||
viewType.controls.touches.one = CameraControls.ACTION.NONE; | ||
viewType.controls.touches.two = CameraControls.ACTION.NONE; | ||
viewType.controls.touches.three = CameraControls.ACTION.NONE; | ||
} | ||
viewType.controls.minDistance = CONST.MIN_DISTANCE; | ||
viewType.controls.maxDistance = CONST.MAX_DISTANCE; | ||
|
@@ -479,7 +483,7 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { | |
{ passive: false }, | ||
); | ||
}); | ||
|
||
this.dispatchEvent(new CustomEvent('canvas.settings')); | ||
model.subscribe(this); | ||
} | ||
|
||
|
@@ -750,12 +754,27 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { | |
return cuboid; | ||
} | ||
|
||
private setupObjects(): void { | ||
private setupObjects(selected?: boolean): void { | ||
const { clientID } = this.model.data.activeElement; | ||
if (this.views.perspective.scene.children[0]) { | ||
this.clearSceneObjects(); | ||
if (!selected) { | ||
this.clearSceneObjects(); | ||
} | ||
this.resetColor(); | ||
this.setHelperVisibility(false); | ||
for (let i = 0; i < this.model.data.objects.length; i++) { | ||
const object = this.model.data.objects[i]; | ||
if (selected) { | ||
const target = this.views.perspective.scene.getObjectByName(clientID); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If target is const, than line: ```this.views.perspective.scene.children[0].remove(target);`` tries to remove the same element a lot of times. |
||
if (`${object.clientID}` !== clientID) { | ||
continue; | ||
} else { | ||
this.views.perspective.scene.children[0].remove(target); | ||
this.views.side.scene.children[0].children = []; | ||
this.views.front.scene.children[0].children = []; | ||
this.views.top.scene.children[0].children = []; | ||
Comment on lines
+773
to
+775
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to clear side/front/top scenes a lot of times if only one object can be there at the same time? |
||
} | ||
} | ||
this.setupObject(object, true); | ||
} | ||
this.action.loading = false; | ||
|
@@ -773,6 +792,14 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { | |
this.views.perspective.renderer.domElement.dispatchEvent(event); | ||
} | ||
|
||
private cancelDraw(): void { | ||
this.controller.drawData.enabled = false; | ||
this.controller.drawData.redraw = undefined; | ||
Object.keys(this.views).forEach((view: string): void => { | ||
this.views[view as keyof Views].scene.children[0].remove(this.cube[view as keyof Views]); | ||
}); | ||
} | ||
|
||
public notify(model: Canvas3dModel & Master, reason: UpdateReasons): void { | ||
if (reason === UpdateReasons.IMAGE_CHANGED) { | ||
if (!model.data.image) return; | ||
|
@@ -789,9 +816,21 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { | |
loader.load(objectURL, this.addScene.bind(this)); | ||
URL.revokeObjectURL(objectURL); | ||
this.dispatchEvent(new CustomEvent('canvas.setup')); | ||
} else if (reason === UpdateReasons.UPDATE_CANVAS_BACKGROUND) { | ||
const { canvasBackgroundColor } = this.model.data.shapeProperties; | ||
this.views.top.scene.background = new THREE.Color(canvasBackgroundColor); | ||
this.views.perspective.scene.background = new THREE.Color(canvasBackgroundColor); | ||
this.views.side.scene.background = new THREE.Color(canvasBackgroundColor); | ||
this.views.front.scene.background = new THREE.Color(canvasBackgroundColor); | ||
Comment on lines
+820
to
+824
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you try to test this code? |
||
} else if (reason === UpdateReasons.UPDATE_OPACITY) { | ||
this.resetColor(); | ||
} else if (reason === UpdateReasons.SHAPE_ACTIVATED) { | ||
const { clientID } = this.model.data.activeElement; | ||
this.setupObjects(); | ||
if (clientID !== 'null') { | ||
this.setupObjects(true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to pass the argument here (based on |
||
} else { | ||
this.setupObjects(); | ||
} | ||
if (clientID !== 'null') { | ||
this.setDefaultZoom(); | ||
} | ||
|
@@ -820,34 +859,14 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { | |
}), | ||
); | ||
this.model.data.activeElement.clientID = 'null'; | ||
if (this.model.mode === Mode.DRAG_CANVAS) { | ||
const { controls } = this.views.perspective; | ||
controls.mouseButtons.left = CameraControls.ACTION.ROTATE; | ||
controls.mouseButtons.right = CameraControls.ACTION.TRUCK; | ||
controls.mouseButtons.wheel = CameraControls.ACTION.DOLLY; | ||
controls.touches.one = CameraControls.ACTION.TOUCH_ROTATE; | ||
controls.touches.two = CameraControls.ACTION.TOUCH_DOLLY_TRUCK; | ||
controls.touches.three = CameraControls.ACTION.TOUCH_TRUCK; | ||
} | ||
this.setupObjects(); | ||
} else if (reason === UpdateReasons.CANCEL) { | ||
if (this.mode === Mode.DRAW) { | ||
this.controller.drawData.enabled = false; | ||
this.controller.drawData.redraw = undefined; | ||
Object.keys(this.views).forEach((view: string): void => { | ||
this.views[view as keyof Views].scene.children[0].remove(this.cube[view as keyof Views]); | ||
}); | ||
this.cancelDraw(); | ||
} | ||
this.model.data.groupData.grouped = []; | ||
this.setHelperVisibility(false); | ||
this.model.mode = Mode.IDLE; | ||
const { controls } = this.views.perspective; | ||
controls.mouseButtons.left = CameraControls.ACTION.NONE; | ||
controls.mouseButtons.right = CameraControls.ACTION.NONE; | ||
controls.mouseButtons.wheel = CameraControls.ACTION.NONE; | ||
controls.touches.one = CameraControls.ACTION.NONE; | ||
controls.touches.two = CameraControls.ACTION.NONE; | ||
controls.touches.three = CameraControls.ACTION.NONE; | ||
this.dispatchEvent(new CustomEvent('canvas.canceled')); | ||
} else if (reason === UpdateReasons.FITTED_CANVAS) { | ||
this.dispatchEvent(new CustomEvent('canvas.fit')); | ||
|
@@ -1154,7 +1173,6 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { | |
return; | ||
} | ||
if (!this.action.selectable) return; | ||
this.resetColor(); | ||
const object = this.views.perspective.scene.getObjectByName(clientID); | ||
if (object === undefined) return; | ||
this.model.data.focusData.clientID = clientID; | ||
|
@@ -1168,18 +1186,23 @@ export class Canvas3dViewImpl implements Canvas3dView, Listener { | |
}), | ||
); | ||
} else if (this.model.data.focusData.clientID !== null) { | ||
this.resetColor(); | ||
this.model.data.focusData.clientID = null; | ||
} | ||
} | ||
}; | ||
|
||
private resetColor(): void { | ||
const { opacity, selectedOpacity } = this.model.data.shapeProperties; | ||
this.model.data.objects.forEach((object: any): void => { | ||
const { clientID } = object; | ||
const target = this.views.perspective.scene.getObjectByName(String(clientID)); | ||
if (target) { | ||
((target as THREE.Mesh).material as THREE.MeshBasicMaterial).color.set((target as any).originalColor); | ||
if (this.model.data.activeElement.clientID === String(clientID)) { | ||
((target as THREE.Mesh).material as THREE.MeshBasicMaterial).opacity = selectedOpacity / 100; | ||
} else { | ||
((target as THREE.Mesh).material as THREE.MeshBasicMaterial).opacity = opacity / 100; | ||
} | ||
} | ||
}); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,6 +55,8 @@ interface Props { | |
automaticBordering: boolean; | ||
showObjectsTextAlways: boolean; | ||
frame: number; | ||
resetZoom : boolean; | ||
canvasBackgroundColor: string; | ||
} | ||
|
||
interface ViewSize { | ||
|
@@ -188,6 +190,8 @@ const CanvasWrapperComponent = (props: Props): ReactElement => { | |
onShapeDrawn, | ||
onCreateAnnotations, | ||
frameFetching, | ||
resetZoom, | ||
canvasBackgroundColor, | ||
} = props; | ||
const { canvasInstance } = props as { canvasInstance: Canvas3d }; | ||
|
||
|
@@ -374,7 +378,7 @@ const CanvasWrapperComponent = (props: Props): ReactElement => { | |
|
||
useEffect(() => { | ||
updateShapesView(); | ||
}, [opacity, outlined, outlineColor, selectedOpacity, colorBy]); | ||
}, [opacity, outlined, outlineColor, selectedOpacity, colorBy, resetZoom, canvasBackgroundColor]); | ||
|
||
useEffect(() => { | ||
const canvasInstanceDOM = canvasInstance.html() as ViewsDOM; | ||
|
@@ -386,6 +390,7 @@ const CanvasWrapperComponent = (props: Props): ReactElement => { | |
canvasInstanceDOM.perspective.addEventListener('click', onCanvasClick); | ||
canvasInstanceDOM.perspective.addEventListener('canvas.fit', onResize); | ||
canvasInstanceDOM.perspective.addEventListener('canvas.groupped', onCanvasObjectsGroupped); | ||
canvasInstanceDOM.perspective.addEventListener('canvas.settings', onCanvasShapeDrawn); | ||
window.addEventListener('resize', onResize); | ||
|
||
return () => { | ||
|
@@ -396,6 +401,7 @@ const CanvasWrapperComponent = (props: Props): ReactElement => { | |
canvasInstanceDOM.perspective.removeEventListener('click', onCanvasClick); | ||
canvasInstanceDOM.perspective.removeEventListener('canvas.fit', onResize); | ||
canvasInstanceDOM.perspective.removeEventListener('canvas.groupped', onCanvasObjectsGroupped); | ||
canvasInstanceDOM.perspective.removeEventListener('canvas.settings', onCanvasShapeDrawn); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to call |
||
window.removeEventListener('resize', onResize); | ||
}; | ||
}, [frameData, annotations, activeLabelID, contextMenuVisibility]); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand how
opacity
,outlined
,colorBy
relates to shapes. But I don't really understand whyresetZoom
andcanvasBackgroundColor
are shape properties.