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_context = ".mesh_edit" # dot on purpose (access from topbar)
|
||||||
bl_label = "Options"
|
bl_label = "Options"
|
||||||
bl_options = {'DEFAULT_CLOSED'}
|
bl_options = {'DEFAULT_CLOSED'}
|
||||||
bl_ui_units_x = 12
|
bl_ui_units_x = 13
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
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")
|
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 ****************
|
# ********** default tools for editmode_armature ****************
|
||||||
|
|
||||||
|
|
||||||
|
@ -2364,6 +2397,7 @@ classes = (
|
||||||
VIEW3D_PT_tools_object_options_transform,
|
VIEW3D_PT_tools_object_options_transform,
|
||||||
VIEW3D_PT_tools_meshedit_options,
|
VIEW3D_PT_tools_meshedit_options,
|
||||||
VIEW3D_PT_tools_meshedit_options_automerge,
|
VIEW3D_PT_tools_meshedit_options_automerge,
|
||||||
|
VIEW3D_PT_tools_meshedit_options_viewport_facing_select,
|
||||||
VIEW3D_PT_tools_armatureedit_options,
|
VIEW3D_PT_tools_armatureedit_options,
|
||||||
VIEW3D_PT_tools_posemode_options,
|
VIEW3D_PT_tools_posemode_options,
|
||||||
|
|
||||||
|
|
|
@ -373,6 +373,12 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
|
||||||
if (idprop) {
|
if (idprop) {
|
||||||
IDP_ClearProperty(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)
|
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 *ob,
|
||||||
struct Object *obedit,
|
struct Object *obedit,
|
||||||
short around,
|
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);
|
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);
|
Object *obedit = CTX_data_edit_object(C);
|
||||||
/* same as transform gizmo when normal is set */
|
/* same as transform gizmo when normal is set */
|
||||||
ED_getTransformOrientationMatrix(
|
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;
|
align_quat = align_quat_buf;
|
||||||
mat3_to_quat(align_quat, twmat);
|
mat3_to_quat(align_quat, twmat);
|
||||||
invert_qt_normalized(align_quat);
|
invert_qt_normalized(align_quat);
|
||||||
|
|
|
@ -80,6 +80,7 @@
|
||||||
#include "ED_screen.h"
|
#include "ED_screen.h"
|
||||||
#include "ED_sculpt.h"
|
#include "ED_sculpt.h"
|
||||||
#include "ED_select_utils.h"
|
#include "ED_select_utils.h"
|
||||||
|
#include "ED_transform.h"
|
||||||
|
|
||||||
#include "UI_interface.h"
|
#include "UI_interface.h"
|
||||||
#include "UI_resources.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
|
/** \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,
|
Depsgraph *depsgraph,
|
||||||
Object *ob,
|
Object *ob,
|
||||||
BMEditMesh *em,
|
BMEditMesh *em,
|
||||||
const eSelectOp sel_op)
|
const eSelectOp sel_op)
|
||||||
{
|
{
|
||||||
|
ToolSettings *ts = vc->scene->toolsettings;
|
||||||
BMVert *eve;
|
BMVert *eve;
|
||||||
BMIter iter;
|
BMIter iter;
|
||||||
bool changed = false;
|
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;
|
const BLI_bitmap *select_bitmap = esel->select_bitmap;
|
||||||
uint index = DRW_select_buffer_context_offset_for_object_elem(depsgraph, ob, SCE_SELECT_VERTEX);
|
uint index = DRW_select_buffer_context_offset_for_object_elem(depsgraph, ob, SCE_SELECT_VERTEX);
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
index -= 1;
|
index -= 1;
|
||||||
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
|
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
|
||||||
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
|
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
|
||||||
const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
|
const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
|
||||||
const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
|
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) {
|
if (sel_op_result != -1) {
|
||||||
BM_vert_select_set(em->bm, eve, sel_op_result);
|
BM_vert_select_set(em->bm, eve, sel_op_result);
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -271,15 +441,19 @@ static bool edbm_backbuf_check_and_select_verts(EditSelectBuf_Cache *esel,
|
||||||
return changed;
|
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,
|
Depsgraph *depsgraph,
|
||||||
Object *ob,
|
Object *ob,
|
||||||
BMEditMesh *em,
|
BMEditMesh *em,
|
||||||
const eSelectOp sel_op)
|
const eSelectOp sel_op)
|
||||||
{
|
{
|
||||||
|
ToolSettings *ts = vc->scene->toolsettings;
|
||||||
BMEdge *eed;
|
BMEdge *eed;
|
||||||
BMIter iter;
|
BMIter iter;
|
||||||
bool changed = false;
|
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;
|
const BLI_bitmap *select_bitmap = esel->select_bitmap;
|
||||||
uint index = DRW_select_buffer_context_offset_for_object_elem(depsgraph, ob, SCE_SELECT_EDGE);
|
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)) {
|
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
|
||||||
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
|
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
|
||||||
const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
|
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) {
|
if (sel_op_result != -1) {
|
||||||
BM_edge_select_set(em->bm, eed, sel_op_result);
|
BM_edge_select_set(em->bm, eed, sel_op_result);
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -303,15 +482,19 @@ static bool edbm_backbuf_check_and_select_edges(EditSelectBuf_Cache *esel,
|
||||||
return changed;
|
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,
|
Depsgraph *depsgraph,
|
||||||
Object *ob,
|
Object *ob,
|
||||||
BMEditMesh *em,
|
BMEditMesh *em,
|
||||||
const eSelectOp sel_op)
|
const eSelectOp sel_op)
|
||||||
{
|
{
|
||||||
|
ToolSettings *ts = vc->scene->toolsettings;
|
||||||
BMFace *efa;
|
BMFace *efa;
|
||||||
BMIter iter;
|
BMIter iter;
|
||||||
bool changed = false;
|
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;
|
const BLI_bitmap *select_bitmap = esel->select_bitmap;
|
||||||
uint index = DRW_select_buffer_context_offset_for_object_elem(depsgraph, ob, SCE_SELECT_FACE);
|
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)) {
|
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
|
||||||
const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
|
const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
|
||||||
const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
|
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) {
|
if (sel_op_result != -1) {
|
||||||
BM_face_select_set(em->bm, efa, sel_op_result);
|
BM_face_select_set(em->bm, efa, sel_op_result);
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -412,6 +600,7 @@ struct LassoSelectUserData {
|
||||||
int mcoords_len;
|
int mcoords_len;
|
||||||
eSelectOp sel_op;
|
eSelectOp sel_op;
|
||||||
eBezTriple_Flag select_flag;
|
eBezTriple_Flag select_flag;
|
||||||
|
bool check_mesh_direction;
|
||||||
|
|
||||||
/* runtime */
|
/* runtime */
|
||||||
int pass;
|
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_rctf_isect_pt_v(data->rect_fl, screen_co) &&
|
||||||
BLI_lasso_is_point_inside(
|
BLI_lasso_is_point_inside(
|
||||||
data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED));
|
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) {
|
if (sel_op_result != -1) {
|
||||||
BM_vert_select_set(data->vc->em->bm, eve, sel_op_result);
|
BM_vert_select_set(data->vc->em->bm, eve, sel_op_result);
|
||||||
data->is_changed = true;
|
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) &&
|
data->mcoords, data->mcoords_len, UNPACK2(screen_co_a), IS_CLIPPED) &&
|
||||||
BLI_lasso_is_point_inside(
|
BLI_lasso_is_point_inside(
|
||||||
data->mcoords, data->mcoords_len, UNPACK2(screen_co_b), IS_CLIPPED));
|
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) {
|
if (sel_op_result != -1) {
|
||||||
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
||||||
data->is_done = true;
|
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_a),
|
||||||
UNPACK2(screen_co_b),
|
UNPACK2(screen_co_b),
|
||||||
IS_CLIPPED));
|
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) {
|
if (sel_op_result != -1) {
|
||||||
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
||||||
data->is_changed = true;
|
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_rctf_isect_pt_v(data->rect_fl, screen_co) &&
|
||||||
BLI_lasso_is_point_inside(
|
BLI_lasso_is_point_inside(
|
||||||
data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED));
|
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) {
|
if (sel_op_result != -1) {
|
||||||
BM_face_select_set(data->vc->em->bm, efa, sel_op_result);
|
BM_face_select_set(data->vc->em->bm, efa, sel_op_result);
|
||||||
data->is_changed = true;
|
data->is_changed = true;
|
||||||
|
@ -841,9 +1054,11 @@ static bool do_lasso_select_mesh(ViewContext *vc,
|
||||||
if (ts->selectmode & SCE_SELECT_VERTEX) {
|
if (ts->selectmode & SCE_SELECT_VERTEX) {
|
||||||
if (use_zbuf) {
|
if (use_zbuf) {
|
||||||
data.is_changed |= edbm_backbuf_check_and_select_verts(
|
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 {
|
else {
|
||||||
|
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||||
|
ts, ts->viewport_facing_select_vert, true);
|
||||||
mesh_foreachScreenVert(
|
mesh_foreachScreenVert(
|
||||||
vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
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 |
|
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_NEAR |
|
||||||
(use_zbuf ? (eV3DProjTest)0 : V3D_PROJ_TEST_CLIP_BB);
|
(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. */
|
/* Fully inside. */
|
||||||
mesh_foreachScreenEdge_clip_bb_segment(
|
mesh_foreachScreenEdge_clip_bb_segment(
|
||||||
vc, do_lasso_select_mesh__doSelectEdge_pass0, &data_for_edge, clip_flag);
|
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 (ts->selectmode & SCE_SELECT_FACE) {
|
||||||
if (use_zbuf) {
|
if (use_zbuf) {
|
||||||
data.is_changed |= edbm_backbuf_check_and_select_faces(
|
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 {
|
else {
|
||||||
|
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||||
|
ts, ts->viewport_facing_select_face, true);
|
||||||
mesh_foreachScreenFace(
|
mesh_foreachScreenFace(
|
||||||
vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||||
}
|
}
|
||||||
|
@ -3231,6 +3456,7 @@ struct BoxSelectUserData {
|
||||||
rctf _rect_fl;
|
rctf _rect_fl;
|
||||||
eSelectOp sel_op;
|
eSelectOp sel_op;
|
||||||
eBezTriple_Flag select_flag;
|
eBezTriple_Flag select_flag;
|
||||||
|
bool check_mesh_direction;
|
||||||
|
|
||||||
/* runtime */
|
/* runtime */
|
||||||
bool is_done;
|
bool is_done;
|
||||||
|
@ -3492,7 +3718,13 @@ static void do_mesh_box_select__doSelectVert(void *userData,
|
||||||
BoxSelectUserData *data = static_cast<BoxSelectUserData *>(userData);
|
BoxSelectUserData *data = static_cast<BoxSelectUserData *>(userData);
|
||||||
const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
|
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 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) {
|
if (sel_op_result != -1) {
|
||||||
BM_vert_select_set(data->vc->em->bm, eve, sel_op_result);
|
BM_vert_select_set(data->vc->em->bm, eve, sel_op_result);
|
||||||
data->is_changed = true;
|
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_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
|
||||||
const bool is_inside = (is_visible &&
|
const bool is_inside = (is_visible &&
|
||||||
edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b));
|
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) {
|
if (sel_op_result != -1) {
|
||||||
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
||||||
data->is_done = true;
|
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_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 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) {
|
if (sel_op_result != -1) {
|
||||||
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
|
||||||
data->is_changed = true;
|
data->is_changed = true;
|
||||||
|
@ -3559,7 +3803,13 @@ static void do_mesh_box_select__doSelectFace(void *userData,
|
||||||
BoxSelectUserData *data = static_cast<BoxSelectUserData *>(userData);
|
BoxSelectUserData *data = static_cast<BoxSelectUserData *>(userData);
|
||||||
const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
|
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 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) {
|
if (sel_op_result != -1) {
|
||||||
BM_face_select_set(data->vc->em->bm, efa, sel_op_result);
|
BM_face_select_set(data->vc->em->bm, efa, sel_op_result);
|
||||||
data->is_changed = true;
|
data->is_changed = true;
|
||||||
|
@ -3602,9 +3852,11 @@ static bool do_mesh_box_select(ViewContext *vc,
|
||||||
if (ts->selectmode & SCE_SELECT_VERTEX) {
|
if (ts->selectmode & SCE_SELECT_VERTEX) {
|
||||||
if (use_zbuf) {
|
if (use_zbuf) {
|
||||||
data.is_changed |= edbm_backbuf_check_and_select_verts(
|
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 {
|
else {
|
||||||
|
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||||
|
ts, ts->viewport_facing_select_vert, true);
|
||||||
mesh_foreachScreenVert(
|
mesh_foreachScreenVert(
|
||||||
vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
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 |
|
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_NEAR |
|
||||||
(use_zbuf ? (eV3DProjTest)0 : V3D_PROJ_TEST_CLIP_BB);
|
(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. */
|
/* Fully inside. */
|
||||||
mesh_foreachScreenEdge_clip_bb_segment(
|
mesh_foreachScreenEdge_clip_bb_segment(
|
||||||
vc, do_mesh_box_select__doSelectEdge_pass0, &cb_data, clip_flag);
|
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 (ts->selectmode & SCE_SELECT_FACE) {
|
||||||
if (use_zbuf) {
|
if (use_zbuf) {
|
||||||
data.is_changed |= edbm_backbuf_check_and_select_faces(
|
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 {
|
else {
|
||||||
|
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||||
|
ts, ts->viewport_facing_select_face, true);
|
||||||
mesh_foreachScreenFace(
|
mesh_foreachScreenFace(
|
||||||
vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
|
||||||
}
|
}
|
||||||
|
@ -4106,6 +4368,7 @@ struct CircleSelectUserData {
|
||||||
float radius;
|
float radius;
|
||||||
float radius_squared;
|
float radius_squared;
|
||||||
eBezTriple_Flag select_flag;
|
eBezTriple_Flag select_flag;
|
||||||
|
bool check_mesh_direction;
|
||||||
|
|
||||||
/* runtime */
|
/* runtime */
|
||||||
bool is_changed;
|
bool is_changed;
|
||||||
|
@ -4141,8 +4404,15 @@ static void mesh_circle_doSelectVert(void *userData,
|
||||||
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
|
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
|
||||||
|
|
||||||
if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
|
if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
|
||||||
BM_vert_select_set(data->vc->em->bm, eve, data->select);
|
bool mesh_facing = true;
|
||||||
data->is_changed = 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,
|
static void mesh_circle_doSelectEdge(void *userData,
|
||||||
|
@ -4154,8 +4424,15 @@ static void mesh_circle_doSelectEdge(void *userData,
|
||||||
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
|
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
|
||||||
|
|
||||||
if (edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) {
|
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);
|
bool mesh_facing = true;
|
||||||
data->is_changed = 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,
|
static void mesh_circle_doSelectFace(void *userData,
|
||||||
|
@ -4166,8 +4443,15 @@ static void mesh_circle_doSelectFace(void *userData,
|
||||||
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
|
CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData);
|
||||||
|
|
||||||
if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
|
if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
|
||||||
BM_face_select_set(data->vc->em->bm, efa, data->select);
|
bool mesh_facing = true;
|
||||||
data->is_changed = 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 (use_zbuf) {
|
||||||
if (esel->select_bitmap != nullptr) {
|
if (esel->select_bitmap != nullptr) {
|
||||||
changed |= edbm_backbuf_check_and_select_verts(
|
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 {
|
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);
|
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 (use_zbuf) {
|
||||||
if (esel->select_bitmap != nullptr) {
|
if (esel->select_bitmap != nullptr) {
|
||||||
changed |= edbm_backbuf_check_and_select_edges(
|
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 {
|
else {
|
||||||
|
data.check_mesh_direction = edbm_facing_viewport_precheck(
|
||||||
|
ts, ts->viewport_facing_select_edge, true);
|
||||||
mesh_foreachScreenEdge_clip_bb_segment(
|
mesh_foreachScreenEdge_clip_bb_segment(
|
||||||
vc,
|
vc,
|
||||||
mesh_circle_doSelectEdge,
|
mesh_circle_doSelectEdge,
|
||||||
|
@ -4245,10 +4533,12 @@ static bool mesh_circle_select(ViewContext *vc,
|
||||||
if (use_zbuf) {
|
if (use_zbuf) {
|
||||||
if (esel->select_bitmap != nullptr) {
|
if (esel->select_bitmap != nullptr) {
|
||||||
changed |= edbm_backbuf_check_and_select_faces(
|
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 {
|
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);
|
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: {
|
case V3D_ORIENT_NORMAL: {
|
||||||
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
/* No break we define 'normal' as 'local' in Object mode. */
|
/* 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
|
* 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
|
* bone and users who select many bones will understand what's going on and what local
|
||||||
* means when they start transforming. */
|
* 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 {
|
else {
|
||||||
transform_orientations_create_from_axis(r_mat, UNPACK3(ob->object_to_world));
|
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,
|
struct Object *obedit,
|
||||||
float normal[3],
|
float normal[3],
|
||||||
float plane[3],
|
float plane[3],
|
||||||
const short around)
|
const short around,
|
||||||
|
struct BMVert *eve,
|
||||||
|
struct BMEdge *eed,
|
||||||
|
struct BMFace *efa)
|
||||||
{
|
{
|
||||||
int result = ORIENTATION_NONE;
|
int result = ORIENTATION_NONE;
|
||||||
const bool activeOnly = (around == V3D_AROUND_ACTIVE);
|
const bool activeOnly = (around == V3D_AROUND_ACTIVE);
|
||||||
|
|
||||||
zero_v3(normal);
|
if (efa == NULL && eed == NULL) {
|
||||||
zero_v3(plane);
|
zero_v3(normal);
|
||||||
|
zero_v3(plane);
|
||||||
|
}
|
||||||
|
|
||||||
if (obedit) {
|
if (obedit) {
|
||||||
float imat[3][3], mat[3][3];
|
float imat[3][3], mat[3][3];
|
||||||
|
@ -777,20 +784,72 @@ int getTransformOrientation_ex(const Scene *scene,
|
||||||
float vec[3] = {0, 0, 0};
|
float vec[3] = {0, 0, 0};
|
||||||
|
|
||||||
/* USE LAST SELECTED WITH ACTIVE */
|
/* USE LAST SELECTED WITH ACTIVE */
|
||||||
if (activeOnly && BM_select_history_active_get(em->bm, &ese)) {
|
if (efa != NULL || eed != NULL || eve != NULL ||
|
||||||
BM_editselection_normal(&ese, normal);
|
activeOnly && BM_select_history_active_get(em->bm, &ese)) {
|
||||||
BM_editselection_plane(&ese, plane);
|
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) {
|
if (BM_edge_is_boundary(eed)) {
|
||||||
case BM_VERT:
|
sub_v3_v3v3(plane, eed->l->v->co, eed->l->next->v->co);
|
||||||
result = ORIENTATION_VERT;
|
}
|
||||||
break;
|
else {
|
||||||
case BM_EDGE:
|
if (eed->v2->co[1] > eed->v1->co[1]) {
|
||||||
result = ORIENTATION_EDGE;
|
sub_v3_v3v3(plane, eed->v2->co, eed->v1->co);
|
||||||
break;
|
}
|
||||||
case BM_FACE:
|
else {
|
||||||
result = ORIENTATION_FACE;
|
sub_v3_v3v3(plane, eed->v1->co, eed->v2->co);
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
|
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 {
|
else {
|
||||||
|
@ -1289,7 +1348,8 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3])
|
||||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||||
View3D *v3d = CTX_wm_view3d(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,
|
void ED_getTransformOrientationMatrix(const Scene *scene,
|
||||||
|
@ -1298,14 +1358,32 @@ void ED_getTransformOrientationMatrix(const Scene *scene,
|
||||||
Object *ob,
|
Object *ob,
|
||||||
Object *obedit,
|
Object *obedit,
|
||||||
const short around,
|
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 normal[3] = {0.0, 0.0, 0.0};
|
||||||
float plane[3] = {0.0, 0.0, 0.0};
|
float plane[3] = {0.0, 0.0, 0.0};
|
||||||
|
|
||||||
int type;
|
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. */
|
/* Fallback, when the plane can't be calculated. */
|
||||||
if (ORIENTATION_USE_PLANE(type) && is_zero_v3(plane)) {
|
if (ORIENTATION_USE_PLANE(type) && is_zero_v3(plane)) {
|
||||||
|
|
|
@ -366,6 +366,12 @@
|
||||||
/* UV painting */ \
|
/* UV painting */ \
|
||||||
.uv_sculpt_settings = 0, \
|
.uv_sculpt_settings = 0, \
|
||||||
.uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN, \
|
.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 */
|
/* clang-format off */
|
||||||
|
|
|
@ -1557,7 +1557,15 @@ typedef struct ToolSettings {
|
||||||
char gpencil_v3d_align;
|
char gpencil_v3d_align;
|
||||||
/** General 2D Editor. */
|
/** General 2D Editor. */
|
||||||
char gpencil_v2d_align;
|
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. */
|
/* Annotations. */
|
||||||
/** Stroke placement settings - 3D View. */
|
/** Stroke placement settings - 3D View. */
|
||||||
|
@ -2331,6 +2339,40 @@ typedef enum eSnapTransformMode {
|
||||||
SCE_SNAP_TRANSFORM_MODE_SCALE = (1 << 2),
|
SCE_SNAP_TRANSFORM_MODE_SCALE = (1 << 2),
|
||||||
} eSnapTransformMode;
|
} 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 */
|
/** #ToolSettings.selectmode */
|
||||||
#define SCE_SELECT_VERTEX (1 << 0) /* for mesh */
|
#define SCE_SELECT_VERTEX (1 << 0) /* for mesh */
|
||||||
#define SCE_SELECT_EDGE (1 << 1)
|
#define SCE_SELECT_EDGE (1 << 1)
|
||||||
|
|
|
@ -3049,6 +3049,112 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
||||||
{0, NULL, 0, NULL, NULL},
|
{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);
|
srna = RNA_def_struct(brna, "ToolSettings", NULL);
|
||||||
RNA_def_struct_path_func(srna, "rna_ToolSettings_path");
|
RNA_def_struct_path_func(srna, "rna_ToolSettings_path");
|
||||||
RNA_def_struct_ui_text(srna, "Tool Settings", "");
|
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_text(prop, "Normal Vector", "Normal Vector used to copy, add or multiply");
|
||||||
RNA_def_property_ui_range(prop, -10000.0, 10000.0, 1, 3);
|
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 */
|
/* Unified Paint Settings */
|
||||||
prop = RNA_def_property(srna, "unified_paint_settings", PROP_POINTER, PROP_NONE);
|
prop = RNA_def_property(srna, "unified_paint_settings", PROP_POINTER, PROP_NONE);
|
||||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
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},
|
{0, NULL, 0, NULL, NULL},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
srna = RNA_def_struct(brna, "SequencerToolSettings", NULL);
|
srna = RNA_def_struct(brna, "SequencerToolSettings", NULL);
|
||||||
RNA_def_struct_path_func(srna, "rna_SequencerToolSettings_path");
|
RNA_def_struct_path_func(srna, "rna_SequencerToolSettings_path");
|
||||||
RNA_def_struct_ui_text(srna, "Sequencer Tool Settings", "");
|
RNA_def_struct_ui_text(srna, "Sequencer Tool Settings", "");
|
||||||
|
|
Loading…
Reference in New Issue