code cleanup: rename BKE_tessmesh -> BKE_editmesh, rename EditDerivedBMesh.tc ->...
[blender-staging.git] / source / blender / editors / mesh / meshtools.c
index 22f7eb707abbd2c89d2ec2806cd03f044f5c0c4a..9e70fe550bc930d301a1c22c4479c988a5c9ede4 100644 (file)
 #include "BKE_mesh.h"
 #include "BKE_material.h"
 #include "BKE_report.h"
-#include "BKE_tessmesh.h"
+#include "BKE_editmesh.h"
 #include "BKE_multires.h"
 
-
 #include "ED_mesh.h"
 #include "ED_object.h"
 #include "ED_view3d.h"
@@ -149,7 +148,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
        }
 
-       /* remove tessface to ensure we don't old references to invalid faces */
+       /* remove tessface to ensure we don't hold references to invalid faces */
        BKE_mesh_tessface_clear(me);
 
        /* new material indices and material array */
@@ -309,6 +308,10 @@ int join_mesh_exec(bContext *C, wmOperator *op)
                        me = base->object->data;
                        
                        if (me->totvert) {
+
+                               /* merge customdata flag */
+                               ((Mesh *)ob->data)->cd_flag |= me->cd_flag;
+
                                /* standard data */
                                CustomData_merge(&me->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
                                CustomData_copy_data(&me->vdata, &vdata, 0, vertofs, me->totvert);
@@ -426,8 +429,8 @@ int join_mesh_exec(bContext *C, wmOperator *op)
 
                                        multiresModifier_prepare_join(scene, base->object, ob);
 
-                                       if ((mmd = get_multires_modifier(scene, base->object, TRUE))) {
-                                               ED_object_iter_other(bmain, base->object, TRUE,
+                                       if ((mmd = get_multires_modifier(scene, base->object, true))) {
+                                               ED_object_iter_other(bmain, base->object, true,
                                                                     ED_object_multires_update_totlevels_cb,
                                                                     &mmd->totlvl);
                                        }
@@ -501,7 +504,10 @@ int join_mesh_exec(bContext *C, wmOperator *op)
        me->pdata = pdata;
 
        /* tessface data removed above, no need to update */
-       mesh_update_customdata_pointers(me, FALSE);
+       BKE_mesh_update_customdata_pointers(me, false);
+
+       /* update normals in case objects with non-uniform scale are joined */
+       ED_mesh_calc_normals(me);
        
        /* old material array */
        for (a = 1; a <= ob->totcol; a++) {
@@ -556,11 +562,11 @@ int join_mesh_exec(bContext *C, wmOperator *op)
        }
 
 
-       DAG_scene_sort(bmain, scene);   // removed objects, need to rebuild dag before editmode call
+       DAG_relations_tag_update(bmain);   // removed objects, need to rebuild dag
 
 #if 0
-       ED_object_enter_editmode(C, EM_WAITCURSOR);
-       ED_object_exit_editmode(C, EM_FREEDATA | EM_WAITCURSOR | EM_DO_UNDO);
+       ED_object_editmode_enter(C, EM_WAITCURSOR);
+       ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR | EM_DO_UNDO);
 #else
        /* toggle editmode using lower level functions so this can be called from python */
        EDBM_mesh_make(scene->toolsettings, scene, ob);
@@ -717,9 +723,9 @@ static void mesh_octree_add_nodes(MocNode **basetable, const float co[3], const
        float fx, fy, fz;
        int vx, vy, vz;
        
-       if ((finite(co[0]) == FALSE) ||
-           (finite(co[1]) == FALSE) ||
-           (finite(co[2]) == FALSE))
+       if ((finite(co[0]) == false) ||
+           (finite(co[1]) == false) ||
+           (finite(co[2]) == false))
        {
                return;
        }
@@ -782,7 +788,9 @@ static intptr_t mesh_octree_find_index(MocNode **bt, MVert *mvert, const float c
                                        return (*bt)->index[a];
                        }
                }
-               else return -1;
+               else {
+                       return -1;
+               }
        }
        if ( (*bt)->next)
                return mesh_octree_find_index(&(*bt)->next, mvert, co);
@@ -901,7 +909,7 @@ int mesh_mirrtopo_table(Object *ob, char mode)
                }
        }
        else if (mode == 's') { /* start table */
-               ED_mesh_mirrtopo_init(ob->data, ob->mode, &mesh_topo_store, FALSE);
+               ED_mesh_mirrtopo_init(ob->data, ob->mode, &mesh_topo_store, false);
        }
        else if (mode == 'e') { /* end table */
                ED_mesh_mirrtopo_free(&mesh_topo_store);
@@ -948,9 +956,9 @@ static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, c
        intptr_t poinval;
        
        /* ignore nan verts */
-       if ((finite(co[0]) == FALSE) ||
-           (finite(co[1]) == FALSE) ||
-           (finite(co[2]) == FALSE))
+       if ((finite(co[0]) == false) ||
+           (finite(co[1]) == false) ||
+           (finite(co[2]) == false))
        {
                return NULL;
        }
@@ -1165,9 +1173,9 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em)
  * Face selection in object mode,
  * currently only weight-paint and vertex-paint use this.
  *
