[Bf-blender-cvs] [439a6ac27b1] rigid_deform: use namespace

Jacques Lucke noreply at git.blender.org
Thu Jan 31 19:56:03 CET 2019


Commit: 439a6ac27b1dfe0d09b729dc2ab3ab9bf413da1a
Author: Jacques Lucke
Date:   Tue Jan 29 20:20:14 2019 +0100
Branches: rigid_deform
https://developer.blender.org/rB439a6ac27b1dfe0d09b729dc2ab3ab9bf413da1a

use namespace

===================================================================

M	source/blender/modifiers/intern/MOD_rigiddeform_system.cc
M	source/blender/modifiers/intern/MOD_rigiddeform_system.hpp
M	source/blender/modifiers/intern/MOD_rigiddeform_system_wrapper.cc

===================================================================

diff --git a/source/blender/modifiers/intern/MOD_rigiddeform_system.cc b/source/blender/modifiers/intern/MOD_rigiddeform_system.cc
index 3ae6926f477..e3a2825c412 100644
--- a/source/blender/modifiers/intern/MOD_rigiddeform_system.cc
+++ b/source/blender/modifiers/intern/MOD_rigiddeform_system.cc
@@ -26,316 +26,320 @@
 #include "MOD_rigiddeform_system.hpp"
 #include "BLI_math.h"
 
