Skip to content

Commit 519133d

Browse files
committed
Fix bug when reordering of elements in the model tree
1 parent 49a45f7 commit 519133d

7 files changed

Lines changed: 39 additions & 62 deletions

File tree

gui/source/pre/models/MainModel.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ MaterialModel* MainModel::getMaterialModel(int index) {
143143

144144
LayerModel* MainModel::getLayerModel(int index) {
145145
if(bow.has_value() && index >= 0 && index < bow->section.layers.size()) {
146-
auto model = new LayerModel(bow->section.layers[index], bow->section.materials);
146+
auto model = new LayerModel(*std::next(bow->section.layers.begin(), index), bow->section.materials);
147147
connectSubModel(model);
148148
return model;
149149
}
@@ -153,7 +153,7 @@ LayerModel* MainModel::getLayerModel(int index) {
153153

154154
TableModel* MainModel::getLayerHeightModel(int index) {
155155
if(bow.has_value() && index >= 0 && index < bow->section.layers.size()) {
156-
auto model = new TableModel(bow->section.layers[index].height, "Position", "Height", Quantities::ratio, Quantities::length);
156+
auto model = new TableModel(std::next(bow->section.layers.begin(), index)->height, "Position", "Height", Quantities::ratio, Quantities::length);
157157
connectSubModel(model);
158158
return model;
159159
}
@@ -202,8 +202,10 @@ DampingModel* MainModel::getDampingModel() {
202202
}
203203

204204
LineModel* MainModel::getLineModel(int index) {
205-
if(bow.has_value() && index >= 0 && index < bow->profile.segments.size() && std::holds_alternative<Line>(bow->profile.segments[index])) {
206-
auto model = new LineModel(std::get<Line>(bow->profile.segments[index]));
205+
ProfileSegment& segment = *std::next(bow->profile.segments.begin(), index);
206+
207+
if(bow.has_value() && index >= 0 && index < bow->profile.segments.size() && std::holds_alternative<Line>(segment)) {
208+
auto model = new LineModel(std::get<Line>(segment));
207209
connectSubModel(model);
208210
return model;
209211
}
@@ -212,8 +214,10 @@ LineModel* MainModel::getLineModel(int index) {
212214
}
213215

214216
ArcModel* MainModel::getArcModel(int index) {
215-
if(bow.has_value() && index >= 0 && index < bow->profile.segments.size() && std::holds_alternative<Arc>(bow->profile.segments[index])) {
216-
auto model = new ArcModel(std::get<Arc>(bow->profile.segments[index]));
217+
ProfileSegment& segment = *std::next(bow->profile.segments.begin(), index);
218+
219+
if(bow.has_value() && index >= 0 && index < bow->profile.segments.size() && std::holds_alternative<Arc>(segment)) {
220+
auto model = new ArcModel(std::get<Arc>(segment));
217221
connectSubModel(model);
218222
return model;
219223
}
@@ -222,8 +226,10 @@ ArcModel* MainModel::getArcModel(int index) {
222226
}
223227

224228
SpiralModel* MainModel::getSpiralModel(int index) {
225-
if(bow.has_value() && index >= 0 && index < bow->profile.segments.size() && std::holds_alternative<Spiral>(bow->profile.segments[index])) {
226-
auto model = new SpiralModel(std::get<Spiral>(bow->profile.segments[index]));
229+
ProfileSegment& segment = *std::next(bow->profile.segments.begin(), index);
230+
231+
if(bow.has_value() && index >= 0 && index < bow->profile.segments.size() && std::holds_alternative<Spiral>(segment)) {
232+
auto model = new SpiralModel(std::get<Spiral>(segment));
227233
connectSubModel(model);
228234
return model;
229235
}
@@ -232,8 +238,10 @@ SpiralModel* MainModel::getSpiralModel(int index) {
232238
}
233239

234240
TableModel* MainModel::getSplineModel(int index) {
235-
if(bow.has_value() && index >= 0 && index < bow->profile.segments.size() && std::holds_alternative<Spline>(bow->profile.segments[index])) {
236-
auto model = new TableModel(std::get<Spline>(bow->profile.segments[index]).points, "X", "Y", Quantities::length, Quantities::length);
241+
ProfileSegment& segment = *std::next(bow->profile.segments.begin(), index);
242+
243+
if(bow.has_value() && index >= 0 && index < bow->profile.segments.size() && std::holds_alternative<Spline>(segment)) {
244+
auto model = new TableModel(std::get<Spline>(segment).points, "X", "Y", Quantities::length, Quantities::length);
237245
connectSubModel(model);
238246
return model;
239247
}

gui/source/pre/models/MainTreeModel.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ void MainTreeModel::insertLayer(int row) {
8888
QModelIndex parent = createIndex(TopLevelItem::LAYERS, 0, ItemType::TOPLEVEL);
8989
beginInsertRows(parent, row, row);
9090

91-
auto position = bow->section.layers.begin() + row;
91+
auto position = std::next(bow->section.layers.begin(), row);
9292
bow->section.layers.insert(position, layer);
9393

9494
endInsertRows();
@@ -120,7 +120,7 @@ void MainTreeModel::insertSegment(int row, SegmentType type) {
120120
QModelIndex parent = createIndex(TopLevelItem::PROFILE, 0, ItemType::TOPLEVEL);
121121
beginInsertRows(parent, row, row);
122122

123-
auto position = bow->profile.segments.begin() + row;
123+
auto position = std::next(bow->profile.segments.begin(), row);
124124
bow->profile.segments.insert(position, createDefaultSegment(type));
125125

126126
endInsertRows();
@@ -188,7 +188,7 @@ void MainTreeModel::removeLayer(int row) {
188188

189189
// Remove layer
190190
// Bow will become invalid when the last layer is removed
191-
auto position = bow->section.layers.begin() + row;
191+
auto position = std::next(bow->section.layers.begin(), row);
192192
bow->section.layers.erase(position);
193193

194194
endRemoveRows();
@@ -204,7 +204,7 @@ void MainTreeModel::removeSegment(int row) {
204204

205205
// Remove segment
206206
// Bow will become invalis when the last segment is removed
207-
auto position = bow->profile.segments.begin() + row;
207+
auto position = std::next(bow->profile.segments.begin(), row);
208208
bow->profile.segments.erase(position);
209209

210210
endRemoveRows();
@@ -348,7 +348,7 @@ void MainTreeModel::swapLayers(int i, int j) {
348348
beginMoveRows(parent, j, j, parent, i);
349349

350350
// Swap the two layers
351-
std::swap(bow->section.layers[i], bow->section.layers[j]);
351+
swapListNodes(bow->section.layers, i, j);
352352

353353
endMoveRows();
354354
}
@@ -363,7 +363,7 @@ void MainTreeModel::swapSegments(int i, int j) {
363363
beginMoveRows(parent, j, j, parent, i);
364364

365365
// Swap the two segments
366-
std::swap(bow->profile.segments[i], bow->profile.segments[j]);
366+
swapListNodes(bow->profile.segments, i, j);
367367

368368
endMoveRows();
369369
}
@@ -479,7 +479,7 @@ QVariant MainTreeModel::data(const QModelIndex &index, int role) const {
479479
}
480480

481481
if(index.parent().row() == TopLevelItem::LAYERS) {
482-
auto& layer = bow->section.layers[index.row()];
482+
auto& layer = *std::next(bow->section.layers.begin(), index.row());
483483
switch(role) {
484484
case Qt::DisplayRole: case Qt::EditRole: return QString::fromStdString(layer.name);
485485
case Qt::ToolTipRole: return "User-defined layer \"" + QString::fromStdString(layer.name) + "\"";
@@ -535,7 +535,7 @@ bool MainTreeModel::setData(const QModelIndex &index, const QVariant &value, int
535535
return false;
536536
}
537537

538-
bow->section.layers[index.row()].name = name;
538+
std::next(bow->section.layers.begin(), index.row())->name = name;
539539
emit dataChanged(index, index);
540540
return true;
541541
}
@@ -592,7 +592,7 @@ QIcon MainTreeModel::topLevelItemIcon(int row) const {
592592
}
593593

594594
QString MainTreeModel::segmentName(int row) const {
595-
ProfileSegment segment = bow->profile.segments[row];
595+
ProfileSegment& segment = *std::next(bow->profile.segments.begin(), row);
596596

597597
if(std::holds_alternative<Line>(segment)) {
598598
return "Line";
@@ -611,7 +611,7 @@ QString MainTreeModel::segmentName(int row) const {
611611
}
612612

613613
QString MainTreeModel::segmentTooltip(int row) const {
614-
ProfileSegment segment = bow->profile.segments[row];
614+
ProfileSegment& segment = *std::next(bow->profile.segments.begin(), row);
615615

616616
if(std::holds_alternative<Line>(segment)) {
617617
return "Line segment defined by a single length";
@@ -631,7 +631,7 @@ QString MainTreeModel::segmentTooltip(int row) const {
631631
}
632632

633633
QIcon MainTreeModel::segmentIcon(int row) const {
634-
ProfileSegment segment = bow->profile.segments[row];
634+
ProfileSegment& segment = *std::next(bow->profile.segments.begin(), row);
635635

636636
if(std::holds_alternative<Line>(segment)) {
637637
return QIcon(":/icons/segment-line.svg");

gui/source/pre/views/limb2d/HeightPlotView.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ void HeightPlotView::updatePlot() {
6969
}
7070

7171
if(model->hasBow()) {
72-
for(auto& point: model->getBow().section.layers[iLayer].height) {
72+
const Layer& layer = *std::next(model->getBow().section.layers.begin(), iLayer);
73+
for(auto& point: layer.height) {
7374
graphPoints->addData(
7475
Quantities::ratio.getUnit().fromBase(point[0]),
7576
Quantities::length.getUnit().fromBase(point[1])

gui/source/pre/views/limb3d/LimbMesh.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ LimbMesh::LimbMesh(const BowModel& bow, const LimbInfo& geometry)
2121

2222
std::vector<QColor> colors(nLayers);
2323
for(size_t i = 0; i < nLayers; ++i) {
24-
colors[i] = getLayerColor(bow.section.layers[i], bow.section.materials);
24+
colors[i] = getLayerColor(*std::next(bow.section.layers.begin(), i), bow.section.materials);
2525
}
2626

2727
// Iterate over segments, i.e. pairs of a previous and a next cross section

gui/source/solver/BowModel.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ void to_json(nlohmann::json& obj, const ProfileSegment& input);
160160
void from_json(const nlohmann::json& obj, ProfileSegment& input);
161161

162162
struct Profile {
163-
std::vector<ProfileSegment> segments;
163+
std::list<ProfileSegment> segments; // List to keep references valid when swapping around elements
164164
};
165165

166166
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(
@@ -219,7 +219,7 @@ struct Section {
219219
LayerAlignment alignment;
220220
Width width;
221221
std::list<Material> materials; // List to keep references valid when swapping around elements
222-
std::vector<Layer> layers;
222+
std::list<Layer> layers; // List to keep references valid when swapping around elements
223223
};
224224

225225
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(

rust/virtualbow/src/export/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pub mod step;
22
pub mod stl;
3-
3+
/*
44
use iter_num_tools::lin_space;
55
use itertools::Itertools;
66
use nalgebra::{vector, SVector};
@@ -61,4 +61,5 @@ impl LimbExportInfo {
6161
layers
6262
}
6363
}
64-
}
64+
}
65+
*/

rust/virtualbow/src/export/stl.rs

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,11 @@
1+
/*
12
use std::fs::File;
23
use std::io::{BufWriter, Write};
34
use std::path::Path;
45
use itertools::Itertools;
56
use nalgebra::vector;
67
use crate::export::{LayerExportInfo, Point};
78
8-
/*
9-
class STL:
10-
def __init__(self):
11-
self.solids = {}
12-
13-
def add_solid(self, name, triangles):
14-
self.solids[name] = triangles
15-
16-
def save(self, path):
17-
with open(path, 'w') as file:
18-
for (name, triangles) in self.solids.items():
19-
# Begin solid
20-
file.write(f"solid {name}\n")
21-
for (p1, p2, p3) in triangles:
22-
# Calculate facet normal
23-
n = np.cross(p2 - p1, p3 - p1)
24-
norm = np.linalg.norm(n)
25-
26-
if norm > 1e-9: # Exclude triangles with zero area
27-
n = n/norm
28-
29-
# Write facet
30-
file.write(f" facet normal {n[0]} {n[1]} {n[2]}\n")
31-
file.write(" outer loop\n")
32-
file.write(f" vertex {p1[0]} {p1[1]} {p1[2]}\n")
33-
file.write(f" vertex {p2[0]} {p2[1]} {p2[2]}\n")
34-
file.write(f" vertex {p3[0]} {p3[1]} {p3[2]}\n")
35-
file.write(" endloop\n")
36-
file.write(" endfacet\n")
37-
38-
# End solid
39-
file.write("endsolid\n")
40-
*/
41-
429
struct StlSolid {
4310
name: String,
4411
triangles: Vec<[Point; 3]>,
@@ -125,7 +92,7 @@ fn layer_to_stl(layer: &LayerExportInfo, path: &str) {
12592
12693
data.save(path).unwrap();
12794
}
128-
/*
95+
12996
#[cfg(test)]
13097
mod tests {
13198
use crate::export::{LayerExportInfo, LimbExportInfo};

0 commit comments

Comments
 (0)