Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2014-08-30 19:54:36 +0400
committerLukas Tönne <lukas.toenne@gmail.com>2015-01-20 11:29:56 +0300
commitd8cf12fe5a18309e968ffc3b326d70554013b5a7 (patch)
treec9ec99742901601a9cd5cccf62b4c8d2291813ed /source/blender
parent5a43e8493e3851d076365dc106e0fa18ab21eebe (diff)
Debug drawing for simulations, to aid in visualizing abstract data such
as forces, velocities, contact points etc. This uses a hash table to store debug elements (dots, lines, vectors at this point). The hash table allows continuous display of elements that are generated only in certain time steps, e.g. contact points, while avoiding massive memory allocation. In any case, this system is really a development feature, but very helpful in finding issues with the internal solver data.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_effect.h26
-rw-r--r--source/blender/blenkernel/intern/effect.c105
-rw-r--r--source/blender/blenkernel/intern/implicit.c38
-rw-r--r--source/blender/blenloader/intern/readfile.c2
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_view3d/drawobject.c6
-rw-r--r--source/blender/editors/space_view3d/drawsimdebug.c140
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h4
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h2
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c28
-rw-r--r--source/blender/modifiers/intern/MOD_cloth.c6
11 files changed, 357 insertions, 1 deletions
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index d5e54d849cd..d6991a473b0 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -136,6 +136,32 @@ int get_effector_data(struct EffectorCache *eff, struct EffectorData *efd, struc
/* EffectorData->flag */
#define PE_VELOCITY_TO_IMPULSE 1
+/* ======== Simulation Debugging ======== */
+
+typedef struct SimDebugElement {
+ int type;
+ int hash;
+ float color[3];
+
+ float v1[3], v2[3];
+} SimDebugElement;
+
+typedef enum eSimDebugElement_Type {
+ SIM_DEBUG_ELEM_DOT,
+ SIM_DEBUG_ELEM_LINE,
+ SIM_DEBUG_ELEM_VECTOR,
+} eSimDebugElement_Type;
+
+typedef struct SimDebugData {
+ struct GHash *gh;
+} SimDebugData;
+
+struct SimDebugData *BKE_sim_debug_data_new(void);
+void BKE_sim_debug_data_add_dot(struct SimDebugData *debug_data, const float p[3], float r, float g, float b, int hash);
+void BKE_sim_debug_data_add_line(struct SimDebugData *debug_data, const float p1[3], const float p2[3], float r, float g, float b, int hash);
+void BKE_sim_debug_data_add_vector(struct SimDebugData *debug_data, const float p[3], const float d[3], float r, float g, float b, int hash);
+void BKE_sim_debug_data_clear(struct SimDebugData *debug_data);
+void BKE_sim_debug_data_free(struct SimDebugData *debug_data);
#endif
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index ced9da8d0b1..94b4af10201 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -51,6 +51,7 @@
#include "BLI_noise.h"
#include "BLI_rand.h"
#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
#include "PIL_time.h"
@@ -1024,3 +1025,107 @@ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *we
}
}
}
+
+/* ======== Simulation Debugging ======== */
+
+static unsigned int debug_element_hash(const void *key)
+{
+ const SimDebugElement *elem = key;
+ return elem->hash;
+}
+
+static int debug_element_compare(const void *a, const void *b)
+{
+ const SimDebugElement *elem1 = a;
+ const SimDebugElement *elem2 = b;
+
+ if (elem1->hash == elem2->hash) {
+ return 0;
+ }
+ return 1;
+}
+
+static void debug_element_free(void *val)
+{
+ SimDebugElement *elem = val;
+ MEM_freeN(elem);
+}
+
+SimDebugData *BKE_sim_debug_data_new(void)
+{
+ SimDebugData *debug_data = MEM_callocN(sizeof(SimDebugData), "sim debug data");
+ debug_data->gh = BLI_ghash_new(debug_element_hash, debug_element_compare, "sim debug element hash");
+ return debug_data;
+
+}
+
+static void debug_data_insert(SimDebugData *debug_data, SimDebugElement *elem)
+{
+ SimDebugElement *old_elem = BLI_ghash_lookup(debug_data->gh, elem);
+ if (old_elem) {
+ *old_elem = *elem;
+ MEM_freeN(elem);
+ }
+ else
+ BLI_ghash_insert(debug_data->gh, elem, elem);
+}
+
+void BKE_sim_debug_data_add_dot(struct SimDebugData *debug_data, const float p[3], float r, float g, float b, int hash)
+{
+ SimDebugElement *elem = MEM_callocN(sizeof(SimDebugElement), "sim debug data element");
+ elem->type = SIM_DEBUG_ELEM_DOT;
+ elem->hash = hash;
+ elem->color[0] = r;
+ elem->color[1] = g;
+ elem->color[2] = b;
+ copy_v3_v3(elem->v1, p);
+
+ debug_data_insert(debug_data, elem);
+}
+
+void BKE_sim_debug_data_add_line(struct SimDebugData *debug_data, const float p1[3], const float p2[3], float r, float g, float b, int hash)
+{
+ SimDebugElement *elem = MEM_callocN(sizeof(SimDebugElement), "sim debug data element");
+ elem->type = SIM_DEBUG_ELEM_LINE;
+ elem->hash = hash;
+ elem->color[0] = r;
+ elem->color[1] = g;
+ elem->color[2] = b;
+ copy_v3_v3(elem->v1, p1);
+ copy_v3_v3(elem->v2, p2);
+
+ debug_data_insert(debug_data, elem);
+}
+
+void BKE_sim_debug_data_add_vector(struct SimDebugData *debug_data, const float p[3], const float d[3], float r, float g, float b, int hash)
+{
+ SimDebugElement *elem = MEM_callocN(sizeof(SimDebugElement), "sim debug data element");
+ elem->type = SIM_DEBUG_ELEM_VECTOR;
+ elem->hash = hash;
+ elem->color[0] = r;
+ elem->color[1] = g;
+ elem->color[2] = b;
+ copy_v3_v3(elem->v1, p);
+ copy_v3_v3(elem->v2, d);
+
+ debug_data_insert(debug_data, elem);
+}
+
+void BKE_sim_debug_data_clear(SimDebugData *debug_data)
+{
+ if (!debug_data)
+ return;
+
+ if (debug_data->gh)
+ BLI_ghash_clear(debug_data->gh, NULL, debug_element_free);
+}
+
+void BKE_sim_debug_data_free(SimDebugData *debug_data)
+{
+ if (!debug_data)
+ return;
+
+ if (debug_data->gh)
+ BLI_ghash_free(debug_data->gh, NULL, debug_element_free);
+ MEM_freeN(debug_data);
+}
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 13403795745..d0f0bc9455a 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -109,6 +109,36 @@ static double itval(void)
static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
static float ZERO[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
+/* ==== hash functions for debugging ==== */
+static unsigned int hash_int_2d(unsigned int kx, unsigned int ky)
+{
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+ unsigned int a, b, c;
+
+ a = b = c = 0xdeadbeef + (2 << 2) + 13;
+ a += kx;
+ b += ky;
+
+ c ^= b; c -= rot(b,14);
+ a ^= c; a -= rot(c,11);
+ b ^= a; b -= rot(a,25);
+ c ^= b; c -= rot(b,16);
+ a ^= c; a -= rot(c,4);
+ b ^= a; b -= rot(a,14);
+ c ^= b; c -= rot(b,24);
+
+ return c;
+
+#undef rot
+}
+
+static int hash_vertex(int type, int vertex)
+{
+ return hash_int_2d((unsigned int)type, (unsigned int)vertex);
+}
+/* ================ */
+
/*
#define C99
#ifdef C99
@@ -1922,7 +1952,7 @@ int implicit_solver(Object *ob, float frame, ClothModifierData *clmd, ListBase *
unsigned int i=0;
float step=0.0f, tf=clmd->sim_parms->timescale;
Cloth *cloth = clmd->clothObject;
- ClothVertex *verts = cloth->verts, *cv;
+ ClothVertex *verts = cloth->verts/*, *cv*/;
unsigned int numverts = cloth->numverts;
float dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
@@ -1943,6 +1973,12 @@ int implicit_solver(Object *ob, float frame, ClothModifierData *clmd, ListBase *
}
}
+ if (clmd->debug_data) {
+ for (i = 0; i < numverts; i++) {
+ BKE_sim_debug_data_add_dot(clmd->debug_data, verts[i].x, 1.0f, 0.1f, 1.0f, hash_vertex(583, i));
+ }
+ }
+
while (step < tf) {
// damping velocity for artistic reasons
mul_lfvectorS(id->V, id->V, clmd->sim_parms->vel_damping, numverts);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 44b441d1a9e..054c9cb96e7 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4674,6 +4674,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL);
}
}
+
+ clmd->debug_data = NULL;
}
else if (md->type == eModifierType_Fluidsim) {
FluidsimModifierData *fluidmd = (FluidsimModifierData *)md;
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index 320267a4a7c..ab69e67361d 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -44,6 +44,7 @@ set(SRC
drawarmature.c
drawmesh.c
drawobject.c
+ drawsimdebug.c
drawvolume.c
space_view3d.c
view3d_buttons.c
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 55b621d5aba..e44012279b4 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -7488,6 +7488,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
draw_new_particle_system(scene, v3d, rv3d, base, psys, dt, dflag);
+
+ /* debug data */
+ if (psys->part->type == PART_HAIR) {
+ if (psys->clmd && psys->clmd->debug_data)
+ draw_sim_debug_data(scene, v3d, ar, base, psys->clmd->debug_data);
+ }
}
invert_m4_m4(ob->imat, ob->obmat);
view3d_cached_text_draw_end(v3d, ar, 0, NULL);
diff --git a/source/blender/editors/space_view3d/drawsimdebug.c b/source/blender/editors/space_view3d/drawsimdebug.c
new file mode 100644
index 00000000000..83fee946c99
--- /dev/null
+++ b/source/blender/editors/space_view3d/drawsimdebug.c
@@ -0,0 +1,140 @@
+/*
+ * ***** 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) 2014 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/drawsimdebug.c
+ * \ingroup spview3d
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+
+#include "BKE_effect.h"
+#include "BKE_global.h"
+#include "BKE_modifier.h"
+
+#include "view3d_intern.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "UI_resources.h"
+
+static void draw_sim_debug_elements(SimDebugData *debug_data)
+{
+ GHashIterator iter;
+
+ /**** dots ****/
+
+ glPointSize(3.0f);
+ glBegin(GL_POINTS);
+ for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
+ SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
+ if (elem->type != SIM_DEBUG_ELEM_DOT)
+ continue;
+
+ glColor3f(elem->color[0], elem->color[1], elem->color[2]);
+ glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ }
+ glEnd();
+ glPointSize(1.0f);
+
+ /**** lines ****/
+
+ glBegin(GL_LINES);
+ for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
+ SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
+ if (elem->type != SIM_DEBUG_ELEM_LINE)
+ continue;
+
+ glColor3f(elem->color[0], elem->color[1], elem->color[2]);
+ glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ glVertex3f(elem->v2[0], elem->v2[1], elem->v2[2]);
+ }
+ glEnd();
+
+ /**** vectors ****/
+
+ glPointSize(2.0f);
+ glBegin(GL_POINTS);
+ for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
+ SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
+ if (elem->type != SIM_DEBUG_ELEM_VECTOR)
+ continue;
+
+ glColor3f(elem->color[0], elem->color[1], elem->color[2]);
+ glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ }
+ glEnd();
+ glPointSize(1.0f);
+
+ glBegin(GL_LINES);
+ for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
+ SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
+ float t[3];
+ if (elem->type != SIM_DEBUG_ELEM_VECTOR)
+ continue;
+
+ glColor3f(elem->color[0], elem->color[1], elem->color[2]);
+ glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ add_v3_v3v3(t, elem->v1, elem->v2);
+ glVertex3f(t[0], t[1], t[2]);
+ }
+ glEnd();
+}
+
+void draw_sim_debug_data(Scene *UNUSED(scene), View3D *UNUSED(v3d), ARegion *ar, Base *UNUSED(base), SimDebugData *debug_data)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ /*Object *ob = base->object;*/
+ /*float imat[4][4];*/
+
+ /*invert_m4_m4(imat, rv3d->viewmatob);*/
+
+// glDepthMask(GL_FALSE);
+// glEnable(GL_BLEND);
+
+ glPushMatrix();
+ glLoadMatrixf(rv3d->viewmat);
+
+ if (debug_data) {
+ draw_sim_debug_elements(debug_data);
+ }
+
+ glPopMatrix();
+
+// glDepthMask(GL_TRUE);
+// glDisable(GL_BLEND);
+}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index d3a9f5ca967..c0517cf1151 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -48,6 +48,7 @@ struct bMotionPath;
struct bPoseChannel;
struct bScreen;
struct Mesh;
+struct SimDebugData;
struct wmNDOFMotionData;
struct wmOperatorType;
struct wmWindowManager;
@@ -177,6 +178,9 @@ void draw_mesh_paint_weight_edges(RegionView3D *rv3d, struct DerivedMesh *dm,
void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
struct Object *ob, struct DerivedMesh *dm, const int draw_flags);
+/* drawsimdebug.c */
+void draw_sim_debug_data(Scene *scene, View3D *v3d, ARegion *ar, Base *base, struct SimDebugData *debug_data);
+
/* view3d_draw.c */
void view3d_main_area_draw(const struct bContext *C, struct ARegion *ar);
void ED_view3d_draw_depth(Scene *scene, struct ARegion *ar, View3D *v3d, bool alphaoverride);
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index b1e9fd254e1..812e7d20e2a 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -564,6 +564,8 @@ typedef struct ClothModifierData {
struct ClothCollSettings *coll_parms; /* definition is in DNA_cloth_types.h */
struct PointCache *point_cache; /* definition is in DNA_object_force.h */
struct ListBase ptcaches;
+
+ struct SimDebugData *debug_data; /* debug info */
} ClothModifierData;
typedef struct CollisionModifierData {
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index c412fd460b3..1ba00056ea5 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -46,6 +46,7 @@
#include "BKE_data_transfer.h"
#include "BKE_DerivedMesh.h"
#include "BKE_dynamicpaint.h"
+#include "BKE_effect.h"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remap.h"
#include "BKE_multires.h"
@@ -719,6 +720,28 @@ static int rna_LaplacianDeformModifier_is_bind_get(PointerRNA *ptr)
return ((lmd->flag & MOD_LAPLACIANDEFORM_BIND) && (lmd->cache_system != NULL));
}
+static int rna_ClothModifier_show_debug_data_get(PointerRNA *ptr)
+{
+ ClothModifierData *clmd = (ClothModifierData *)ptr->data;
+ return clmd->debug_data != NULL;
+}
+
+static void rna_ClothModifier_show_debug_data_set(PointerRNA *ptr, int value)
+{
+ ClothModifierData *clmd = (ClothModifierData *)ptr->data;
+ if (value) {
+ if (!clmd->debug_data) {
+ clmd->debug_data = BKE_sim_debug_data_new();
+ }
+ }
+ else {
+ if (clmd->debug_data) {
+ BKE_sim_debug_data_free(clmd->debug_data);
+ clmd->debug_data = NULL;
+ }
+ }
+}
+
/* NOTE: Curve and array modifiers requires curve path to be evaluated,
* dependency graph will make sure that curve eval would create such a path,
* but if curve was already evaluated we might miss path.
@@ -2468,6 +2491,11 @@ static void rna_def_modifier_cloth(BlenderRNA *brna)
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", "");
+
+ prop = RNA_def_property(srna, "show_debug_data", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_ClothModifier_show_debug_data_get", "rna_ClothModifier_show_debug_data_set");
+ RNA_def_property_ui_text(prop, "Debug", "Show debug info");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
static void rna_def_modifier_smoke(BlenderRNA *brna)
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index 1561fd1a981..15a73c0a34d 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -46,6 +46,7 @@
#include "BKE_cloth.h"
#include "BKE_cdderivedmesh.h"
+#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_key.h"
#include "BKE_modifier.h"
@@ -68,6 +69,8 @@ static void initData(ModifierData *md)
return;
cloth_init(clmd);
+
+ clmd->debug_data = NULL;
}
static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3],
@@ -175,6 +178,7 @@ static void copyData(ModifierData *md, ModifierData *target)
tclmd->point_cache = BKE_ptcache_add(&tclmd->ptcaches);
tclmd->point_cache->step = 1;
tclmd->clothObject = NULL;
+ tclmd->debug_data = NULL;
}
static bool dependsOnTime(ModifierData *UNUSED(md))
@@ -202,6 +206,8 @@ static void freeData(ModifierData *md)
BKE_ptcache_free_list(&clmd->ptcaches);
clmd->point_cache = NULL;
+
+ BKE_sim_debug_data_free(clmd->debug_data);
}
}