-/* expects the anchor indices to be sorted */
-/* (6, [1, 4]) -> [0, 2, 3, 5,  1, 4] */
-static std::vector<uint> sort_vertices_by_anchors(const std::vector<uint> &anchors, uint vertex_amount)
-{
-	std::vector<uint> sorted;
-
-	int anchor_index = 0;
-	for (int i = 0; i < vertex_amount; i++) {
-		if (anchor_index < anchors.size() && i == anchors[anchor_index]) {
-			anchor_index++;
-			continue;
+namespace RigidDeform {
+
+	/* expects the anchor indices to be sorted */
+	/* (6, [1, 4]) -> [0, 2, 3, 5,  1, 4] */
+	static std::vector<uint> sort_vertices_by_anchors(const std::vector<uint> &anchors, uint vertex_amount)
+	{
+		std::vector<uint> sorted;
+
+		int anchor_index = 0;
+		for (int i = 0; i < vertex_amount; i++) {
+			if (anchor_index < anchors.size() && i == anchors[anchor_index]) {
+				anchor_index++;
+				continue;
+			}
+			sorted.push_back(i);
 		}
-		sorted.push_back(i);
+
+		sorted.insert(sorted.end(), anchors.begin(), anchors.end());
+		return sorted;
 	}
 
-	sorted.insert(sorted.end(), anchors.begin(), anchors.end());
-	return sorted;
-}
-
-/* Build Laplace Matrix
- ******************************************/
-
-static std::vector<double> calc_total_weight_per_vertex(
-		const std::vector<WeightedEdge> &edges,
-		uint vertex_amount)
-{
-	std::vector<double> total_weights(vertex_amount, 0);
-	for (WeightedEdge edge : edges) {
-		total_weights[edge.v1] += edge.weight;
-		total_weights[edge.v2] += edge.weight;
+	/* Build Laplace Matrix
+	******************************************/
+
+	static std::vector<double> calc_total_weight_per_vertex(
+			const std::vector<WeightedEdge> &edges,
+			uint vertex_amount)
+	{
+		std::vector<double> total_weights(vertex_amount, 0);
+		for (WeightedEdge edge : edges) {
+			total_weights[edge.v1] += edge.weight;
+			total_weights[edge.v2] += edge.weight;
+		}
+		return total_weights;
 	}
-	return total_weights;
-}
-
-static std::array<double, 3> triangle_corner_angles(
-	Eigen::Vector3d v1, Eigen::Vector3d v2, Eigen::Vector3d v3)
-{
-	Eigen::Vector3f v1_f = v1.cast<float>();
-	Eigen::Vector3f v2_f = v2.cast<float>();
-	Eigen::Vector3f v3_f = v3.cast<float>();
-
-	float angles[3];
-	angle_tri_v3(angles, v1_f.data(), v2_f.data(), v3_f.data());
-	return {angles[0], angles[1], angles[2]};
-}
-
-static inline double cotan(double angle)
-{
-	return std::cos(angle) / std::sin(angle);
-}
-
-static std::vector<WeightedEdge> calculate_cotan_edge_weights(
-	const Vectors &positions,
-	const std::vector<std::array<uint, 3>> &triangles)
-{
-	std::vector<WeightedEdge> edges;
-
-	for (auto verts : triangles) {
-		std::array<double, 3> angles = triangle_corner_angles(
-			positions[verts[0]],
-			positions[verts[1]],
-			positions[verts[2]]);
-
-		double w1 = (angles[0] > 0.0001) ? cotan(angles[0]) / 2.0 : 1.0;
-		double w2 = (angles[0] > 0.0001) ? cotan(angles[1]) / 2.0 : 1.0;
-		double w3 = (angles[0] > 0.0001) ? cotan(angles[2]) / 2.0 : 1.0;
-
-		if (w1 > 0) edges.push_back(WeightedEdge(verts[1], verts[2], w1));
-		if (w2 > 0) edges.push_back(WeightedEdge(verts[0], verts[2], w2));
-		if (w3 > 0) edges.push_back(WeightedEdge(verts[0], verts[1], w3));
+
+	static std::array<double, 3> triangle_corner_angles(
+		Eigen::Vector3d v1, Eigen::Vector3d v2, Eigen::Vector3d v3)
+	{
+		Eigen::Vector3f v1_f = v1.cast<float>();
+		Eigen::Vector3f v2_f = v2.cast<float>();
+		Eigen::Vector3f v3_f = v3.cast<float>();
+
+		float angles[3];
+		angle_tri_v3(angles, v1_f.data(), v2_f.data(), v3_f.data());
+		return {angles[0], angles[1], angles[2]};
 	}
 
-	return edges;
-}
+	static inline double cotan(double angle)
+	{
+		return std::cos(angle) / std::sin(angle);
+	}
 
-static std::vector<Triplet> get_laplace_matrix_triplets(
-        uint vertex_amount, std::vector<WeightedEdge> &edges)
-{
-	auto total_weights = calc_total_weight_per_vertex(edges, vertex_amount);
+	static std::vector<WeightedEdge> calculate_cotan_edge_weights(
+		const Vectors &positions,
+		const std::vector<std::array<uint, 3>> &triangles)
+	{
+		std::vector<WeightedEdge> edges;
+
+		for (auto verts : triangles) {
+			std::array<double, 3> angles = triangle_corner_angles(
+				positions[verts[0]],
+				positions[verts[1]],
+				positions[verts[2]]);
+
+			double w1 = (angles[0] > 0.0001) ? cotan(angles[0]) / 2.0 : 1.0;
+			double w2 = (angles[0] > 0.0001) ? cotan(angles[1]) / 2.0 : 1.0;
+			double w3 = (angles[0] > 0.0001) ? cotan(angles[2]) / 2.0 : 1.0;
+
+			if (w1 > 0) edges.push_back(WeightedEdge(verts[1], verts[2], w1));
+			if (w2 > 0) edges.push_back(WeightedEdge(verts[0], verts[2], w2));
+			if (w3 > 0) edges.push_back(WeightedEdge(verts[0], verts[1], w3));
+		}
+
+		return edges;
+	}
+
+	static std::vector<Triplet> get_laplace_matrix_triplets(
+			uint vertex_amount, std::vector<WeightedEdge> &edges)
+	{
+		auto total_weights = calc_total_weight_per_vertex(edges, vertex_amount);
+
+		std::vector<Triplet> triplets;
+
+		for (int i = 0; i < vertex_amount; i++) {
+			triplets.push_back(Triplet(i, i, total_weights[i]));
+		}
 
-	std::vector<Triplet> triplets;
+		for (WeightedEdge edge : edges) {
+			if (edge.weight == 0) continue;
 
-	for (int i = 0; i < vertex_amount; i++) {
-		triplets.push_back(Triplet(i, i, total_weights[i]));
+			triplets.push_back(Triplet(edge.v1, edge.v2, -edge.weight));
+			triplets.push_back(Triplet(edge.v2, edge.v1, -edge.weight));
+		}
+
+		return triplets;
 	}
 
-	for (WeightedEdge edge : edges) {
-		if (edge.weight == 0) continue;
+	ReorderData::ReorderData(const std::vector<uint> &anchors, uint vertex_amount)
+	{
+		m_new_to_orig = sort_vertices_by_anchors(anchors, vertex_amount);
+
+		m_orig_to_new.resize(vertex_amount);
+		for (int i = 0; i < vertex_amount; i++) {
+			m_orig_to_new[m_new_to_orig[i]] = i;
+		}
 
-		triplets.push_back(Triplet(edge.v1, edge.v2, -edge.weight));
-		triplets.push_back(Triplet(edge.v2, edge.v1, -edge.weight));
+		this->m_inner_amount = vertex_amount - anchors.size();
 	}
 
-	return triplets;
-}
 
-ReorderData::ReorderData(const std::vector<uint> &anchors, uint vertex_amount)
-{
-	m_new_to_orig = sort_vertices_by_anchors(anchors, vertex_amount);
+	/* Optimize Rotations
+	*********************************************/
 
-	m_orig_to_new.resize(vertex_amount);
-	for (int i = 0; i < vertex_amount; i++) {
-		m_orig_to_new[m_new_to_orig[i]] = i;
+	static inline Eigen::Vector3d get_position(
+		uint index,
+		const ReorderData &order,
+		const Vectors &anchor_positions,
+		const Vectors &inner_positions)
+	{
+		if (order.is_inner__orig(index)) {
+			return inner_positions[order.to_new(index)];
+		}
+		else {
+			return anchor_positions[order.to_new_anchor(index)];
+		}
 	}
 
-	this->m_inner_amount = vertex_amount - anchors.size();
-}
+	std::vector<Eigen::Matrix3d> RigidDeformSystem::optimize_rotations(
+		const Vectors &anchor_positions,
+		const Vectors &new_inner_positions)
+	{
+		std::vector<Eigen::Matrix3d> S(this->vertex_amount());
+		for (uint i = 0; i < S.size(); i++) S[i].setZero();
 
+		for (WeightedEdge edge : m_edges) {
+			uint v1 = edge.v1;
+			uint v2 = edge.v2;
 
-/* Optimize Rotations
- *********************************************/
+			Eigen::Vector3d edge_old = m_initial_positions[v1] - m_initial_positions[v2];
 
-static inline Eigen::Vector3d get_position(
-	uint index,
-	const ReorderData &order,
-	const Vectors &anchor_positions,
-	const Vectors &inner_positions)
-{
-	if (order.is_inner__orig(index)) {
-		return inner_positions[order.to_new(index)];
-	}
-	else {
-		return anchor_positions[order.to_new_anchor(index)];
+			Eigen::Vector3d edge_new_start =
+				get_position(v1, m_order, anchor_positions, new_inner_positions);
+			Eigen::Vector3d edge_new_end =
+				get_position(v2, m_order, anchor_positions, new_inner_positions);
+
+			Eigen::RowVector3d edge_new = edge_new_start - edge_new_end;
+
+			Eigen::Matrix3d mat = edge.weight * edge_old * edge_new;
+			S[v1] += mat;
+			S[v2] += mat;
+		}
+
+		std::vector<Eigen::Matrix3d> R(S.size());
+		for (int i = 0; i < S.size(); i++) {
+			Eigen::JacobiSVD<Eigen::Matrix3d> svd(S[i], Eigen::ComputeFullU | Eigen::ComputeFullV);
+			R[i] = svd.matrixV() * svd.matrixU().transpose();
+			if (R[i].determinant() < 0) {
+				Eigen::Matrix3d U = svd.matrixU();
+				U.col(2) = -U.col(2);
+				R[i] = svd.matrixV() * U.transpose();
+			}
+		}
+
+		return R;
 	}
-}
 
-std::vector<Eigen::Matrix3d> RigidDeformSystem::optimize_rotations(
-	const Vectors &anchor_positions,
-	const Vectors &new_inner_positions)
-{
-	std::vector<Eigen::Matrix3d> S(this->vertex_amount());
-	for (uint i = 0; i < S.size(); i++) S[i].setZero();
 
-	for (WeightedEdge edge : m_edges) {
-		uint v1 = edge.v1;
-		uint v2 = edge.v2;
+	/* Optimize Inner Vertex Positions
+	**********************************************/
+
+	Vectors RigidDeformSystem::optimize_inner_positions(
+		const Vectors &anchor_positions,
+		const std::vector<Eigen::Matrix3d> &rotations)
+	{
+		Vectors new_inner_diffs = this->calculate_new_inner_diffs(rotations);
+		return this->solve_for_new_inner_positions(anchor_positions, new_inner_diffs);
+	}
+
+	Vectors RigidDeformSystem::calculate_new_inner_diffs(
+		const std::vector<Eigen::Matrix3d> &rotations)
+	{
+		Vectors new_inner_diffs(m_order.inner_amount());
+		new_inner_diffs.set_zero();
 
-		Eigen::Vector3d edge_old = m_initial_positions[v1] - m_initial_positions[v2];
+		for (WeightedEdge edge : m_edges) {
+			uint v1 = edge.v1;
+			uint v2 = edge.v2;
+			bool v1_is_inner = m_order.is_inner__orig(v1);
+			bool v2_is_inner = m_order.is_inner__orig(v2);
+			if (!(v1_is_inner || v2_is_inner)) continue;
 
-		Eigen::Vector3d edge_new_start =
-			get_position(v1, m_order, anchor_positions, new_inner_positions);
-		Eigen::Vector3d edge_new_end =
-			get_position(v2, m_order, anchor_positions, new_inner_positions);
+			Eigen::Vector3d old_edge = m_initial_positions[v1] - m_initial_positions[v2];
+	

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list