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) {
|
||||
points.clear();
|
||||
std::vector<float> Spline::GetPointList(std::vector<int>& first, std::vector<int>& count) {
|
||||
first.clear();
|
||||
count.clear();
|
||||
|
||||
std::vector<float> points;
|
||||
points.reserve((size() + 1) * 2);
|
||||
int curCount = 0;
|
||||
|
||||
|
@ -207,11 +207,12 @@ void Spline::GetPointList(std::vector<float>& points, std::vector<int>& first, s
|
|||
}
|
||||
|
||||
count.push_back(curCount);
|
||||
return points;
|
||||
}
|
||||
|
||||
void Spline::GetPointList(std::vector<float> &points, iterator curve) {
|
||||
points.clear();
|
||||
if (curve == end()) return;
|
||||
std::vector<float> Spline::GetPointList(iterator curve) {
|
||||
std::vector<float> points;
|
||||
if (curve == end()) return points;
|
||||
switch (curve->type) {
|
||||
case SplineCurve::LINE:
|
||||
points.push_back(curve->p1.X());
|
||||
|
@ -226,6 +227,7 @@ void Spline::GetPointList(std::vector<float> &points, iterator curve) {
|
|||
|
||||
default: break;
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
void Spline::GetClosestParametricPoint(Vector2D reference, iterator &curve, float &t, Vector2D &pt) {
|
||||
|
@ -237,24 +239,22 @@ void Spline::GetClosestParametricPoint(Vector2D reference,iterator &curve,float
|
|||
emplace_back(back().EndPoint(), front().p1);
|
||||
|
||||
float closest = std::numeric_limits<float>::infinity();
|
||||
for (auto cur = begin(); cur != end(); ++cur) {
|
||||
float param = cur->GetClosestParam(reference);
|
||||
Vector2D p1 = cur->GetPoint(param);
|
||||
size_t idx = 0;
|
||||
for (size_t i = 0; i < size(); ++i) {
|
||||
auto& cur = (*this)[i];
|
||||
float param = cur.GetClosestParam(reference);
|
||||
Vector2D p1 = cur.GetPoint(param);
|
||||
float dist = (p1-reference).SquareLen();
|
||||
if (dist < closest) {
|
||||
closest = dist;
|
||||
t = param;
|
||||
curve = cur;
|
||||
idx = i;
|
||||
pt = p1;
|
||||
}
|
||||
}
|
||||
|
||||
if (&*curve == &back()) {
|
||||
curve = end();
|
||||
}
|
||||
|
||||
// Remove closing and return
|
||||
pop_back();
|
||||
curve = begin() + idx;
|
||||
}
|
||||
|
||||
Vector2D Spline::GetClosestPoint(Vector2D reference) {
|
||||
|
|
23
src/spline.h
23
src/spline.h
|
@ -71,9 +71,9 @@ public:
|
|||
void Smooth(float smooth=1.0f);
|
||||
|
||||
/// 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
|
||||
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
|
||||
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>::const_reverse_iterator;
|
||||
|
||||
using std::vector<SplineCurve>::back;
|
||||
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>::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>::rend;
|
||||
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/
|
||||
|
||||
/// @file visual_tool_vector_clip.cpp
|
||||
/// @brief Vector clipping visual typesetting tool
|
||||
/// @ingroup visual_ts
|
||||
|
||||
#include "visual_tool_vector_clip.h"
|
||||
|
||||
#include "ass_dialogue.h"
|
||||
|
@ -90,11 +86,9 @@ void VisualToolVectorClip::Draw() {
|
|||
if (spline.empty()) return;
|
||||
|
||||
// Parse vector
|
||||
std::vector<float> points;
|
||||
std::vector<int> start;
|
||||
std::vector<int> count;
|
||||
|
||||
spline.GetPointList(points, start, count);
|
||||
auto points = spline.GetPointList(start, count);
|
||||
assert(!start.empty());
|
||||
assert(!count.empty());
|
||||
|
||||
|
@ -121,8 +115,7 @@ void VisualToolVectorClip::Draw() {
|
|||
|
||||
// Draw highlighted line
|
||||
if ((mode == 3 || mode == 4) && !active_feature && points.size() > 2) {
|
||||
std::vector<float> highlighted_points;
|
||||
spline.GetPointList(highlighted_points, highlighted_curve);
|
||||
auto highlighted_points = spline.GetPointList(highlighted_curve);
|
||||
if (!highlighted_points.empty()) {
|
||||
gl.SetLineColour(colour[2], 1.f, 2);
|
||||
gl.DrawLineStrip(2, highlighted_points);
|
||||
|
@ -173,38 +166,39 @@ void VisualToolVectorClip::Draw() {
|
|||
gl.DrawCircle(pt, 4);
|
||||
}
|
||||
|
||||
void VisualToolVectorClip::MakeFeature(Spline::iterator cur) {
|
||||
void VisualToolVectorClip::MakeFeature(size_t idx) {
|
||||
auto feat = agi::make_unique<Feature>();
|
||||
feat->curve = cur;
|
||||
feat->idx = idx;
|
||||
|
||||
if (cur->type == SplineCurve::POINT) {
|
||||
feat->pos = cur->p1;
|
||||
auto const& curve = spline[idx];
|
||||
if (curve.type == SplineCurve::POINT) {
|
||||
feat->pos = curve.p1;
|
||||
feat->type = DRAG_SMALL_CIRCLE;
|
||||
feat->point = 0;
|
||||
}
|
||||
else if (cur->type == SplineCurve::LINE) {
|
||||
feat->pos = cur->p2;
|
||||
else if (curve.type == SplineCurve::LINE) {
|
||||
feat->pos = curve.p2;
|
||||
feat->type = DRAG_SMALL_CIRCLE;
|
||||
feat->point = 1;
|
||||
}
|
||||
else if (cur->type == SplineCurve::BICUBIC) {
|
||||
else if (curve.type == SplineCurve::BICUBIC) {
|
||||
// Control points
|
||||
feat->pos = cur->p2;
|
||||
feat->pos = curve.p2;
|
||||
feat->point = 1;
|
||||
feat->type = DRAG_SMALL_SQUARE;
|
||||
features.push_back(*feat.release());
|
||||
|
||||
feat = agi::make_unique<Feature>();
|
||||
feat->curve = cur;
|
||||
feat->pos = cur->p3;
|
||||
feat->idx = idx;
|
||||
feat->pos = curve.p3;
|
||||
feat->point = 2;
|
||||
feat->type = DRAG_SMALL_SQUARE;
|
||||
features.push_back(*feat.release());
|
||||
|
||||
// End point
|
||||
feat = agi::make_unique<Feature>();
|
||||
feat->curve = cur;
|
||||
feat->pos = cur->p4;
|
||||
feat->idx = idx;
|
||||
feat->pos = curve.p4;
|
||||
feat->point = 3;
|
||||
feat->type = DRAG_SMALL_CIRCLE;
|
||||
}
|
||||
|
@ -215,8 +209,8 @@ void VisualToolVectorClip::MakeFeatures() {
|
|||
sel_features.clear();
|
||||
features.clear();
|
||||
active_feature = nullptr;
|
||||
for (auto it = spline.begin(); it != spline.end(); ++it)
|
||||
MakeFeature(it);
|
||||
for (size_t i = 0; i < spline.size(); ++i)
|
||||
MakeFeature(i);
|
||||
}
|
||||
|
||||
void VisualToolVectorClip::Save() {
|
||||
|
@ -239,30 +233,31 @@ void VisualToolVectorClip::Commit(wxString message) {
|
|||
}
|
||||
|
||||
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) {
|
||||
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
|
||||
feature->curve->type = SplineCurve::LINE;
|
||||
feature->curve->p2 = feature->curve->p4;
|
||||
curve->type = SplineCurve::LINE;
|
||||
curve->p2 = curve->p4;
|
||||
}
|
||||
else {
|
||||
auto next = std::next(feature->curve);
|
||||
auto next = std::next(curve);
|
||||
if (next != spline.end()) {
|
||||
if (feature->curve->type == SplineCurve::POINT) {
|
||||
if (curve->type == SplineCurve::POINT) {
|
||||
next->p1 = next->EndPoint();
|
||||
next->type = SplineCurve::POINT;
|
||||
}
|
||||
else {
|
||||
next->p1 = feature->curve->p1;
|
||||
next->p1 = curve->p1;
|
||||
}
|
||||
}
|
||||
|
||||
spline.erase(feature->curve);
|
||||
spline.erase(curve);
|
||||
}
|
||||
active_feature = nullptr;
|
||||
|
||||
|
@ -297,7 +292,7 @@ bool VisualToolVectorClip::InitializeHold() {
|
|||
|
||||
spline.push_back(curve);
|
||||
sel_features.clear();
|
||||
MakeFeature(--spline.end());
|
||||
MakeFeature(spline.size() - 1);
|
||||
UpdateHold();
|
||||
return true;
|
||||
}
|
||||
|
@ -424,7 +419,7 @@ void VisualToolVectorClip::UpdateHold() {
|
|||
float len = (last - mouse_pos).SquareLen();
|
||||
if ((mode == 6 && len >= 900) || (mode == 7 && len >= 3600)) {
|
||||
spline.emplace_back(last, mouse_pos);
|
||||
MakeFeature(--spline.end());
|
||||
MakeFeature(spline.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,11 +14,6 @@
|
|||
//
|
||||
// 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_tool.h"
|
||||
#include "spline.h"
|
||||
|
@ -30,7 +25,7 @@ class wxToolBar;
|
|||
/// in the spline
|
||||
struct VisualToolVectorClipDraggableFeature final : public VisualDraggableFeature {
|
||||
/// 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
|
||||
int point = 0;
|
||||
};
|
||||
|
@ -51,7 +46,7 @@ class VisualToolVectorClip final : public VisualTool<VisualToolVectorClipDraggab
|
|||
void Commit(wxString message="") override;
|
||||
|
||||
void SelectAll();
|
||||
void MakeFeature(Spline::iterator cur);
|
||||
void MakeFeature(size_t idx);
|
||||
void MakeFeatures();
|
||||
|
||||
bool InitializeHold() override;
|
||||
|
@ -62,6 +57,7 @@ class VisualToolVectorClip final : public VisualTool<VisualToolVectorClipDraggab
|
|||
|
||||
void DoRefresh() override;
|
||||
void Draw() override;
|
||||
|
||||
public:
|
||||
VisualToolVectorClip(VideoDisplay *parent, agi::Context *context);
|
||||
void SetToolbar(wxToolBar *tb) override;
|
||||
|
|
Loading…
Reference in a new issue