Fix a bunch of crashes in the vector clip tool
This commit is contained in:
parent
5fcb287ed0
commit
0bf93ec263
4 changed files with 58 additions and 66 deletions
|
@ -185,11 +185,11 @@ void Spline::MovePoint(iterator curve,int point,Vector2D pos) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spline::GetPointList(std::vector<float>& points, std::vector<int>& first, std::vector<int>& count) {
|
std::vector<float> Spline::GetPointList(std::vector<int>& first, std::vector<int>& count) {
|
||||||
points.clear();
|
|
||||||
first.clear();
|
first.clear();
|
||||||
count.clear();
|
count.clear();
|
||||||
|
|
||||||
|
std::vector<float> points;
|
||||||
points.reserve((size() + 1) * 2);
|
points.reserve((size() + 1) * 2);
|
||||||
int curCount = 0;
|
int curCount = 0;
|
||||||
|
|
||||||
|
@ -207,11 +207,12 @@ void Spline::GetPointList(std::vector<float>& points, std::vector<int>& first, s
|
||||||
}
|
}
|
||||||
|
|
||||||
count.push_back(curCount);
|
count.push_back(curCount);
|
||||||
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spline::GetPointList(std::vector<float> &points, iterator curve) {
|
std::vector<float> Spline::GetPointList(iterator curve) {
|
||||||
points.clear();
|
std::vector<float> points;
|
||||||
if (curve == end()) return;
|
if (curve == end()) return points;
|
||||||
switch (curve->type) {
|
switch (curve->type) {
|
||||||
case SplineCurve::LINE:
|
case SplineCurve::LINE:
|
||||||
points.push_back(curve->p1.X());
|
points.push_back(curve->p1.X());
|
||||||
|
@ -226,9 +227,10 @@ void Spline::GetPointList(std::vector<float> &points, iterator curve) {
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spline::GetClosestParametricPoint(Vector2D reference,iterator &curve,float &t,Vector2D &pt) {
|
void Spline::GetClosestParametricPoint(Vector2D reference, iterator &curve, float &t, Vector2D &pt) {
|
||||||
curve = end();
|
curve = end();
|
||||||
t = 0.f;
|
t = 0.f;
|
||||||
if (empty()) return;
|
if (empty()) return;
|
||||||
|
@ -237,24 +239,22 @@ void Spline::GetClosestParametricPoint(Vector2D reference,iterator &curve,float
|
||||||
emplace_back(back().EndPoint(), front().p1);
|
emplace_back(back().EndPoint(), front().p1);
|
||||||
|
|
||||||
float closest = std::numeric_limits<float>::infinity();
|
float closest = std::numeric_limits<float>::infinity();
|
||||||
for (auto cur = begin(); cur != end(); ++cur) {
|
size_t idx = 0;
|
||||||
float param = cur->GetClosestParam(reference);
|
for (size_t i = 0; i < size(); ++i) {
|
||||||
Vector2D p1 = cur->GetPoint(param);
|
auto& cur = (*this)[i];
|
||||||
|
float param = cur.GetClosestParam(reference);
|
||||||
|
Vector2D p1 = cur.GetPoint(param);
|
||||||
float dist = (p1-reference).SquareLen();
|
float dist = (p1-reference).SquareLen();
|
||||||
if (dist < closest) {
|
if (dist < closest) {
|
||||||
closest = dist;
|
closest = dist;
|
||||||
t = param;
|
t = param;
|
||||||
curve = cur;
|
idx = i;
|
||||||
pt = p1;
|
pt = p1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (&*curve == &back()) {
|
|
||||||
curve = end();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove closing and return
|
|
||||||
pop_back();
|
pop_back();
|
||||||
|
curve = begin() + idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2D Spline::GetClosestPoint(Vector2D reference) {
|
Vector2D Spline::GetClosestPoint(Vector2D reference) {
|
||||||
|
|
23
src/spline.h
23
src/spline.h
|
@ -71,9 +71,9 @@ public:
|
||||||
void Smooth(float smooth=1.0f);
|
void Smooth(float smooth=1.0f);
|
||||||
|
|
||||||
/// Gets a list of points in the curve
|
/// Gets a list of points in the curve
|
||||||
void GetPointList(std::vector<float>& points, std::vector<int>& first, std::vector<int>& count);
|
std::vector<float> GetPointList(std::vector<int>& first, std::vector<int>& count);
|
||||||
/// Gets a list of points in the curve
|
/// Gets a list of points in the curve
|
||||||
void GetPointList(std::vector<float> &points, iterator curve);
|
std::vector<float> GetPointList(iterator curve);
|
||||||
|
|
||||||
/// Get t value and curve of the point closest to reference
|
/// Get t value and curve of the point closest to reference
|
||||||
void GetClosestParametricPoint(Vector2D reference, iterator& curve, float &t, Vector2D &point);
|
void GetClosestParametricPoint(Vector2D reference, iterator& curve, float &t, Vector2D &point);
|
||||||
|
@ -92,18 +92,19 @@ public:
|
||||||
using std::vector<SplineCurve>::reverse_iterator;
|
using std::vector<SplineCurve>::reverse_iterator;
|
||||||
using std::vector<SplineCurve>::const_reverse_iterator;
|
using std::vector<SplineCurve>::const_reverse_iterator;
|
||||||
|
|
||||||
|
using std::vector<SplineCurve>::back;
|
||||||
using std::vector<SplineCurve>::begin;
|
using std::vector<SplineCurve>::begin;
|
||||||
|
using std::vector<SplineCurve>::clear;
|
||||||
|
using std::vector<SplineCurve>::emplace_back;
|
||||||
|
using std::vector<SplineCurve>::empty;
|
||||||
using std::vector<SplineCurve>::end;
|
using std::vector<SplineCurve>::end;
|
||||||
|
using std::vector<SplineCurve>::erase;
|
||||||
|
using std::vector<SplineCurve>::front;
|
||||||
|
using std::vector<SplineCurve>::insert;
|
||||||
|
using std::vector<SplineCurve>::operator[];
|
||||||
|
using std::vector<SplineCurve>::pop_back;
|
||||||
|
using std::vector<SplineCurve>::push_back;
|
||||||
using std::vector<SplineCurve>::rbegin;
|
using std::vector<SplineCurve>::rbegin;
|
||||||
using std::vector<SplineCurve>::rend;
|
using std::vector<SplineCurve>::rend;
|
||||||
using std::vector<SplineCurve>::size;
|
using std::vector<SplineCurve>::size;
|
||||||
using std::vector<SplineCurve>::empty;
|
|
||||||
using std::vector<SplineCurve>::front;
|
|
||||||
using std::vector<SplineCurve>::back;
|
|
||||||
using std::vector<SplineCurve>::push_back;
|
|
||||||
using std::vector<SplineCurve>::pop_back;
|
|
||||||
using std::vector<SplineCurve>::emplace_back;
|
|
||||||
using std::vector<SplineCurve>::insert;
|
|
||||||
using std::vector<SplineCurve>::erase;
|
|
||||||
using std::vector<SplineCurve>::clear;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,10 +14,6 @@
|
||||||
//
|
//
|
||||||
// Aegisub Project http://www.aegisub.org/
|
// Aegisub Project http://www.aegisub.org/
|
||||||
|
|
||||||
/// @file visual_tool_vector_clip.cpp
|
|
||||||
/// @brief Vector clipping visual typesetting tool
|
|
||||||
/// @ingroup visual_ts
|
|
||||||
|
|
||||||
#include "visual_tool_vector_clip.h"
|
#include "visual_tool_vector_clip.h"
|
||||||
|
|
||||||
#include "ass_dialogue.h"
|
#include "ass_dialogue.h"
|
||||||
|
@ -90,11 +86,9 @@ void VisualToolVectorClip::Draw() {
|
||||||
if (spline.empty()) return;
|
if (spline.empty()) return;
|
||||||
|
|
||||||
// Parse vector
|
// Parse vector
|
||||||
std::vector<float> points;
|
|
||||||
std::vector<int> start;
|
std::vector<int> start;
|
||||||
std::vector<int> count;
|
std::vector<int> count;
|
||||||
|
auto points = spline.GetPointList(start, count);
|
||||||
spline.GetPointList(points, start, count);
|
|
||||||
assert(!start.empty());
|
assert(!start.empty());
|
||||||
assert(!count.empty());
|
assert(!count.empty());
|
||||||
|
|
||||||
|
@ -121,8 +115,7 @@ void VisualToolVectorClip::Draw() {
|
||||||
|
|
||||||
// Draw highlighted line
|
// Draw highlighted line
|
||||||
if ((mode == 3 || mode == 4) && !active_feature && points.size() > 2) {
|
if ((mode == 3 || mode == 4) && !active_feature && points.size() > 2) {
|
||||||
std::vector<float> highlighted_points;
|
auto highlighted_points = spline.GetPointList(highlighted_curve);
|
||||||
spline.GetPointList(highlighted_points, highlighted_curve);
|
|
||||||
if (!highlighted_points.empty()) {
|
if (!highlighted_points.empty()) {
|
||||||
gl.SetLineColour(colour[2], 1.f, 2);
|
gl.SetLineColour(colour[2], 1.f, 2);
|
||||||
gl.DrawLineStrip(2, highlighted_points);
|
gl.DrawLineStrip(2, highlighted_points);
|
||||||
|
@ -173,38 +166,39 @@ void VisualToolVectorClip::Draw() {
|
||||||
gl.DrawCircle(pt, 4);
|
gl.DrawCircle(pt, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolVectorClip::MakeFeature(Spline::iterator cur) {
|
void VisualToolVectorClip::MakeFeature(size_t idx) {
|
||||||
auto feat = agi::make_unique<Feature>();
|
auto feat = agi::make_unique<Feature>();
|
||||||
feat->curve = cur;
|
feat->idx = idx;
|
||||||
|
|
||||||
if (cur->type == SplineCurve::POINT) {
|
auto const& curve = spline[idx];
|
||||||
feat->pos = cur->p1;
|
if (curve.type == SplineCurve::POINT) {
|
||||||
|
feat->pos = curve.p1;
|
||||||
feat->type = DRAG_SMALL_CIRCLE;
|
feat->type = DRAG_SMALL_CIRCLE;
|
||||||
feat->point = 0;
|
feat->point = 0;
|
||||||
}
|
}
|
||||||
else if (cur->type == SplineCurve::LINE) {
|
else if (curve.type == SplineCurve::LINE) {
|
||||||
feat->pos = cur->p2;
|
feat->pos = curve.p2;
|
||||||
feat->type = DRAG_SMALL_CIRCLE;
|
feat->type = DRAG_SMALL_CIRCLE;
|
||||||
feat->point = 1;
|
feat->point = 1;
|
||||||
}
|
}
|
||||||
else if (cur->type == SplineCurve::BICUBIC) {
|
else if (curve.type == SplineCurve::BICUBIC) {
|
||||||
// Control points
|
// Control points
|
||||||
feat->pos = cur->p2;
|
feat->pos = curve.p2;
|
||||||
feat->point = 1;
|
feat->point = 1;
|
||||||
feat->type = DRAG_SMALL_SQUARE;
|
feat->type = DRAG_SMALL_SQUARE;
|
||||||
features.push_back(*feat.release());
|
features.push_back(*feat.release());
|
||||||
|
|
||||||
feat = agi::make_unique<Feature>();
|
feat = agi::make_unique<Feature>();
|
||||||
feat->curve = cur;
|
feat->idx = idx;
|
||||||
feat->pos = cur->p3;
|
feat->pos = curve.p3;
|
||||||
feat->point = 2;
|
feat->point = 2;
|
||||||
feat->type = DRAG_SMALL_SQUARE;
|
feat->type = DRAG_SMALL_SQUARE;
|
||||||
features.push_back(*feat.release());
|
features.push_back(*feat.release());
|
||||||
|
|
||||||
// End point
|
// End point
|
||||||
feat = agi::make_unique<Feature>();
|
feat = agi::make_unique<Feature>();
|
||||||
feat->curve = cur;
|
feat->idx = idx;
|
||||||
feat->pos = cur->p4;
|
feat->pos = curve.p4;
|
||||||
feat->point = 3;
|
feat->point = 3;
|
||||||
feat->type = DRAG_SMALL_CIRCLE;
|
feat->type = DRAG_SMALL_CIRCLE;
|
||||||
}
|
}
|
||||||
|
@ -215,8 +209,8 @@ void VisualToolVectorClip::MakeFeatures() {
|
||||||
sel_features.clear();
|
sel_features.clear();
|
||||||
features.clear();
|
features.clear();
|
||||||
active_feature = nullptr;
|
active_feature = nullptr;
|
||||||
for (auto it = spline.begin(); it != spline.end(); ++it)
|
for (size_t i = 0; i < spline.size(); ++i)
|
||||||
MakeFeature(it);
|
MakeFeature(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolVectorClip::Save() {
|
void VisualToolVectorClip::Save() {
|
||||||
|
@ -239,30 +233,31 @@ void VisualToolVectorClip::Commit(wxString message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolVectorClip::UpdateDrag(Feature *feature) {
|
void VisualToolVectorClip::UpdateDrag(Feature *feature) {
|
||||||
spline.MovePoint(feature->curve, feature->point, feature->pos);
|
spline.MovePoint(spline.begin() + feature->idx, feature->point, feature->pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VisualToolVectorClip::InitializeDrag(Feature *feature) {
|
bool VisualToolVectorClip::InitializeDrag(Feature *feature) {
|
||||||
if (mode != 5) return true;
|
if (mode != 5) return true;
|
||||||
|
|
||||||
if (feature->curve->type == SplineCurve::BICUBIC && (feature->point == 1 || feature->point == 2)) {
|
auto curve = spline.begin() + feature->idx;
|
||||||
|
if (curve->type == SplineCurve::BICUBIC && (feature->point == 1 || feature->point == 2)) {
|
||||||
// Deleting bicubic curve handles, so convert to line
|
// Deleting bicubic curve handles, so convert to line
|
||||||
feature->curve->type = SplineCurve::LINE;
|
curve->type = SplineCurve::LINE;
|
||||||
feature->curve->p2 = feature->curve->p4;
|
curve->p2 = curve->p4;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto next = std::next(feature->curve);
|
auto next = std::next(curve);
|
||||||
if (next != spline.end()) {
|
if (next != spline.end()) {
|
||||||
if (feature->curve->type == SplineCurve::POINT) {
|
if (curve->type == SplineCurve::POINT) {
|
||||||
next->p1 = next->EndPoint();
|
next->p1 = next->EndPoint();
|
||||||
next->type = SplineCurve::POINT;
|
next->type = SplineCurve::POINT;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
next->p1 = feature->curve->p1;
|
next->p1 = curve->p1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spline.erase(feature->curve);
|
spline.erase(curve);
|
||||||
}
|
}
|
||||||
active_feature = nullptr;
|
active_feature = nullptr;
|
||||||
|
|
||||||
|
@ -297,7 +292,7 @@ bool VisualToolVectorClip::InitializeHold() {
|
||||||
|
|
||||||
spline.push_back(curve);
|
spline.push_back(curve);
|
||||||
sel_features.clear();
|
sel_features.clear();
|
||||||
MakeFeature(--spline.end());
|
MakeFeature(spline.size() - 1);
|
||||||
UpdateHold();
|
UpdateHold();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -424,7 +419,7 @@ void VisualToolVectorClip::UpdateHold() {
|
||||||
float len = (last - mouse_pos).SquareLen();
|
float len = (last - mouse_pos).SquareLen();
|
||||||
if ((mode == 6 && len >= 900) || (mode == 7 && len >= 3600)) {
|
if ((mode == 6 && len >= 900) || (mode == 7 && len >= 3600)) {
|
||||||
spline.emplace_back(last, mouse_pos);
|
spline.emplace_back(last, mouse_pos);
|
||||||
MakeFeature(--spline.end());
|
MakeFeature(spline.size() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,6 @@
|
||||||
//
|
//
|
||||||
// Aegisub Project http://www.aegisub.org/
|
// Aegisub Project http://www.aegisub.org/
|
||||||
|
|
||||||
/// @file visual_tool_vector_clip.h
|
|
||||||
/// @see visual_tool_vector_clip.cpp
|
|
||||||
/// @ingroup visual_ts
|
|
||||||
///
|
|
||||||
|
|
||||||
#include "visual_feature.h"
|
#include "visual_feature.h"
|
||||||
#include "visual_tool.h"
|
#include "visual_tool.h"
|
||||||
#include "spline.h"
|
#include "spline.h"
|
||||||
|
@ -30,7 +25,7 @@ class wxToolBar;
|
||||||
/// in the spline
|
/// in the spline
|
||||||
struct VisualToolVectorClipDraggableFeature final : public VisualDraggableFeature {
|
struct VisualToolVectorClipDraggableFeature final : public VisualDraggableFeature {
|
||||||
/// Which curve in the spline this feature is a point on
|
/// Which curve in the spline this feature is a point on
|
||||||
Spline::iterator curve;
|
size_t idx = 0;
|
||||||
/// 0-3; indicates which part of the curve this point is
|
/// 0-3; indicates which part of the curve this point is
|
||||||
int point = 0;
|
int point = 0;
|
||||||
};
|
};
|
||||||
|
@ -51,7 +46,7 @@ class VisualToolVectorClip final : public VisualTool<VisualToolVectorClipDraggab
|
||||||
void Commit(wxString message="") override;
|
void Commit(wxString message="") override;
|
||||||
|
|
||||||
void SelectAll();
|
void SelectAll();
|
||||||
void MakeFeature(Spline::iterator cur);
|
void MakeFeature(size_t idx);
|
||||||
void MakeFeatures();
|
void MakeFeatures();
|
||||||
|
|
||||||
bool InitializeHold() override;
|
bool InitializeHold() override;
|
||||||
|
@ -62,6 +57,7 @@ class VisualToolVectorClip final : public VisualTool<VisualToolVectorClipDraggab
|
||||||
|
|
||||||
void DoRefresh() override;
|
void DoRefresh() override;
|
||||||
void Draw() override;
|
void Draw() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VisualToolVectorClip(VideoDisplay *parent, agi::Context *context);
|
VisualToolVectorClip(VideoDisplay *parent, agi::Context *context);
|
||||||
void SetToolbar(wxToolBar *tb) override;
|
void SetToolbar(wxToolBar *tb) override;
|
||||||
|
|
Loading…
Reference in a new issue