[Bf-blender-cvs] [0401103f2ba] rigid_deform: bring old functionality back

Jacques Lucke noreply at git.blender.org
Thu Jan 31 19:55:40 CET 2019


Commit: 0401103f2ba3b90ef3a52eedd8a6f519a685b638
Author: Jacques Lucke
Date:   Sun Dec 9 15:48:34 2018 +0100
Branches: rigid_deform
https://developer.blender.org/rB0401103f2ba3b90ef3a52eedd8a6f519a685b638

bring old functionality back

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

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/blenkernel/BKE_mesh_runtime.h
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/CMakeLists.txt
M	source/blender/modifiers/intern/MOD_rigiddeform.c
A	source/blender/modifiers/intern/MOD_rigiddeform_system.cc
A	source/blender/modifiers/intern/MOD_rigiddeform_system.h

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

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index f15ba356e20..db8257c2fc2 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1636,6 +1636,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
     def RIGID_DEFORM(self, layout, ob, md):
         layout.prop_search(md, "anchor_group_name", ob, "vertex_groups", text="Anchors")
         layout.operator("object.rigiddeform_bind", text="Bind")
+        layout.prop(md, "iterations")
         layout.label(text=f"Is Bound: {md.is_bind}")
 
 
diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h
index 8211a7301ff..edfd1d866f8 100644
--- a/source/blender/blenkernel/BKE_mesh_runtime.h
+++ b/source/blender/blenkernel/BKE_mesh_runtime.h
@@ -33,6 +33,10 @@
  * This file contains access functions for the Mesh.runtime struct.
  */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "BKE_customdata.h"  /* for CustomDataMask */
 
 struct ColorBand;
