Blender V4.3
area_compensation.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 "BLI_assert.h"
10
11#include <Eigen/Dense>
12
13#include "area_compensation.h"
14#include "doublearea.h"
15#include "slim.h"
16
17using namespace Eigen;
18
19namespace slim {
20
21static void correct_geometry_size(double surface_area_to_map_area_ratio,
22 MatrixXd &vertex_positions,
23 double desired_surface_area_to_map_ration)
24{
25 BLI_assert(surface_area_to_map_area_ratio > 0);
26 double sqrt_of_ratio = sqrt(surface_area_to_map_area_ratio / desired_surface_area_to_map_ration);
27 vertex_positions = vertex_positions / sqrt_of_ratio;
28}
29
30template<typename VertexPositionType, typename FaceIndicesType>
31static double compute_surface_area(const VertexPositionType v, const FaceIndicesType f)
32{
33 Eigen::VectorXd doubled_area_of_triangles;
34 doublearea(v, f, doubled_area_of_triangles);
35 double area_of_map = doubled_area_of_triangles.sum() / 2;
36 return area_of_map;
37}
38
40{
41 if (!slim_data.valid) {
42 return;
43 }
44
45 bool mesh_surface_area_was_corrected = (slim_data.expectedSurfaceAreaOfResultingMap != 0);
46 int number_of_pinned_vertices = slim_data.b.rows();
47 bool no_pinned_vertices_exist = number_of_pinned_vertices == 0;
48
49 bool needs_area_correction = mesh_surface_area_was_corrected && no_pinned_vertices_exist;
50 if (!needs_area_correction) {
51 return;
52 }
53
54 double area_ofresulting_map = compute_surface_area(slim_data.V_o, slim_data.F);
55 if (!area_ofresulting_map) {
56 return;
57 }
58
59 double resulting_area_to_expected_area_ratio = area_ofresulting_map /
61 double desired_ratio = 1.0;
62 correct_geometry_size(resulting_area_to_expected_area_ratio, slim_data.V_o, desired_ratio);
63}
64
66{
67 BLI_assert(slim_data.valid);
68
69 int number_of_pinned_vertices = slim_data.b.rows();
70 bool pinned_vertices_exist = number_of_pinned_vertices > 0;
71 bool needs_area_correction = slim_data.skipInitialization || pinned_vertices_exist;
72
73 if (!needs_area_correction) {
74 return;
75 }
76
77 double area_of_preinitialized_map = compute_surface_area(slim_data.V_o, slim_data.F);
78 if (!area_of_preinitialized_map) {
79 return;
80 }
81
82 if (area_of_preinitialized_map < 0) {
83 area_of_preinitialized_map *= -1;
84 }
85
86 slim_data.expectedSurfaceAreaOfResultingMap = area_of_preinitialized_map;
87 double surface_area_of3d_mesh = compute_surface_area(slim_data.V, slim_data.F);
88 double surface_area_to_map_area_ratio = surface_area_of3d_mesh / area_of_preinitialized_map;
89
90 double desired_ratio = 1.0;
91 correct_geometry_size(surface_area_to_map_area_ratio, slim_data.V, desired_ratio);
92}
93
94} // namespace slim
#define BLI_assert(a)
Definition BLI_assert.h:50
sqrt(x)+1/max(0
ATTR_WARN_UNUSED_RESULT const BMVert * v
static double compute_surface_area(const VertexPositionType v, const FaceIndicesType f)
void doublearea(const Eigen::PlainObjectBase< DerivedV > &V, const Eigen::PlainObjectBase< DerivedF > &F, Eigen::PlainObjectBase< DeriveddblA > &dblA)
static void correct_geometry_size(double surface_area_to_map_area_ratio, MatrixXd &vertex_positions, double desired_surface_area_to_map_ration)
void correct_map_surface_area_if_necessary(SLIMData &slim_data)
void correct_mesh_surface_area_if_necessary(SLIMData &slim_data)
Eigen::MatrixXi F
Definition slim.h:30
bool skipInitialization
Definition slim.h:51
Eigen::VectorXi b
Definition slim.h:43
Eigen::MatrixXd V
Definition slim.h:29
double expectedSurfaceAreaOfResultingMap
Definition slim.h:53
bool valid
Definition slim.h:26
Eigen::MatrixXd V_o
Definition slim.h:56