Merge branch 'blender-v4.4-release'
This commit is contained in:
@@ -572,6 +572,11 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], uint dist_px,
|
||||
*/
|
||||
bool ED_mesh_pick_face_vert(
|
||||
bContext *C, Object *ob, const int mval[2], uint dist_px, uint *r_index);
|
||||
/**
|
||||
* Used for paint face loop selection which needs to get closest edge even though in face select
|
||||
* mode. Changes the select_buffer context to edge selection for this.
|
||||
*/
|
||||
bool ED_mesh_pick_edge(bContext *C, Object *ob, const int mval[2], uint dist_px, uint *r_index);
|
||||
|
||||
MDeformVert *ED_mesh_active_dvert_get_em(Object *ob, BMVert **r_eve);
|
||||
MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index);
|
||||
|
||||
@@ -347,36 +347,6 @@ void paintface_select_linked(bContext *C, Object *ob, const int mval[2], const b
|
||||
paintface_flush_flags(C, ob, true, false);
|
||||
}
|
||||
|
||||
static int find_closest_edge_in_poly(ARegion *region,
|
||||
blender::Span<blender::int2> edges,
|
||||
blender::Span<int> face_edges,
|
||||
blender::Span<blender::float3> vert_positions,
|
||||
const int mval[2])
|
||||
{
|
||||
using namespace blender;
|
||||
int closest_edge_index = -1;
|
||||
|
||||
const float2 mval_f = {float(mval[0]), float(mval[1])};
|
||||
float min_distance = FLT_MAX;
|
||||
for (const int i : face_edges) {
|
||||
float2 screen_coordinate;
|
||||
const int2 edge = edges[i];
|
||||
const float3 edge_vert_average = math::midpoint(vert_positions[edge[0]],
|
||||
vert_positions[edge[1]]);
|
||||
eV3DProjStatus status = ED_view3d_project_float_object(
|
||||
region, edge_vert_average, screen_coordinate, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
if (status != V3D_PROJ_RET_OK) {
|
||||
continue;
|
||||
}
|
||||
const float distance = math::distance_squared(mval_f, screen_coordinate);
|
||||
if (distance < min_distance) {
|
||||
min_distance = distance;
|
||||
closest_edge_index = i;
|
||||
}
|
||||
}
|
||||
return closest_edge_index;
|
||||
}
|
||||
|
||||
static int get_opposing_edge_index(const blender::IndexRange face,
|
||||
const blender::Span<int> corner_edges,
|
||||
const int current_edge_index)
|
||||
@@ -458,8 +428,12 @@ void paintface_select_loop(bContext *C, Object *ob, const int mval[2], const boo
|
||||
return;
|
||||
}
|
||||
|
||||
uint poly_pick_index = uint(-1);
|
||||
if (!ED_mesh_pick_face(C, ob, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &poly_pick_index)) {
|
||||
uint closest_edge_index = uint(-1);
|
||||
if (!ED_mesh_pick_edge(C, ob, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, &closest_edge_index)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (closest_edge_index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -469,16 +443,7 @@ void paintface_select_loop(bContext *C, Object *ob, const int mval[2], const boo
|
||||
|
||||
Mesh *mesh = BKE_mesh_from_object(ob);
|
||||
const Span<int> corner_edges = mesh->corner_edges();
|
||||
const Span<float3> verts = mesh->vert_positions();
|
||||
const OffsetIndices faces = mesh->faces();
|
||||
const Span<int2> edges = mesh->edges();
|
||||
|
||||
const IndexRange face = faces[poly_pick_index];
|
||||
const int closest_edge_index = find_closest_edge_in_poly(
|
||||
region, edges, corner_edges.slice(face), verts, mval);
|
||||
if (closest_edge_index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Array<int> edge_to_face_offsets;
|
||||
Array<int> edge_to_face_indices;
|
||||
@@ -492,6 +457,12 @@ void paintface_select_loop(bContext *C, Object *ob, const int mval[2], const boo
|
||||
".hide_poly", bke::AttrDomain::Face, false);
|
||||
|
||||
const Span<int> faces_to_closest_edge = edge_to_face_map[closest_edge_index];
|
||||
|
||||
/* Picked edge may not be linked to a face (loose edge). */
|
||||
if (faces_to_closest_edge.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool traced_full_loop = follow_face_loop(faces_to_closest_edge[0],
|
||||
closest_edge_index,
|
||||
faces,
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "BKE_deform.hh"
|
||||
#include "BKE_editmesh.hh"
|
||||
#include "BKE_key.hh"
|
||||
#include "BKE_layer.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_material.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
@@ -1287,6 +1288,49 @@ bool ED_mesh_pick_face_vert(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ED_mesh_pick_edge(bContext *C, Object *ob, const int mval[2], uint dist_px, uint *r_index)
|
||||
{
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
||||
|
||||
BLI_assert(mesh && GS(mesh->id.name) == ID_ME);
|
||||
|
||||
if (!mesh || mesh->edges_num == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ViewContext vc = ED_view3d_viewcontext_init(C, depsgraph);
|
||||
ED_view3d_select_id_validate(&vc);
|
||||
Base *base = BKE_view_layer_base_find(vc.view_layer, vc.obact);
|
||||
DRW_select_buffer_context_create(vc.depsgraph, {base}, SCE_SELECT_EDGE);
|
||||
|
||||
uint edge_idx_best = ORIGINDEX_NONE;
|
||||
|
||||
if (dist_px) {
|
||||
/* Sample rect to increase chances of selecting, so that when clicking
|
||||
* on an edge in the back-buffer, we can still select a face. */
|
||||
edge_idx_best = DRW_select_buffer_find_nearest_to_point(
|
||||
vc.depsgraph, vc.region, vc.v3d, mval, 1, mesh->edges_num + 1, &dist_px);
|
||||
}
|
||||
else {
|
||||
/* sample only on the exact position */
|
||||
edge_idx_best = DRW_select_buffer_sample_point(vc.depsgraph, vc.region, vc.v3d, mval);
|
||||
}
|
||||
|
||||
if (edge_idx_best == 0 || edge_idx_best > uint(mesh->edges_num)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
edge_idx_best--;
|
||||
|
||||
if ((edge_idx_best != ORIGINDEX_NONE)) {
|
||||
*r_index = edge_idx_best;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vertex selection in object mode,
|
||||
* currently only weight paint uses this.
|
||||
|
||||
@@ -160,6 +160,7 @@ void ED_transverts_update_obedit(TransVertStore *tvs, Object *obedit)
|
||||
Curves *curves_id = static_cast<Curves *>(obedit->data);
|
||||
blender::bke::CurvesGeometry &curves = curves_id->geometry.wrap();
|
||||
curves.tag_positions_changed();
|
||||
curves.calculate_bezier_auto_handles();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user