Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2020-08-12 21:19:05 +0300
committerHans Goudey <h.goudey@me.com>2020-08-12 21:19:05 +0300
commit31705201dddebf7e3be5c4533b89f380aad1ede1 (patch)
tree53c8be86b15e9ebd96dd60cad52e6acac8ce2324 /source/blender/editors/space_view3d/view3d_placement.c
parentea4c327c977223922c41c889fa2bd51403409dca (diff)
parent337b6d075880ea44ff5183804a387dc98673ffb9 (diff)
Merge branch 'master' into active-fcurve-keyframe
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_placement.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_placement.c175
1 files changed, 158 insertions, 17 deletions
diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c
index ee14d19c177..a828dbc2ee0 100644
--- a/source/blender/editors/space_view3d/view3d_placement.c
+++ b/source/blender/editors/space_view3d/view3d_placement.c
@@ -86,6 +86,11 @@ enum ePlace_Depth {
PLACE_DEPTH_CURSOR_VIEW = 3,
};
+enum ePlace_Orient {
+ PLACE_ORIENT_SURFACE = 1,
+ PLACE_ORIENT_DEFAULT = 2,
+};
+
struct InteractivePlaceData {
/* Window manager variables (set these even when waiting for input). */
Scene *scene;
@@ -145,23 +150,103 @@ struct InteractivePlaceData {
/* On-screen snap distance. */
#define MVAL_MAX_PX_DIST 12.0f
-static bool idp_snap_point_from_gizmo(wmGizmo *gz, float r_location[3])
+static bool idp_snap_point_from_gizmo_ex(wmGizmo *gz, const char *prop_id, float r_location[3])
{
if (gz->state & WM_GIZMO_STATE_HIGHLIGHT) {
- PropertyRNA *prop_location = RNA_struct_find_property(gz->ptr, "location");
+ PropertyRNA *prop_location = RNA_struct_find_property(gz->ptr, prop_id);
RNA_property_float_get_array(gz->ptr, prop_location, r_location);
return true;
}
return false;
}
+static bool idp_snap_point_from_gizmo(wmGizmo *gz, float r_location[3])
+{
+ return idp_snap_point_from_gizmo_ex(gz, "location", r_location);
+}
+
+static bool idp_snap_normal_from_gizmo(wmGizmo *gz, float r_normal[3])
+{
+ return idp_snap_point_from_gizmo_ex(gz, "normal", r_normal);
+}
+
+/**
+ * Calculate a 3x3 orientation matrix from the surface under the cursor.
+ */
+static bool idp_poject_surface_normal(SnapObjectContext *snap_context,
+ struct Depsgraph *depsgraph,
+ const float mval_fl[2],
+ const float mat_fallback[3][3],
+ const float normal_fallback[3],
+ float r_mat[3][3])
+{
+ bool success = false;
+ float normal[3] = {0.0f};
+ float co_dummy[3];
+ /* We could use the index to get the orientation from the face. */
+ Object *ob_snap;
+ float obmat[4][4];
+
+ if (ED_transform_snap_object_project_view3d_ex(snap_context,
+ depsgraph,
+ SCE_SNAP_MODE_FACE,
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_ALL,
+ .use_object_edit_cage = true,
+ },
+ mval_fl,
+ NULL,
+ NULL,
+ co_dummy,
+ normal,
+ NULL,
+ &ob_snap,
+ obmat)) {
+ /* pass */
+ }
+ else if (normal_fallback != NULL) {
+ copy_m4_m3(obmat, mat_fallback);
+ copy_v3_v3(normal, normal_fallback);
+ }
+
+ if (!is_zero_v3(normal)) {
+ float mat[3][3];
+ copy_m3_m4(mat, obmat);
+ normalize_m3(mat);
+
+ float dot_best = fabsf(dot_v3v3(mat[0], normal));
+ int i_best = 0;
+ for (int i = 1; i < 3; i++) {
+ float dot_test = fabsf(dot_v3v3(mat[i], normal));
+ if (dot_test > dot_best) {
+ i_best = i;
+ dot_best = dot_test;
+ }
+ }
+ if (dot_v3v3(mat[i_best], normal) < 0.0f) {
+ negate_v3(mat[(i_best + 1) % 3]);
+ negate_v3(mat[(i_best + 2) % 3]);
+ }
+ copy_v3_v3(mat[i_best], normal);
+ orthogonalize_m3(mat, i_best);
+ normalize_m3(mat);
+
+ copy_v3_v3(r_mat[0], mat[(i_best + 1) % 3]);
+ copy_v3_v3(r_mat[1], mat[(i_best + 2) % 3]);
+ copy_v3_v3(r_mat[2], mat[i_best]);
+ success = true;
+ }
+
+ return success;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
/** \name Primitive Drawing (Cube, Cone, Cylinder...)
* \{ */
-static void draw_line_loop(float coords[][3], int coords_len, const float color[4])
+static void draw_line_loop(const float coords[][3], int coords_len, const float color[4])
{
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
@@ -194,7 +279,7 @@ static void draw_line_loop(float coords[][3], int coords_len, const float color[
GPU_blend(false);
}
-static void draw_line_pairs(float coords_a[][3],
+static void draw_line_pairs(const float coords_a[][3],
float coords_b[][3],
int coords_len,
const float color[4])
@@ -236,7 +321,7 @@ static void draw_line_bounds(const BoundBox *bounds, const float color[4])
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- int edges[12][2] = {
+ const int edges[12][2] = {
/* First side. */
{0, 1},
{1, 2},
@@ -422,7 +507,7 @@ static void draw_circle_in_quad(const float v1[2],
float theta = ((2.0f * M_PI) * ((float)i / (float)resolution)) + 0.01f;
float x = cosf(theta);
float y = sinf(theta);
- float pt[2] = {x, y};
+ const float pt[2] = {x, y};
float w[4];
barycentric_weights_v2_quad(UNPACK4(quad), pt, w);
@@ -549,30 +634,69 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
const int plane_axis = RNA_enum_get(op->ptr, "plane_axis");
const enum ePlace_Depth plane_depth = RNA_enum_get(op->ptr, "plane_depth");
const enum ePlace_Origin plane_origin = RNA_enum_get(op->ptr, "plane_origin");
+ const enum ePlace_Orient plane_orient = RNA_enum_get(op->ptr, "plane_orientation");
+
+ const float mval_fl[2] = {UNPACK2(event->mval)};
struct InteractivePlaceData *ipd = op->customdata;
RegionView3D *rv3d = ipd->region->regiondata;
+ /* Assign snap gizmo which is may be used as part of the tool. */
+ {
+ wmGizmoMap *gzmap = ipd->region->gizmo_map;
+ wmGizmoGroup *gzgroup = gzmap ? WM_gizmomap_group_find(gzmap, view3d_gzgt_placement_id) : NULL;
+ if ((gzgroup != NULL) && gzgroup->gizmos.first) {
+ ipd->snap_gizmo = gzgroup->gizmos.first;
+ }
+ }
+
ipd->launch_event = WM_userdef_event_type_from_keymap_type(event->type);
ED_transform_calc_orientation_from_type(C, ipd->matrix_orient);
+ /* Set the orientation. */
+ if (plane_orient == PLACE_ORIENT_SURFACE) {
+ bool snap_context_free = false;
+ SnapObjectContext *snap_context =
+ (ipd->snap_gizmo ? ED_gizmotypes_snap_3d_context_ensure(
+ ipd->scene, ipd->region, ipd->v3d, ipd->snap_gizmo) :
+ NULL);
+ if (snap_context == NULL) {
+ snap_context = ED_transform_snap_object_context_create_view3d(
+ ipd->scene, 0, ipd->region, ipd->v3d);
+ snap_context_free = true;
+ }
+
+ float matrix_orient_surface[3][3];
+
+ /* Use the snap normal as a fallback in case the cursor isn't over a surface
+ * but snapping is enabled. */
+ float normal_fallback[3];
+ bool use_normal_fallback = ipd->snap_gizmo ?
+ idp_snap_normal_from_gizmo(ipd->snap_gizmo, normal_fallback) :
+ false;
+
+ if (idp_poject_surface_normal(snap_context,
+ CTX_data_ensure_evaluated_depsgraph(C),
+ mval_fl,
+ use_normal_fallback ? ipd->matrix_orient : NULL,
+ use_normal_fallback ? normal_fallback : NULL,
+ matrix_orient_surface)) {
+ copy_m3_m3(ipd->matrix_orient, matrix_orient_surface);
+ }
+
+ if (snap_context_free) {
+ ED_transform_snap_object_context_destroy(snap_context);
+ }
+ }
+
ipd->orient_axis = plane_axis;
ipd->is_centered_init = (plane_origin == PLACE_ORIGIN_CENTER);
ipd->step[0].is_centered = ipd->is_centered_init;
ipd->step[1].is_centered = ipd->is_centered_init;
ipd->step_index = STEP_BASE;
- /* Assign snap gizmo which is may be used as part of the tool. */
- {
- wmGizmoMap *gzmap = ipd->region->gizmo_map;
- wmGizmoGroup *gzgroup = gzmap ? WM_gizmomap_group_find(gzmap, view3d_gzgt_placement_id) : NULL;
- if ((gzgroup != NULL) && gzgroup->gizmos.first) {
- ipd->snap_gizmo = gzgroup->gizmos.first;
- }
- }
-
{
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "primitive_type");
if (RNA_property_is_set(op->ptr, prop)) {
@@ -618,8 +742,6 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv
plane_from_point_normal_v3(
ipd->step[0].plane, ipd->scene->cursor.location, ipd->matrix_orient[ipd->orient_axis]);
- const float mval_fl[2] = {UNPACK2(event->mval)};
-
const bool is_snap_found = ipd->snap_gizmo ?
idp_snap_point_from_gizmo(ipd->snap_gizmo, ipd->co_src) :
false;
@@ -1102,6 +1224,25 @@ void VIEW3D_OT_interactive_add(struct wmOperatorType *ot)
RNA_def_property_enum_items(prop, origin_items);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ static const EnumPropertyItem plane_orientation_items[] = {
+ {PLACE_ORIENT_SURFACE,
+ "SURFACE",
+ ICON_SNAP_NORMAL,
+ "Surface",
+ "Use the surface normal (the transform orientation as a fallback)"},
+ {PLACE_ORIENT_DEFAULT,
+ "DEFAULT",
+ ICON_ORIENTATION_GLOBAL,
+ "Default",
+ "Use the current transform orientation"},
+ {0, NULL, 0, NULL, NULL},
+ };
+ prop = RNA_def_property(ot->srna, "plane_orientation", PROP_ENUM, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Orientation", "The initial depth used when placing the cursor");
+ RNA_def_property_enum_default(prop, PLACE_ORIENT_SURFACE);
+ RNA_def_property_enum_items(prop, plane_orientation_items);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
/* When not accessed via a tool. */
prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);