Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Wed, 22 Aug 2018 05:27:03 +0000 (15:27 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 22 Aug 2018 05:27:03 +0000 (15:27 +1000)
1  2 
source/blender/editors/include/ED_mesh.h
source/blender/editors/mesh/editmesh_extrude.c
source/blender/editors/mesh/editmesh_tools.c

index c2a8ad7c3fecd47e007060b88d5fabb5f9d02e1e,7ea89c564323086ffa120c6f00d3380160885ce8..6e87f20cf8c5051b62722be018f45a27a4580759
@@@ -994,194 -560,147 +994,194 @@@ static int edbm_dupli_extrude_cursor_in
        zero_v3(center);
        verts_len = 0;
  
 -      BM_ITER_MESH (v1, &iter, vc.em->bm, BM_VERTS_OF_MESH) {
 -              if (BM_elem_flag_test(v1, BM_ELEM_SELECT)) {
 -                      add_v3_v3(center, v1->co);
 -                      verts_len += 1;
 +      uint objects_len = 0;
 +      Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(vc.view_layer, &objects_len);
 +      for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
 +              Object *obedit = objects[ob_index];
 +              ED_view3d_viewcontext_init_object(&vc, obedit);
 +              const int local_verts_len = vc.em->bm->totvertsel;
 +
 +              if (vc.em->bm->totvertsel == 0) {
 +                      continue;
 +              }
 +
 +              float local_center[3];
 +              zero_v3(local_center);
 +
 +              BM_ITER_MESH(v1, &iter, vc.em->bm, BM_VERTS_OF_MESH) {
 +                      if (BM_elem_flag_test(v1, BM_ELEM_SELECT)) {
 +                              add_v3_v3(local_center, v1->co);
 +                      }
                }
 +
 +              mul_v3_fl(local_center, 1.0f / (float)local_verts_len);
 +              mul_m4_v3(vc.obedit->obmat, local_center);
 +              mul_v3_fl(local_center, (float)local_verts_len);
 +
 +              add_v3_v3(center, local_center);
 +              verts_len += local_verts_len;
        }
  
 -      /* call extrude? */
        if (verts_len != 0) {
 -              const char extrude_htype = edbm_extrude_htype_from_em_select(vc.em);
 -              const bool rot_src = RNA_boolean_get(op->ptr, "rotate_source");
 -              BMEdge *eed;
 -              float mat[3][3];
 -              float vec[3], ofs[3];
 -              float nor[3] = {0.0, 0.0, 0.0};
 +              mul_v3_fl(center, 1.0f / (float)verts_len);
 +      }
  
 -              /* 2D normal calc */
 -              const float mval_f[2] = {(float)event->mval[0],
 -                                       (float)event->mval[1]};
 +      /* Then we process the meshes. */
 +      for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
 +              Object *obedit = objects[ob_index];
 +              ED_view3d_viewcontext_init_object(&vc, obedit);
  
 -              mul_v3_fl(center, 1.0f / (float)verts_len);
 +              if (verts_len != 0) {
 +                      if (vc.em->bm->totvertsel == 0) {
 +                              continue;
 +                      }
 +              }
 +              else if (obedit != object_active) {
 +                      continue;
 +              }
  
 -              /* check for edges that are half selected, use for rotation */
 -              bool done = false;
 -              BM_ITER_MESH (eed, &iter, vc.em->bm, BM_EDGES_OF_MESH) {
 -                      if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
 -                              float co1[2], co2[2];
 -
 -                              if ((ED_view3d_project_float_object(vc.ar, eed->v1->co, co1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
 -                                  (ED_view3d_project_float_object(vc.ar, eed->v2->co, co2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
 -                              {
 -                                      /* 2D rotate by 90d while adding.
 -                                       *  (x, y) = (y, -x)
 -                                       *
 -                                       * accumulate the screenspace normal in 2D,
 -                                       * with screenspace edge length weighting the result. */
 -                                      if (line_point_side_v2(co1, co2, mval_f) >= 0.0f) {
 -                                              nor[0] +=  (co1[1] - co2[1]);
 -                                              nor[1] += -(co1[0] - co2[0]);
 -                                      }
 -                                      else {
 -                                              nor[0] +=  (co2[1] - co1[1]);
 -                                              nor[1] += -(co2[0] - co1[0]);
 +              invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
 +              ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
 +
 +              float local_center[3];
 +              mul_v3_m4v3(local_center, vc.obedit->imat, center);
 +
 +              /* call extrude? */
 +              if (verts_len != 0) {
 +                      const char extrude_htype = edbm_extrude_htype_from_em_select(vc.em);
 +                      BMEdge *eed;
 +                      float mat[3][3];
 +                      float vec[3], ofs[3];
 +                      float nor[3] = { 0.0, 0.0, 0.0 };
 +
 +                      /* 2D normal calc */
 +                      const float mval_f[2] = { (float)event->mval[0],
 +                                                (float)event->mval[1] };
 +
 +                      /* check for edges that are half selected, use for rotation */
 +                      bool done = false;
 +                      BM_ITER_MESH(eed, &iter, vc.em->bm, BM_EDGES_OF_MESH) {
 +                              if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
 +                                      float co1[2], co2[2];
 +
 +                                      if ((ED_view3d_project_float_object(vc.ar, eed->v1->co, co1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
 +                                          (ED_view3d_project_float_object(vc.ar, eed->v2->co, co2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
 +                                      {
 +                                              /* 2D rotate by 90d while adding.
 +                                               *  (x, y) = (y, -x)
 +                                               *
 +                                               * accumulate the screenspace normal in 2D,
 +                                               * with screenspace edge length weighting the result. */
 +                                              if (line_point_side_v2(co1, co2, mval_f) >= 0.0f) {
 +                                                      nor[0] += (co1[1] - co2[1]);
 +                                                      nor[1] += -(co1[0] - co2[0]);
 +                                              }
 +                                              else {
 +                                                      nor[0] += (co2[1] - co1[1]);
 +                                                      nor[1] += -(co2[0] - co1[0]);
 +                                              }
 +                                              done = true;
                                        }
 -                                      done = true;
                                }
                        }
 -              }
  
 -              if (done) {
 -                      float view_vec[3], cross[3];
 +                      if (done) {
 +                              float view_vec[3], cross[3];
  
 -                      /* convert the 2D nomal into 3D */
 -                      mul_mat3_m4_v3(vc.rv3d->viewinv, nor); /* worldspace */
 -                      mul_mat3_m4_v3(vc.obedit->imat, nor); /* local space */
 +                              /* convert the 2D normal into 3D */
 +                              mul_mat3_m4_v3(vc.rv3d->viewinv, nor); /* worldspace */
 +                              mul_mat3_m4_v3(vc.obedit->imat, nor); /* local space */
  
 -                      /* correct the normal to be aligned on the view plane */
 -                      mul_v3_mat3_m4v3(view_vec, vc.obedit->imat, vc.rv3d->viewinv[2]);
 -                      cross_v3_v3v3(cross, nor, view_vec);
 -                      cross_v3_v3v3(nor, view_vec, cross);
 -                      normalize_v3(nor);
 -              }
 +                              /* correct the normal to be aligned on the view plane */
 +                              mul_v3_mat3_m4v3(view_vec, vc.obedit->imat, vc.rv3d->viewinv[2]);
 +                              cross_v3_v3v3(cross, nor, view_vec);
 +                              cross_v3_v3v3(nor, view_vec, cross);
 +                              normalize_v3(nor);
 +                      }
 +
 +                      /* center */
 +                      copy_v3_v3(ofs, local_center);
  
 -              /* center */
 -              copy_v3_v3(ofs, center);
 +                      mul_m4_v3(vc.obedit->obmat, ofs);  /* view space */
 +                      ED_view3d_win_to_3d_int(vc.v3d, vc.ar, ofs, event->mval, ofs);
 +                      mul_m4_v3(vc.obedit->imat, ofs); // back in object space
  
 -              mul_m4_v3(vc.obedit->obmat, ofs);  /* view space */
 -              ED_view3d_win_to_3d_int(vc.v3d, vc.ar, ofs, event->mval, ofs);
 -              mul_m4_v3(vc.obedit->imat, ofs); // back in object space
 +                      sub_v3_v3(ofs, local_center);
  
 -              sub_v3_v3(ofs, center);
 +                      /* calculate rotation */
 +                      unit_m3(mat);
 +                      if (done) {
 +                              float angle;
  
 -              /* calculate rotation */
 -              unit_m3(mat);
 -              if (done) {
 -                      float angle;
 +                              normalize_v3_v3(vec, ofs);
  
 -                      normalize_v3_v3(vec, ofs);
 +                              angle = angle_normalized_v3v3(vec, nor);
  
 -                      angle = angle_normalized_v3v3(vec, nor);
 +                              if (angle != 0.0f) {
 +                                      float axis[3];
  
 -                      if (angle != 0.0f) {
 -                              float axis[3];
 +                                      cross_v3_v3v3(axis, nor, vec);
  
 -                              cross_v3_v3v3(axis, nor, vec);
 +                                      /* halve the rotation if its applied twice */
 +                                      if (rot_src) {
 +                                              angle *= 0.5f;
 +                                      }
  
 -                              /* halve the rotation if its applied twice */
 -                              if (rot_src) {
 -                                      angle *= 0.5f;
 +                                      axis_angle_to_mat3(mat, axis, angle);
                                }
 +                      }
 +
 +                      if (rot_src) {
 +                              EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v matrix=%m3",
 +                                            BM_ELEM_SELECT, local_center, mat);
  
 -                              axis_angle_to_mat3(mat, axis, angle);
 +                              /* also project the source, for retopo workflow */
 +                              if (use_proj) {
-                                       EMBM_project_snap_verts(C, vc.ar, vc.em);
++                                      EDBM_project_snap_verts(C, vc.ar, vc.em);
 +                              }
                        }
 -              }
  
 -              if (rot_src) {
 +                      edbm_extrude_ex(vc.obedit, vc.em, extrude_htype, BM_ELEM_SELECT, true, true);
                        EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v matrix=%m3",
 -                                    BM_ELEM_SELECT, center, mat);
 -
 -                      /* also project the source, for retopo workflow */
 -                      if (use_proj)
 -                              EDBM_project_snap_verts(C, vc.ar, vc.em);
 +                                    BM_ELEM_SELECT, local_center, mat);
 +                      EDBM_op_callf(vc.em, op, "translate verts=%hv vec=%v",
 +                                    BM_ELEM_SELECT, ofs);
                }
 +              else {
 +                      /* This only runs for the active object. */
 +                      const float *cursor = ED_view3d_cursor3d_get(vc.scene, vc.v3d)->location;
 +                      BMOperator bmop;
 +                      BMOIter oiter;
  
 -              edbm_extrude_ex(vc.obedit, vc.em, extrude_htype, BM_ELEM_SELECT, true, true);
 -              EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v matrix=%m3",
 -                            BM_ELEM_SELECT, center, mat);
 -              EDBM_op_callf(vc.em, op, "translate verts=%hv vec=%v",
 -                            BM_ELEM_SELECT, ofs);
 -      }
 -      else {
 -              const float *cursor = ED_view3d_cursor3d_get(vc.scene, vc.v3d);
 -              BMOperator bmop;
 -              BMOIter oiter;
 +                      copy_v3_v3(local_center, cursor);
 +                      ED_view3d_win_to_3d_int(vc.v3d, vc.ar, local_center, event->mval, local_center);
  
 -              copy_v3_v3(center, cursor);
 -              ED_view3d_win_to_3d_int(vc.v3d, vc.ar, center, event->mval, center);
 +                      mul_m4_v3(vc.obedit->imat, local_center); // back in object space
  
 -              mul_m4_v3(vc.obedit->imat, center); // back in object space
 +                      EDBM_op_init(vc.em, &bmop, op, "create_vert co=%v", local_center);
 +                      BMO_op_exec(vc.em->bm, &bmop);
  
 -              EDBM_op_init(vc.em, &bmop, op, "create_vert co=%v", center);
 -              BMO_op_exec(vc.em->bm, &bmop);
 +                      BMO_ITER(v1, &oiter, bmop.slots_out, "vert.out", BM_VERT) {
 +                              BM_vert_select_set(vc.em->bm, v1, true);
 +                      }
  
 -              BMO_ITER (v1, &oiter, bmop.slots_out, "vert.out", BM_VERT) {
 -                      BM_vert_select_set(vc.em->bm, v1, true);
 +                      if (!EDBM_op_finish(vc.em, &bmop, op, true)) {
 +                              continue;
 +                      }
                }
  
 -              if (!EDBM_op_finish(vc.em, &bmop, op, true)) {
 -                      return OPERATOR_CANCELLED;
 +              if (use_proj) {
-                       EMBM_project_snap_verts(C, vc.ar, vc.em);
++                      EDBM_project_snap_verts(C, vc.ar, vc.em);
                }
 -      }
 -
 -      if (use_proj)
 -              EDBM_project_snap_verts(C, vc.ar, vc.em);
  
 -      /* This normally happens when pushing undo but modal operators
 -       * like this one don't push undo data until after modal mode is
 -       * done. */
 -      EDBM_mesh_normals_update(vc.em);
 +              /* This normally happens when pushing undo but modal operators
 +               * like this one don't push undo data until after modal mode is
 +               * done. */
 +              EDBM_mesh_normals_update(vc.em);
  
 -      EDBM_update_generic(vc.em, true, true);
 +              EDBM_update_generic(vc.em, true, true);
 +      }
 +      MEM_freeN(objects);
  
        return OPERATOR_FINISHED;
  }
index cb008c376c3a591cc9a8cf36fe0d7b242f133022,313dd28e806eed0d3f29d699625e80ad9a527c41..4fe2351ef7d59154dea7bd2364975e50b45e5590
@@@ -363,9 -312,8 +363,9 @@@ void MESH_OT_unsubdivide(wmOperatorTyp
        RNA_def_int(ot->srna, "iterations", 2, 1, 1000, "Iterations", "Number of times to unsubdivide", 1, 100);
  }
  
- void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em)
+ void EDBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em)
  {
 +      Main *bmain = CTX_data_main(C);
        Object *obedit = em->ob;
        BMIter iter;
        BMVert *eve;