Add Chromium-only Blender WebEngine parity work
This commit is contained in:
30
blender-5.2.0/intern/eigen/CMakeLists.txt
Normal file
30
blender-5.2.0/intern/eigen/CMakeLists.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
# SPDX-FileCopyrightText: 2015 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(INC
|
||||
.
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
eigen_capi.h
|
||||
|
||||
intern/eigenvalues.cc
|
||||
intern/linear_solver.cc
|
||||
intern/matrix.cc
|
||||
intern/svd.cc
|
||||
|
||||
intern/eigenvalues.h
|
||||
intern/linear_solver.h
|
||||
intern/matrix.h
|
||||
intern/svd.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
PRIVATE bf::dependencies::eigen
|
||||
)
|
||||
|
||||
blender_add_lib(bf_intern_eigen "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
17
blender-5.2.0/intern/eigen/eigen_capi.h
Normal file
17
blender-5.2.0/intern/eigen/eigen_capi.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* SPDX-FileCopyrightText: 2015 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
*/
|
||||
|
||||
#ifndef __EIGEN_C_API_H__
|
||||
#define __EIGEN_C_API_H__
|
||||
|
||||
#include "intern/eigenvalues.h" // IWYU pragma: export
|
||||
#include "intern/linear_solver.h" // IWYU pragma: export
|
||||
#include "intern/matrix.h" // IWYU pragma: export
|
||||
#include "intern/svd.h" // IWYU pragma: export
|
||||
|
||||
#endif /* __EIGEN_C_API_H__ */
|
||||
51
blender-5.2.0/intern/eigen/intern/eigenvalues.cc
Normal file
51
blender-5.2.0/intern/eigen/intern/eigenvalues.cc
Normal file
@@ -0,0 +1,51 @@
|
||||
/* SPDX-FileCopyrightText: 2015 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef __EIGEN3_EIGENVALUES_C_API_CC__
|
||||
#define __EIGEN3_EIGENVALUES_C_API_CC__
|
||||
|
||||
/* Eigen gives annoying huge amount of warnings here, silence them! */
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
# pragma GCC diagnostic ignored "-Wlogical-op"
|
||||
#endif
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Eigenvalues>
|
||||
|
||||
#include "eigenvalues.h"
|
||||
|
||||
using Eigen::SelfAdjointEigenSolver;
|
||||
|
||||
using Eigen::Map;
|
||||
using Eigen::MatrixXf;
|
||||
using Eigen::VectorXf;
|
||||
|
||||
using Eigen::Success;
|
||||
|
||||
bool EIG_self_adjoint_eigen_solve(const int size,
|
||||
const float *matrix,
|
||||
float *r_eigen_values,
|
||||
float *r_eigen_vectors)
|
||||
{
|
||||
SelfAdjointEigenSolver<MatrixXf> eigen_solver;
|
||||
|
||||
/* Blender and Eigen matrices are both column-major. */
|
||||
eigen_solver.compute(Map<MatrixXf>((float *)matrix, size, size));
|
||||
|
||||
if (eigen_solver.info() != Success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (r_eigen_values) {
|
||||
Map<VectorXf>(r_eigen_values, size) = eigen_solver.eigenvalues().transpose();
|
||||
}
|
||||
|
||||
if (r_eigen_vectors) {
|
||||
Map<MatrixXf>(r_eigen_vectors, size, size) = eigen_solver.eigenvectors();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* __EIGEN3_EIGENVALUES_C_API_CC__ */
|
||||
25
blender-5.2.0/intern/eigen/intern/eigenvalues.h
Normal file
25
blender-5.2.0/intern/eigen/intern/eigenvalues.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/* SPDX-FileCopyrightText: 2015 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
*/
|
||||
|
||||
#ifndef __EIGEN3_EIGENVALUES_C_API_H__
|
||||
#define __EIGEN3_EIGENVALUES_C_API_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool EIG_self_adjoint_eigen_solve(const int size,
|
||||
const float *matrix,
|
||||
float *r_eigen_values,
|
||||
float *r_eigen_vectors);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EIGEN3_EIGENVALUES_C_API_H__ */
|
||||
362
blender-5.2.0/intern/eigen/intern/linear_solver.cc
Normal file
362
blender-5.2.0/intern/eigen/intern/linear_solver.cc
Normal file
@@ -0,0 +1,362 @@
|
||||
/* SPDX-FileCopyrightText: 2004 Bruno Levy
|
||||
* SPDX-FileCopyrightText: 2005-2015 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
* Sparse linear solver.
|
||||
*/
|
||||
|
||||
#include "linear_solver.h"
|
||||
|
||||
#include <Eigen/Sparse>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
/* Eigen data structures */
|
||||
|
||||
using EigenSparseMatrix = Eigen::SparseMatrix<double, Eigen::ColMajor>;
|
||||
using EigenSparseLU = Eigen::SparseLU<EigenSparseMatrix>;
|
||||
using EigenVectorX = Eigen::VectorXd;
|
||||
using EigenTriplet = Eigen::Triplet<double>;
|
||||
|
||||
/* Linear Solver data structure */
|
||||
|
||||
struct LinearSolver {
|
||||
struct Coeff {
|
||||
Coeff()
|
||||
{
|
||||
index = 0;
|
||||
value = 0.0;
|
||||
}
|
||||
|
||||
int index;
|
||||
double value;
|
||||
};
|
||||
|
||||
struct Variable {
|
||||
Variable()
|
||||
{
|
||||
memset(value, 0, sizeof(value));
|
||||
locked = false;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
double value[4];
|
||||
bool locked;
|
||||
int index;
|
||||
std::vector<Coeff> a;
|
||||
};
|
||||
|
||||
enum State { STATE_VARIABLES_CONSTRUCT, STATE_MATRIX_CONSTRUCT, STATE_MATRIX_SOLVED };
|
||||
|
||||
LinearSolver(int num_rows_, int num_variables_, int num_rhs_, bool lsq_)
|
||||
{
|
||||
assert(num_variables_ > 0);
|
||||
assert(num_rhs_ <= 4);
|
||||
|
||||
state = STATE_VARIABLES_CONSTRUCT;
|
||||
m = 0;
|
||||
n = 0;
|
||||
sparseLU = nullptr;
|
||||
num_variables = num_variables_;
|
||||
num_rhs = num_rhs_;
|
||||
num_rows = num_rows_;
|
||||
least_squares = lsq_;
|
||||
|
||||
variable.resize(num_variables);
|
||||
}
|
||||
|
||||
~LinearSolver()
|
||||
{
|
||||
delete sparseLU;
|
||||
}
|
||||
|
||||
State state;
|
||||
|
||||
int n;
|
||||
int m;
|
||||
|
||||
std::vector<EigenTriplet> Mtriplets;
|
||||
EigenSparseMatrix M;
|
||||
EigenSparseMatrix MtM;
|
||||
std::vector<EigenVectorX> b;
|
||||
std::vector<EigenVectorX> x;
|
||||
|
||||
EigenSparseLU *sparseLU;
|
||||
|
||||
int num_variables;
|
||||
std::vector<Variable> variable;
|
||||
|
||||
int num_rows;
|
||||
int num_rhs;
|
||||
|
||||
bool least_squares;
|
||||
};
|
||||
|
||||
LinearSolver *EIG_linear_solver_new(int num_rows, int num_columns, int num_right_hand_sides)
|
||||
{
|
||||
return new LinearSolver(num_rows, num_columns, num_right_hand_sides, false);
|
||||
}
|
||||
|
||||
LinearSolver *EIG_linear_least_squares_solver_new(int num_rows,
|
||||
int num_columns,
|
||||
int num_right_hand_sides)
|
||||
{
|
||||
return new LinearSolver(num_rows, num_columns, num_right_hand_sides, true);
|
||||
}
|
||||
|
||||
void EIG_linear_solver_delete(LinearSolver *solver)
|
||||
{
|
||||
delete solver;
|
||||
}
|
||||
|
||||
/* Variables */
|
||||
|
||||
void EIG_linear_solver_variable_set(LinearSolver *solver, int rhs, int index, double value)
|
||||
{
|
||||
solver->variable[index].value[rhs] = value;
|
||||
}
|
||||
|
||||
double EIG_linear_solver_variable_get(LinearSolver *solver, int rhs, int index)
|
||||
{
|
||||
return solver->variable[index].value[rhs];
|
||||
}
|
||||
|
||||
void EIG_linear_solver_variable_lock(LinearSolver *solver, int index)
|
||||
{
|
||||
if (!solver->variable[index].locked) {
|
||||
assert(solver->state == LinearSolver::STATE_VARIABLES_CONSTRUCT);
|
||||
solver->variable[index].locked = true;
|
||||
}
|
||||
}
|
||||
|
||||
void EIG_linear_solver_variable_unlock(LinearSolver *solver, int index)
|
||||
{
|
||||
if (solver->variable[index].locked) {
|
||||
assert(solver->state == LinearSolver::STATE_VARIABLES_CONSTRUCT);
|
||||
solver->variable[index].locked = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void linear_solver_variables_to_vector(LinearSolver *solver)
|
||||
{
|
||||
int num_rhs = solver->num_rhs;
|
||||
|
||||
for (int i = 0; i < solver->num_variables; i++) {
|
||||
LinearSolver::Variable *v = &solver->variable[i];
|
||||
if (!v->locked) {
|
||||
for (int j = 0; j < num_rhs; j++) {
|
||||
solver->x[j][v->index] = v->value[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void linear_solver_vector_to_variables(LinearSolver *solver)
|
||||
{
|
||||
int num_rhs = solver->num_rhs;
|
||||
|
||||
for (int i = 0; i < solver->num_variables; i++) {
|
||||
LinearSolver::Variable *v = &solver->variable[i];
|
||||
if (!v->locked) {
|
||||
for (int j = 0; j < num_rhs; j++) {
|
||||
v->value[j] = solver->x[j][v->index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Matrix */
|
||||
|
||||
static void linear_solver_ensure_matrix_construct(LinearSolver *solver)
|
||||
{
|
||||
/* transition to matrix construction if necessary */
|
||||
if (solver->state == LinearSolver::STATE_VARIABLES_CONSTRUCT) {
|
||||
int n = 0;
|
||||
|
||||
for (int i = 0; i < solver->num_variables; i++) {
|
||||
if (solver->variable[i].locked) {
|
||||
solver->variable[i].index = ~0;
|
||||
}
|
||||
else {
|
||||
solver->variable[i].index = n++;
|
||||
}
|
||||
}
|
||||
|
||||
int m = (solver->num_rows == 0) ? n : solver->num_rows;
|
||||
|
||||
solver->m = m;
|
||||
solver->n = n;
|
||||
|
||||
assert(solver->least_squares || m == n);
|
||||
|
||||
/* reserve reasonable estimate */
|
||||
solver->Mtriplets.clear();
|
||||
solver->Mtriplets.reserve(std::max(m, n) * 3);
|
||||
|
||||
solver->b.resize(solver->num_rhs);
|
||||
solver->x.resize(solver->num_rhs);
|
||||
|
||||
for (int i = 0; i < solver->num_rhs; i++) {
|
||||
solver->b[i].setZero(m);
|
||||
solver->x[i].setZero(n);
|
||||
}
|
||||
|
||||
linear_solver_variables_to_vector(solver);
|
||||
|
||||
solver->state = LinearSolver::STATE_MATRIX_CONSTRUCT;
|
||||
}
|
||||
}
|
||||
|
||||
void EIG_linear_solver_matrix_add(LinearSolver *solver, int row, int col, double value)
|
||||
{
|
||||
if (solver->state == LinearSolver::STATE_MATRIX_SOLVED) {
|
||||
return;
|
||||
}
|
||||
|
||||
linear_solver_ensure_matrix_construct(solver);
|
||||
|
||||
if (!solver->least_squares && solver->variable[row].locked) {
|
||||
;
|
||||
}
|
||||
else if (solver->variable[col].locked) {
|
||||
if (!solver->least_squares) {
|
||||
row = solver->variable[row].index;
|
||||
}
|
||||
|
||||
LinearSolver::Coeff coeff;
|
||||
coeff.index = row;
|
||||
coeff.value = value;
|
||||
solver->variable[col].a.push_back(coeff);
|
||||
}
|
||||
else {
|
||||
if (!solver->least_squares) {
|
||||
row = solver->variable[row].index;
|
||||
}
|
||||
col = solver->variable[col].index;
|
||||
|
||||
/* direct insert into matrix is too slow, so use triplets */
|
||||
EigenTriplet triplet(row, col, value);
|
||||
solver->Mtriplets.push_back(triplet);
|
||||
}
|
||||
}
|
||||
|
||||
/* Right hand side */
|
||||
|
||||
void EIG_linear_solver_right_hand_side_add(LinearSolver *solver, int rhs, int index, double value)
|
||||
{
|
||||
linear_solver_ensure_matrix_construct(solver);
|
||||
|
||||
if (solver->least_squares) {
|
||||
solver->b[rhs][index] += value;
|
||||
}
|
||||
else if (!solver->variable[index].locked) {
|
||||
index = solver->variable[index].index;
|
||||
solver->b[rhs][index] += value;
|
||||
}
|
||||
}
|
||||
|
||||
/* Solve */
|
||||
|
||||
bool EIG_linear_solver_solve(LinearSolver *solver)
|
||||
{
|
||||
/* nothing to solve, perhaps all variables were locked */
|
||||
if (solver->m == 0 || solver->n == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
|
||||
assert(solver->state != LinearSolver::STATE_VARIABLES_CONSTRUCT);
|
||||
|
||||
if (solver->state == LinearSolver::STATE_MATRIX_CONSTRUCT) {
|
||||
/* create matrix from triplets */
|
||||
solver->M.resize(solver->m, solver->n);
|
||||
solver->M.setFromTriplets(solver->Mtriplets.begin(), solver->Mtriplets.end());
|
||||
solver->Mtriplets.clear();
|
||||
|
||||
/* create least squares matrix */
|
||||
if (solver->least_squares) {
|
||||
solver->MtM = solver->M.transpose() * solver->M;
|
||||
}
|
||||
|
||||
/* convert M to compressed column format */
|
||||
EigenSparseMatrix &M = (solver->least_squares) ? solver->MtM : solver->M;
|
||||
M.makeCompressed();
|
||||
|
||||
/* perform sparse LU factorization */
|
||||
EigenSparseLU *sparseLU = new EigenSparseLU();
|
||||
solver->sparseLU = sparseLU;
|
||||
|
||||
sparseLU->compute(M);
|
||||
result = (sparseLU->info() == Eigen::Success);
|
||||
|
||||
solver->state = LinearSolver::STATE_MATRIX_SOLVED;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
/* solve for each right hand side */
|
||||
for (int rhs = 0; rhs < solver->num_rhs; rhs++) {
|
||||
/* modify for locked variables */
|
||||
EigenVectorX &b = solver->b[rhs];
|
||||
|
||||
for (int i = 0; i < solver->num_variables; i++) {
|
||||
LinearSolver::Variable *variable = &solver->variable[i];
|
||||
|
||||
if (variable->locked) {
|
||||
std::vector<LinearSolver::Coeff> &a = variable->a;
|
||||
|
||||
for (int j = 0; j < a.size(); j++) {
|
||||
b[a[j].index] -= a[j].value * variable->value[rhs];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* solve */
|
||||
if (solver->least_squares) {
|
||||
EigenVectorX Mtb = solver->M.transpose() * b;
|
||||
solver->x[rhs] = solver->sparseLU->solve(Mtb);
|
||||
}
|
||||
else {
|
||||
EigenVectorX &b = solver->b[rhs];
|
||||
solver->x[rhs] = solver->sparseLU->solve(b);
|
||||
}
|
||||
|
||||
if (solver->sparseLU->info() != Eigen::Success) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
linear_solver_vector_to_variables(solver);
|
||||
}
|
||||
}
|
||||
|
||||
/* clear for next solve */
|
||||
for (int rhs = 0; rhs < solver->num_rhs; rhs++) {
|
||||
solver->b[rhs].setZero(solver->m);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Debugging */
|
||||
|
||||
void EIG_linear_solver_print_matrix(LinearSolver *solver)
|
||||
{
|
||||
std::cout << "A:" << solver->M << std::endl;
|
||||
|
||||
for (int rhs = 0; rhs < solver->num_rhs; rhs++) {
|
||||
std::cout << "b " << rhs << ":" << solver->b[rhs] << std::endl;
|
||||
}
|
||||
|
||||
if (solver->MtM.rows() && solver->MtM.cols()) {
|
||||
std::cout << "AtA:" << solver->MtM << std::endl;
|
||||
}
|
||||
}
|
||||
51
blender-5.2.0/intern/eigen/intern/linear_solver.h
Normal file
51
blender-5.2.0/intern/eigen/intern/linear_solver.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* SPDX-FileCopyrightText: 2004 Bruno Levy
|
||||
* SPDX-FileCopyrightText: 2005-2015 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
* Sparse linear solver.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Solvers for Ax = b and AtAx = Atb */
|
||||
|
||||
struct LinearSolver;
|
||||
|
||||
LinearSolver *EIG_linear_solver_new(int num_rows, int num_columns, int num_right_hand_sides);
|
||||
|
||||
LinearSolver *EIG_linear_least_squares_solver_new(int num_rows,
|
||||
int num_columns,
|
||||
int num_right_hand_sides);
|
||||
|
||||
void EIG_linear_solver_delete(LinearSolver *solver);
|
||||
|
||||
/* Variables (x). Any locking must be done before matrix construction. */
|
||||
|
||||
void EIG_linear_solver_variable_set(LinearSolver *solver, int rhs, int index, double value);
|
||||
double EIG_linear_solver_variable_get(LinearSolver *solver, int rhs, int index);
|
||||
void EIG_linear_solver_variable_lock(LinearSolver *solver, int index);
|
||||
void EIG_linear_solver_variable_unlock(LinearSolver *solver, int index);
|
||||
|
||||
/* Matrix (A) and right hand side (b) */
|
||||
|
||||
void EIG_linear_solver_matrix_add(LinearSolver *solver, int row, int col, double value);
|
||||
void EIG_linear_solver_right_hand_side_add(LinearSolver *solver, int rhs, int index, double value);
|
||||
|
||||
/* Solve. Repeated solves are supported, by changing b between solves. */
|
||||
|
||||
bool EIG_linear_solver_solve(LinearSolver *solver);
|
||||
|
||||
/* Debugging */
|
||||
|
||||
void EIG_linear_solver_print_matrix(LinearSolver *solver);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
42
blender-5.2.0/intern/eigen/intern/matrix.cc
Normal file
42
blender-5.2.0/intern/eigen/intern/matrix.cc
Normal file
@@ -0,0 +1,42 @@
|
||||
/* SPDX-FileCopyrightText: 2018 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
*/
|
||||
|
||||
#ifndef __EIGEN3_MATRIX_C_API_CC__
|
||||
#define __EIGEN3_MATRIX_C_API_CC__
|
||||
|
||||
/* Eigen gives annoying huge amount of warnings here, silence them! */
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
# pragma GCC diagnostic ignored "-Wlogical-op"
|
||||
#endif
|
||||
|
||||
#ifdef __EIGEN3_MATRIX_C_API_CC__
|
||||
/* Quiet warning. */
|
||||
#endif
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Dense>
|
||||
|
||||
#include "matrix.h"
|
||||
|
||||
using Eigen::Map;
|
||||
using Eigen::Matrix4f;
|
||||
|
||||
bool EIG_invert_m4_m4(float inverse[4][4], const float matrix[4][4])
|
||||
{
|
||||
Map<Matrix4f> M = Map<Matrix4f>((float *)matrix);
|
||||
Matrix4f R;
|
||||
bool invertible = true;
|
||||
M.computeInverseWithCheck(R, invertible, 0.0f);
|
||||
if (!invertible) {
|
||||
R = Matrix4f::Zero();
|
||||
}
|
||||
memcpy(inverse, R.data(), sizeof(float) * 4 * 4);
|
||||
return invertible;
|
||||
}
|
||||
|
||||
#endif /* __EIGEN3_MATRIX_C_API_CC__ */
|
||||
22
blender-5.2.0/intern/eigen/intern/matrix.h
Normal file
22
blender-5.2.0/intern/eigen/intern/matrix.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* SPDX-FileCopyrightText: 2015 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
*/
|
||||
|
||||
#ifndef __EIGEN3_MATRIX_C_API_H__
|
||||
#define __EIGEN3_MATRIX_C_API_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool EIG_invert_m4_m4(float inverse[4][4], const float matrix[4][4]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EIGEN3_MATRIX_C_API_H__ */
|
||||
61
blender-5.2.0/intern/eigen/intern/svd.cc
Normal file
61
blender-5.2.0/intern/eigen/intern/svd.cc
Normal file
@@ -0,0 +1,61 @@
|
||||
/* SPDX-FileCopyrightText: 2015 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
*/
|
||||
|
||||
#ifndef __EIGEN3_SVD_C_API_CC__
|
||||
#define __EIGEN3_SVD_C_API_CC__
|
||||
|
||||
/* Eigen gives annoying huge amount of warnings here, silence them! */
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
# pragma GCC diagnostic ignored "-Wlogical-op"
|
||||
#endif
|
||||
|
||||
#ifdef __EIGEN3_SVD_C_API_CC__
|
||||
/* Quiet warning. */
|
||||
#endif
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Dense>
|
||||
#include <Eigen/SVD>
|
||||
|
||||
#include "svd.h"
|
||||
|
||||
using Eigen::JacobiSVD;
|
||||
|
||||
using Eigen::NoQRPreconditioner;
|
||||
|
||||
using Eigen::ComputeThinU;
|
||||
using Eigen::ComputeThinV;
|
||||
|
||||
using Eigen::Map;
|
||||
using Eigen::MatrixXf;
|
||||
using Eigen::VectorXf;
|
||||
|
||||
using Eigen::Matrix4f;
|
||||
|
||||
void EIG_svd_square_matrix(const int size, const float *matrix, float *r_U, float *r_S, float *r_V)
|
||||
{
|
||||
/* Since our matrix is squared, we can use thinU/V. */
|
||||
unsigned int flags = (r_U ? ComputeThinU : 0) | (r_V ? ComputeThinV : 0);
|
||||
|
||||
/* Blender and Eigen matrices are both column-major. */
|
||||
JacobiSVD<MatrixXf, NoQRPreconditioner> svd(Map<MatrixXf>((float *)matrix, size, size), flags);
|
||||
|
||||
if (r_U) {
|
||||
Map<MatrixXf>(r_U, size, size) = svd.matrixU();
|
||||
}
|
||||
|
||||
if (r_S) {
|
||||
Map<VectorXf>(r_S, size) = svd.singularValues();
|
||||
}
|
||||
|
||||
if (r_V) {
|
||||
Map<MatrixXf>(r_V, size, size) = svd.matrixV();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __EIGEN3_SVD_C_API_CC__ */
|
||||
23
blender-5.2.0/intern/eigen/intern/svd.h
Normal file
23
blender-5.2.0/intern/eigen/intern/svd.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/* SPDX-FileCopyrightText: 2015 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
*/
|
||||
|
||||
#ifndef __EIGEN3_SVD_C_API_H__
|
||||
#define __EIGEN3_SVD_C_API_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void EIG_svd_square_matrix(
|
||||
const int size, const float *matrix, float *r_U, float *r_S, float *r_V);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EIGEN3_SVD_C_API_H__ */
|
||||
Reference in New Issue
Block a user