Files
workinf_Blender_Wasm/blender-5.2.0/extern/quadriflow/patches/blender.patch
2026-08-12 04:47:48 -04:00

558 lines
22 KiB
Diff

diff --git a/extern/quadriflow/3rd/lemon-1.3.1/lemon/arg_parser.cc b/extern/quadriflow/3rd/lemon-1.3.1/lemon/arg_parser.cc
index 35a73d9f308..0eeba8ab6c2 100644
--- a/extern/quadriflow/3rd/lemon-1.3.1/lemon/arg_parser.cc
+++ b/extern/quadriflow/3rd/lemon-1.3.1/lemon/arg_parser.cc
@@ -221,9 +221,8 @@ namespace lemon {
const std::string &opt)
{
Opts::iterator o = _opts.find(opt);
- Opts::iterator s = _opts.find(syn);
LEMON_ASSERT(o!=_opts.end(), "Unknown option: '"+opt+"'");
- LEMON_ASSERT(s==_opts.end(), "Option already used: '"+syn+"'");
+ LEMON_ASSERT(_opts.find(syn)==_opts.end(), "Option already used: '"+syn+"'");
ParData p;
p.help=opt;
p.mandatory=false;
diff --git a/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/array_map.h b/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/array_map.h
index 355ee008246..a770bbee60c 100644
--- a/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/array_map.h
+++ b/extern/quadriflow/3rd/lemon-1.3.1/lemon/bits/array_map.h
@@ -88,7 +88,7 @@ namespace lemon {
Item it;
for (nf->first(it); it != INVALID; nf->next(it)) {
int id = nf->id(it);;
- allocator.construct(&(values[id]), Value());
+ std::allocator_traits<Allocator>::construct(allocator, &(values[id]), Value());
}
}
@@ -218,15 +218,15 @@ namespace lemon {
for (nf->first(it); it != INVALID; nf->next(it)) {
int jd = nf->id(it);;
if (id != jd) {
- allocator.construct(&(new_values[jd]), values[jd]);
- allocator.destroy(&(values[jd]));
+ std::allocator_traits<Allocator>::construct(allocator, &(new_values[jd]), values[jd]);
+ std::allocator_traits<Allocator>::destroy(allocator, &(values[jd]));
}
}
if (capacity != 0) allocator.deallocate(values, capacity);
values = new_values;
capacity = new_capacity;
}
- allocator.construct(&(values[id]), Value());
+ std::allocator_traits<Allocator>::construct(allocator, &(values[id]), Value());
}
// \brief Adds more new keys to the map.
@@ -260,8 +260,8 @@ namespace lemon {
}
}
if (found) continue;
- allocator.construct(&(new_values[id]), values[id]);
- allocator.destroy(&(values[id]));
+ std::allocator_traits<Allocator>::construct(allocator, &(new_values[id]), values[id]);
+ std::allocator_traits<Allocator>::destroy(allocator, &(values[id]));
}
if (capacity != 0) allocator.deallocate(values, capacity);
values = new_values;
@@ -269,7 +269,7 @@ namespace lemon {
}
for (int i = 0; i < int(keys.size()); ++i) {
int id = nf->id(keys[i]);
- allocator.construct(&(values[id]), Value());
+ std::allocator_traits<Allocator>::construct(allocator, &(values[id]), Value());
}
}
@@ -279,7 +279,7 @@ namespace lemon {
// and it overrides the erase() member function of the observer base.
virtual void erase(const Key& key) {
int id = Parent::notifier()->id(key);
- allocator.destroy(&(values[id]));
+ std::allocator_traits<Allocator>::destroy(allocator, &(values[id]));
}
// \brief Erase more keys from the map.
@@ -289,7 +289,7 @@ namespace lemon {
virtual void erase(const std::vector<Key>& keys) {
for (int i = 0; i < int(keys.size()); ++i) {
int id = Parent::notifier()->id(keys[i]);
- allocator.destroy(&(values[id]));
+ std::allocator_traits<Allocator>::destroy(allocator, &(values[id]));
}
}
@@ -303,7 +303,7 @@ namespace lemon {
Item it;
for (nf->first(it); it != INVALID; nf->next(it)) {
int id = nf->id(it);;
- allocator.construct(&(values[id]), Value());
+ std::allocator_traits<Allocator>::construct(allocator, &(values[id]), Value());
}
}
@@ -317,7 +317,7 @@ namespace lemon {
Item it;
for (nf->first(it); it != INVALID; nf->next(it)) {
int id = nf->id(it);
- allocator.destroy(&(values[id]));
+ std::allocator_traits<Allocator>::destroy(allocator, &(values[id]));
}
allocator.deallocate(values, capacity);
capacity = 0;
diff --git a/extern/quadriflow/3rd/lemon-1.3.1/lemon/network_simplex.h b/extern/quadriflow/3rd/lemon-1.3.1/lemon/network_simplex.h
index 6ccad33e68e..388e990ec3b 100644
--- a/extern/quadriflow/3rd/lemon-1.3.1/lemon/network_simplex.h
+++ b/extern/quadriflow/3rd/lemon-1.3.1/lemon/network_simplex.h
@@ -234,7 +234,7 @@ namespace lemon {
int in_arc, join, u_in, v_in, u_out, v_out;
Value delta;
- const Value MAX;
+ const Value MAX_VALUE;
public:
@@ -649,9 +649,9 @@ namespace lemon {
NetworkSimplex(const GR& graph, bool arc_mixing = true) :
_graph(graph), _node_id(graph), _arc_id(graph),
_arc_mixing(arc_mixing),
- MAX(std::numeric_limits<Value>::max()),
+ MAX_VALUE(std::numeric_limits<Value>::max()),
INF(std::numeric_limits<Value>::has_infinity ?
- std::numeric_limits<Value>::infinity() : MAX)
+ std::numeric_limits<Value>::infinity() : MAX_VALUE)
{
// Check the number types
LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
@@ -1076,9 +1076,9 @@ namespace lemon {
for (int i = 0; i != _arc_num; ++i) {
Value c = _lower[i];
if (c >= 0) {
- _cap[i] = _upper[i] < MAX ? _upper[i] - c : INF;
+ _cap[i] = _upper[i] < MAX_VALUE ? _upper[i] - c : INF;
} else {
- _cap[i] = _upper[i] < MAX + c ? _upper[i] - c : INF;
+ _cap[i] = _upper[i] < MAX_VALUE + c ? _upper[i] - c : INF;
}
_supply[_source[i]] -= c;
_supply[_target[i]] += c;
@@ -1282,7 +1282,7 @@ namespace lemon {
d = _flow[e];
if (_pred_dir[u] == DIR_DOWN) {
c = _cap[e];
- d = c >= MAX ? INF : c - d;
+ d = c >= MAX_VALUE ? INF : c - d;
}
if (d < delta) {
delta = d;
@@ -1297,7 +1297,7 @@ namespace lemon {
d = _flow[e];
if (_pred_dir[u] == DIR_UP) {
c = _cap[e];
- d = c >= MAX ? INF : c - d;
+ d = c >= MAX_VALUE ? INF : c - d;
}
if (d <= delta) {
delta = d;
@@ -1559,7 +1559,7 @@ namespace lemon {
_pi[_target[in_arc]]) >= 0) continue;
findJoinNode();
bool change = findLeavingArc();
- if (delta >= MAX) return false;
+ if (delta >= MAX_VALUE) return false;
changeFlow(change);
if (change) {
updateTreeStructure();
@@ -1598,7 +1598,7 @@ namespace lemon {
while (pivot.findEnteringArc()) {
findJoinNode();
bool change = findLeavingArc();
- if (delta >= MAX) return UNBOUNDED;
+ if (delta >= MAX_VALUE) return UNBOUNDED;
changeFlow(change);
if (change) {
updateTreeStructure();
diff --git a/extern/quadriflow/3rd/lemon-1.3.1/lemon/random.h b/extern/quadriflow/3rd/lemon-1.3.1/lemon/random.h
index 8de74ede8a9..f9861f39169 100644
--- a/extern/quadriflow/3rd/lemon-1.3.1/lemon/random.h
+++ b/extern/quadriflow/3rd/lemon-1.3.1/lemon/random.h
@@ -249,8 +249,8 @@ namespace lemon {
current = state + length;
- register Word *curr = state + length - 1;
- register long num;
+ Word *curr = state + length - 1;
+ long num;
num = length - shift;
while (num--) {
diff --git a/extern/quadriflow/src/hierarchy.cpp b/extern/quadriflow/src/hierarchy.cpp
index c333256a139..70a9628320f 100644
--- a/extern/quadriflow/src/hierarchy.cpp
+++ b/extern/quadriflow/src/hierarchy.cpp
@@ -269,7 +269,13 @@ void Hierarchy::DownsampleGraph(const AdjacentMatrix adj, const MatrixXd& V, con
for (auto it = ad.begin(); it != ad.end(); ++it, ++entry_it) {
int k = it->id;
double dp = N.col(i).dot(N.col(k));
- double ratio = A[i] > A[k] ? (A[i] / A[k]) : (A[k] / A[i]);
+ double ratio;
+ if (A[i] > A[k]) {
+ ratio = (A[k] == 0.0f) ? 1.0f : A[i] / A[k];
+ }
+ else {
+ ratio = (A[i] == 0.0f) ? 1.0f : A[k] / A[i];
+ }
*entry_it = Entry(i, k, dp * ratio);
}
}
@@ -1133,7 +1139,8 @@ void Hierarchy::propagateConstraints() {
auto& COw = mCOw[l];
auto& COw_next = mCOw[l + 1];
auto& toUpper = mToUpper[l];
- MatrixXd& S = mS[l];
+ // FIXME
+ // MatrixXd& S = mS[l];
for (uint32_t i = 0; i != mV[l + 1].cols(); ++i) {
Vector2i upper = toUpper.col(i);
diff --git a/extern/quadriflow/src/loader.cpp b/extern/quadriflow/src/loader.cpp
index aa27066e6e4..5b9d717db71 100644
--- a/extern/quadriflow/src/loader.cpp
+++ b/extern/quadriflow/src/loader.cpp
@@ -8,6 +8,7 @@
#include "loader.hpp"
+#include <cstdint>
#include <fstream>
#include <unordered_map>
@@ -69,7 +70,7 @@ void load(const char* filename, MatrixXd& V, MatrixXi& F)
};
/// Hash function for obj_vertex
- struct obj_vertexHash : std::unary_function<obj_vertex, size_t> {
+ struct obj_vertexHash {
std::size_t operator()(const obj_vertex &v) const {
size_t hash = std::hash<uint32_t>()(v.p);
hash = hash * 37 + std::hash<uint32_t>()(v.uv);
diff --git a/extern/quadriflow/src/flow.hpp b/extern/quadriflow/src/flow.hpp
index ab4a01c..a77f7ae 100644
--- a/extern/quadriflow/src/flow.hpp
+++ b/extern/quadriflow/src/flow.hpp
@@ -7,17 +7,12 @@
#include <vector>
#include "config.hpp"
-
-#include <boost/graph/adjacency_list.hpp>
-#include <boost/graph/boykov_kolmogorov_max_flow.hpp>
-#include <boost/graph/edmonds_karp_max_flow.hpp>
-#include <boost/graph/push_relabel_max_flow.hpp>
+#include "../patches/boykov_kolmogorov_max_flow.hpp"
#include <lemon/network_simplex.h>
#include <lemon/preflow.h>
#include <lemon/smart_graph.h>
-using namespace boost;
using namespace Eigen;
namespace qflow {
@@ -34,78 +29,52 @@ class MaxFlowHelper {
class BoykovMaxFlowHelper : public MaxFlowHelper {
public:
- typedef int EdgeWeightType;
- typedef adjacency_list_traits<vecS, vecS, directedS> Traits;
- // clang-format off
- typedef adjacency_list < vecS, vecS, directedS,
- property < vertex_name_t, std::string,
- property < vertex_index_t, long,
- property < vertex_color_t, boost::default_color_type,
- property < vertex_distance_t, long,
- property < vertex_predecessor_t, Traits::edge_descriptor > > > > >,
-
- property < edge_capacity_t, EdgeWeightType,
- property < edge_residual_capacity_t, EdgeWeightType,
- property < edge_reverse_t, Traits::edge_descriptor > > > > Graph;
- // clang-format on
-
- public:
- BoykovMaxFlowHelper() { rev = get(edge_reverse, g); }
- void resize(int n, int m) {
- vertex_descriptors.resize(n);
- for (int i = 0; i < n; ++i) vertex_descriptors[i] = add_vertex(g);
- }
- int compute() {
- EdgeWeightType flow =
- boykov_kolmogorov_max_flow(g, vertex_descriptors.front(), vertex_descriptors.back());
- return flow;
+ BoykovMaxFlowHelper() = default;
+ void resize(int n, int m) override {
+ num_verts = n;
+ num_edges = 0;
+ flow.resize(num_verts, m * 2);
}
- void addDirectEdge(Traits::vertex_descriptor& v1, Traits::vertex_descriptor& v2,
- property_map<Graph, edge_reverse_t>::type& rev, const int capacity,
- const int inv_capacity, Graph& g, Traits::edge_descriptor& e1,
- Traits::edge_descriptor& e2) {
- e1 = add_edge(v1, v2, g).first;
- e2 = add_edge(v2, v1, g).first;
- put(edge_capacity, g, e1, capacity);
- put(edge_capacity, g, e2, inv_capacity);
-
- rev[e1] = e2;
- rev[e2] = e1;
+ int compute() override {
+ return flow.max_flow(0, num_verts - 1);
}
- void addEdge(int x, int y, int c, int rc, int v, int cost = 1) {
- Traits::edge_descriptor e1, e2;
- addDirectEdge(vertex_descriptors[x], vertex_descriptors[y], rev, c, rc, g, e1, e2);
+ void addEdge(int x, int y, int c, int rc, int v, int cost = 1) override {
+ const int e1 = num_edges++;
+ const int e2 = num_edges++;
+ flow.set_edge(e1, e2, x, y, c);
+ flow.set_edge(e2, e1, y, x, rc);
if (v != -1) {
- edge_to_variables[e1] = std::make_pair(v, -1);
- edge_to_variables[e2] = std::make_pair(v, 1);
+ edge_to_variables.emplace_back(v, -1);
+ edge_to_variables.emplace_back(v, 1);
+ }
+ else {
+ edge_to_variables.emplace_back(-1, -1);
+ edge_to_variables.emplace_back(-1, -1);
}
}
- void applyTo(std::vector<Vector2i>& edge_diff) {
- property_map<Graph, edge_capacity_t>::type capacity = get(edge_capacity, g);
- property_map<Graph, edge_residual_capacity_t>::type residual_capacity =
- get(edge_residual_capacity, g);
-
- graph_traits<Graph>::vertex_iterator u_iter, u_end;
- graph_traits<Graph>::out_edge_iterator ei, e_end;
- for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
- for (tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
- if (capacity[*ei] > 0) {
- int flow = (capacity[*ei] - residual_capacity[*ei]);
+ void applyTo(std::vector<Vector2i>& edge_diff) override {
+ for (int vert = 0; vert < num_verts; vert++) {
+ for (int edge : flow.vertex_out_edges(vert)) {
+ const int capacity = flow.edge_capacity(edge);
+ const int residual_capacity = flow.edge_residual_capacity(edge);
+ if (capacity > 0) {
+ int flow = (capacity - residual_capacity);
if (flow > 0) {
- auto it = edge_to_variables.find(*ei);
- if (it != edge_to_variables.end()) {
- edge_diff[it->second.first / 2][it->second.first % 2] +=
- it->second.second * flow;
+ std::pair<int, int> e2v = edge_to_variables[edge];
+ if (e2v.first != -1) {
+ edge_diff[e2v.first / 2][e2v.first % 2] += e2v.second * flow;
}
}
}
+ }
+ }
}
private:
- Graph g;
- property_map<Graph, edge_reverse_t>::type rev;
- std::vector<Traits::vertex_descriptor> vertex_descriptors;
- std::map<Traits::edge_descriptor, std::pair<int, int>> edge_to_variables;
+ BoykovKolmogorovMaxFlow flow;
+ std::vector<std::pair<int, int>> edge_to_variables;
+ int num_verts = 0;
+ int num_edges = 0;
};
class NetworkSimplexFlowHelper : public MaxFlowHelper {
diff --git a/extern/quadriflow/src/main.cpp b/extern/quadriflow/src/main.cpp
index 18bc4063c42..63c9e61b8c9 100644
--- a/extern/quadriflow/src/main.cpp
+++ b/extern/quadriflow/src/main.cpp
@@ -110,7 +110,10 @@ int main(int argc, char** argv) {
printf("Use %lf seconds\n", (t2 - t1) * 1e-3);
t1 = GetCurrentTime64();
printf("Solve index map...\n");
- field.ComputeIndexMap();
+ if (!field.ComputeIndexMap()) {
+ fprintf(stderr, "Failed to solve result, exiting!\n");
+ return 1;
+ }
t2 = GetCurrentTime64();
printf("Indexmap Use %lf seconds\n", (t2 - t1) * 1e-3);
printf("Writing the file...\n");
diff --git a/extern/quadriflow/src/parametrizer.cpp b/extern/quadriflow/src/parametrizer.cpp
index b85383566c9..3dbdc386eca 100644
--- a/extern/quadriflow/src/parametrizer.cpp
+++ b/extern/quadriflow/src/parametrizer.cpp
@@ -18,7 +18,7 @@
namespace qflow {
-void Parametrizer::ComputeIndexMap(int with_scale) {
+bool Parametrizer::ComputeIndexMap(int with_scale) {
// build edge info
auto& V = hierarchy.mV[0];
auto& F = hierarchy.mF;
@@ -80,9 +80,12 @@ void Parametrizer::ComputeIndexMap(int with_scale) {
#ifdef LOG_OUTPUT
printf("subdivide...\n");
#endif
- subdivide_edgeDiff(F, V, N, Q, O, &hierarchy.mS[0], V2E, hierarchy.mE2E, boundary, nonManifold,
- edge_diff, edge_values, face_edgeOrients, face_edgeIds, sharp_edges,
- singularities, 1);
+ if (!subdivide_edgeDiff(F, V, N, Q, O, &hierarchy.mS[0], V2E, hierarchy.mE2E, boundary, nonManifold,
+ edge_diff, edge_values, face_edgeOrients, face_edgeIds, sharp_edges,
+ singularities, 1))
+ {
+ return false;
+ }
allow_changes.clear();
allow_changes.resize(edge_diff.size() * 2, 1);
@@ -99,9 +102,12 @@ void Parametrizer::ComputeIndexMap(int with_scale) {
int t1 = GetCurrentTime64();
#endif
FixFlipHierarchy();
- subdivide_edgeDiff(F, V, N, Q, O, &hierarchy.mS[0], V2E, hierarchy.mE2E, boundary, nonManifold,
+ if (!subdivide_edgeDiff(F, V, N, Q, O, &hierarchy.mS[0], V2E, hierarchy.mE2E, boundary, nonManifold,
edge_diff, edge_values, face_edgeOrients, face_edgeIds, sharp_edges,
- singularities, 1);
+ singularities, 1))
+ {
+ return false;
+ }
FixFlipSat();
#ifdef LOG_OUTPUT
@@ -242,6 +248,7 @@ void Parametrizer::ComputeIndexMap(int with_scale) {
// E2E_compact,
// V, N, Q, O, F, V2E, hierarchy.mE2E, disajoint_tree,
// hierarchy.mScale, false);
+ return true;
}
} // namespace qflow
diff --git a/extern/quadriflow/src/parametrizer.hpp b/extern/quadriflow/src/parametrizer.hpp
index 1f4a02be6c2..9703ebbfff6 100644
--- a/extern/quadriflow/src/parametrizer.hpp
+++ b/extern/quadriflow/src/parametrizer.hpp
@@ -54,7 +54,8 @@ class Parametrizer {
void ComputePositionSingularities();
// Integer Grid Map Pipeline
- void ComputeIndexMap(int with_scale = 0);
+ // Return false when the solver fails.
+ bool ComputeIndexMap(int with_scale = 0);
void BuildEdgeInfo();
void ComputeMaxFlow();
void MarkInteger();
diff --git a/extern/quadriflow/src/post-solver.cpp b/extern/quadriflow/src/post-solver.cpp
index 6027ddd..ccefd15 100644
--- a/extern/quadriflow/src/post-solver.cpp
+++ b/extern/quadriflow/src/post-solver.cpp
@@ -5,7 +5,9 @@
// Created by Jingwei on 2/5/18.
//
#include <algorithm>
+#ifdef POST_SOLVER
#include <boost/program_options.hpp>
+#endif
#include <cmath>
#include <cstdio>
#include <string>
diff --git a/extern/quadriflow/src/subdivide.cpp b/extern/quadriflow/src/subdivide.cpp
index c408bbc6394..babff96ccb4 100644
--- a/extern/quadriflow/src/subdivide.cpp
+++ b/extern/quadriflow/src/subdivide.cpp
@@ -145,7 +145,7 @@ void subdivide(MatrixXi &F, MatrixXd &V, VectorXd& rho, VectorXi &V2E, VectorXi
E2E.conservativeResize(nF * 3);
}
-void subdivide_edgeDiff(MatrixXi &F, MatrixXd &V, MatrixXd &N, MatrixXd &Q, MatrixXd &O, MatrixXd* S,
+bool subdivide_edgeDiff(MatrixXi &F, MatrixXd &V, MatrixXd &N, MatrixXd &Q, MatrixXd &O, MatrixXd* S,
VectorXi &V2E, VectorXi &E2E, VectorXi &boundary, VectorXi &nonmanifold,
std::vector<Vector2i> &edge_diff, std::vector<DEdge> &edge_values,
std::vector<Vector3i> &face_edgeOrients, std::vector<Vector3i> &face_edgeIds,
@@ -500,17 +500,18 @@ void subdivide_edgeDiff(MatrixXi &F, MatrixXd &V, MatrixXd &N, MatrixXd &Q, Matr
for (int j = 0; j < 3; ++j) {
auto diff = edge_diff[face_edgeIds[i][j]];
if (abs(diff[0]) > 1 || abs(diff[1]) > 1) {
- printf("wrong init %d %d!\n", face_edgeIds[i][j], i * 3 + j);
- exit(0);
+ fprintf(stderr, "wrong init %d %d!\n", face_edgeIds[i][j], i * 3 + j);
+ return false;
}
}
}
for (int i = 0; i < edge_diff.size(); ++i) {
if (abs(edge_diff[i][0]) > 1 || abs(edge_diff[i][1]) > 1) {
- printf("wrong...\n");
- exit(0);
+ fprintf(stderr, "wrong...\n");
+ return false;
}
}
+ return true;
}
} // namespace qflow
diff --git a/extern/quadriflow/src/subdivide.hpp b/extern/quadriflow/src/subdivide.hpp
index a93c58ac2a7..8c682b6d9f2 100644
--- a/extern/quadriflow/src/subdivide.hpp
+++ b/extern/quadriflow/src/subdivide.hpp
@@ -9,7 +9,8 @@ namespace qflow {
void subdivide(MatrixXi &F, MatrixXd &V, VectorXd& rho, VectorXi &V2E, VectorXi &E2E, VectorXi &boundary,
VectorXi &nonmanifold, double maxLength);
-void subdivide_edgeDiff(MatrixXi &F, MatrixXd &V, MatrixXd &N, MatrixXd &Q, MatrixXd &O, MatrixXd* S,
+// Return false when solving fails.
+bool subdivide_edgeDiff(MatrixXi &F, MatrixXd &V, MatrixXd &N, MatrixXd &Q, MatrixXd &O, MatrixXd* S,
VectorXi &V2E, VectorXi &E2E, VectorXi &boundary, VectorXi &nonmanifold,
std::vector<Vector2i> &edge_diff, std::vector<DEdge> &edge_values,
std::vector<Vector3i> &face_edgeOrients, std::vector<Vector3i> &face_edgeIds,
diff --git a/extern/quadriflow/src/optimizer.cpp b/extern/quadriflow/src/optimizer.cpp
index 1c59ad0f70c..f8836ed0d0e 100644
--- a/extern/quadriflow/src/optimizer.cpp
+++ b/extern/quadriflow/src/optimizer.cpp
@@ -1296,7 +1296,9 @@ void Optimizer::optimize_integer_constraints(Hierarchy& mRes, std::map<int, int>
solver = std::make_unique<GurobiFlowHelper>();
}
#endif
- solver->resize(initial.size() + 2, arc_ids.size());
+ /* This used to be arc_ids.size() which is wrong, the loop below adds
+ * exactly arcs.size() edges. */
+ solver->resize(initial.size() + 2, arcs.size());
std::set<int> ids;
for (int i = 0; i < arcs.size(); ++i) {
diff --git a/extern/quadriflow/src/field-math.hpp b/extern/quadriflow/src/field-math.hpp
index 86ed4b2b1f4..3f4fe3fa097 100644
--- a/extern/quadriflow/src/field-math.hpp
+++ b/extern/quadriflow/src/field-math.hpp
@@ -292,7 +292,6 @@ inline Vector3d Travel(Vector3d p, const Vector3d &dir, double &len, int &f, Vec
double max_len = 1e30;
bool found = false;
int next_id, next_f;
- Vector3d next_q;
Matrix3d m, n;
m.col(0) = t1;
m.col(1) = t2;
@@ -399,7 +398,6 @@ inline Vector3d TravelField(Vector3d p, Vector3d &pt, double &len, int &f, Vecto
double max_len = 1e30;
bool found = false;
int next_id = -1, next_f = -1;
- Vector3d next_q;
Matrix3d m, n;
m.col(0) = t1;
m.col(1) = t2;