add mesh distort display mode (highlights distorted faces)
authorCampbell Barton <ideasman42@gmail.com>
Thu, 18 Apr 2013 04:24:18 +0000 (04:24 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 18 Apr 2013 04:24:18 +0000 (04:24 +0000)
release/scripts/startup/bl_ui/space_view3d.py
source/blender/blenkernel/BKE_editmesh_bvh.h
source/blender/blenkernel/intern/editderivedmesh.c
source/blender/blenkernel/intern/editmesh_bvh.c
source/blender/blenkernel/intern/scene.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/mesh/editmesh_knife.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_scene.c

index 403090675495a782267470c1a032fcdfe98f06bb..aedbacf1b2b00d570ac3d1a6d1fd3e2167608711 100644 (file)
@@ -2643,6 +2643,10 @@ class VIEW3D_PT_view3d_meshstatvis(Panel):
             layout.prop(statvis, "thickness_samples")
         elif statvis_type == 'INTERSECT':
             pass
+        elif statvis_type == 'DISTORT':
+            row = layout.row(align=True)
+            row.prop(statvis, "distort_min", text="")
+            row.prop(statvis, "distort_max", text="")
 
 
 class VIEW3D_PT_view3d_curvedisplay(Panel):
index 90520c49983f926c26aa48e67393b5712e9e1dd1..6750ee1ff3e745a25716ffef89d846bdd2f3b1a5 100644 (file)
@@ -41,7 +41,7 @@ struct Scene;
 
 typedef struct BMBVHTree BMBVHTree;
 
-BMBVHTree      *BKE_bmbvh_new(struct BMEditMesh *em, int flag, float (*cos_cage)[3], const bool cos_cage_free);
+BMBVHTree      *BKE_bmbvh_new(struct BMEditMesh *em, int flag, const float (*cos_cage)[3], const bool cos_cage_free);
 void            BKE_bmbvh_free(BMBVHTree *tree);
 struct BVHTree *BKE_bmbvh_tree_get(BMBVHTree *tree);
 struct BMFace  *BKE_bmbvh_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3],
