WIP: Viewport-Facing Mesh Select #106531
|
@ -153,7 +153,7 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
|
|||
bl_context = ".mesh_edit" # dot on purpose (access from topbar)
|
||||
bl_label = "Options"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_ui_units_x = 12
|
||||
bl_ui_units_x = 13
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@ -220,6 +220,39 @@ class VIEW3D_PT_tools_meshedit_options_automerge(View3DPanel, Panel):
|
|||
col.prop(tool_settings, "double_threshold", text="Threshold")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_meshedit_options_viewport_facing_select(View3DPanel, Panel):
|
||||
bl_category = "Tool"
|
||||
bl_context = ".mesh_edit" # dot on purpose (access from topbar)
|
||||
bl_label = "Viewport Facing Select"
|
||||
bl_parent_id = "VIEW3D_PT_tools_meshedit_options"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.active_object
|
||||
|
||||
def draw_header(self, context):
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
self.layout.prop(tool_settings, "viewport_facing_select", text="", toggle=False)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = tool_settings.viewport_facing_select
|
||||
col.prop(tool_settings, "viewport_facing_select_mode")
|
||||
col.prop(tool_settings, "viewport_facing_select_threshold", text="Threshold")
|
||||
col.prop(tool_settings, "viewport_facing_select_vert")
|
||||
col.prop(tool_settings, "viewport_facing_select_edge")
|
||||
col.prop(tool_settings, "viewport_facing_select_face")
|
||||
|
||||
|
||||
# ********** default tools for editmode_armature ****************
|
||||
|
||||
|
||||
|
@ -2364,6 +2397,7 @@ classes = (
|
|||
VIEW3D_PT_tools_object_options_transform,
|
||||
VIEW3D_PT_tools_meshedit_options,
|
||||
VIEW3D_PT_tools_meshedit_options_automerge,
|
||||
VIEW3D_PT_tools_meshedit_options_viewport_facing_select,
|
||||
VIEW3D_PT_tools_armatureedit_options,
|
||||
VIEW3D_PT_tools_posemode_options,
|
||||
|
||||
|
|
|
@ -373,6 +373,12 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
|
|||
if (idprop) {
|
||||
IDP_ClearProperty(idprop);
|
||||
}
|
||||
|
||||
/* Viewport-Facing Select */
|
||||
ts->viewport_facing_select_mode = 1;
|
||||
ts->viewport_facing_select_vert = 1;
|
||||
ts->viewport_facing_select_edge = 1;
|
||||
ts->viewport_facing_select_face = 1;
|
||||
}
|
||||
|
||||
void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
|
||||
|
|
|
@ -100,7 +100,10 @@ void ED_getTransformOrientationMatrix(const struct Scene *scene,
|
|||
struct Object *ob,
|
||||
struct Object *obedit,
|
||||
short around,
|
||||
float r_orientation_mat[3][3]);
|
||||
float r_orientation_mat[3][3],
|
||||
struct BMVert *eve,
|
||||
struct BMEdge *eed,
|
||||
struct BMFace *efa);
|
||||
|
||||
int BIF_countTransformOrientation(const struct bContext *C);
|
||||
|
||||
|
|
|
@ -1192,7 +1192,7 @@ static int view_axis_exec(bContext *C, wmOperator *op)
|
|||
Object *obedit = CTX_data_edit_object(C);
|
||||
/* same as transform gizmo when normal is set */
|
||||
ED_getTransformOrientationMatrix(
|
||||
scene, view_layer, v3d, obact, obedit, V3D_AROUND_ACTIVE, twmat);
|
||||
scene, view_layer, v3d, obact, obedit, V3D_AROUND_ACTIVE, twmat, NULL, NULL, NULL);
|
||||
align_quat = align_quat_buf;
|
||||
mat3_to_quat(align_quat, twmat);
|
||||
invert_qt_normalized(align_quat);
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
#include "ED_screen.h"
|
||||
#include "ED_sculpt.h"
|
||||
#include "ED_select_utils.h"
|
||||
#include "ED_transform.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
@ -239,28 +240,197 @@ static void editselect_buf_cache_init_with_generic_userdata(wmGenericUserData *w
|
|||
/** \name Internal Edit-Mesh Utilities
|
||||
* \{ */
|
||||
|
||||
static bool edbm_backbuf_check_and_select_verts(EditSelectBuf_Cache *esel,
|
||||
bool edbm_normal_facing_viewport(ViewContext *vc,
|
||||
struct BMVert *eve,
|
||||
struct BMEdge *eed,
|
||||
struct BMFace *efa,
|
||||
bool use_direction)
|
||||
{
|
||||
ToolSettings *ts = vc->scene->toolsettings;
|
||||
float meshmat[3][3];
|
||||
bool backface = false;
|
||||
int direction = 0;
|
||||
if (eve != NULL) {
|
||||
ED_getTransformOrientationMatrix(vc->scene,
|
||||
vc->view_layer,
|
||||
vc->v3d,
|
||||
vc->obact,
|
||||
vc->obedit,
|
||||
V3D_AROUND_ACTIVE,
|
||||
meshmat,
|
||||
eve,
|
||||
NULL,
|
||||
NULL);
|
||||
direction = ts->viewport_facing_select_vert;
|
||||
if (use_direction && (direction == 4 || direction == 8)) {
|
||||
backface = true;
|
||||
}
|
||||
}
|
||||
else if (eed != NULL) {
|
||||
ED_getTransformOrientationMatrix(vc->scene,
|
||||
vc->view_layer,
|
||||
vc->v3d,
|
||||
vc->obact,
|
||||
vc->obedit,
|
||||
V3D_AROUND_ACTIVE,
|
||||
meshmat,
|
||||
NULL,
|
||||
eed,
|
||||
NULL);
|
||||
direction = ts->viewport_facing_select_edge;
|
||||
if (use_direction && (direction == 4 || direction == 8)) {
|
||||
backface = true;
|
||||
}
|
||||
}
|
||||
else if (efa != NULL) {
|
||||
ED_getTransformOrientationMatrix(vc->scene,
|
||||
vc->view_layer,
|
||||
vc->v3d,
|
||||
vc->obact,
|
||||
vc->obedit,
|
||||
V3D_AROUND_ACTIVE,
|
||||
meshmat,
|
||||
NULL,
|
||||
NULL,
|
||||
efa);
|
||||
direction = ts->viewport_facing_select_face;
|
||||
if (use_direction && (direction == 4 || direction == 8)) {
|
||||
backface = true;
|
||||
}
|
||||
}
|
||||
normalize_m3(meshmat);
|
||||
invert_m3(meshmat);
|
||||
float meshcol3[3] = {0, 0, 0};
|
||||
meshcol3[0] = meshmat[0][2];
|
||||
meshcol3[1] = meshmat[1][2];
|
||||
meshcol3[2] = meshmat[2][2];
|
||||
float viewcol3[3] = {0, 0, 0};
|
||||
viewcol3[0] = vc->rv3d->viewmat[0][2];
|
||||
viewcol3[1] = vc->rv3d->viewmat[1][2];
|
||||
viewcol3[2] = vc->rv3d->viewmat[2][2];
|
||||
bool mesh_facing;
|
||||
if (backface) {
|
||||
mesh_facing = dot_v3v3(meshcol3, viewcol3) < -ts->viewport_facing_select_threshold;
|
||||
}
|
||||
else {
|
||||
mesh_facing = dot_v3v3(meshcol3, viewcol3) > ts->viewport_facing_select_threshold;
|
||||
}
|
||||
return mesh_facing;
|
||||
}
|
||||
|
||||
bool edbm_facing_viewport_precheck(ToolSettings *ts, int style, bool xray)
|
||||
{
|
||||
if (!ts->viewport_facing_select) {
|
||||
return false;
|
||||
}
|
||||
const bool mode_match = xray ? ts->viewport_facing_select_mode == 1 ||
|
||||
ts->viewport_facing_select_mode == 4 :
|
||||
ts->viewport_facing_select_mode < 4;
|
||||
const bool check_mesh_facing = mode_match && style > 0 && style < 16;
|
||||
return check_mesh_facing;
|
||||
}
|
||||
|
||||
bool edbm_facing_viewport(ViewContext *vc, BMVert *eve, BMEdge *eed, BMFace *efa, int style)
|
||||
{
|
||||
BMIter iter;
|
||||
bool mesh_facing = false;
|
||||
if (eve != NULL) {
|
||||
/* viewport-facing or rear-facing vert */
|
||||
mesh_facing = edbm_normal_facing_viewport(vc, eve, NULL, NULL, true);
|
||||
if (!mesh_facing && eve->e && eve->e->l && (style == 2 || style == 8)) {
|
||||
BM_ITER_ELEM (efa, &iter, eve, BM_FACES_OF_VERT) {
|
||||
const bool eve_efa_facing = edbm_normal_facing_viewport(vc, NULL, NULL, efa, false);
|
||||
/* vert of a viewport-facing face */
|
||||
if (style == 2) {
|
||||
if (eve_efa_facing) {
|
||||
mesh_facing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* vert of a rear-facing face */
|
||||
else if (!eve_efa_facing) {
|
||||
mesh_facing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (eed != NULL) {
|
||||
/* viewport-facing or rear-facing edge */
|
||||
mesh_facing = edbm_normal_facing_viewport(vc, NULL, eed, NULL, true);
|
||||
if (!mesh_facing && eed->l && (style == 2 || style == 8)) {
|
||||
BM_ITER_ELEM (efa, &iter, eed, BM_FACES_OF_EDGE) {
|
||||
const bool eed_efa_facing = edbm_normal_facing_viewport(vc, NULL, NULL, efa, false);
|
||||
/* edge of a viewport-facing face */
|
||||
if (style == 2) {
|
||||
if (eed_efa_facing) {
|
||||
mesh_facing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* edge of a rear-facing face */
|
||||
else if (!eed_efa_facing) {
|
||||
mesh_facing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (efa != NULL) {
|
||||
/* viewport-facing or rear-facing face */
|
||||
mesh_facing = edbm_normal_facing_viewport(vc, NULL, NULL, efa, true);
|
||||
if (!mesh_facing && (style == 2 || style == 8)) {
|
||||
BM_ITER_ELEM (eve, &iter, efa, BM_VERTS_OF_FACE) {
|
||||
const bool efa_eve_facing = edbm_normal_facing_viewport(vc, eve, NULL, NULL, false);
|
||||
/* face has a viewport-facing vert */
|
||||
if (style == 2) {
|
||||
if (efa_eve_facing) {
|
||||
mesh_facing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* face has a rear-facing vert */
|
||||
else if (!efa_eve_facing) {
|
||||
mesh_facing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return mesh_facing;
|
||||
}
|
||||
|
||||
static bool edbm_backbuf_check_and_select_verts(ViewContext *vc,
|
||||
EditSelectBuf_Cache *esel,
|
||||
Depsgraph *depsgraph,
|
||||
Object *ob,
|
||||
BMEditMesh *em,
|
||||
const eSelectOp sel_op)
|
||||
{
|
||||
ToolSettings *ts = vc->scene->toolsettings;
|
||||
BMVert *eve;
|
||||
BMIter iter;
|
||||
bool changed = false;
|
||||
const int style = ts->viewport_facing_select_vert;
|
||||
const bool check_mesh_facing = edbm_facing_viewport_precheck(ts, style, false);
|
||||
|
||||
const BLI_bitmap *select_bitmap = esel->select_bitmap;
|
||||
uint index = DRW_select_buffer_context_offset_for_object_elem(depsgraph, ob, SCE_SELECT_VERTEX);
|
||||
if (index == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
index -= 1;
|
||||
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
|
||||
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
|
||||
const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
|
||||
const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
|
||||
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && check_mesh_facing) {
|
||||
mesh_facing = edbm_facing_viewport(vc, eve, NULL, NULL, style);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_vert_select_set(em->bm, eve, sel_op_result);
|
||||
changed = true;
|
||||
|
@ -271,15 +441,19 @@ static bool edbm_backbuf_check_and_select_verts(EditSelectBuf_Cache *esel,
|
|||
return changed;
|
||||
}
|
||||
|
||||
static bool edbm_backbuf_check_and_select_edges(EditSelectBuf_Cache *esel,
|
||||
static bool edbm_backbuf_check_and_select_edges(ViewContext *vc,
|
||||
EditSelectBuf_Cache *esel,
|
||||
Depsgraph *depsgraph,
|
||||
Object *ob,
|
||||
BMEditMesh *em,
|
||||
const eSelectOp sel_op)
|
||||
{
|
||||
ToolSettings *ts = vc->scene->toolsettings;
|
||||
BMEdge *eed;
|
||||
BMIter iter;
|
||||
bool changed = false;
|
||||
const int style = ts->viewport_facing_select_edge;
|
||||
const bool check_mesh_facing = edbm_facing_viewport_precheck(ts, style, false);
|
||||
|
||||
const BLI_bitmap *select_bitmap = esel->select_bitmap;
|
||||
uint index = DRW_select_buffer_context_offset_for_object_elem(depsgraph, ob, SCE_SELECT_EDGE);
|
||||
|
@ -292,7 +466,12 @@ static bool edbm_backbuf_check_and_select_edges(EditSelectBuf_Cache *esel,
|
|||
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
|
||||
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
|
||||
const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
|
||||
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && check_mesh_facing) {
|
||||
mesh_facing = edbm_facing_viewport(vc, NULL, eed, NULL, style);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_edge_select_set(em->bm, eed, sel_op_result);
|
||||
changed = true;
|
||||
|
@ -303,15 +482,19 @@ static bool edbm_backbuf_check_and_select_edges(EditSelectBuf_Cache *esel,
|
|||
return changed;
|
||||
}
|
||||
|
||||
static bool edbm_backbuf_check_and_select_faces(EditSelectBuf_Cache *esel,
|
||||
static bool edbm_backbuf_check_and_select_faces(ViewContext *vc,
|
||||
EditSelectBuf_Cache *esel,
|
||||
Depsgraph *depsgraph,
|
||||
Object *ob,
|
||||
BMEditMesh *em,
|
||||
const eSelectOp sel_op)
|
||||
{
|
||||
ToolSettings *ts = vc->scene->toolsettings;
|
||||
BMFace *efa;
|
||||
BMIter iter;
|
||||
bool changed = false;
|
||||
const int style = ts->viewport_facing_select_face;
|
||||
const bool check_mesh_facing = edbm_facing_viewport_precheck(ts, style, false);
|
||||
|
||||
const BLI_bitmap *select_bitmap = esel->select_bitmap;
|
||||
uint index = DRW_select_buffer_context_offset_for_object_elem(depsgraph, ob, SCE_SELECT_FACE);
|
||||
|
@ -324,7 +507,12 @@ static bool edbm_backbuf_check_and_select_faces(EditSelectBuf_Cache *esel,
|
|||
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
|
||||
const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
|
||||
const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
|
||||
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && check_mesh_facing) {
|
||||
mesh_facing = edbm_facing_viewport(vc, NULL, NULL, efa, style);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_face_select_set(em->bm, efa, sel_op_result);
|
||||
changed = true;
|
||||
|
@ -412,6 +600,7 @@ struct LassoSelectUserData {
|
|||
int mcoords_len;
|
||||
eSelectOp sel_op;
|
||||
eBezTriple_Flag select_flag;
|
||||
bool check_mesh_direction;
|
||||
|
||||
/* runtime */
|
||||
int pass;
|
||||
|
@ -711,7 +900,13 @@ static void do_lasso_select_mesh__doSelectVert(void *userData,
|
|||
(BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
|
||||
BLI_lasso_is_point_inside(
|
||||
data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED));
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, eve, NULL, NULL, data->vc->scene->toolsettings->viewport_facing_select_vert);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_vert_select_set(data->vc->em->bm, eve, sel_op_result);
|
||||
data->is_changed = true;
|
||||
|
@ -744,7 +939,13 @@ static void do_lasso_select_mesh__doSelectEdge_pass0(void *user_data,
|
|||
data->mcoords, data->mcoords_len, UNPACK2(screen_co_a), IS_CLIPPED) &&
|
||||
BLI_lasso_is_point_inside(
|
||||
data->mcoords, data->mcoords_len, UNPACK2(screen_co_b), IS_CLIPPED));
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, eed, NULL, data->vc->scene->toolsettings->viewport_facing_select_edge);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
||||
data->is_done = true;
|
||||
|
@ -772,7 +973,13 @@ static void do_lasso_select_mesh__doSelectEdge_pass1(void *user_data,
|
|||
UNPACK2(screen_co_a),
|
||||
UNPACK2(screen_co_b),
|
||||
IS_CLIPPED));
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, eed, NULL, data->vc->scene->toolsettings->viewport_facing_select_edge);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
||||
data->is_changed = true;
|
||||
|
@ -790,7 +997,13 @@ static void do_lasso_select_mesh__doSelectFace(void *userData,
|
|||
(BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
|
||||
BLI_lasso_is_point_inside(
|
||||
data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED));
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, NULL, efa, data->vc->scene->toolsettings->viewport_facing_select_face);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_face_select_set(data->vc->em->bm, efa, sel_op_result);
|
||||
data->is_changed = true;
|
||||
|
@ -841,9 +1054,11 @@ static bool do_lasso_select_mesh(ViewContext *vc,
|
|||
if (ts->selectmode & SCE_SELECT_VERTEX) {
|
||||
if (use_zbuf) {
|
||||
data.is_changed |= edbm_backbuf_check_and_select_verts(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_vert, true);
|
||||
mesh_foreachScreenVert(
|
||||
vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
}
|
||||
|
@ -859,6 +1074,14 @@ static bool do_lasso_select_mesh(ViewContext *vc,
|
|||
|
||||
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_NEAR |
|
||||
(use_zbuf ? (eV3DProjTest)0 : V3D_PROJ_TEST_CLIP_BB);
|
||||
if (use_zbuf) {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_edge, false);
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_edge, true);
|
||||
}
|
||||
/* Fully inside. */
|
||||
mesh_foreachScreenEdge_clip_bb_segment(
|
||||
vc, do_lasso_select_mesh__doSelectEdge_pass0, &data_for_edge, clip_flag);
|
||||
|
@ -875,9 +1098,11 @@ static bool do_lasso_select_mesh(ViewContext *vc,
|
|||
if (ts->selectmode & SCE_SELECT_FACE) {
|
||||
if (use_zbuf) {
|
||||
data.is_changed |= edbm_backbuf_check_and_select_faces(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_face, true);
|
||||
mesh_foreachScreenFace(
|
||||
vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
}
|
||||
|
@ -3231,6 +3456,7 @@ struct BoxSelectUserData {
|
|||
rctf _rect_fl;
|
||||
eSelectOp sel_op;
|
||||
eBezTriple_Flag select_flag;
|
||||
bool check_mesh_direction;
|
||||
|
||||
/* runtime */
|
||||
bool is_done;
|
||||
|
@ -3492,7 +3718,13 @@ static void do_mesh_box_select__doSelectVert(void *userData,
|
|||
BoxSelectUserData *data = static_cast<BoxSelectUserData *>(userData);
|
||||
const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
|
||||
const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, eve, NULL, NULL, data->vc->scene->toolsettings->viewport_facing_select_vert);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_vert_select_set(data->vc->em->bm, eve, sel_op_result);
|
||||
data->is_changed = true;
|
||||
|
@ -3521,7 +3753,13 @@ static void do_mesh_box_select__doSelectEdge_pass0(
|
|||
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
|
||||
const bool is_inside = (is_visible &&
|
||||
edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b));
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, eed, NULL, data->vc->scene->toolsettings->viewport_facing_select_edge);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
||||
data->is_done = true;
|
||||
|
@ -3545,7 +3783,13 @@ static void do_mesh_box_select__doSelectEdge_pass1(
|
|||
|
||||
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
|
||||
const bool is_inside = (is_visible && edge_inside_rect(data->rect_fl, screen_co_a, screen_co_b));
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, eed, NULL, data->vc->scene->toolsettings->viewport_facing_select_edge);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
||||
data->is_changed = true;
|
||||
|
@ -3559,7 +3803,13 @@ static void do_mesh_box_select__doSelectFace(void *userData,
|
|||
BoxSelectUserData *data = static_cast<BoxSelectUserData *>(userData);
|
||||
const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
|
||||
const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co);
|
||||
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
|
||||
bool mesh_facing = true;
|
||||
if (is_inside && data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, NULL, efa, data->vc->scene->toolsettings->viewport_facing_select_face);
|
||||
}
|
||||
const int sel_op_result = ED_select_op_action_deselected(
|
||||
data->sel_op, is_select, is_inside && mesh_facing);
|
||||
if (sel_op_result != -1) {
|
||||
BM_face_select_set(data->vc->em->bm, efa, sel_op_result);
|
||||
data->is_changed = true;
|
||||
|
@ -3602,9 +3852,11 @@ static bool do_mesh_box_select(ViewContext *vc,
|
|||
if (ts->selectmode & SCE_SELECT_VERTEX) {
|
||||
if (use_zbuf) {
|
||||
data.is_changed |= edbm_backbuf_check_and_select_verts(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_vert, true);
|
||||
mesh_foreachScreenVert(
|
||||
vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
}
|
||||
|
@ -3621,6 +3873,14 @@ static bool do_mesh_box_select(ViewContext *vc,
|
|||
|
||||
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_NEAR |
|
||||
(use_zbuf ? (eV3DProjTest)0 : V3D_PROJ_TEST_CLIP_BB);
|
||||
if (use_zbuf) {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_edge, false);
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_edge, true);
|
||||
}
|
||||
/* Fully inside. */
|
||||
mesh_foreachScreenEdge_clip_bb_segment(
|
||||
vc, do_mesh_box_select__doSelectEdge_pass0, &cb_data, clip_flag);
|
||||
|
@ -3637,9 +3897,11 @@ static bool do_mesh_box_select(ViewContext *vc,
|
|||
if (ts->selectmode & SCE_SELECT_FACE) {
|
||||
if (use_zbuf) {
|
||||
data.is_changed |= edbm_backbuf_check_and_select_faces(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, sel_op);
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_face, true);
|
||||
mesh_foreachScreenFace(
|
||||
vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
}
|
||||
|
@ -4106,6 +4368,7 @@ struct CircleSelectUserData {
|
|||
float radius;
|
||||
float radius_squared;
|
||||
eBezTriple_Flag select_flag;
|
||||
bool check_mesh_direction;
|
||||
|
||||
/* runtime */
|
||||
bool is_changed;
|
||||
|
@ -4141,8 +4404,15 @@ static void mesh_circle_doSelectVert(void *userData,
|
|||
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
|
||||
|
||||
if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
|
||||
BM_vert_select_set(data->vc->em->bm, eve, data->select);
|
||||
data->is_changed = true;
|
||||
bool mesh_facing = true;
|
||||
if (data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, eve, NULL, NULL, data->vc->scene->toolsettings->viewport_facing_select_vert);
|
||||
}
|
||||
if (mesh_facing) {
|
||||
BM_vert_select_set(data->vc->em->bm, eve, data->select);
|
||||
data->is_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void mesh_circle_doSelectEdge(void *userData,
|
||||
|
@ -4154,8 +4424,15 @@ static void mesh_circle_doSelectEdge(void *userData,
|
|||
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
|
||||
|
||||
if (edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) {
|
||||
BM_edge_select_set(data->vc->em->bm, eed, data->select);
|
||||
data->is_changed = true;
|
||||
bool mesh_facing = true;
|
||||
if (data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, eed, NULL, data->vc->scene->toolsettings->viewport_facing_select_edge);
|
||||
}
|
||||
if (mesh_facing) {
|
||||
BM_edge_select_set(data->vc->em->bm, eed, data->select);
|
||||
data->is_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void mesh_circle_doSelectFace(void *userData,
|
||||
|
@ -4166,8 +4443,15 @@ static void mesh_circle_doSelectFace(void *userData,
|
|||
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
|
||||
|
||||
if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
|
||||
BM_face_select_set(data->vc->em->bm, efa, data->select);
|
||||
data->is_changed = true;
|
||||
bool mesh_facing = true;
|
||||
if (data->check_mesh_direction) {
|
||||
mesh_facing = edbm_facing_viewport(
|
||||
data->vc, NULL, NULL, efa, data->vc->scene->toolsettings->viewport_facing_select_face);
|
||||
}
|
||||
if (mesh_facing) {
|
||||
BM_face_select_set(data->vc->em->bm, efa, data->select);
|
||||
data->is_changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4217,10 +4501,12 @@ static bool mesh_circle_select(ViewContext *vc,
|
|||
if (use_zbuf) {
|
||||
if (esel->select_bitmap != nullptr) {
|
||||
changed |= edbm_backbuf_check_and_select_verts(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
|
||||
}
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_vert, true);
|
||||
mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
@ -4229,10 +4515,12 @@ static bool mesh_circle_select(ViewContext *vc,
|
|||
if (use_zbuf) {
|
||||
if (esel->select_bitmap != nullptr) {
|
||||
changed |= edbm_backbuf_check_and_select_edges(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
|
||||
}
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_edge, true);
|
||||
mesh_foreachScreenEdge_clip_bb_segment(
|
||||
vc,
|
||||
mesh_circle_doSelectEdge,
|
||||
|
@ -4245,10 +4533,12 @@ static bool mesh_circle_select(ViewContext *vc,
|
|||
if (use_zbuf) {
|
||||
if (esel->select_bitmap != nullptr) {
|
||||
changed |= edbm_backbuf_check_and_select_faces(
|
||||
esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
|
||||
vc, esel, vc->depsgraph, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
|
||||
}
|
||||
}
|
||||
else {
|
||||
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||
ts, ts->viewport_facing_select_face, true);
|
||||
mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -516,7 +516,8 @@ short ED_transform_calc_orientation_from_type_ex(const Scene *scene,
|
|||
}
|
||||
case V3D_ORIENT_NORMAL: {
|
||||
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
|
||||
ED_getTransformOrientationMatrix(scene, view_layer, v3d, ob, obedit, pivot_point, r_mat);
|
||||
ED_getTransformOrientationMatrix(
|
||||
scene, view_layer, v3d, ob, obedit, pivot_point, r_mat, NULL, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
/* No break we define 'normal' as 'local' in Object mode. */
|
||||
|
@ -529,7 +530,8 @@ short ED_transform_calc_orientation_from_type_ex(const Scene *scene,
|
|||
* use the active pones axis for display #33575, this works as expected on a single
|
||||
* bone and users who select many bones will understand what's going on and what local
|
||||
* means when they start transforming. */
|
||||
ED_getTransformOrientationMatrix(scene, view_layer, v3d, ob, obedit, pivot_point, r_mat);
|
||||
ED_getTransformOrientationMatrix(
|
||||
scene, view_layer, v3d, ob, obedit, pivot_point, r_mat, NULL, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
transform_orientations_create_from_axis(r_mat, UNPACK3(ob->object_to_world));
|
||||
|
@ -752,13 +754,18 @@ int getTransformOrientation_ex(const Scene *scene,
|
|||
struct Object *obedit,
|
||||
float normal[3],
|
||||
float plane[3],
|
||||
const short around)
|
||||
const short around,
|
||||
struct BMVert *eve,
|
||||
struct BMEdge *eed,
|
||||
struct BMFace *efa)
|
||||
{
|
||||
int result = ORIENTATION_NONE;
|
||||
const bool activeOnly = (around == V3D_AROUND_ACTIVE);
|
||||
|
||||
zero_v3(normal);
|
||||
zero_v3(plane);
|
||||
if (efa == NULL && eed == NULL) {
|
||||
zero_v3(normal);
|
||||
zero_v3(plane);
|
||||
}
|
||||
|
||||
if (obedit) {
|
||||
float imat[3][3], mat[3][3];
|
||||
|
@ -777,20 +784,72 @@ int getTransformOrientation_ex(const Scene *scene,
|
|||
float vec[3] = {0, 0, 0};
|
||||
|
||||
/* USE LAST SELECTED WITH ACTIVE */
|
||||
if (activeOnly && BM_select_history_active_get(em->bm, &ese)) {
|
||||
BM_editselection_normal(&ese, normal);
|
||||
BM_editselection_plane(&ese, plane);
|
||||
if (efa != NULL || eed != NULL || eve != NULL ||
|
||||
activeOnly && BM_select_history_active_get(em->bm, &ese)) {
|
||||
if (efa != NULL) {
|
||||
copy_v3_v3(normal, efa->no);
|
||||
BM_face_calc_tangent_auto(efa, plane);
|
||||
result = ORIENTATION_FACE;
|
||||
}
|
||||
else if (eed != NULL) {
|
||||
float eed_plane[3];
|
||||
float vec[3];
|
||||
add_v3_v3v3(normal, eed->v1->no, eed->v2->no);
|
||||
sub_v3_v3v3(eed_plane, eed->v2->co, eed->v1->co);
|
||||
cross_v3_v3v3(vec, normal, eed_plane);
|
||||
cross_v3_v3v3(normal, eed_plane, vec);
|
||||
normalize_v3(normal);
|
||||
|
||||
switch (ese.htype) {
|
||||
case BM_VERT:
|
||||
result = ORIENTATION_VERT;
|
||||
break;
|
||||
case BM_EDGE:
|
||||
result = ORIENTATION_EDGE;
|
||||
break;
|
||||
case BM_FACE:
|
||||
result = ORIENTATION_FACE;
|
||||
break;
|
||||
if (BM_edge_is_boundary(eed)) {
|
||||
sub_v3_v3v3(plane, eed->l->v->co, eed->l->next->v->co);
|
||||
}
|
||||
else {
|
||||
if (eed->v2->co[1] > eed->v1->co[1]) {
|
||||
sub_v3_v3v3(plane, eed->v2->co, eed->v1->co);
|
||||
}
|
||||
else {
|
||||
sub_v3_v3v3(plane, eed->v1->co, eed->v2->co);
|
||||
}
|
||||
}
|
||||
normalize_v3(plane);
|
||||
result = ORIENTATION_EDGE;
|
||||
}
|
||||
else if (eve != NULL) {
|
||||
copy_v3_v3(normal, eve->no);
|
||||
if (eve->e) {
|
||||
float vert1v3[3] = {eve->e->v1->co[0], eve->e->v1->co[1], eve->e->v1->co[2]};
|
||||
float vert2v3[3] = {eve->e->v2->co[0], eve->e->v2->co[1], eve->e->v2->co[2]};
|
||||
sub_v3_v3v3(plane, vert2v3, vert1v3);
|
||||
}
|
||||
else {
|
||||
if (eve->no[0] < 0.5f) {
|
||||
vec[0] = 1.0f;
|
||||
}
|
||||
else if (eve->no[1] < 0.5f) {
|
||||
vec[1] = 1.0f;
|
||||
}
|
||||
else {
|
||||
vec[2] = 1.0f;
|
||||
}
|
||||
cross_v3_v3v3(plane, eve->no, vec);
|
||||
}
|
||||
normalize_v3(plane);
|
||||
result = ORIENTATION_VERT;
|
||||
}
|
||||
else {
|
||||
BM_editselection_normal(&ese, normal);
|
||||
BM_editselection_plane(&ese, plane);
|
||||
switch (ese.htype) {
|
||||
case BM_VERT:
|
||||
result = ORIENTATION_VERT;
|
||||
break;
|
||||
case BM_EDGE:
|
||||
result = ORIENTATION_EDGE;
|
||||
break;
|
||||
case BM_FACE:
|
||||
result = ORIENTATION_FACE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1289,7 +1348,8 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3])
|
|||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
|
||||
return getTransformOrientation_ex(scene, view_layer, v3d, obact, obedit, normal, plane, around);
|
||||
return getTransformOrientation_ex(
|
||||
scene, view_layer, v3d, obact, obedit, normal, plane, around, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void ED_getTransformOrientationMatrix(const Scene *scene,
|
||||
|
@ -1298,14 +1358,32 @@ void ED_getTransformOrientationMatrix(const Scene *scene,
|
|||
Object *ob,
|
||||
Object *obedit,
|
||||
const short around,
|
||||
float r_orientation_mat[3][3])
|
||||
float r_orientation_mat[3][3],
|
||||
struct BMVert *eve,
|
||||
struct BMEdge *eed,
|
||||
struct BMFace *efa)
|
||||
{
|
||||
float normal[3] = {0.0, 0.0, 0.0};
|
||||
float plane[3] = {0.0, 0.0, 0.0};
|
||||
|
||||
int type;
|
||||
|
||||
type = getTransformOrientation_ex(scene, view_layer, v3d, ob, obedit, normal, plane, around);
|
||||
if (efa != NULL) {
|
||||
type = getTransformOrientation_ex(
|
||||
scene, view_layer, v3d, ob, obedit, normal, plane, around, NULL, NULL, efa);
|
||||
}
|
||||
else if (eed != NULL) {
|
||||
type = getTransformOrientation_ex(
|
||||
scene, view_layer, v3d, ob, obedit, normal, plane, around, NULL, eed, NULL);
|
||||
}
|
||||
else if (eve != NULL) {
|
||||
type = getTransformOrientation_ex(
|
||||
scene, view_layer, v3d, ob, obedit, normal, plane, around, eve, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
type = getTransformOrientation_ex(
|
||||
scene, view_layer, v3d, ob, obedit, normal, plane, around, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Fallback, when the plane can't be calculated. */
|
||||
if (ORIENTATION_USE_PLANE(type) && is_zero_v3(plane)) {
|
||||
|
|
|
@ -366,6 +366,12 @@
|
|||
/* UV painting */ \
|
||||
.uv_sculpt_settings = 0, \
|
||||
.uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN, \
|
||||
\
|
||||
/* Viewport-Facing Select */ \
|
||||
.viewport_facing_select_mode = 1, \
|
||||
.viewport_facing_select_vert = 1, \
|
||||
.viewport_facing_select_edge = 1, \
|
||||
.viewport_facing_select_face = 1, \
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
|
|
|
@ -1557,7 +1557,15 @@ typedef struct ToolSettings {
|
|||
char gpencil_v3d_align;
|
||||
/** General 2D Editor. */
|
||||
char gpencil_v2d_align;
|
||||
char _pad0[2];
|
||||
|
||||
/* Mesh Normal Direction Select */
|
||||
char viewport_facing_select;
|
||||
char viewport_facing_select_mode;
|
||||
char _pad0[1];
|
||||
float viewport_facing_select_threshold;
|
||||
char viewport_facing_select_vert;
|
||||
char viewport_facing_select_edge;
|
||||
char viewport_facing_select_face;
|
||||
|
||||
/* Annotations. */
|
||||
/** Stroke placement settings - 3D View. */
|
||||
|
@ -2331,6 +2339,40 @@ typedef enum eSnapTransformMode {
|
|||
SCE_SNAP_TRANSFORM_MODE_SCALE = (1 << 2),
|
||||
} eSnapTransformMode;
|
||||
|
||||
/** #ToolSettings.viewport_facing_mode */
|
||||
enum {
|
||||
VIEWPORT_FACING_SELECT_BOTH = (1 << 0),
|
||||
VIEWPORT_FACING_SELECT_NEAR = (1 << 1),
|
||||
VIEWPORT_FACING_SELECT_XRAY = (1 << 2),
|
||||
};
|
||||
|
||||
/** #ToolSettings.viewport_facing_select_vert */
|
||||
enum {
|
||||
VIEWPORT_FACING_SELECT_FRONT_VERTS = (1 << 0),
|
||||
VIEWPORT_FACING_SELECT_FRONT_VERTS_FACE = (1 << 1),
|
||||
VIEWPORT_FACING_SELECT_REAR_VERTS = (1 << 2),
|
||||
VIEWPORT_FACING_SELECT_REAR_VERTS_FACE = (1 << 3),
|
||||
VIEWPORT_FACING_SELECT_ALL_VERTS = (1 << 4),
|
||||
};
|
||||
|
||||
/** #ToolSettings.viewport_facing_select_edge */
|
||||
enum {
|
||||
VIEWPORT_FACING_SELECT_FRONT_EDGES = (1 << 0),
|
||||
VIEWPORT_FACING_SELECT_FRONT_EDGES_FACE = (1 << 1),
|
||||
VIEWPORT_FACING_SELECT_REAR_EDGES = (1 << 2),
|
||||
VIEWPORT_FACING_SELECT_REAR_EDGES_FACE = (1 << 3),
|
||||
VIEWPORT_FACING_SELECT_ALL_EDGES = (1 << 4),
|
||||
};
|
||||
|
||||
/** #ToolSettings.viewport_facing_select_face */
|
||||
enum {
|
||||
VIEWPORT_FACING_SELECT_FRONT_FACES = (1 << 0),
|
||||
VIEWPORT_FACING_SELECT_FRONT_FACES_VERT = (1 << 1),
|
||||
VIEWPORT_FACING_SELECT_REAR_FACES = (1 << 2),
|
||||
VIEWPORT_FACING_SELECT_REAR_FACES_VERT = (1 << 3),
|
||||
VIEWPORT_FACING_SELECT_ALL_FACES = (1 << 4),
|
||||
};
|
||||
|
||||
/** #ToolSettings.selectmode */
|
||||
#define SCE_SELECT_VERTEX (1 << 0) /* for mesh */
|
||||
#define SCE_SELECT_EDGE (1 << 1)
|
||||
|
|
|
@ -3049,6 +3049,112 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem viewport_facing_select_mode_items[] = {
|
||||
{VIEWPORT_FACING_SELECT_BOTH,
|
||||
"BOTH",
|
||||
0,
|
||||
"Near and X-Ray",
|
||||
"Use viewport-facing selection in near select and X-Ray"},
|
||||
{VIEWPORT_FACING_SELECT_NEAR,
|
||||
"NEAR",
|
||||
0,
|
||||
"Near",
|
||||
"Use viewport-facing selection in near select"},
|
||||
{VIEWPORT_FACING_SELECT_XRAY,
|
||||
"XRAY",
|
||||
0,
|
||||
"X-Ray",
|
||||
"Use viewport-facing selection in X-Ray"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem viewport_facing_select_vert_items[] = {
|
||||
{VIEWPORT_FACING_SELECT_FRONT_VERTS,
|
||||
"FRONT_VERTS",
|
||||
0,
|
||||
"Front Verts",
|
||||
"Select vertices with viewport-facing normals"},
|
||||
{VIEWPORT_FACING_SELECT_FRONT_VERTS_FACE,
|
||||
"FRONT_VERTS_FACE",
|
||||
0,
|
||||
"Verts of Front Face",
|
||||
"Select vertices if they are part of a face that has a viewport-facing normal"},
|
||||
{VIEWPORT_FACING_SELECT_REAR_VERTS,
|
||||
"REAR_VERTS",
|
||||
0,
|
||||
"Rear Verts",
|
||||
"Select vertices without viewport-facing normals"},
|
||||
{VIEWPORT_FACING_SELECT_REAR_VERTS_FACE,
|
||||
"REAR_VERTS_FACE",
|
||||
0,
|
||||
"Verts of Rear Face",
|
||||
"Select vertices if they are part of a face that does not have a viewport-facing normal"},
|
||||
{VIEWPORT_FACING_SELECT_ALL_VERTS,
|
||||
"ALL_VERTS",
|
||||
0,
|
||||
"All Verts",
|
||||
"Select vertices regarless of their normal direction"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem viewport_facing_select_edge_items[] = {
|
||||
{VIEWPORT_FACING_SELECT_FRONT_EDGES,
|
||||
"FRONT_EDGES",
|
||||
0,
|
||||
"Front Edges",
|
||||
"Select edges with viewport-facing normals"},
|
||||
{VIEWPORT_FACING_SELECT_FRONT_EDGES_FACE,
|
||||
"FRONT_EDGES_FACE",
|
||||
0,
|
||||
"Edges of Front Face",
|
||||
"Select edges if they are part of a face that has a viewport-facing normal"},
|
||||
{VIEWPORT_FACING_SELECT_REAR_EDGES,
|
||||
"REAR_EDGES",
|
||||
0,
|
||||
"Rear Edges",
|
||||
"Select edges without viewport-facing normals"},
|
||||
{VIEWPORT_FACING_SELECT_REAR_EDGES_FACE,
|
||||
"REAR_EDGES_FACE",
|
||||
0,
|
||||
"Edges of Rear Face",
|
||||
"Select edges if they are part of a face that does not have a viewport-facing normal"},
|
||||
{VIEWPORT_FACING_SELECT_ALL_EDGES,
|
||||
"ALL_EDGES",
|
||||
0,
|
||||
"All Edges",
|
||||
"Select edges regarless of their normal direction"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem viewport_facing_select_face_items[] = {
|
||||
{VIEWPORT_FACING_SELECT_FRONT_FACES,
|
||||
"FRONT_FACES",
|
||||
0,
|
||||
"Front Faces",
|
||||
"Select faces with viewport-facing normals"},
|
||||
{VIEWPORT_FACING_SELECT_FRONT_FACES_VERT,
|
||||
"FRONT_FACES_VERT",
|
||||
0,
|
||||
"Faces of Front Vert",
|
||||
"Select faces if they have a vertex with a viewport-facing normal"},
|
||||
{VIEWPORT_FACING_SELECT_REAR_FACES,
|
||||
"REAR_FACES",
|
||||
0,
|
||||
"Rear Faces",
|
||||
"Select faces without viewport-facing normals"},
|
||||
{VIEWPORT_FACING_SELECT_REAR_FACES_VERT,
|
||||
"REAR_FACES_VERT",
|
||||
0,
|
||||
"Faces of Rear Vert",
|
||||
"Select faces if they have a vertex without a viewport-facing normal"},
|
||||
{VIEWPORT_FACING_SELECT_ALL_FACES,
|
||||
"ALL_FACES",
|
||||
0,
|
||||
"All Faces",
|
||||
"Select faces regarless of their normal direction"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "ToolSettings", NULL);
|
||||
RNA_def_struct_path_func(srna, "rna_ToolSettings_path");
|
||||
RNA_def_struct_ui_text(srna, "Tool Settings", "");
|
||||
|
@ -3725,6 +3831,43 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Normal Vector", "Normal Vector used to copy, add or multiply");
|
||||
RNA_def_property_ui_range(prop, -10000.0, 10000.0, 1, 3);
|
||||
|
||||
prop = RNA_def_property(srna, "viewport_facing_select", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "viewport_facing_select", 0);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Viewport Facing Select",
|
||||
"Filter box, lasso, and circle selection of mesh elements based on the direction of their "
|
||||
"normals compared to the viewport");
|
||||
|
||||
prop = RNA_def_property(srna, "viewport_facing_select_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "viewport_facing_select_mode");
|
||||
RNA_def_property_enum_items(prop, viewport_facing_select_mode_items);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Mode", "Which selection modes to use viewport-facing selection");
|
||||
|
||||
prop = RNA_def_property(srna, "viewport_facing_select_vert", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "viewport_facing_select_vert");
|
||||
RNA_def_property_enum_items(prop, viewport_facing_select_vert_items);
|
||||
RNA_def_property_ui_text(prop, "Vert", "Direction and mode for vertices");
|
||||
|
||||
prop = RNA_def_property(srna, "viewport_facing_select_edge", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "viewport_facing_select_edge");
|
||||
RNA_def_property_enum_items(prop, viewport_facing_select_edge_items);
|
||||
RNA_def_property_ui_text(prop, "Edge", "Direction and mode for edges");
|
||||
|
||||
prop = RNA_def_property(srna, "viewport_facing_select_face", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "viewport_facing_select_face");
|
||||
RNA_def_property_enum_items(prop, viewport_facing_select_face_items);
|
||||
RNA_def_property_ui_text(prop, "Face", "Direction and mode for faces");
|
||||
|
||||
prop = RNA_def_property(srna, "viewport_facing_select_threshold", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1.0f, 2);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Threshold",
|
||||
"How close the angles of the viewport and mesh element need to be for selection to occur");
|
||||
|
||||
/* Unified Paint Settings */
|
||||
prop = RNA_def_property(srna, "unified_paint_settings", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||
|
@ -3800,6 +3943,8 @@ static void rna_def_sequencer_tool_settings(BlenderRNA *brna)
|
|||
{0, NULL, 0, NULL, NULL},
|
||||
|
||||
};
|
||||
|
||||
|
||||
srna = RNA_def_struct(brna, "SequencerToolSettings", NULL);
|
||||
RNA_def_struct_path_func(srna, "rna_SequencerToolSettings_path");
|
||||
RNA_def_struct_ui_text(srna, "Sequencer Tool Settings", "");
|
||||
|
|
Loading…
Reference in New Issue