@@ -130,4 +134,8 @@ void BKE_mesh_runtime_debug_print_cdlayers(struct CustomData *data);
 bool BKE_mesh_runtime_is_valid(struct Mesh *me_eval);
 #endif  /* NDEBUG */
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* __BKE_MESH_RUNTIME_H__ */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index a67470214f5..39603e2b4a7 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1958,7 +1958,11 @@ typedef struct RigidDeformModifierData {
 	ModifierData modifier;
 	char anchor_group_name[64];  /* MAX_VGROUP_NAME */
 	RigidDeformModifierBindData *bind_data;
-	char bind_next_execution, pad[7];
+	int iterations;
+	char bind_next_execution, pad[3];
+
+	/* runtime only */
+	void *cache;
 } RigidDeformModifierData;
 
 #endif  /* __DNA_MODIFIER_TYPES_H__ */
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index e3b93aeb9c3..00051cdc037 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -5095,6 +5095,11 @@ static void rna_def_modifier_rigiddeform(BlenderRNA *brna)
 	RNA_def_property_boolean_funcs(prop, "rna_RigidDeformModifier_is_bind_get", NULL);
 	RNA_def_property_ui_text(prop, "Bound", "Geometry has been bound to the modifier");
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+	prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE);
+	RNA_def_property_range(prop, 0, 20000);
+	RNA_def_property_ui_text(prop, "Iterations", "More means better result but slower");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
 }
 
 void RNA_def_modifier(BlenderRNA *brna)
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index a134401c10d..0e8ac3759e7 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -42,6 +42,7 @@ set(INC
 
 set(INC_SYS
 	${ZLIB_INCLUDE_DIRS}
+	${EIGEN3_INCLUDE_DIRS}
 )
 
 set(SRC
@@ -83,6 +84,7 @@ set(SRC
 	intern/MOD_particlesystem.c
 	intern/MOD_remesh.c
 	intern/MOD_rigiddeform.c
+	intern/MOD_rigiddeform_system.cc
 	intern/MOD_screw.c
 	intern/MOD_shapekey.c
 	intern/MOD_shrinkwrap.c
@@ -111,6 +113,7 @@ set(SRC
 	MOD_modifiertypes.h
 	intern/MOD_fluidsim_util.h
 	intern/MOD_meshcache_util.h
+	intern/MOD_rigiddeform_system.h
 	intern/MOD_util.h
 	intern/MOD_weightvg_util.h
 )
diff --git a/source/blender/modifiers/intern/MOD_rigiddeform.c b/source/blender/modifiers/intern/MOD_rigiddeform.c
index 6bdcfc94af5..cf62f77d395 100644
--- a/source/blender/modifiers/intern/MOD_rigiddeform.c
+++ b/source/blender/modifiers/intern/MOD_rigiddeform.c
@@ -45,6 +45,8 @@
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_query.h"
 
+#include "MOD_rigiddeform_system.h"
+
 typedef float (*VectorArray)[3];
 typedef RigidDeformModifierBindData BindData;
 
@@ -160,12 +162,41 @@ static void bind_current_mesh_to_modifier(
 
 /* ********** Calculate new positions *********** */
 
+typedef struct Cache {
+	struct LaplacianSystem *system;
+} Cache;
 
-static void deform_vertices(
-        RigidDeformModifierData *rdmd,
-        Object *ob, Mesh *mesh, VectorArray vertex_cos)
+static Cache *cache_new(void)
 {
+	return MEM_callocN(sizeof(Cache), __func__);
+}
 
+static void cache_free(Cache *cache)
+{
+	if (cache->system) {
+		LaplacianSystem_free(cache->system);
+	}
+	MEM_freeN(cache);
+}
+
+static void ensure_cache_exists(RigidDeformModifierData *rdmd, RigidDeformModifierData *rdmd_orig)
+{
+	if (rdmd->cache == NULL) {
+		rdmd_orig->cache = cache_new();
+		rdmd->cache = rdmd_orig->cache;
+	}
+}
+
+static void deform_vertices(RigidDeformModifierData *rdmd, Mesh *mesh, VectorArray vertex_cos)
+{
+	Cache *cache = (Cache *)rdmd->cache;
+
+	if (cache->system == NULL) {
+		cache->system = LaplacianSystem_new(mesh);
+		LaplacianSystem_setAnchors(cache->system, rdmd->bind_data->anchor_indices, rdmd->bind_data->anchor_amount);
+	}
+
+	LaplacianSystem_correctNonAnchors(cache->system, vertex_cos, rdmd->iterations);
 }
 
 static RigidDeformModifierData *get_original_modifier_data(
@@ -182,11 +213,16 @@ static void run_modifier(
 	Object *ob = ctx->object;
 	RigidDeformModifierData *rdmd = (RigidDeformModifierData *)md;
 	RigidDeformModifierData *rdmd_orig = get_original_modifier_data(rdmd, ctx);
+	ensure_cache_exists(rdmd, rdmd_orig);
 
 	if (rdmd->bind_next_execution) {
 		bind_current_mesh_to_modifier(rdmd, rdmd_orig, ob, mesh, vertex_cos);
 		rdmd->bind_next_execution = false;
 	}
+
+	if (rdmd->bind_data != NULL) {
+		deform_vertices(rdmd, mesh, vertex_cos);
+	}
 }
 
 static void deformVerts(
@@ -221,6 +257,8 @@ static void initData(ModifierData *md)
 	rdmd->anchor_group_name[0] = '\0';
 	rdmd->bind_data = NULL;
 	rdmd->bind_next_execution = false;
+	rdmd->cache = cache_new();
+	rdmd->iterations = 5;
 }
 
 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md))
@@ -230,6 +268,11 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(
 	return dataMask;
 }
 
+static void freeData(ModifierData *md)
+{
+	RigidDeformModifierData *UNUSED(rdmd) = (RigidDeformModifierData *)md;
+}
+
  ModifierTypeInfo modifierType_RigidDeform = {
 	/* name */              "Rigid Deform",
 	/* structName */        "RigidDeformModifierData",
@@ -249,7 +292,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(
 	/* applyModifier */     NULL,
  	/* initData */          initData,
 	/* requiredDataMask */  requiredDataMask,
-	/* freeData */          NULL,
+	/* freeData */          freeData,
 	/* isDisabled */        NULL,
 	/* updateDepsgraph */   NULL,
 	/* dependsOnTime */     NULL,
diff --git a/source/blender/modifiers/intern/MOD_rigiddeform_system.cc b/source/blender/modifiers/intern/MOD_rigiddeform_system.cc
new file mode 100644
index 00000000000..23b3c1027cf
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_rigiddeform_system.cc
@@ -0,0 +1,607 @@
+/*
+
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software  Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2013 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+#include "Eigen/Sparse"
+#include "Eigen/Dense"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_mesh_runtime.h"
+
+#include "BLI_math.h"
+
+#include "MOD_rigiddeform_system.h"
+
+#include <iostream>
+#include <vector>
+#include <set>
+#include <unordered_set>
+
+#include <chrono>
+#include <iostream>
+
+/* ************** Timer ***************** */
+
+class Timer {
+    const char *name;
+    std::chrono::high_resolution_clock::time_point start, end;
+    std::chrono::duration<float> duration;
+
+public:
+    Timer(const char *name = "");
+    ~Timer();
+};
+
+Timer::Timer(const char *name) {
+    this->name = name;
+    this->start = std::chrono::high_resolution_clock::now();
+}
+
+Timer::~Timer() {
+    end = std::chrono::high_resolution_clock::now();
+    duration = end - start;
+    double ms = duration.count() * 1000.0f;
+    std::cout << "Timer '" << name << "' took " << ms << " ms" << std::endl;
+}
+
+#define TIMEIT(name) Timer t(name);
+
+/* ************ Timer End *************** */
+
+
+typedef Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<3>> StridedVector;
+typedef Eigen::SparseMatrix<float, Eigen::ColMajor> SparseMatrixF;
+typedef Eigen::SparseMatrix<double, Eigen::ColMajor> SparseMatrixD;
+typedef Eigen::Triplet<float> Triplet;
+
+struct WeightedEdge {
+	int v1, v2;
+	float weight;
+};
+
+
+class Vectors {
+	Eigen::VectorXf data;
+
+public:
+	Vectors() {}
+
+	Vectors(int size)
+	{
+		this->data = Eigen::VectorXf(size * 3);
+	}
+
+	Vectors(std::vector<Eigen::Vector3f> &vectors)
+		: Vectors((Vector3Ds)&vectors[0][0], vectors.size()) {}
+
+	Vectors(Vector3Ds vectors, int amount)
+	{
+		this->data = Eigen::VectorXf(3 * amount);
+		memcpy(&this->data[0], vectors, this->byte_size());
+	}
+
+	void set_zero()
+	{
+		this->data.setZero();
+	}
+
+	StridedVector get_coord(int coord)
+	{
+		return StridedVector(this->data.data() + coord, this->size());
+	}
+
+	void set_coord(int coord, Eigen::VectorXf &values)
+	{
+		BLI_assert(values.size() == this->size());
+		this->get_coord(coord) = values;
+	}
+
+	void copy_to(Vector3Ds dst)
+	{
+		memcpy(dst, &this->data[0], th

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list