[Bf-blender-cvs] [491e749] master: Basic solver result feedback from the mass-spring (cloth/hair) solver.
Lukas Tönne
noreply at git.blender.org
Tue Jan 20 09:51:15 CET 2015
Commit: 491e7493c7f35a0b2d03a9fc6e934e5868c88b10
Author: Lukas Tönne
Date: Sat Sep 20 21:05:46 2014 +0200
Branches: master
https://developer.blender.org/rB491e7493c7f35a0b2d03a9fc6e934e5868c88b10
Basic solver result feedback from the mass-spring (cloth/hair) solver.
This returns a general status (success/no-convergence/other) along with
basic statistics (min/max/average) for the error value and the number
of iterations. It allows some general estimation of the simulation
quality and detection of critical settings that could become a problem.
Better visualization and extended feedback can follow later.
===================================================================
M release/scripts/startup/bl_ui/properties_particle.py
M source/blender/blenkernel/BKE_cloth.h
M source/blender/blenloader/intern/readfile.c
M source/blender/makesdna/DNA_modifier_types.h
M source/blender/makesrna/intern/CMakeLists.txt
M source/blender/makesrna/intern/rna_cloth.c
M source/blender/makesrna/intern/rna_modifier.c
M source/blender/modifiers/intern/MOD_cloth.c
M source/blender/physics/BPH_mass_spring.h
M source/blender/physics/intern/BPH_mass_spring.cpp
M source/blender/physics/intern/implicit.h
M source/blender/physics/intern/implicit_blender.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index 8afd2d0..d725738 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -304,6 +304,7 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
cloth_md = psys.cloth
cloth = cloth_md.settings
+ result = cloth_md.solver_result
layout.enabled = psys.use_hair_dynamics and psys.point_cache.is_baked is False
@@ -335,6 +336,24 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
col.prop(cloth_md, "show_debug_data", text="Debug")
+ if result:
+ box = layout.box()
+
+ if not result.status:
+ label = " "
+ icon = 'NONE'
+ elif result.status == {'SUCCESS'}:
+ label = "Success"
+ icon = 'NONE'
+ elif result.status - {'SUCCESS'} == {'NO_CONVERGENCE'}:
+ label = "No Convergence"
+ icon = 'ERROR'
+ else:
+ label = "ERROR"
+ icon = 'ERROR'
+ box.label(label, icon=icon)
+ box.label("Iterations: %d .. %d (avg. %d)" % (result.min_iterations, result.max_iterations, result.avg_iterations))
+ box.label("Error: %.5f .. %.5f (avg. %.5f)" % (result.min_error, result.max_error, result.avg_error))
class PARTICLE_PT_cache(ParticleButtonsPanel, Panel):
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 838388f..b7be7c6 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -64,6 +64,14 @@ typedef struct ClothHairRoot {
float rot[3][3];
} ClothHairRoot;
+typedef struct ClothSolverResult {
+ int status;
+
+ int max_iterations, min_iterations;
+ float avg_iterations;
+ float max_error, min_error, avg_error;
+} ClothSolverResult;
+
/**
* This structure describes a cloth object against which the
* simulation can run.
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 53ceaa0..709032b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4683,6 +4683,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
}
}
+ clmd->solver_result = NULL;
clmd->debug_data = NULL;
}
else if (md->type == eModifierType_Fluidsim) {
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 3dd9ebb..6c6d24c 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -567,6 +567,8 @@ typedef struct ClothModifierData {
/* XXX nasty hack, remove once hair can be separated from cloth modifier data */
struct ClothHairRoot *roots;
+ struct ClothSolverResult *solver_result;
+
struct SimDebugData *debug_data; /* debug info */
} ClothModifierData;
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index e64743c..0778b14 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -293,6 +293,7 @@ blender_include_dirs(
../../ikplugin
../../makesdna
../../nodes/
+ ../../physics
../../windowmanager
../../editors/include
../../render/extern/include
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 154ab7d..57dc3ea 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -38,6 +38,8 @@
#include "BKE_cloth.h"
#include "BKE_modifier.h"
+#include "BPH_mass_spring.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -268,6 +270,64 @@ static char *rna_ClothCollisionSettings_path(PointerRNA *ptr)
#else
+static void rna_def_cloth_solver_result(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem status_items[] = {
+ {BPH_SOLVER_SUCCESS, "SUCCESS", 0, "Success", "Computation was successful"},
+ {BPH_SOLVER_NUMERICAL_ISSUE, "NUMERICAL_ISSUE", 0, "Numerical Issue", "The provided data did not satisfy the prerequisites"},
+ {BPH_SOLVER_NO_CONVERGENCE, "NO_CONVERGENCE", 0, "No Convergence", "Iterative procedure did not converge"},
+ {BPH_SOLVER_INVALID_INPUT, "INVALID_INPUT", 0, "Invalid Input", "The inputs are invalid, or the algorithm has been improperly called"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ srna = RNA_def_struct(brna, "ClothSolverResult", NULL);
+ RNA_def_struct_ui_text(srna, "Solver Result", "Result of cloth solver iteration");
+
+ RNA_define_verify_sdna(0);
+
+ prop = RNA_def_property(srna, "status", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, status_items);
+ RNA_def_property_enum_sdna(prop, NULL, "status");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Status", "Status of the solver iteration");
+
+ prop = RNA_def_property(srna, "max_error", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "max_error");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Maximum Error", "Maximum error during substeps");
+
+ prop = RNA_def_property(srna, "min_error", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "min_error");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Minimum Error", "Minimum error during substeps");
+
+ prop = RNA_def_property(srna, "avg_error", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "avg_error");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Average Error", "Average error during substeps");
+
+ prop = RNA_def_property(srna, "max_iterations", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "max_iterations");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Maximum Iterations", "Maximum iterations during substeps");
+
+ prop = RNA_def_property(srna, "min_iterations", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "min_iterations");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Minimum Iterations", "Minimum iterations during substeps");
+
+ prop = RNA_def_property(srna, "avg_iterations", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "avg_iterations");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Average Iterations", "Average iterations during substeps");
+
+ RNA_define_verify_sdna(1);
+}
+
static void rna_def_cloth_sim_settings(BlenderRNA *brna)
{
StructRNA *srna;
@@ -660,6 +720,7 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
void RNA_def_cloth(BlenderRNA *brna)
{
+ rna_def_cloth_solver_result(brna);
rna_def_cloth_sim_settings(brna);
rna_def_cloth_collision_settings(brna);
}
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 1ba0005..8e7a1d8 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -2488,6 +2488,11 @@ static void rna_def_modifier_cloth(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "coll_parms");
RNA_def_property_ui_text(prop, "Cloth Collision Settings", "");
+ prop = RNA_def_property(srna, "solver_result", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "ClothSolverResult");
+ RNA_def_property_pointer_sdna(prop, NULL, "solver_result");
+ RNA_def_property_ui_text(prop, "Solver Result", "");
+
prop = RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Point Cache", "");
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index 5c5e38f..1b513dd 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -179,6 +179,7 @@ static void copyData(ModifierData *md, ModifierData *target)
tclmd->point_cache->step = 1;
tclmd->clothObject = NULL;
tclmd->roots = NULL;
+ tclmd->solver_result = NULL;
tclmd->debug_data = NULL;
}
@@ -211,6 +212,9 @@ static void freeData(ModifierData *md)
if (clmd->roots)
MEM_freeN(clmd->roots);
+ if (clmd->solver_result)
+ MEM_freeN(clmd->solver_result);
+
BKE_sim_debug_data_free(clmd->debug_data);
}
}
diff --git a/source/blender/physics/BPH_mass_spring.h b/source/blender/physics/BPH_mass_spring.h
index 14c03d8..a1d7af9 100644
--- a/source/blender/physics/BPH_mass_spring.h
+++ b/source/blender/physics/BPH_mass_spring.h
@@ -35,9 +35,18 @@ extern "C" {
struct Implicit_Data;
struct ClothModifierData;
+typedef enum eMassSpringSolverStatus {
+ BPH_SOLVER_SUCCESS = (1 << 0),
+ BPH_SOLVER_NUMERICAL_ISSUE = (1 << 1),
+ BPH_SOLVER_NO_CONVERGENCE = (1 << 2),
+ BPH_SOLVER_INVALID_INPUT = (1 << 3),
+} eMassSpringSolverStatus;
+
struct Implicit_Data *BPH_mass_spring_solver_create(int numverts, int numsprings);
void BPH_mass_spring_solver_free(struct Implicit_Data *id);
+const struct MassSpringSolverResult *BPH_mass_spring_solver_result(struct Implicit_Data *data);
+
int BPH_cloth_solver_init(struct Object *ob, struct ClothModifierData *clmd);
void BPH_cloth_solver_free(struct ClothModifierData *clmd);
int BPH_cloth_solve(struct Object *ob, float frame, struct ClothModifierData *clmd, struct ListBase *effectors);
diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp
index 6a64e17..4130895 100644
--- a/source/blender/physics/intern/BPH_mass_spring.cpp
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -530,6 +530,46 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListB
}
}
+static void cloth_clear_result(ClothModifierData *clmd)
+{
+ ClothSolverResult *sr
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list