index eda8957bb1b4abb63362011967eb8271dbae132d..c9e8cd2e249628596301c244a1465462a90e8e29 100644 (file)
@@ -1556,7 +1556,7 @@ static void axis_from_enum_v3(float v[3], const char axis)
 
 static void statvis_calc_overhang(
         BMEditMesh *em,
-        float (*polyNos)[3],
+        const float (*polyNos)[3],
         /* values for calculating */
         const float min, const float max, const char axis,
         /* result */
@@ -1616,7 +1616,7 @@ static void uv_from_jitter_v2(float uv[2])
 
 static void statvis_calc_thickness(
         BMEditMesh *em,
-        float (*vertexCos)[3],
+        const float (*vertexCos)[3],
         /* values for calculating */
         const float min, const float max, const int samples,
         /* result */
@@ -1732,7 +1732,7 @@ static void statvis_calc_thickness(
 
 static void statvis_calc_intersect(
         BMEditMesh *em,
-        float (*vertexCos)[3],
+        const float (*vertexCos)[3],
         /* result */
         unsigned char (*r_face_colors)[4])
 {
@@ -1797,6 +1797,72 @@ static void statvis_calc_intersect(
        BKE_bmbvh_free(bmtree);
 }
 
+static void statvis_calc_distort(
+        BMEditMesh *em,
+        const float (*vertexCos)[3],
+        /* values for calculating */
+        const float min, const float max,
+        /* result */
+        unsigned char (*r_face_colors)[4])
+{
+       BMIter iter;
+       BMesh *bm = em->bm;
+       BMFace *f;
+       float f_no[3];
+       int index;
+       const float minmax_irange = 1.0f / (max - min);
+
+       /* fallback */
+       const char col_fallback[4] = {64, 64, 64, 255};
+
+       /* now convert into global space */
+       BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, index) {
+               float fac;
+
+               if (f->len == 3) {
+                       fac = -1.0f;
+               }
+               else {
+                       BMLoop *l_iter, *l_first;
+                       if (vertexCos) {
+                               BM_face_normal_update_vcos(bm, f, f_no, vertexCos);
+                       }
+                       else {
+                               copy_v3_v3(f_no, f->no);
+                       }
+
+                       fac = 0.0f;
+                       l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+                       do {
+                               float no_corner[3];
+                               if (vertexCos) {
+                                       normal_tri_v3(no_corner,
+                                                     vertexCos[BM_elem_index_get(l_iter->prev->v)],
+                                                     vertexCos[BM_elem_index_get(l_iter->v)],
+                                                     vertexCos[BM_elem_index_get(l_iter->next->v)]);
+                               }
+                               else {
+                                       BM_loop_calc_face_normal(l_iter, no_corner);
+                               }
+                               fac = max_ff(fac, angle_normalized_v3v3(f_no, no_corner));
+                       } while ((l_iter = l_iter->next) != l_first);
+                       fac /= (float)M_1_PI;
+               }
+
+               /* remap */
+               if (fac >= min) {
+                       float fcol[3];
+                       fac = (fac - min) * minmax_irange;
+                       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);
+               }
+       }
+}
+
 void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm,
                                MeshStatVis *statvis,
                                unsigned char (*r_face_colors)[4])
@@ -1808,7 +1874,7 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm,
                case SCE_STATVIS_OVERHANG:
                {
                        statvis_calc_overhang(
-                                   em, bmdm ? bmdm->polyNos : NULL,
+                                   em, bmdm ? (const float (*)[3])bmdm->polyNos : NULL,
                                    statvis->overhang_min / (float)M_PI,
                                    statvis->overhang_max / (float)M_PI,
                                    statvis->overhang_axis,
@@ -1819,7 +1885,7 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm,
                {
                        const float scale = 1.0f / mat4_to_scale(em->ob->obmat);
                        statvis_calc_thickness(
-                                   em, bmdm ? bmdm->vertexCos : NULL,
+                                   em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL,
                                    statvis->thickness_min * scale,
                                    statvis->thickness_max * scale,
                                    statvis->thickness_samples,
@@ -1829,10 +1895,19 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm,
                case SCE_STATVIS_INTERSECT:
                {
                        statvis_calc_intersect(
-                                   em, bmdm ? bmdm->vertexCos : NULL,
+                                   em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL,
                                    r_face_colors);
                        break;
                }
+               case SCE_STATVIS_DISTORT:
+               {
+                       statvis_calc_distort(
+                               em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL,
+                               statvis->distort_min / (float)M_PI,
+                               statvis->distort_max / (float)M_PI,
+                               r_face_colors);
+                       break;
+               }
        }
 }
 
index 27fb1798e7ca05264d9e1b236cf1f6e183de7f3a..14e6eedec7c0eb58ce4f5375a23c3fa6d21130d3 100644 (file)
@@ -47,13 +47,13 @@ struct BMBVHTree {
        BMEditMesh *em;
        BMesh *bm;
 
-       float (*cos_cage)[3];
+       const float (*cos_cage)[3];
        bool cos_cage_free;
 
        int flag;
 };
 
-BMBVHTree *BKE_bmbvh_new(BMEditMesh *em, int flag, float (*cos_cage)[3], const bool cos_cage_free)
+BMBVHTree *BKE_bmbvh_new(BMEditMesh *em, int flag, const float (*cos_cage)[3], const bool cos_cage_free)
 {
        /* could become argument */
        const float epsilon = FLT_EPSILON * 2.0f;
index 86dbc2a36b3cf515a249a8a297d2ca81a03f9307..ff384b282931cf43f85a445a90cce202846cb464 100644 (file)
@@ -525,6 +525,8 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
        sce->toolsettings->statvis.overhang_max = DEG2RADF(45.0f);
        sce->toolsettings->statvis.thickness_max = 0.1f;
        sce->toolsettings->statvis.thickness_samples = 1;
+       sce->toolsettings->statvis.distort_min = DEG2RADF(5.0f);
+       sce->toolsettings->statvis.distort_max = DEG2RADF(45.0f);
 
        sce->toolsettings->proportional_size = 1.0f;
 
index c5b319706e4121bf5fceb4ba0415e482704d4404..09835852c0fea340d25a056afd4955e498dd31f4 100644 (file)
@@ -9356,6 +9356,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
                                        statvis->thickness_max = 0.1f;
                                        statvis->thickness_samples = 1;
+
+                                       statvis->distort_min = DEG2RADF(5.0f);
+                                       statvis->distort_max = DEG2RADF(45.0f);
                                }
                        }
 
index 040a40c470af55560cc166454978007e4fb52967..3811e8b7d8c388ced952b23ce2823740fed0761b 100644 (file)
@@ -209,7 +209,7 @@ typedef struct KnifeTool_OpData {
                ANGLE_135
        } angle_snapping;
 
-       float (*cagecos)[3];
+       const float (*cagecos)[3];
 } KnifeTool_OpData;
 
 static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, BMFace *f);
