Fix a bunch of crashes in the vector clip tool

This commit is contained in:
Thomas Goyne 2014-06-03 10:07:19 -07:00
parent 5fcb287ed0
commit 0bf93ec263
4 changed files with 58 additions and 66 deletions

View file

@ -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) {

View file

@ -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;
};

View file

@ -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);
}
}

View file

@ -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;