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:
authorCampbell Barton <ideasman42@gmail.com>2013-04-17 13:27:23 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-04-17 13:27:23 +0400
commit14f9f167b2686a92883b754d111adbb5efec2515 (patch)
tree27132ff7ff9d8c65ecbcc26fab38bd3885870dea /source/blender/blenkernel
parentbb1b2529a0b0dce1b9c34e616436599ab5fd8021 (diff)
display options to help with 3d printing.
editmesh debug info, - overhang (with axis angle options) - wall thickness (with min/max distance) - self-intersections. access below 'Mesh Display' panel.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_editmesh.h7
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c37
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c305
-rw-r--r--source/blender/blenkernel/intern/editmesh.c2
-rw-r--r--source/blender/blenkernel/intern/scene.c6
5 files changed, 353 insertions, 4 deletions
diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h
index 934689424fa..7052cb6012c 100644
--- a/source/blender/blenkernel/BKE_editmesh.h
+++ b/source/blender/blenkernel/BKE_editmesh.h
@@ -30,6 +30,8 @@ struct BMesh;
struct BMLoop;
struct BMFace;
struct Mesh;
+struct DerivedMesh;
+struct MeshStatVis;
/* ok: the EDBM module is for editmode bmesh stuff. in contrast, the
* BMEdit module is for code shared with blenkernel that concerns
@@ -61,6 +63,8 @@ typedef struct BMEditMesh {
CustomDataMask lastDataMask;
unsigned char (*derivedVertColor)[4];
int derivedVertColorLen;
+ unsigned char (*derivedFaceColor)[4];
+ int derivedFaceColorLen;
/* index tables, to map indices to elements via
* EDBM_index_arrays_init and associated functions. don't
@@ -89,5 +93,8 @@ BMEditMesh *BKE_editmesh_copy(BMEditMesh *em);
BMEditMesh *BKE_editmesh_from_object(struct Object *ob);
void BKE_editmesh_free(BMEditMesh *em);
void BKE_editmesh_update_linked_customdata(BMEditMesh *em);
+void BKE_editmesh_statvis_calc(BMEditMesh *em, struct DerivedMesh *dm,
+ struct MeshStatVis *statvis,
+ unsigned char (*r_face_colors)[4]);
#endif /* __BKE_EDITMESH_H__ */
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index d1a1163d5c7..255723b0977 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1204,6 +1204,14 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag,
int i;
if (em) {
+
+ /* no need to store both */
+ if (em->derivedFaceColor) {
+ MEM_freeN(em->derivedFaceColor);
+ em->derivedFaceColor = NULL;
+ em->derivedFaceColorLen = 0;
+ }
+
if (em->derivedVertColor && em->derivedVertColorLen == numVerts) {
wtcol_v = em->derivedVertColor;
}
@@ -1283,6 +1291,30 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag,
}
}
+static void DM_update_statvis_color(Scene *scene, Object *ob, DerivedMesh *dm)
+{
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ int numFaces = em->bm->totface;
+ unsigned char (*wtcol_f)[4];
+
+ /* no need to store both */
+ if (em->derivedVertColor) {
+ MEM_freeN(em->derivedVertColor);
+ em->derivedVertColor = NULL;
+ em->derivedVertColorLen = 0;
+ }
+
+ if (em->derivedFaceColor && em->derivedFaceColorLen == numFaces) {
+ wtcol_f = em->derivedFaceColor;
+ }
+ else {
+ if (em->derivedFaceColor) MEM_freeN(em->derivedFaceColor);
+ wtcol_f = em->derivedFaceColor = MEM_mallocN(sizeof(*wtcol_f) * numFaces, __func__);
+ em->derivedFaceColorLen = numFaces;
+ }
+
+ BKE_editmesh_statvis_calc(em, dm, &scene->toolsettings->statvis, wtcol_f);
+}
static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid)
{
@@ -1939,6 +1971,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
#endif
const int do_final_wmcol = FALSE;
int do_init_wmcol = ((((Mesh *)ob->data)->drawflag & ME_DRAWEIGHT) && !do_final_wmcol);
+ int do_init_statvis = ((((Mesh *)ob->data)->drawflag & ME_DRAW_STATVIS) && !do_init_wmcol);
modifiers_clearErrors(ob);
@@ -2127,6 +2160,8 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
/* In this case, we should never have weight-modifying modifiers in stack... */
if (do_init_wmcol)
DM_update_weight_mcol(ob, *final_r, draw_flag, NULL, 0, NULL);
+ if (do_init_statvis)
+ DM_update_statvis_color(scene, ob, *final_r);
}
else {
/* this is just a copy of the editmesh, no need to calc normals */
@@ -2136,6 +2171,8 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
/* In this case, we should never have weight-modifying modifiers in stack... */
if (do_init_wmcol)
DM_update_weight_mcol(ob, *final_r, draw_flag, NULL, 0, NULL);
+ if (do_init_statvis)
+ DM_update_statvis_color(scene, ob, *final_r);
}
/* --- */
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 447dd88a0a6..6435e6e98a7 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -44,12 +44,15 @@
#include "GL/glew.h"
#include "BLI_math.h"
+#include "BLI_jitter.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_mesh.h"
#include "BKE_editmesh.h"
+#include "BKE_editmesh_bvh.h"
#include "DNA_mesh_types.h"
+#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "MEM_guardedalloc.h"
@@ -320,8 +323,10 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
const int skip_normals = !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */
MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
- unsigned char(*color_vert_array)[4] = (((Mesh *)em->ob->data)->drawflag & ME_DRAWEIGHT) ? em->derivedVertColor : NULL;
+ unsigned char(*color_vert_array)[4] = (((Mesh *)em->ob->data)->drawflag & ME_DRAWEIGHT) ? em->derivedVertColor : NULL;
+ unsigned char(*color_face_array)[4] = (((Mesh *)em->ob->data)->drawflag & ME_DRAW_STATVIS) ? em->derivedFaceColor : NULL;
bool has_vcol_preview = (color_vert_array != NULL) && !skip_normals;
+ bool has_fcol_preview = (color_face_array != NULL) && !skip_normals;
bool has_vcol_any = has_vcol_preview;
/* GL_ZERO is used to detect if drawing has started or not */
@@ -336,6 +341,11 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
/* call again below is ok */
if (has_vcol_preview) {
BM_mesh_elem_index_ensure(bm, BM_VERT);
+ }
+ if (has_fcol_preview) {
+ BM_mesh_elem_index_ensure(bm, BM_FACE);
+ }
+ if (has_vcol_preview || has_fcol_preview) {
flag |= DM_DRAW_ALWAYS_SMOOTH;
glDisable(GL_LIGHTING); /* grr */
}
@@ -370,8 +380,8 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
glPolygonStipple(stipple_quarttone);
}
- if (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
-
+ if (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
+ else if (has_fcol_preview) glColor3ubv((const GLubyte *)&(color_face_array[BM_elem_index_get(efa)]));
if (skip_normals) {
if (poly_type != poly_prev) {
if (poly_prev != GL_ZERO) glEnd();
@@ -455,7 +465,8 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
glPolygonStipple(stipple_quarttone);
}
- if (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
+ if (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
+ else if (has_fcol_preview) glColor3ubv((const GLubyte *)&(color_face_array[BM_elem_index_get(efa)]));
if (skip_normals) {
if (poly_type != poly_prev) {
@@ -1530,3 +1541,289 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
return (DerivedMesh *)bmdm;
}
+
+
+
+/* -------------------------------------------------------------------- */
+/* StatVis Functions */
+
+static void axis_from_enum_v3(float v[3], const char axis)
+{
+ zero_v3(v);
+ if (axis < 3) v[axis] = 1.0f;
+ else v[axis - 3] = -1.0f;
+}
+
+static void statvis_calc_overhang(
+ BMEditMesh *em,
+ float (*polyNos)[3],
+ /* values for calculating */
+ const float min, const float max, const char axis,
+ /* result */
+ unsigned char (*r_face_colors)[4])
+{
+ BMIter iter;
+ BMesh *bm = em->bm;
+ BMFace *f;
+ float dir[3];
+ int index;
+ const float minmax_irange = 1.0f / (max - min);
+
+ /* fallback */
+ const char col_fallback[4] = {64, 64, 64, 255};
+
+ BLI_assert(min <= max);
+
+ axis_from_enum_v3(dir, axis);
+
+ /* now convert into global space */
+ BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, index) {
+ float fac = angle_normalized_v3v3(polyNos ? polyNos[index] : f->no, dir) / (float)M_PI;
+
+ /* remap */
+ if (fac >= min && fac <= max) {
+ float fcol[3];
+ fac = (fac - min) * minmax_irange;
+ fac = 1.0f - fac;
+ CLAMP(fac, 0.0f, 1.0f);
+ weight_to_rgb(fcol, fac);
+ rgb_float_to_uchar(r_face_colors[index], fcol);
+ }
+ else {
+ copy_v4_v4_char((char *)r_face_colors[index], (const char *)col_fallback);
+ }
+ }
+}
+
+/* so we can use jitter values for face interpolation */
+static void uv_from_jitter_v2(float uv[2])
+{
+ uv[0] += 0.5f;
+ uv[1] += 0.5f;
+ if (uv[0] + uv[1] > 1.0f) {
+ uv[0] = 1.0f - uv[0];
+ uv[1] = 1.0f - uv[1];
+ }
+
+ CLAMP(uv[0], 0.0f, 1.0f);
+ CLAMP(uv[1], 0.0f, 1.0f);
+}
+
+static void statvis_calc_thickness(
+ BMEditMesh *em,
+ float (*vertexCos)[3],
+ /* values for calculating */
+ const float min, const float max, const int samples,
+ /* result */
+ unsigned char (*r_face_colors)[4])
+{
+ const float eps_offset = FLT_EPSILON * 10.0f;
+ float *face_dists = (float *)r_face_colors; /* cheating */
+ const bool use_jit = samples < 32;
+ float jit_ofs[32][2];
+ BMesh *bm = em->bm;
+ const int tottri = em->tottri;
+ const float minmax_irange = 1.0f / (max - min);
+ int i;
+
+ struct BMLoop *(*looptris)[3] = em->looptris;
+
+ /* fallback */
+ const char col_fallback[4] = {64, 64, 64, 255};
+
+ struct BMBVHTree *bmtree;
+
+ BLI_assert(min <= max);
+
+ fill_vn_fl(face_dists, em->bm->totface, max);
+
+ if (use_jit) {
+ int j;
+ BLI_assert(samples < 32);
+ BLI_jitter_init(jit_ofs[0], samples);
+
+ for (j = 0; j < samples; j++) {
+ uv_from_jitter_v2(jit_ofs[j]);
+ }
+ }
+
+ (void)vertexCos;
+
+ BM_mesh_elem_index_ensure(bm, BM_FACE);
+ if (vertexCos) {
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
+ }
+
+ bmtree = BKE_bmbvh_new(em, 0, NULL);
+
+ for (i = 0; i < tottri; i++) {
+ BMFace *f_hit;
+ BMLoop **ltri = looptris[i];
+ const int index = BM_elem_index_get(ltri[0]->f);
+ const float *cos[3];
+ float ray_co[3];
+ float ray_no[3];
+
+ if (vertexCos) {
+ cos[0] = vertexCos[BM_elem_index_get(ltri[0]->v)];
+ cos[1] = vertexCos[BM_elem_index_get(ltri[1]->v)];
+ cos[3] = vertexCos[BM_elem_index_get(ltri[2]->v)];
+ }
+ else {
+ cos[0] = ltri[0]->v->co;
+ cos[1] = ltri[1]->v->co;
+ cos[2] = ltri[2]->v->co;
+ }
+
+ normal_tri_v3(ray_no, cos[2], cos[1], cos[0]);
+
+ if (use_jit) {
+ int j;
+ for (j = 0; j < samples; j++) {
+ interp_v3_v3v3v3_uv(ray_co, cos[0], cos[1], cos[2], jit_ofs[j]);
+ madd_v3_v3fl(ray_co, ray_no, eps_offset);
+
+ f_hit = BKE_bmbvh_ray_cast(bmtree, ray_co, ray_no,
+ &face_dists[index], NULL, NULL);
+ /* duplicate */
+ if (f_hit) {
+ const int index_hit = BM_elem_index_get(f_hit);
+ face_dists[index] = face_dists[index_hit] = min_ff(face_dists[index], face_dists[index_hit]);
+ }
+ }
+ }
+ else {
+ mid_v3_v3v3v3(ray_co, cos[0], cos[1], cos[2]);
+ madd_v3_v3fl(ray_co, ray_no, eps_offset);
+
+ f_hit = BKE_bmbvh_ray_cast(bmtree, ray_co, ray_no,
+ &face_dists[index], NULL, NULL);
+ /* duplicate */
+ if (f_hit) {
+ const int index_hit = BM_elem_index_get(f_hit);
+ face_dists[index] = face_dists[index_hit] = min_ff(face_dists[index], face_dists[index_hit]);
+ }
+ }
+ }
+
+ /* convert floats into color! */
+ for (i = 0; i < bm->totface; i++) {
+ float fac = face_dists[i];
+
+ /* important not '<=' */
+ if (fac < max) {
+ float fcol[3];
+ fac = (fac - min) * minmax_irange;
+ fac = 1.0f - fac;
+ CLAMP(fac, 0.0f, 1.0f);
+ weight_to_rgb(fcol, fac);
+ rgb_float_to_uchar(r_face_colors[i], fcol);
+ }
+ else {
+ copy_v4_v4_char((char *)r_face_colors[i], (const char *)col_fallback);
+ }
+ }
+
+ BKE_bmbvh_free(bmtree);
+}
+
+static void statvis_calc_intersect(
+ BMEditMesh *em,
+ float (*vertexCos)[3],
+ /* result */
+ unsigned char (*r_face_colors)[4])
+{
+ BMIter iter;
+ BMesh *bm = em->bm;
+ BMEdge *e;
+ int index;
+
+ /* fallback */
+ // const char col_fallback[4] = {64, 64, 64, 255};
+
+ struct BMBVHTree *bmtree;
+
+ memset(r_face_colors, 64, sizeof(int) * em->bm->totface);
+
+ (void)vertexCos;
+
+ BM_mesh_elem_index_ensure(bm, BM_FACE);
+ if (vertexCos) {
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
+ }
+
+ bmtree = BKE_bmbvh_new(em, 0, NULL);
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ BMFace *f_hit;
+ float cos[2][3];
+ float cos_mid[3];
+ float ray_no[3];
+
+ if (vertexCos) {
+ copy_v3_v3(cos[0], vertexCos[BM_elem_index_get(e->v1)]);
+ copy_v3_v3(cos[1], vertexCos[BM_elem_index_get(e->v2)]);
+ }
+ else {
+ copy_v3_v3(cos[0], e->v1->co);
+ copy_v3_v3(cos[1], e->v2->co);
+ }
+
+ mid_v3_v3v3(cos_mid, cos[0], cos[1]);
+ sub_v3_v3v3(ray_no, cos[1], cos[0]);
+
+ f_hit = BKE_bmbvh_find_face_segment(bmtree, cos[0], cos[1],
+ NULL, NULL, NULL);
+
+ if (f_hit) {
+ BMLoop *l_iter, *l_first;
+ float fcol[3];
+
+ index = BM_elem_index_get(f_hit);
+ weight_to_rgb(fcol, 1.0f);
+ rgb_float_to_uchar(r_face_colors[index], fcol);
+
+ l_iter = l_first = e->l;
+ do {
+ index = BM_elem_index_get(l_iter->f);
+ weight_to_rgb(fcol, 1.0f);
+ rgb_float_to_uchar(r_face_colors[index], fcol);
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+
+ }
+
+ BKE_bmbvh_free(bmtree);
+}
+
+void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm,
+ MeshStatVis *statvis,
+ unsigned char (*r_face_colors)[4])
+{
+ EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
+ BLI_assert(dm == NULL || dm->type == DM_TYPE_EDITBMESH);
+
+ switch (statvis->type) {
+ case SCE_STATVIS_OVERHANG:
+ statvis_calc_overhang(
+ em, bmdm ? bmdm->polyNos : NULL,
+ statvis->overhang_min / (float)M_PI,
+ statvis->overhang_max / (float)M_PI,
+ statvis->overhang_axis,
+ r_face_colors);
+ break;
+ case SCE_STATVIS_THICKNESS:
+ statvis_calc_thickness(
+ em, bmdm ? bmdm->vertexCos : NULL,
+ statvis->thickness_min,
+ statvis->thickness_max,
+ statvis->thickness_samples,
+ r_face_colors);
+ break;
+ case SCE_STATVIS_INTERSECT:
+ statvis_calc_intersect(
+ em, bmdm ? bmdm->vertexCos : NULL,
+ r_face_colors);
+ break;
+ }
+}
diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.c
index 2782cecfd8d..6ddc7c07d0a 100644
--- a/source/blender/blenkernel/intern/editmesh.c
+++ b/source/blender/blenkernel/intern/editmesh.c
@@ -61,6 +61,7 @@ BMEditMesh *BKE_editmesh_copy(BMEditMesh *em)
em_copy->derivedCage = em_copy->derivedFinal = NULL;
em_copy->derivedVertColor = NULL;
+ em_copy->derivedFaceColor = NULL;
em_copy->bm = BM_mesh_copy(em->bm);
@@ -327,6 +328,7 @@ void BKE_editmesh_free(BMEditMesh *em)
}
if (em->derivedVertColor) MEM_freeN(em->derivedVertColor);
+ if (em->derivedFaceColor) MEM_freeN(em->derivedFaceColor);
if (em->looptris) MEM_freeN(em->looptris);
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 2685484b576..86dbc2a36b3 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -520,6 +520,12 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH;
sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE;
+ sce->toolsettings->statvis.overhang_axis = OB_NEGZ;
+ sce->toolsettings->statvis.overhang_min = 0;
+ sce->toolsettings->statvis.overhang_max = DEG2RADF(45.0f);
+ sce->toolsettings->statvis.thickness_max = 0.1f;
+ sce->toolsettings->statvis.thickness_samples = 1;
+
sce->toolsettings->proportional_size = 1.0f;
sce->physics_settings.gravity[0] = 0.0f;