- * \return boolean TRUE == Found
+ * \return boolean true == Found
  */
-int ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size)
+bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size)
 {
        ViewContext vc;
        Mesh *me = ob->data;
@@ -1175,7 +1183,7 @@ int ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int *
        BLI_assert(me && GS(me->id.name) == ID_ME);
 
        if (!me || me->totpoly == 0)
-               return 0;
+               return false;
 
        view3d_set_viewcontext(C, &vc);
 
@@ -1192,17 +1200,17 @@ int ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int *
        }
 
        if ((*index) <= 0 || (*index) > (unsigned int)me->totpoly)
-               return 0;
+               return false;
 
        (*index)--;
 
-       return 1;
+       return true;
 }
 /**
  * Use when the back buffer stores face index values. but we want a vert.
  * This gets the face then finds the closest vertex to mval.
  */
-int ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size)
+bool ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size)
 {
        unsigned int poly_index;
        Mesh *me = ob->data;
@@ -1248,20 +1256,46 @@ int ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned
 
                if (v_idx_best != -1) {
                        *index = v_idx_best;
-                       return 1;
+                       return true;
                }
        }
 
-       return 0;
+       return false;
 }
 
 /**
  * Vertex selection in object mode,
  * currently only weight paint uses this.
  *
- * \return boolean TRUE == Found
+ * \return boolean true == Found
  */
-int ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size, int use_zbuf)
+typedef struct VertPickData {
+       const MVert *mvert;
+       const float *mval_f;  /* [2] */
+       ARegion *ar;
+
+       /* runtime */
+       float len_best;
+       int v_idx_best;
+} VertPickData;
+
+static void ed_mesh_pick_vert__mapFunc(void *userData, int index, const float co[3],
+                                       const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+{
+       VertPickData *data = userData;
+       if ((data->mvert[index].flag & ME_HIDE) == 0) {
+               float sco[2];
+
+               if (ED_view3d_project_float_object(data->ar, co, sco, V3D_PROJ_TEST_CLIP_DEFAULT) == V3D_PROJ_RET_OK) {
+                       const float len = len_manhattan_v2v2(data->mval_f, sco);
+                       if (len < data->len_best) {
+                               data->len_best = len;
+                               data->v_idx_best = index;
+                       }
+               }
+       }
+}
+bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size, bool use_zbuf)
 {
        ViewContext vc;
        Mesh *me = ob->data;
@@ -1269,7 +1303,7 @@ int ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int *
        BLI_assert(me && GS(me->id.name) == ID_ME);
 
        if (!me || me->totvert == 0)
-               return 0;
+               return false;
 
        view3d_set_viewcontext(C, &vc);
 
@@ -1287,54 +1321,45 @@ int ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int *
                }
 
                if ((*index) <= 0 || (*index) > (unsigned int)me->totvert)
-                       return 0;
+                       return false;
 
                (*index)--;
        }
        else {
                /* derived mesh to find deformed locations */
                DerivedMesh *dm = mesh_get_derived_final(vc.scene, ob, CD_MASK_BAREMESH);
-               struct ARegion *ar = vc.ar;
+               ARegion *ar = vc.ar;
+               RegionView3D *rv3d = ar->regiondata;
 
-               int v_idx_best = -1;
-               int v_idx;
+               /* find the vert closest to 'mval' */
+               const float mval_f[2] = {(float)mval[0],
+                                        (float)mval[1]};
+
+               VertPickData data = {0};
 
+               ED_view3d_init_mats_rv3d(ob, rv3d);
 
                if (dm == NULL) {
-                       return 0;
+                       return false;
                }
 
-               if (dm->getVertCo) {
-                       RegionView3D *rv3d = ar->regiondata;
+               /* setup data */
+               data.mvert = me->mvert;
+               data.ar = ar;
+               data.mval_f = mval_f;
+               data.len_best = FLT_MAX;
+               data.v_idx_best = -1;
 
-                       /* find the vert closest to 'mval' */
-                       const float mval_f[2] = {(float)mval[0],
-                                                (float)mval[1]};
-                       float len_best = FLT_MAX;
-
-                       ED_view3d_init_mats_rv3d(ob, rv3d);
-
-                       v_idx = me->totvert - 1;
-                       do {
-                               float co[3], sco[2], len;
-                               dm->getVertCo(dm, v_idx, co);
-                               if (ED_view3d_project_float_object(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
-                                       len = len_manhattan_v2v2(mval_f, sco);
-                                       if (len < len_best) {
-                                               len_best = len;
-                                               v_idx_best = v_idx;
-                                       }
-                               }
-                       } while (v_idx--);
-               }
+               dm->foreachMappedVert(dm, ed_mesh_pick_vert__mapFunc, &data);
 
                dm->release(dm);
 
-               if (v_idx_best != -1) {
-                       *index = v_idx_best;
-                       return 1;
+               if (data.v_idx_best == -1) {
+                       return false;
                }
+
+               *index = data.v_idx_best;
        }
 
-       return 1;
+       return true;
 }