@@ -54,7 +54,8 @@ class ShapeCreatorModel extends Listener {
54
54
}
55
55
56
56
// FIXME: In the future we have to make some generic solution
57
- if ( this . _defaultMode === 'interpolation' && [ 'box' , 'points' ] . includes ( this . _defaultType ) ) {
57
+ if ( this . _defaultMode === 'interpolation'
58
+ && [ 'box' , 'points' , 'box_by_4_points' ] . includes ( this . _defaultType ) ) {
58
59
data . shapes = [ ] ;
59
60
data . shapes . push ( Object . assign ( { } , result , data ) ) ;
60
61
this . _shapeCollection . add ( data , `interpolation_${ this . _defaultType } ` ) ;
@@ -125,7 +126,7 @@ class ShapeCreatorModel extends Listener {
125
126
}
126
127
127
128
set defaultType ( type ) {
128
- if ( ! [ 'box' , 'points' , 'polygon' , 'polyline' ] . includes ( type ) ) {
129
+ if ( ! [ 'box' , 'box_by_4_points' , ' points', 'polygon' , 'polyline' ] . includes ( type ) ) {
129
130
throw Error ( `Unknown shape type found ${ type } ` ) ;
130
131
}
131
132
this . _defaultType = type ;
@@ -234,8 +235,8 @@ class ShapeCreatorView {
234
235
// FIXME: In the future we have to make some generic solution
235
236
const mode = this . _modeSelector . prop ( 'value' ) ;
236
237
const type = $ ( e . target ) . prop ( 'value' ) ;
237
- if ( type !== 'box' && ! ( type === 'points' && this . _polyShapeSize === 1 )
238
- && mode !== 'annotation' ) {
238
+ if ( type !== 'box' && type !== 'box_by_4_points'
239
+ && ! ( type === 'points' && this . _polyShapeSize === 1 ) && mode !== 'annotation' ) {
239
240
this . _modeSelector . prop ( 'value' , 'annotation' ) ;
240
241
this . _controller . setDefaultShapeMode ( 'annotation' ) ;
241
242
showMessage ( 'Only the annotation mode allowed for the shape' ) ;
@@ -252,7 +253,7 @@ class ShapeCreatorView {
252
253
const mode = $ ( e . target ) . prop ( 'value' ) ;
253
254
const type = this . _typeSelector . prop ( 'value' ) ;
254
255
if ( mode !== 'annotation' && ! ( type === 'points' && this . _polyShapeSize === 1 )
255
- && type !== 'box' ) {
256
+ && type !== 'box' && type !== 'box_by_4_points' ) {
256
257
this . _typeSelector . prop ( 'value' , 'box' ) ;
257
258
this . _controller . setDefaultShapeType ( 'box' ) ;
258
259
showMessage ( 'Only boxes and single point allowed in the interpolation mode' ) ;
@@ -492,7 +493,7 @@ class ShapeCreatorView {
492
493
ytl,
493
494
xbr,
494
495
ybr,
495
- }
496
+ } ;
496
497
497
498
if ( this . _mode === 'interpolation' ) {
498
499
box . outside = false ;
@@ -511,6 +512,67 @@ class ShapeCreatorView {
511
512
}
512
513
} ) ;
513
514
break ;
515
+ case 'box_by_4_points' :
516
+ let numberOfPoints = 0 ;
517
+ this . _drawInstance = this . _frameContent . polyline ( ) . draw ( { snapToGrid : 0.1 } )
518
+ . addClass ( 'shapeCreation' ) . attr ( {
519
+ 'stroke-width' : 0 ,
520
+ } ) . on ( 'drawstart' , ( ) => {
521
+ // init numberOfPoints as one on drawstart
522
+ numberOfPoints = 1 ;
523
+ } ) . on ( 'drawpoint' , ( e ) => {
524
+ // increase numberOfPoints by one on drawpoint
525
+ numberOfPoints += 1 ;
526
+
527
+ // finish if numberOfPoints are exactly four
528
+ if ( numberOfPoints === 4 ) {
529
+ let actualPoints = window . cvat . translate . points . canvasToActual ( e . target . getAttribute ( 'points' ) ) ;
530
+ actualPoints = PolyShapeModel . convertStringToNumberArray ( actualPoints ) ;
531
+ const { frameWidth, frameHeight } = window . cvat . player . geometry ;
532
+
533
+ // init bounding box
534
+ const box = {
535
+ 'xtl' : frameWidth ,
536
+ 'ytl' : frameHeight ,
537
+ 'xbr' : 0 ,
538
+ 'ybr' : 0
539
+ } ;
540
+
541
+ for ( const point of actualPoints ) {
542
+ // clamp point
543
+ point . x = Math . clamp ( point . x , 0 , frameWidth ) ;
544
+ point . y = Math . clamp ( point . y , 0 , frameHeight ) ;
545
+
546
+ // update bounding box
547
+ box . xtl = Math . min ( point . x , box . xtl ) ;
548
+ box . ytl = Math . min ( point . y , box . ytl ) ;
549
+ box . xbr = Math . max ( point . x , box . xbr ) ;
550
+ box . ybr = Math . max ( point . y , box . ybr ) ;
551
+ }
552
+
553
+ if ( ( box . ybr - box . ytl ) * ( box . xbr - box . xtl ) >= AREA_TRESHOLD ) {
554
+ if ( this . _mode === 'interpolation' ) {
555
+ box . outside = false ;
556
+ }
557
+ // finish drawing
558
+ this . _controller . finish ( box , this . _type ) ;
559
+ }
560
+ this . _controller . switchCreateMode ( true ) ;
561
+ }
562
+ } ) . on ( 'undopoint' , ( ) => {
563
+ if ( numberOfPoints > 0 ) {
564
+ numberOfPoints -= 1 ;
565
+ }
566
+ } ) . off ( 'drawdone' ) . on ( 'drawdone' , ( ) => {
567
+ if ( numberOfPoints !== 4 ) {
568
+ showMessage ( 'Click exactly four extreme points for an object' ) ;
569
+ this . _controller . switchCreateMode ( true ) ;
570
+ } else {
571
+ throw Error ( 'numberOfPoints is exactly four, but box drawing did not finish.' ) ;
572
+ }
573
+ } ) ;
574
+ this . _createPolyEvents ( ) ;
575
+ break ;
514
576
case 'points' :
515
577
this . _drawInstance = this . _frameContent . polyline ( ) . draw ( { snapToGrid : 0.1 } )
516
578
. addClass ( 'shapeCreation' ) . attr ( {
0 commit comments