2011-11-06 18:18:20 +01:00
// Copyright (c) 2011, Thomas Goyne <plorkyeran@aegisub.org>
2007-07-05 06:32:46 +02:00
//
2011-11-06 18:18:20 +01:00
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
2007-07-05 06:32:46 +02:00
//
2011-11-06 18:18:20 +01:00
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2007-07-05 06:32:46 +02:00
//
2009-07-29 07:43:02 +02:00
// Aegisub Project http://www.aegisub.org/
2013-01-04 16:01:50 +01:00
# include "visual_tool_vector_clip.h"
2007-07-05 06:32:46 +02:00
# include "ass_dialogue.h"
2018-04-15 23:59:32 +02:00
# include "compat.h"
2012-10-20 17:07:15 +02:00
# include "include/aegisub/context.h"
2009-07-24 02:08:25 +02:00
# include "libresrc/libresrc.h"
2013-01-07 02:50:09 +01:00
# include "options.h"
2012-10-20 17:07:15 +02:00
# include "selection_controller.h"
2007-07-05 06:32:46 +02:00
2014-04-23 22:53:24 +02:00
# include <libaegisub/make_unique.h>
2013-09-17 20:13:52 +02:00
2013-01-04 16:01:50 +01:00
# include <algorithm>
2013-09-19 00:52:48 +02:00
# include <boost/range/algorithm/copy.hpp>
# include <boost/range/algorithm/set_algorithm.hpp>
2013-01-04 16:01:50 +01:00
# include <wx/toolbar.h>
2022-07-12 00:58:14 +02:00
int BUTTON_ID_BASE = 1300 ;
2007-07-05 08:13:22 +02:00
2011-11-06 18:18:20 +01:00
VisualToolVectorClip : : VisualToolVectorClip ( VideoDisplay * parent , agi : : Context * context )
: VisualTool < VisualToolVectorClipDraggableFeature > ( parent , context )
, spline ( * this )
{
2010-06-30 08:29:14 +02:00
}
2011-11-06 18:18:20 +01:00
void VisualToolVectorClip : : SetToolbar ( wxToolBar * toolBar ) {
this - > toolBar = toolBar ;
2012-01-21 00:42:33 +01:00
2021-03-27 13:09:11 +01:00
toolBar - > AddSeparator ( ) ;
2012-01-21 00:42:33 +01:00
int icon_size = OPT_GET ( " App/Toolbar Icon Size " ) - > GetInt ( ) ;
# define ICON(name) icon_size == 16 ? GETIMAGE(name ## _16) : GETIMAGE(name ## _24)
2022-07-12 00:58:14 +02:00
toolBar - > AddTool ( BUTTON_ID_BASE + VCLIP_DRAG , _ ( " Drag " ) , ICON ( visual_vector_clip_drag ) , _ ( " Drag control points " ) , wxITEM_CHECK ) ;
toolBar - > AddTool ( BUTTON_ID_BASE + VCLIP_LINE , _ ( " Line " ) , ICON ( visual_vector_clip_line ) , _ ( " Appends a line " ) , wxITEM_CHECK ) ;
toolBar - > AddTool ( BUTTON_ID_BASE + VCLIP_BICUBIC , _ ( " Bicubic " ) , ICON ( visual_vector_clip_bicubic ) , _ ( " Appends a bezier bicubic curve " ) , wxITEM_CHECK ) ;
2007-07-07 05:21:52 +02:00
toolBar - > AddSeparator ( ) ;
2022-07-12 00:58:14 +02:00
toolBar - > AddTool ( BUTTON_ID_BASE + VCLIP_CONVERT , _ ( " Convert " ) , ICON ( visual_vector_clip_convert ) , _ ( " Converts a segment between line and bicubic " ) , wxITEM_CHECK ) ;
toolBar - > AddTool ( BUTTON_ID_BASE + VCLIP_INSERT , _ ( " Insert " ) , ICON ( visual_vector_clip_insert ) , _ ( " Inserts a control point " ) , wxITEM_CHECK ) ;
toolBar - > AddTool ( BUTTON_ID_BASE + VCLIP_REMOVE , _ ( " Remove " ) , ICON ( visual_vector_clip_remove ) , _ ( " Removes a control point " ) , wxITEM_CHECK ) ;
2007-07-07 05:21:52 +02:00
toolBar - > AddSeparator ( ) ;
2022-07-12 00:58:14 +02:00
toolBar - > AddTool ( BUTTON_ID_BASE + VCLIP_FREEHAND , _ ( " Freehand " ) , ICON ( visual_vector_clip_freehand ) , _ ( " Draws a freehand shape " ) , wxITEM_CHECK ) ;
toolBar - > AddTool ( BUTTON_ID_BASE + VCLIP_FREEHAND_SMOOTH , _ ( " Freehand smooth " ) , ICON ( visual_vector_clip_freehand_smooth ) , _ ( " Draws a smoothed freehand shape " ) , wxITEM_CHECK ) ;
toolBar - > ToggleTool ( BUTTON_ID_BASE + VCLIP_DRAG , true ) ;
2007-07-07 05:21:52 +02:00
toolBar - > Realize ( ) ;
toolBar - > Show ( true ) ;
2022-07-12 00:58:14 +02:00
toolBar - > Bind ( wxEVT_TOOL , [ = ] ( wxCommandEvent & e ) { SetMode ( ( VisualToolVectorClipMode ) ( e . GetId ( ) - BUTTON_ID_BASE ) ) ; } ) ;
SetMode ( VCLIP_DRAG ) ;
2012-01-21 00:42:33 +01:00
# undef ICON
2007-07-05 06:32:46 +02:00
}
2022-07-12 00:58:14 +02:00
void VisualToolVectorClip : : SetMode ( VisualToolVectorClipMode new_mode ) {
2022-07-12 14:14:44 +02:00
if ( toolBar = = nullptr ) {
throw agi : : InternalError ( " Vector clip toolbar hasn't been set yet! " ) ;
}
2010-06-08 08:09:19 +02:00
// Manually enforce radio behavior as we want one selection in the bar
// rather than one per group
2022-07-12 00:58:14 +02:00
for ( int i = 0 ; i < VCLIP_LAST ; i + + )
toolBar - > ToggleTool ( BUTTON_ID_BASE + i , i = = new_mode ) ;
2010-06-08 08:09:19 +02:00
2011-11-06 18:18:20 +01:00
mode = new_mode ;
2007-07-07 07:51:18 +02:00
}
2022-07-12 14:14:44 +02:00
VisualToolVectorClipMode VisualToolVectorClip : : GetMode ( ) {
return mode ;
}
2007-07-05 06:32:46 +02:00
void VisualToolVectorClip : : Draw ( ) {
2011-11-06 18:18:20 +01:00
if ( ! active_line ) return ;
2010-06-08 08:09:19 +02:00
if ( spline . empty ( ) ) return ;
2007-07-05 06:32:46 +02:00
// Parse vector
2010-06-08 08:09:19 +02:00
std : : vector < int > start ;
std : : vector < int > count ;
2014-06-03 19:07:19 +02:00
auto points = spline . GetPointList ( start , count ) ;
2010-06-08 08:09:19 +02:00
assert ( ! start . empty ( ) ) ;
assert ( ! count . empty ( ) ) ;
2011-11-06 18:18:20 +01:00
2018-04-15 23:59:32 +02:00
// Load colors from options
wxColour line_color = to_wx ( line_color_primary_opt - > GetColor ( ) ) ;
wxColour highlight_color_primary = to_wx ( highlight_color_primary_opt - > GetColor ( ) ) ;
wxColour highlight_color_secondary = to_wx ( highlight_color_secondary_opt - > GetColor ( ) ) ;
float shaded_alpha = static_cast < float > ( shaded_area_alpha_opt - > GetDouble ( ) ) ;
gl . SetLineColour ( line_color , .5f , 2 ) ;
gl . SetFillColour ( * wxBLACK , shaded_alpha ) ;
2011-11-06 18:18:20 +01:00
2013-09-19 00:52:48 +02:00
// draw the shade over clipped out areas and line showing the clip
2011-11-12 02:23:40 +01:00
gl . DrawMultiPolygon ( points , start , count , video_pos , video_res , ! inverse ) ;
2010-06-08 08:09:19 +02:00
2022-07-12 00:58:14 +02:00
if ( mode = = VCLIP_DRAG & & holding & & drag_start & & mouse_pos ) {
2013-09-19 00:52:48 +02:00
// Draw drag-select box
Vector2D top_left = drag_start . Min ( mouse_pos ) ;
Vector2D bottom_right = drag_start . Max ( mouse_pos ) ;
gl . DrawDashedLine ( top_left , Vector2D ( top_left . X ( ) , bottom_right . Y ( ) ) , 6 ) ;
gl . DrawDashedLine ( Vector2D ( top_left . X ( ) , bottom_right . Y ( ) ) , bottom_right , 6 ) ;
gl . DrawDashedLine ( bottom_right , Vector2D ( bottom_right . X ( ) , top_left . Y ( ) ) , 6 ) ;
gl . DrawDashedLine ( Vector2D ( bottom_right . X ( ) , top_left . Y ( ) ) , top_left , 6 ) ;
}
2010-06-08 08:09:19 +02:00
Vector2D pt ;
float t ;
2011-11-06 18:18:20 +01:00
Spline : : iterator highlighted_curve ;
spline . GetClosestParametricPoint ( mouse_pos , highlighted_curve , t , pt ) ;
2010-06-07 09:24:43 +02:00
// Draw highlighted line
2022-07-12 00:58:14 +02:00
if ( ( mode = = VCLIP_CONVERT | | mode = = VCLIP_INSERT ) & & ! active_feature & & points . size ( ) > 2 ) {
2014-06-03 19:07:19 +02:00
auto highlighted_points = spline . GetPointList ( highlighted_curve ) ;
2011-11-06 18:18:20 +01:00
if ( ! highlighted_points . empty ( ) ) {
2018-04-15 23:59:32 +02:00
gl . SetLineColour ( highlight_color_secondary , 1.f , 2 ) ;
2011-11-06 18:18:20 +01:00
gl . DrawLineStrip ( 2 , highlighted_points ) ;
2007-07-08 09:22:09 +02:00
}
}
2007-07-05 06:32:46 +02:00
// Draw lines connecting the bicubic features
2018-04-15 23:59:32 +02:00
gl . SetLineColour ( line_color , 0.9f , 1 ) ;
2012-11-04 04:53:03 +01:00
for ( auto const & curve : spline ) {
if ( curve . type = = SplineCurve : : BICUBIC ) {
gl . DrawDashedLine ( curve . p1 , curve . p2 , 6 ) ;
gl . DrawDashedLine ( curve . p3 , curve . p4 , 6 ) ;
2007-07-05 06:32:46 +02:00
}
}
2007-07-07 08:41:14 +02:00
2014-03-04 05:08:01 +01:00
// Draw features
for ( auto & feature : features ) {
2018-04-15 23:59:32 +02:00
wxColour feature_color = line_color ;
2014-03-04 05:08:01 +01:00
if ( & feature = = active_feature )
2018-04-15 23:59:32 +02:00
feature_color = highlight_color_primary ;
2014-03-04 05:08:01 +01:00
else if ( sel_features . count ( & feature ) )
2018-04-15 23:59:32 +02:00
feature_color = highlight_color_secondary ;
gl . SetFillColour ( feature_color , .6f ) ;
2014-03-04 05:08:01 +01:00
if ( feature . type = = DRAG_SMALL_SQUARE ) {
2018-04-15 23:59:32 +02:00
gl . SetLineColour ( line_color , .5f , 1 ) ;
2014-03-04 05:08:01 +01:00
gl . DrawRectangle ( feature . pos - 3 , feature . pos + 3 ) ;
}
else {
2018-04-15 23:59:32 +02:00
gl . SetLineColour ( feature_color , .5f , 1 ) ;
2014-03-04 05:08:01 +01:00
gl . DrawCircle ( feature . pos , 2.f ) ;
}
}
2007-07-08 09:22:09 +02:00
2007-07-07 08:41:14 +02:00
// Draw preview of inserted line
2022-07-12 00:58:14 +02:00
if ( mode = = VCLIP_LINE | | mode = = VCLIP_BICUBIC ) {
2011-11-06 18:18:20 +01:00
if ( spline . size ( ) & & mouse_pos ) {
2012-11-13 04:36:25 +01:00
auto c0 = std : : find_if ( spline . rbegin ( ) , spline . rend ( ) ,
[ ] ( SplineCurve const & s ) { return s . type = = SplineCurve : : POINT ; } ) ;
2010-06-08 08:09:19 +02:00
SplineCurve * c1 = & spline . back ( ) ;
2011-11-06 18:18:20 +01:00
gl . DrawDashedLine ( mouse_pos , c0 - > p1 , 6 ) ;
gl . DrawDashedLine ( mouse_pos , c1 - > EndPoint ( ) , 6 ) ;
2007-07-07 08:41:14 +02:00
}
}
2012-03-25 06:05:06 +02:00
2007-07-07 10:53:11 +02:00
// Draw preview of insert point
2022-07-12 00:58:14 +02:00
if ( mode = = VCLIP_INSERT )
2011-11-06 18:18:20 +01:00
gl . DrawCircle ( pt , 4 ) ;
2007-07-05 06:32:46 +02:00
}
2014-06-03 19:07:19 +02:00
void VisualToolVectorClip : : MakeFeature ( size_t idx ) {
2014-04-23 22:53:24 +02:00
auto feat = agi : : make_unique < Feature > ( ) ;
2014-06-03 19:07:19 +02:00
feat - > idx = idx ;
2011-11-06 18:18:20 +01:00
2014-06-03 19:07:19 +02:00
auto const & curve = spline [ idx ] ;
if ( curve . type = = SplineCurve : : POINT ) {
feat - > pos = curve . p1 ;
2013-09-17 20:13:52 +02:00
feat - > type = DRAG_SMALL_CIRCLE ;
feat - > point = 0 ;
2010-06-18 09:14:23 +02:00
}
2014-06-03 19:07:19 +02:00
else if ( curve . type = = SplineCurve : : LINE ) {
feat - > pos = curve . p2 ;
2013-09-17 20:13:52 +02:00
feat - > type = DRAG_SMALL_CIRCLE ;
feat - > point = 1 ;
2010-06-18 09:14:23 +02:00
}
2014-06-03 19:07:19 +02:00
else if ( curve . type = = SplineCurve : : BICUBIC ) {
2010-06-18 09:14:23 +02:00
// Control points
2014-06-03 19:07:19 +02:00
feat - > pos = curve . p2 ;
2013-09-17 20:13:52 +02:00
feat - > point = 1 ;
feat - > type = DRAG_SMALL_SQUARE ;
features . push_back ( * feat . release ( ) ) ;
2014-04-23 22:53:24 +02:00
feat = agi : : make_unique < Feature > ( ) ;
2014-06-03 19:07:19 +02:00
feat - > idx = idx ;
feat - > pos = curve . p3 ;
2013-09-17 20:13:52 +02:00
feat - > point = 2 ;
feat - > type = DRAG_SMALL_SQUARE ;
features . push_back ( * feat . release ( ) ) ;
2010-06-18 09:14:23 +02:00
// End point
2014-04-23 22:53:24 +02:00
feat = agi : : make_unique < Feature > ( ) ;
2014-06-03 19:07:19 +02:00
feat - > idx = idx ;
feat - > pos = curve . p4 ;
2013-09-17 20:13:52 +02:00
feat - > point = 3 ;
feat - > type = DRAG_SMALL_CIRCLE ;
2010-06-18 09:14:23 +02:00
}
2013-09-17 20:13:52 +02:00
features . push_back ( * feat . release ( ) ) ;
2010-06-18 09:14:23 +02:00
}
2010-06-30 08:29:14 +02:00
void VisualToolVectorClip : : MakeFeatures ( ) {
2011-11-06 18:18:20 +01:00
sel_features . clear ( ) ;
2007-07-05 06:32:46 +02:00
features . clear ( ) ;
2013-09-17 20:13:52 +02:00
active_feature = nullptr ;
2014-06-03 19:07:19 +02:00
for ( size_t i = 0 ; i < spline . size ( ) ; + + i )
MakeFeature ( i ) ;
2010-06-30 08:29:14 +02:00
}
2007-07-05 06:32:46 +02:00
2010-06-30 08:29:14 +02:00
void VisualToolVectorClip : : Save ( ) {
2013-01-04 16:01:50 +01:00
std : : string value = " ( " ;
2012-01-26 01:29:08 +01:00
if ( spline . GetScale ( ) ! = 1 )
2013-01-04 16:01:50 +01:00
value + = std : : to_string ( spline . GetScale ( ) ) + " , " ;
2012-10-12 03:52:36 +02:00
value + = spline . EncodeToAss ( ) + " ) " ;
2012-01-26 01:29:08 +01:00
2012-11-04 04:53:03 +01:00
for ( auto line : c - > selectionController - > GetSelectedSet ( ) ) {
2012-10-20 17:07:15 +02:00
// This check is technically not correct as it could be outside of an
// override block... but that's rather unlikely
2013-01-04 16:01:50 +01:00
bool has_iclip = line - > Text . get ( ) . find ( " \\ iclip " ) ! = std : : string : : npos ;
2012-11-04 04:53:03 +01:00
SetOverride ( line , has_iclip ? " \\ iclip " : " \\ clip " , value ) ;
2012-10-20 17:07:15 +02:00
}
2007-07-05 06:32:46 +02:00
}
2013-09-19 01:18:38 +02:00
void VisualToolVectorClip : : Commit ( wxString message ) {
Save ( ) ;
VisualToolBase : : Commit ( message ) ;
}
2013-09-17 20:13:52 +02:00
void VisualToolVectorClip : : UpdateDrag ( Feature * feature ) {
2014-06-03 19:07:19 +02:00
spline . MovePoint ( spline . begin ( ) + feature - > idx , feature - > point , feature - > pos ) ;
2007-07-05 06:32:46 +02:00
}
2013-09-17 20:13:52 +02:00
bool VisualToolVectorClip : : InitializeDrag ( Feature * feature ) {
2010-06-30 08:29:14 +02:00
if ( mode ! = 5 ) return true ;
2014-06-03 19:07:19 +02:00
auto curve = spline . begin ( ) + feature - > idx ;
if ( curve - > type = = SplineCurve : : BICUBIC & & ( feature - > point = = 1 | | feature - > point = = 2 ) ) {
2010-06-30 08:29:14 +02:00
// Deleting bicubic curve handles, so convert to line
2014-06-03 19:07:19 +02:00
curve - > type = SplineCurve : : LINE ;
curve - > p2 = curve - > p4 ;
2010-06-30 08:29:14 +02:00
}
else {
2014-06-03 19:07:19 +02:00
auto next = std : : next ( curve ) ;
2010-06-08 08:09:19 +02:00
if ( next ! = spline . end ( ) ) {
2014-06-03 19:07:19 +02:00
if ( curve - > type = = SplineCurve : : POINT ) {
2010-06-08 08:09:19 +02:00
next - > p1 = next - > EndPoint ( ) ;
2011-11-06 18:18:20 +01:00
next - > type = SplineCurve : : POINT ;
2010-06-08 08:09:19 +02:00
}
else {
2014-06-03 19:07:19 +02:00
next - > p1 = curve - > p1 ;
2007-07-07 09:27:28 +02:00
}
}
2010-06-08 08:09:19 +02:00
2014-06-03 19:07:19 +02:00
spline . erase ( curve ) ;
2007-07-07 09:27:28 +02:00
}
2013-09-17 20:13:52 +02:00
active_feature = nullptr ;
2010-06-30 08:29:14 +02:00
MakeFeatures ( ) ;
2010-10-26 06:12:10 +02:00
Commit ( _ ( " delete control point " ) ) ;
2010-06-30 08:29:14 +02:00
return false ;
2007-07-07 07:51:18 +02:00
}
2010-05-20 10:55:35 +02:00
bool VisualToolVectorClip : : InitializeHold ( ) {
2013-09-19 00:52:48 +02:00
// Box selection
2022-07-12 00:58:14 +02:00
if ( mode = = VCLIP_DRAG ) {
2013-09-19 00:52:48 +02:00
box_added . clear ( ) ;
return true ;
}
2007-07-07 08:41:14 +02:00
// Insert line/bicubic
2022-07-12 00:58:14 +02:00
if ( mode = = VCLIP_LINE | | mode = = VCLIP_BICUBIC ) {
2007-07-07 08:41:14 +02:00
SplineCurve curve ;
2011-11-06 18:18:20 +01:00
// New spline beginning at the clicked point
if ( spline . empty ( ) ) {
curve . p1 = mouse_pos ;
curve . type = SplineCurve : : POINT ;
2007-07-07 08:41:14 +02:00
}
else {
2011-11-06 18:18:20 +01:00
// Continue from the spline in progress
// Don't bother setting p2 as UpdateHold will handle that
curve . p1 = spline . back ( ) . EndPoint ( ) ;
2022-07-12 00:58:14 +02:00
curve . type = mode = = VCLIP_LINE ? SplineCurve : : LINE : SplineCurve : : BICUBIC ;
2007-07-07 08:41:14 +02:00
}
2010-06-08 08:09:19 +02:00
spline . push_back ( curve ) ;
2011-11-06 18:18:20 +01:00
sel_features . clear ( ) ;
2014-06-03 19:07:19 +02:00
MakeFeature ( spline . size ( ) - 1 ) ;
2010-05-20 10:55:35 +02:00
UpdateHold ( ) ;
return true ;
2007-07-07 08:41:14 +02:00
}
2007-07-07 23:13:20 +02:00
// Convert and insert
2022-07-12 00:58:14 +02:00
if ( mode = = VCLIP_CONVERT | | mode = = VCLIP_INSERT ) {
2007-07-07 23:13:20 +02:00
// Get closest point
Vector2D pt ;
2010-06-08 08:09:19 +02:00
Spline : : iterator curve ;
2007-07-07 23:13:20 +02:00
float t ;
2011-11-06 18:18:20 +01:00
spline . GetClosestParametricPoint ( mouse_pos , curve , t , pt ) ;
2007-07-07 23:13:20 +02:00
2011-11-06 18:18:20 +01:00
// Convert line <-> bicubic
2022-07-12 00:58:14 +02:00
if ( mode = = VCLIP_CONVERT ) {
2010-06-08 08:09:19 +02:00
if ( curve ! = spline . end ( ) ) {
2011-11-06 18:18:20 +01:00
if ( curve - > type = = SplineCurve : : LINE ) {
curve - > type = SplineCurve : : BICUBIC ;
2010-06-08 08:09:19 +02:00
curve - > p4 = curve - > p2 ;
curve - > p2 = curve - > p1 * 0.75 + curve - > p4 * 0.25 ;
curve - > p3 = curve - > p1 * 0.25 + curve - > p4 * 0.75 ;
2007-07-08 09:22:09 +02:00
}
2011-11-06 18:18:20 +01:00
else if ( curve - > type = = SplineCurve : : BICUBIC ) {
curve - > type = SplineCurve : : LINE ;
2010-06-08 08:09:19 +02:00
curve - > p2 = curve - > p4 ;
2007-07-08 09:22:09 +02:00
}
}
2007-07-07 23:13:20 +02:00
}
// Insert
else {
2010-06-08 08:09:19 +02:00
if ( spline . empty ( ) ) return false ;
2007-08-03 19:22:06 +02:00
2007-07-07 23:13:20 +02:00
// Split the curve
2010-06-08 08:09:19 +02:00
if ( curve = = spline . end ( ) ) {
2011-11-06 18:18:20 +01:00
SplineCurve ct ( spline . back ( ) . EndPoint ( ) , spline . front ( ) . p1 ) ;
ct . p2 = ct . p1 * ( 1 - t ) + ct . p2 * t ;
2010-06-08 08:09:19 +02:00
spline . push_back ( ct ) ;
2007-07-07 23:13:20 +02:00
}
else {
2011-12-22 22:25:08 +01:00
std : : pair < SplineCurve , SplineCurve > split = curve - > Split ( t ) ;
* curve = split . first ;
spline . insert ( + + curve , split . second ) ;
2007-07-07 23:13:20 +02:00
}
}
2010-06-30 08:29:14 +02:00
MakeFeatures ( ) ;
2010-10-26 06:12:10 +02:00
Commit ( ) ;
2010-05-20 10:55:35 +02:00
return false ;
2007-07-07 23:13:20 +02:00
}
2011-11-06 18:18:20 +01:00
// Freehand spline draw
2022-07-12 00:58:14 +02:00
if ( mode = = VCLIP_FREEHAND | | mode = = VCLIP_FREEHAND_SMOOTH ) {
2011-11-06 18:18:20 +01:00
sel_features . clear ( ) ;
2007-07-08 09:22:09 +02:00
features . clear ( ) ;
2013-09-17 20:13:52 +02:00
active_feature = nullptr ;
2010-06-08 08:09:19 +02:00
spline . clear ( ) ;
2012-11-28 16:35:26 +01:00
spline . emplace_back ( mouse_pos ) ;
2010-05-20 10:55:35 +02:00
return true ;
2007-07-07 08:41:14 +02:00
}
2011-11-06 18:18:20 +01:00
// Nothing to do for mode 5 (remove)
2010-05-20 10:55:35 +02:00
return false ;
2007-07-07 07:51:18 +02:00
}
2013-09-19 00:52:48 +02:00
static bool in_box ( Vector2D top_left , Vector2D bottom_right , Vector2D p ) {
return p . X ( ) > = top_left . X ( )
& & p . X ( ) < = bottom_right . X ( )
& & p . Y ( ) > = top_left . Y ( )
& & p . Y ( ) < = bottom_right . Y ( ) ;
}
2007-07-07 07:51:18 +02:00
void VisualToolVectorClip : : UpdateHold ( ) {
2013-09-19 00:52:48 +02:00
// Box selection
2022-07-12 00:58:14 +02:00
if ( mode = = VCLIP_DRAG ) {
2013-09-19 00:52:48 +02:00
std : : set < Feature * > boxed_features ;
Vector2D p1 = drag_start . Min ( mouse_pos ) ;
Vector2D p2 = drag_start . Max ( mouse_pos ) ;
for ( auto & feature : features ) {
if ( in_box ( p1 , p2 , feature . pos ) )
boxed_features . insert ( & feature ) ;
}
// Keep track of which features were selected by the box selection so
// that only those are deselected if the user is holding ctrl
boost : : set_difference ( boxed_features , sel_features ,
std : : inserter ( box_added , end ( box_added ) ) ) ;
boost : : copy ( boxed_features , std : : inserter ( sel_features , end ( sel_features ) ) ) ;
std : : vector < Feature * > to_deselect ;
boost : : set_difference ( box_added , boxed_features , std : : back_inserter ( to_deselect ) ) ;
for ( auto feature : to_deselect )
sel_features . erase ( feature ) ;
return ;
}
2022-07-12 00:58:14 +02:00
if ( mode = = VCLIP_LINE ) {
2011-11-06 18:18:20 +01:00
spline . back ( ) . EndPoint ( ) = mouse_pos ;
features . back ( ) . pos = mouse_pos ;
2007-07-07 08:41:14 +02:00
}
// Insert bicubic
2022-07-12 00:58:14 +02:00
else if ( mode = = VCLIP_BICUBIC ) {
2010-06-08 08:09:19 +02:00
SplineCurve & curve = spline . back ( ) ;
2011-11-06 18:18:20 +01:00
curve . EndPoint ( ) = mouse_pos ;
2007-07-07 08:41:14 +02:00
// Control points
2010-06-08 08:09:19 +02:00
if ( spline . size ( ) > 1 ) {
2011-11-06 18:18:20 +01:00
SplineCurve & c0 = spline . back ( ) ;
float len = ( curve . p4 - curve . p1 ) . Len ( ) ;
curve . p2 = ( c0 . type = = SplineCurve : : LINE ? c0 . p2 - c0 . p1 : c0 . p4 - c0 . p3 ) . Unit ( ) * ( 0.25f * len ) + curve . p1 ;
2007-07-07 08:41:14 +02:00
}
2011-11-06 18:18:20 +01:00
else
curve . p2 = curve . p1 * 0.75 + curve . p4 * 0.25 ;
2007-07-07 08:41:14 +02:00
curve . p3 = curve . p1 * 0.25 + curve . p4 * 0.75 ;
2010-06-30 08:29:14 +02:00
MakeFeatures ( ) ;
2007-07-07 08:41:14 +02:00
}
// Freehand
2022-07-12 00:58:14 +02:00
else if ( mode = = VCLIP_FREEHAND | | mode = = VCLIP_FREEHAND_SMOOTH ) {
2010-06-08 08:09:19 +02:00
// See if distance is enough
Vector2D const & last = spline . back ( ) . EndPoint ( ) ;
2011-11-06 18:18:20 +01:00
float len = ( last - mouse_pos ) . SquareLen ( ) ;
2022-07-12 00:58:14 +02:00
if ( ( mode = = VCLIP_FREEHAND & & len > = 900 ) | | ( mode = = VCLIP_FREEHAND_SMOOTH & & len > = 3600 ) ) {
2012-11-28 16:35:26 +01:00
spline . emplace_back ( last , mouse_pos ) ;
2014-06-03 19:07:19 +02:00
MakeFeature ( spline . size ( ) - 1 ) ;
2012-05-11 04:47:18 +02:00
}
2007-07-07 07:51:18 +02:00
}
2022-07-12 00:58:14 +02:00
if ( mode = = VCLIP_CONVERT | | mode = = VCLIP_INSERT ) return ;
2010-06-30 08:29:14 +02:00
2007-07-07 07:51:18 +02:00
// Smooth spline
2022-07-12 00:58:14 +02:00
if ( ! holding & & mode = = VCLIP_FREEHAND_SMOOTH )
2010-06-18 09:14:23 +02:00
spline . Smooth ( ) ;
2007-07-08 09:22:09 +02:00
// End freedraw
2022-07-12 00:58:14 +02:00
if ( ! holding & & ( mode = = VCLIP_FREEHAND | | mode = = VCLIP_FREEHAND_SMOOTH ) ) {
SetMode ( VCLIP_DRAG ) ;
2010-06-30 08:29:14 +02:00
MakeFeatures ( ) ;
2010-06-18 09:14:23 +02:00
}
2007-07-07 07:51:18 +02:00
}
2007-07-05 06:32:46 +02:00
void VisualToolVectorClip : : DoRefresh ( ) {
2011-11-06 18:18:20 +01:00
if ( ! active_line ) return ;
2010-06-28 09:13:15 +02:00
int scale ;
2013-01-04 16:01:50 +01:00
std : : string vect = GetLineVectorClip ( active_line , scale , inverse ) ;
2012-01-26 01:29:08 +01:00
spline . SetScale ( scale ) ;
2012-10-12 03:52:36 +02:00
spline . DecodeFromAss ( vect ) ;
2010-06-30 08:29:14 +02:00
MakeFeatures ( ) ;
2010-06-18 09:14:23 +02:00
}