Blender V4.3
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
9#include <stdlib.h>
10#include <string>
11#include <vector>
12
13#include "area_compensation.h"
14#include "doublearea.h"
17#include "slim.h"
18#include "uv_initializer.h"
19
20#include <Eigen/Dense>
21#include <Eigen/Sparse>
22#include <Eigen/SparseCholesky>
23
24namespace slim {
25
26using namespace Eigen;
27
28static void transfer_uvs_back_to_native_part(MatrixTransferChart &chart, Eigen::MatrixXd &uv)
29{
30 if (!chart.succeeded) {
31 return;
32 }
33
34 auto &uv_coordinate_array = chart.uv_matrices;
35 int number_of_vertices = chart.verts_num;
36
37 for (int i = 0; i < number_of_vertices; i++) {
38 uv_coordinate_array[i] = uv(i, 0);
39 uv_coordinate_array[number_of_vertices + i] = uv(i, 1);
40 }
41}
42
44 const SLIMData &slim_data)
45{
46 Eigen::MatrixXd original_map_weighted = blend * slim_data.oldUVs;
47 Eigen::MatrixXd interactive_result_map = (1.0 - blend) * slim_data.V_o;
48 return original_map_weighted + interactive_result_map;
49}
50
51static void adjust_pins(SLIMData &slim_data, const PinnedVertexData &pinned_vertex_data)
52{
53 if (!slim_data.valid) {
54 return;
55 }
56
57 auto &pinned_vertex_indices = pinned_vertex_data.pinned_vertex_indices;
58 auto &pinned_vertex_positions_2D = pinned_vertex_data.pinned_vertex_positions_2D;
59 auto &selected_pins = pinned_vertex_data.selected_pins;
60
61 int n_pins = pinned_vertex_indices.size();
62 int n_selected_pins = selected_pins.size();
63
64 Eigen::VectorXi old_pin_indices = slim_data.b;
65 Eigen::MatrixXd old_pin_positions = slim_data.bc;
66
67 slim_data.b.resize(n_pins);
68 slim_data.bc.resize(n_pins, 2);
69
70 int old_pin_pointer = 0;
71 int selected_pin_pointer = 0;
72
73 for (int new_pin_pointer = 0; new_pin_pointer < n_pins; new_pin_pointer++) {
74
75 int pinned_vertex_index = pinned_vertex_indices[new_pin_pointer];
76 slim_data.b(new_pin_pointer) = pinned_vertex_index;
77
78 while ((old_pin_pointer < old_pin_indices.size()) &&
79 (old_pin_indices(old_pin_pointer) < pinned_vertex_index))
80 {
81 ++old_pin_pointer;
82 }
83 bool old_pointer_valid = (old_pin_pointer < old_pin_indices.size()) &&
84 (old_pin_indices(old_pin_pointer) == pinned_vertex_index);
85
86 while ((selected_pin_pointer < n_selected_pins) &&
87 (selected_pins[selected_pin_pointer] < pinned_vertex_index))
88 {
89 ++selected_pin_pointer;
90 }
91 bool pin_selected = (selected_pin_pointer < n_selected_pins) &&
92 (selected_pins[selected_pin_pointer] == pinned_vertex_index);
93
94 if (!pin_selected && old_pointer_valid) {
95 slim_data.bc.row(new_pin_pointer) = old_pin_positions.row(old_pin_pointer);
96 }
97 else {
98 slim_data.bc(new_pin_pointer, 0) = pinned_vertex_positions_2D[2 * new_pin_pointer];
99 slim_data.bc(new_pin_pointer, 1) = pinned_vertex_positions_2D[2 * new_pin_pointer + 1];
100 }
101 }
102}
103
105{
106 if (!succeeded) {
107 return;
108 }
109
110 Eigen::MatrixXd blended_uvs = get_interactive_result_blended_with_original(blend, *data);
112 transfer_uvs_back_to_native_part(*this, blended_uvs);
113}
114
116{
117 if (!succeeded) {
118 return;
119 }
120
121 try {
122 slim_solve(*data, iter_num);
123 }
124 catch (SlimFailedException &) {
125 succeeded = false;
126 }
127}
128
130{
131 int number_of_iterations = 1;
132 try_slim_solve(number_of_iterations);
133}
134
136 const PinnedVertexData &pinned_vertex_data)
137{
138 int number_of_iterations = 3;
140
141 chart.try_slim_solve(number_of_iterations);
142
144 transfer_uvs_back_to_native_part(chart, chart.data->V_o);
145}
146
148{
149 for (MatrixTransferChart &chart : charts) {
150 setup_slim_data(chart);
151
152 chart.try_slim_solve(n_iterations);
153
155 transfer_uvs_back_to_native_part(chart, chart.data->V_o);
156
157 chart.free_slim_data();
158 }
159}
160
161} // 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:764
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