@@ -327,7 +327,7 @@ static BMFace *knife_find_common_face(ListBase *faces1, ListBase *faces2)
        return NULL;
 }
 
-static KnifeVert *new_knife_vert(KnifeTool_OpData *kcd, const float co[3], float *cageco)
+static KnifeVert *new_knife_vert(KnifeTool_OpData *kcd, const float co[3], const float cageco[3])
 {
        KnifeVert *kfv = BLI_mempool_calloc(kcd->kverts);
 
@@ -2987,7 +2987,7 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
 
        BM_mesh_elem_index_ensure(kcd->em->bm, BM_VERT);
 
-       kcd->cagecos = BKE_editmesh_vertexCos_get(kcd->em, scene, NULL);
+       kcd->cagecos = (const float (*)[3])BKE_editmesh_vertexCos_get(kcd->em, scene, NULL);
 
        kcd->bmbvh = BKE_bmbvh_new(kcd->em,
                                  BMBVH_RETURN_ORIG |
index 2626c128b3ac73e357235b35c17fd5421277037c..f3809c4090eda638bb656efd222e628c3384e51c 100644 (file)
@@ -946,6 +946,9 @@ typedef struct MeshStatVis {
        float thickness_min, thickness_max;
        char thickness_samples;
        char _pad2[3];
+
+       /* distort */
+       float distort_min, distort_max;
 } MeshStatVis;
 
 
@@ -1466,6 +1469,7 @@ typedef struct Scene {
 #define SCE_STATVIS_OVERHANG   0
 #define SCE_STATVIS_THICKNESS  1
 #define SCE_STATVIS_INTERSECT  2
+#define SCE_STATVIS_DISTORT            3
 
 /* toolsettings->particle.selectmode for particles */
 #define SCE_SELECT_PATH                1
index e931b35f83f9f8f99953d1d804d890c9f48da1dc..1ff2805f4e2e60693cdacabd8ac404b8137938e1 100644 (file)
@@ -2009,6 +2009,7 @@ static void rna_def_statvis(BlenderRNA  *brna)
                {SCE_STATVIS_OVERHANG,  "OVERHANG",  0, "Overhang",  ""},
                {SCE_STATVIS_THICKNESS, "THICKNESS", 0, "Thickness", ""},
                {SCE_STATVIS_INTERSECT, "INTERSECT", 0, "Intersect", ""},
+               {SCE_STATVIS_DISTORT,   "DISTORT",   0, "Distort", ""},
                {0, NULL, 0, NULL, NULL}};
 
        srna = RNA_def_struct(brna, "MeshStatVis", NULL);
@@ -2062,12 +2063,27 @@ static void rna_def_statvis(BlenderRNA  *brna)
        RNA_def_property_ui_text(prop, "Thickness Max", "Maximum for measuring thickness");
        RNA_def_property_update(prop, 0, "rna_EditMesh_update");
 
-       /* intersect */
        prop = RNA_def_property(srna, "thickness_samples", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "thickness_samples");
        RNA_def_property_range(prop, 1, 32);
        RNA_def_property_ui_text(prop, "Samples", "Number of samples to test per face");
        RNA_def_property_update(prop, 0, "rna_EditMesh_update");
+
+       prop = RNA_def_property(srna, "distort_min", PROP_FLOAT, PROP_ANGLE);
+       RNA_def_property_float_sdna(prop, NULL, "distort_min");
+       RNA_def_property_float_default(prop, 0.5f);
+       RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f));
+       RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 0.001, 3);
+       RNA_def_property_ui_text(prop, "Distort Min", "Minimum angle to display");
+       RNA_def_property_update(prop, 0, "rna_EditMesh_update");
+
+       prop = RNA_def_property(srna, "distort_max", PROP_FLOAT, PROP_ANGLE);
+       RNA_def_property_float_sdna(prop, NULL, "distort_max");
+       RNA_def_property_float_default(prop, 0.5f);
+       RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f));
+       RNA_def_property_ui_range(prop, 0.0f, DEG2RADF(180.0f), 0.001, 3);
+       RNA_def_property_ui_text(prop, "Distort Max", "Maximum angle to display");
+       RNA_def_property_update(prop, 0, "rna_EditMesh_update");
 }
 
 static void rna_def_unit_settings(BlenderRNA  *brna)