Blender V5.0
slim_parametrizer.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdlib>
10
11#include "slim.h"
13
14#include "area_compensation.h"
15
16#include <Eigen/Dense>
17#include <Eigen/Sparse>
18#include <Eigen/SparseCholesky>
19
20namespace slim {
21
22using namespace Eigen;
23
24static void transfer_uvs_back_to_native_part(MatrixTransferChart &chart, Eigen::MatrixXd &uv)
25{
26 if (!chart.succeeded) {
27 return;
28 }
29
30 auto &uv_coordinate_array = chart.uv_matrices;
31 int number_of_vertices = chart.verts_num;
32
33 for (int i = 0; i < number_of_vertices; i++) {
34 uv_coordinate_array[i] = uv(i, 0);
35 uv_coordinate_array[number_of_vertices + i] = uv(i, 1);
36 }
37}
38
40 const SLIMData &slim_data)
41{
42 Eigen::MatrixXd original_map_weighted = blend * slim_data.oldUVs;
43 Eigen::MatrixXd interactive_result_map = (1.0 - blend) * slim_data.V_o;
44 return original_map_weighted + interactive_result_map;
45}
46
47static void adjust_pins(SLIMData &slim_data, const PinnedVertexData &pinned_vertex_data)
48{
49 if (!slim_data.valid) {
50 return;
51 }
52
53 const auto &pinned_vertex_indices = pinned_vertex_data.pinned_vertex_indices;
54 const auto &pinned_vertex_positions_2D = pinned_vertex_data.pinned_vertex_positions_2D;
55 const auto &selected_pins = pinned_vertex_data.selected_pins;
56
57 int n_pins = pinned_vertex_indices.size();
58 int n_selected_pins = selected_pins.size();
59
60 Eigen::VectorXi old_pin_indices = slim_data.b;
61 Eigen::MatrixXd old_pin_positions = slim_data.bc;
62
63 slim_data.b.resize(n_pins);
64 slim_data.bc.resize(n_pins, 2);
65
66 int old_pin_pointer = 0;
67 int selected_pin_pointer = 0;
68
69 for (int new_pin_pointer = 0; new_pin_pointer < n_pins; new_pin_pointer++) {
70
71 int pinned_vertex_index = pinned_vertex_indices[new_pin_pointer];
72 slim_data.b(new_pin_pointer) = pinned_vertex_index;
73
74 while ((old_pin_pointer < old_pin_indices.size()) &&
75 (old_pin_indices(old_pin_pointer) < pinned_vertex_index))
76 {
77 ++old_pin_pointer;
78 }
79 bool old_pointer_valid = (old_pin_pointer < old_pin_indices.size()) &&
80 (old_pin_indices(old_pin_pointer) == pinned_vertex_index);
81
82 while ((selected_pin_pointer < n_selected_pins) &&
83 (selected_pins[selected_pin_pointer] < pinned_vertex_index))
84 {
85 ++selected_pin_pointer;
86 }
87 bool pin_selected = (selected_pin_pointer < n_selected_pins) &&
88 (selected_pins[selected_pin_pointer] == pinned_vertex_index);
89
90 if (!pin_selected && old_pointer_valid) {
91 slim_data.bc.row(new_pin_pointer) = old_pin_positions.row(old_pin_pointer);
92 }
93 else {
94 slim_data.bc(new_pin_pointer, 0) = pinned_vertex_positions_2D[2 * new_pin_pointer];
95 slim_data.bc(new_pin_pointer, 1) = pinned_vertex_positions_2D[2 * new_pin_pointer + 1];
96 }
97 }
98}
99
101{
102 if (!succeeded) {
103 return;
104 }
105
106 Eigen::MatrixXd blended_uvs = get_interactive_result_blended_with_original(blend, *data);
108 transfer_uvs_back_to_native_part(*this, blended_uvs);
109}
110
112{
113 if (!succeeded) {
114 return;
115 }
116
117 try {
118 slim_solve(*data, iter_num);
119 }
120 catch (SlimFailedException &) {
121 succeeded = false;
122 }
123}
124
126{
127 int number_of_iterations = 1;
128 try_slim_solve(number_of_iterations);
129}
130
133{
134 int number_of_iterations = 3;
136
137 chart.try_slim_solve(number_of_iterations);
138
140 transfer_uvs_back_to_native_part(chart, chart.data->V_o);
141}
142
144{
145 for (MatrixTransferChart &chart : charts) {
146 setup_slim_data(chart);
147
148 chart.try_slim_solve(n_iterations);
149
151 transfer_uvs_back_to_native_part(chart, chart.data->V_o);
152
153 chart.free_slim_data();
154 }
155}
156
157} // namespace slim
static void adjust_pins(SLIMData &slim_data, const PinnedVertexData &pinned_vertex_data)
static Eigen::MatrixXd get_interactive_result_blended_with_original(float blend, const SLIMData &slim_data)
static void transfer_uvs_back_to_native_part(MatrixTransferChart &chart, Eigen::MatrixXd &uv)
void correct_map_surface_area_if_necessary(SLIMData &slim_data)
Eigen::MatrixXd slim_solve(SLIMData &data, int iter_num)
Definition slim.cpp:787
std::vector< double > uv_matrices
void transfer_uvs_blended(float blend)
void try_slim_solve(int iter_num)
void setup_slim_data(MatrixTransferChart &chart) const
std::vector< MatrixTransferChart > charts
PinnedVertexData pinned_vertex_data
void parametrize_live(MatrixTransferChart &chart, const PinnedVertexData &pinned_vertex_data)
std::vector< int > selected_pins
std::vector< int > pinned_vertex_indices
std::vector< double > pinned_vertex_positions_2D
Eigen::MatrixXd bc
Definition slim.h:44
Eigen::VectorXi b
Definition slim.h:43
Eigen::MatrixXd oldUVs
Definition slim.h:59
bool valid
Definition slim.h:26
Eigen::MatrixXd V_o
Definition slim.h:56
i
Definition text_draw.cc:230
static int blend(const Tex *tex, const float texvec[3], TexResult *texres)