2023-05-31 16:19:06 +02:00
|
|
|
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
/** \file
|
|
|
|
* \ingroup edtransform
|
|
|
|
*/
|
|
|
|
|
2023-07-22 03:27:25 +02:00
|
|
|
#include <cstdlib>
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
Cleanup: reduce amount of math-related includes
Using ClangBuildAnalyzer on the whole Blender build, it was pointing
out that BLI_math.h is the heaviest "header hub" (i.e. non tiny file
that is included a lot).
However, there's very little (actually zero) source files in Blender
that need "all the math" (base, colors, vectors, matrices,
quaternions, intersection, interpolation, statistics, solvers and
time). A common use case is source files needing just vectors, or
just vectors & matrices, or just colors etc. Actually, 181 files
were including the whole math thing without needing it at all.
This change removes BLI_math.h completely, and instead in all the
places that need it, includes BLI_math_vector.h or BLI_math_color.h
and so on.
Change from that:
- BLI_math_color.h was included 1399 times -> now 408 (took 114.0sec
to parse -> now 36.3sec)
- BLI_simd.h 1403 -> 418 (109.7sec -> 34.9sec).
Full rebuild of Blender (Apple M1, Xcode, RelWithDebInfo) is not
affected much (342sec -> 334sec). Most of benefit would be when
someone's changing BLI_simd.h or BLI_math_color.h or similar files,
that now there's 3x fewer files result in a recompile.
Pull Request #110944
2023-08-09 10:39:20 +02:00
|
|
|
#include "BLI_math_matrix.h"
|
2020-02-14 12:42:17 +01:00
|
|
|
#include "BLI_string.h"
|
|
|
|
|
2023-11-16 11:41:55 +01:00
|
|
|
#include "BKE_context.hh"
|
|
|
|
#include "BKE_editmesh.hh"
|
2020-02-14 12:42:17 +01:00
|
|
|
#include "BKE_unit.h"
|
|
|
|
|
|
|
|
#include "GPU_immediate.h"
|
|
|
|
#include "GPU_matrix.h"
|
|
|
|
#include "GPU_state.h"
|
|
|
|
|
2023-08-04 23:11:22 +02:00
|
|
|
#include "ED_screen.hh"
|
2020-02-14 12:42:17 +01:00
|
|
|
|
2023-08-04 23:11:22 +02:00
|
|
|
#include "WM_api.hh"
|
|
|
|
#include "WM_types.hh"
|
2020-02-14 12:42:17 +01:00
|
|
|
|
2023-08-10 22:40:27 +02:00
|
|
|
#include "RNA_access.hh"
|
2023-06-02 14:42:27 +02:00
|
|
|
|
2023-08-05 02:57:52 +02:00
|
|
|
#include "UI_interface.hh"
|
|
|
|
#include "UI_resources.hh"
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
#include "BLT_translation.h"
|
|
|
|
|
2023-07-13 17:59:52 +02:00
|
|
|
#include "transform.hh"
|
|
|
|
#include "transform_constraints.hh"
|
|
|
|
#include "transform_convert.hh"
|
|
|
|
#include "transform_mode.hh"
|
|
|
|
#include "transform_snap.hh"
|
2020-02-14 12:42:17 +01:00
|
|
|
|
2023-08-02 20:00:47 +02:00
|
|
|
using namespace blender;
|
|
|
|
|
2020-02-14 12:42:17 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name Transform (Vert Slide)
|
|
|
|
* \{ */
|
|
|
|
|
2023-07-13 17:59:52 +02:00
|
|
|
struct TransDataVertSlideVert {
|
2020-02-15 22:43:58 +01:00
|
|
|
/** #TransDataGenericSlideVert (header) */
|
2023-06-03 00:36:28 +02:00
|
|
|
BMVert *v;
|
2023-07-13 17:59:52 +02:00
|
|
|
LinkNode **cd_loop_groups;
|
2020-02-15 22:43:58 +01:00
|
|
|
float co_orig_3d[3];
|
|
|
|
/* end generic */
|
|
|
|
|
|
|
|
float (*co_link_orig_3d)[3];
|
|
|
|
int co_link_tot;
|
|
|
|
int co_link_curr;
|
2023-07-13 17:59:52 +02:00
|
|
|
};
|
2020-02-15 22:43:58 +01:00
|
|
|
|
2023-07-13 17:59:52 +02:00
|
|
|
struct VertSlideData {
|
2020-02-15 22:43:58 +01:00
|
|
|
TransDataVertSlideVert *sv;
|
|
|
|
int totsv;
|
|
|
|
int curr_sv_index;
|
|
|
|
|
|
|
|
/* result of ED_view3d_ob_project_mat_get */
|
|
|
|
float proj_mat[4][4];
|
2023-07-13 17:59:52 +02:00
|
|
|
};
|
2020-02-15 22:43:58 +01:00
|
|
|
|
2023-07-13 17:59:52 +02:00
|
|
|
struct VertSlideParams {
|
2020-02-15 22:43:58 +01:00
|
|
|
float perc;
|
|
|
|
|
|
|
|
bool use_even;
|
|
|
|
bool flipped;
|
2023-07-13 17:59:52 +02:00
|
|
|
};
|
2020-02-15 22:43:58 +01:00
|
|
|
|
2022-08-26 18:17:30 +02:00
|
|
|
static void vert_slide_update_input(TransInfo *t)
|
2020-02-14 12:42:17 +01:00
|
|
|
{
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideParams *slp = static_cast<VertSlideParams *>(t->custom.mode.data);
|
|
|
|
VertSlideData *sld = static_cast<VertSlideData *>(
|
|
|
|
TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data);
|
2020-02-14 12:42:17 +01:00
|
|
|
TransDataVertSlideVert *sv = &sld->sv[sld->curr_sv_index];
|
|
|
|
|
|
|
|
const float *co_orig_3d = sv->co_orig_3d;
|
|
|
|
const float *co_curr_3d = sv->co_link_orig_3d[sv->co_link_curr];
|
|
|
|
|
|
|
|
float co_curr_2d[2], co_orig_2d[2];
|
|
|
|
|
|
|
|
int mval_ofs[2], mval_start[2], mval_end[2];
|
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
ED_view3d_project_float_v2_m4(t->region, co_orig_3d, co_orig_2d, sld->proj_mat);
|
|
|
|
ED_view3d_project_float_v2_m4(t->region, co_curr_3d, co_curr_2d, sld->proj_mat);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
ARRAY_SET_ITEMS(mval_ofs, t->mouse.imval[0] - co_orig_2d[0], t->mouse.imval[1] - co_orig_2d[1]);
|
|
|
|
ARRAY_SET_ITEMS(mval_start, co_orig_2d[0] + mval_ofs[0], co_orig_2d[1] + mval_ofs[1]);
|
|
|
|
ARRAY_SET_ITEMS(mval_end, co_curr_2d[0] + mval_ofs[0], co_curr_2d[1] + mval_ofs[1]);
|
|
|
|
|
|
|
|
if (slp->flipped && slp->use_even) {
|
|
|
|
setCustomPoints(t, &t->mouse, mval_start, mval_end);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
setCustomPoints(t, &t->mouse, mval_end, mval_start);
|
|
|
|
}
|
2022-08-26 18:17:30 +02:00
|
|
|
}
|
|
|
|
|
2023-06-03 00:36:28 +02:00
|
|
|
static void calcVertSlideCustomPoints(TransInfo *t)
|
2022-08-26 18:17:30 +02:00
|
|
|
{
|
|
|
|
vert_slide_update_input(t);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
/* setCustomPoints isn't normally changing as the mouse moves,
|
|
|
|
* in this case apply mouse input immediately so we don't refresh
|
|
|
|
* with the value from the previous points */
|
|
|
|
applyMouseInput(t, &t->mouse, t->mval, t->values);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run once when initializing vert slide to find the reference edge
|
|
|
|
*/
|
2023-08-02 20:00:47 +02:00
|
|
|
static void calcVertSlideMouseActiveVert(TransInfo *t, const float2 &mval_fl)
|
2020-02-14 12:42:17 +01:00
|
|
|
{
|
|
|
|
/* Active object may have no selected vertices. */
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideData *sld = static_cast<VertSlideData *>(
|
|
|
|
TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data);
|
2020-02-14 12:42:17 +01:00
|
|
|
TransDataVertSlideVert *sv;
|
|
|
|
|
|
|
|
/* set the vertex to use as a reference for the mouse direction 'curr_sv_index' */
|
|
|
|
float dist_sq = 0.0f;
|
|
|
|
float dist_min_sq = FLT_MAX;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0, sv = sld->sv; i < sld->totsv; i++, sv++) {
|
|
|
|
float co_2d[2];
|
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
ED_view3d_project_float_v2_m4(t->region, sv->co_orig_3d, co_2d, sld->proj_mat);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
dist_sq = len_squared_v2v2(mval_fl, co_2d);
|
|
|
|
if (dist_sq < dist_min_sq) {
|
|
|
|
dist_min_sq = dist_sq;
|
|
|
|
sld->curr_sv_index = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run while moving the mouse to slide along the edge matching the mouse direction
|
|
|
|
*/
|
2023-08-02 20:00:47 +02:00
|
|
|
static void calcVertSlideMouseActiveEdges(TransInfo *t, const float2 &mval_fl)
|
2020-02-14 12:42:17 +01:00
|
|
|
{
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideData *sld = static_cast<VertSlideData *>(
|
|
|
|
TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
float dir[3];
|
|
|
|
TransDataVertSlideVert *sv;
|
|
|
|
int i;
|
|
|
|
|
2021-07-03 15:08:40 +02:00
|
|
|
/* NOTE: we could save a matrix-multiply for each vertex
|
2020-02-14 12:42:17 +01:00
|
|
|
* by finding the closest edge in local-space.
|
|
|
|
* However this skews the outcome with non-uniform-scale. */
|
|
|
|
|
2022-03-01 00:56:28 +01:00
|
|
|
/* First get the direction of the original mouse position. */
|
2023-08-02 20:00:47 +02:00
|
|
|
sub_v2_v2v2(dir, t->mouse.imval, mval_fl);
|
2022-03-01 00:56:28 +01:00
|
|
|
ED_view3d_win_to_delta(t->region, dir, t->zfac, dir);
|
2020-02-14 12:42:17 +01:00
|
|
|
normalize_v3(dir);
|
|
|
|
|
|
|
|
for (i = 0, sv = sld->sv; i < sld->totsv; i++, sv++) {
|
|
|
|
if (sv->co_link_tot > 1) {
|
|
|
|
float dir_dot_best = -FLT_MAX;
|
|
|
|
int co_link_curr_best = -1;
|
|
|
|
int j;
|
|
|
|
|
|
|
|
for (j = 0; j < sv->co_link_tot; j++) {
|
|
|
|
float tdir[3];
|
|
|
|
float dir_dot;
|
|
|
|
|
|
|
|
sub_v3_v3v3(tdir, sv->co_orig_3d, sv->co_link_orig_3d[j]);
|
2022-10-24 14:16:37 +02:00
|
|
|
mul_mat3_m4_v3(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world, tdir);
|
2020-02-14 12:42:17 +01:00
|
|
|
project_plane_v3_v3v3(tdir, tdir, t->viewinv[2]);
|
|
|
|
|
|
|
|
normalize_v3(tdir);
|
|
|
|
dir_dot = dot_v3v3(dir, tdir);
|
|
|
|
if (dir_dot > dir_dot_best) {
|
|
|
|
dir_dot_best = dir_dot;
|
|
|
|
co_link_curr_best = j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (co_link_curr_best != -1) {
|
|
|
|
sv->co_link_curr = co_link_curr_best;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-15 14:53:10 +02:00
|
|
|
static VertSlideData *createVertSlideVerts(TransInfo *t, const TransDataContainer *tc)
|
2020-02-14 12:42:17 +01:00
|
|
|
{
|
|
|
|
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
|
|
|
|
BMesh *bm = em->bm;
|
|
|
|
BMIter iter;
|
|
|
|
BMIter eiter;
|
|
|
|
BMEdge *e;
|
|
|
|
BMVert *v;
|
|
|
|
TransDataVertSlideVert *sv_array;
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideData *sld = static_cast<VertSlideData *>(MEM_callocN(sizeof(*sld), "sld"));
|
2020-02-14 12:42:17 +01:00
|
|
|
int j;
|
|
|
|
|
|
|
|
sld->curr_sv_index = 0;
|
|
|
|
|
|
|
|
j = 0;
|
|
|
|
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
|
|
|
bool ok = false;
|
|
|
|
if (BM_elem_flag_test(v, BM_ELEM_SELECT) && v->e) {
|
|
|
|
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
|
|
|
|
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
|
|
|
|
ok = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ok) {
|
|
|
|
BM_elem_flag_enable(v, BM_ELEM_TAG);
|
|
|
|
j += 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
BM_elem_flag_disable(v, BM_ELEM_TAG);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!j) {
|
|
|
|
MEM_freeN(sld);
|
2023-07-13 17:59:52 +02:00
|
|
|
return nullptr;
|
2020-02-14 12:42:17 +01:00
|
|
|
}
|
|
|
|
|
2023-07-13 17:59:52 +02:00
|
|
|
sv_array = static_cast<TransDataVertSlideVert *>(
|
|
|
|
MEM_callocN(sizeof(TransDataVertSlideVert) * j, "sv_array"));
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
j = 0;
|
|
|
|
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
|
|
|
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
|
|
|
|
int k;
|
|
|
|
sv_array[j].v = v;
|
|
|
|
copy_v3_v3(sv_array[j].co_orig_3d, v->co);
|
|
|
|
|
|
|
|
k = 0;
|
|
|
|
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
|
|
|
|
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
|
|
|
|
k++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-13 17:59:52 +02:00
|
|
|
sv_array[j].co_link_orig_3d = static_cast<float(*)[3]>(
|
|
|
|
MEM_mallocN(sizeof(*sv_array[j].co_link_orig_3d) * k, __func__));
|
2020-02-14 12:42:17 +01:00
|
|
|
sv_array[j].co_link_tot = k;
|
|
|
|
|
|
|
|
k = 0;
|
|
|
|
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
|
|
|
|
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
|
|
|
|
BMVert *v_other = BM_edge_other_vert(e, v);
|
|
|
|
copy_v3_v3(sv_array[j].co_link_orig_3d[k], v_other->co);
|
|
|
|
k++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sld->sv = sv_array;
|
|
|
|
sld->totsv = j;
|
|
|
|
|
|
|
|
/* most likely will be set below */
|
|
|
|
unit_m4(sld->proj_mat);
|
|
|
|
|
|
|
|
if (t->spacetype == SPACE_VIEW3D) {
|
|
|
|
/* view vars */
|
2023-07-13 17:59:52 +02:00
|
|
|
RegionView3D *rv3d = nullptr;
|
2020-03-06 16:56:42 +01:00
|
|
|
ARegion *region = t->region;
|
2020-02-14 12:42:17 +01:00
|
|
|
|
2023-07-13 17:59:52 +02:00
|
|
|
rv3d = static_cast<RegionView3D *>(region ? region->regiondata : nullptr);
|
2020-02-14 12:42:17 +01:00
|
|
|
if (rv3d) {
|
|
|
|
ED_view3d_ob_project_mat_get(rv3d, tc->obedit, sld->proj_mat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-15 14:53:10 +02:00
|
|
|
return sld;
|
2020-02-14 12:42:17 +01:00
|
|
|
}
|
|
|
|
|
2023-07-13 17:59:52 +02:00
|
|
|
static void freeVertSlideVerts(TransInfo * /*t*/,
|
|
|
|
TransDataContainer * /*tc*/,
|
2020-02-14 12:42:17 +01:00
|
|
|
TransCustomData *custom_data)
|
|
|
|
{
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideData *sld = static_cast<VertSlideData *>(custom_data->data);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
if (!sld) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sld->totsv > 0) {
|
|
|
|
TransDataVertSlideVert *sv = sld->sv;
|
|
|
|
int i = 0;
|
|
|
|
for (i = 0; i < sld->totsv; i++, sv++) {
|
|
|
|
MEM_freeN(sv->co_link_orig_3d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(sld->sv);
|
|
|
|
MEM_freeN(sld);
|
|
|
|
|
2023-07-13 17:59:52 +02:00
|
|
|
custom_data->data = nullptr;
|
2020-02-14 12:42:17 +01:00
|
|
|
}
|
|
|
|
|
2023-06-03 00:36:28 +02:00
|
|
|
static eRedrawFlag handleEventVertSlide(TransInfo *t, const wmEvent *event)
|
2020-02-14 12:42:17 +01:00
|
|
|
{
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideParams *slp = static_cast<VertSlideParams *>(t->custom.mode.data);
|
2023-06-02 14:42:27 +02:00
|
|
|
|
|
|
|
if (slp) {
|
|
|
|
switch (event->type) {
|
|
|
|
case EVT_EKEY:
|
|
|
|
if (event->val == KM_PRESS) {
|
|
|
|
slp->use_even = !slp->use_even;
|
|
|
|
if (slp->flipped) {
|
2020-02-14 12:42:17 +01:00
|
|
|
calcVertSlideCustomPoints(t);
|
|
|
|
}
|
2023-06-02 14:42:27 +02:00
|
|
|
return TREDRAW_HARD;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EVT_FKEY:
|
|
|
|
if (event->val == KM_PRESS) {
|
|
|
|
slp->flipped = !slp->flipped;
|
2020-02-14 12:42:17 +01:00
|
|
|
calcVertSlideCustomPoints(t);
|
2023-06-02 14:42:27 +02:00
|
|
|
return TREDRAW_HARD;
|
2020-02-14 12:42:17 +01:00
|
|
|
}
|
2023-06-02 14:42:27 +02:00
|
|
|
break;
|
|
|
|
case EVT_CKEY:
|
|
|
|
/* use like a modifier key */
|
|
|
|
if (event->val == KM_PRESS) {
|
|
|
|
t->flag ^= T_ALT_TRANSFORM;
|
|
|
|
calcVertSlideCustomPoints(t);
|
|
|
|
return TREDRAW_HARD;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOUSEMOVE: {
|
|
|
|
/* don't recalculate the best edge */
|
|
|
|
const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
|
|
|
|
if (is_clamp) {
|
2023-08-02 20:00:47 +02:00
|
|
|
calcVertSlideMouseActiveEdges(t, float2(event->mval));
|
2023-06-02 14:42:27 +02:00
|
|
|
}
|
|
|
|
calcVertSlideCustomPoints(t);
|
|
|
|
break;
|
2020-02-14 12:42:17 +01:00
|
|
|
}
|
2023-06-02 14:42:27 +02:00
|
|
|
default:
|
|
|
|
break;
|
2020-02-14 12:42:17 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return TREDRAW_NOTHING;
|
|
|
|
}
|
|
|
|
|
2023-06-02 14:42:27 +02:00
|
|
|
static void drawVertSlide(TransInfo *t)
|
2020-02-14 12:42:17 +01:00
|
|
|
{
|
2023-06-02 14:42:27 +02:00
|
|
|
if (TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data) {
|
2023-07-13 17:59:52 +02:00
|
|
|
const VertSlideParams *slp = static_cast<const VertSlideParams *>(t->custom.mode.data);
|
|
|
|
VertSlideData *sld = static_cast<VertSlideData *>(
|
|
|
|
TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data);
|
2020-02-14 12:42:17 +01:00
|
|
|
const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
|
|
|
|
|
|
|
|
/* Non-Prop mode */
|
|
|
|
{
|
|
|
|
TransDataVertSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
|
|
|
|
TransDataVertSlideVert *sv;
|
|
|
|
const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f;
|
|
|
|
const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f;
|
|
|
|
const int alpha_shade = -160;
|
|
|
|
int i;
|
|
|
|
|
2020-08-20 16:38:34 +02:00
|
|
|
GPU_depth_test(GPU_DEPTH_NONE);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
2020-08-16 15:38:34 +02:00
|
|
|
GPU_blend(GPU_BLEND_ALPHA);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
GPU_matrix_push();
|
2022-10-24 14:16:37 +02:00
|
|
|
GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
GPU_line_width(line_size);
|
|
|
|
|
|
|
|
const uint shdr_pos = GPU_vertformat_attr_add(
|
|
|
|
immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
|
|
|
|
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
|
|
|
immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
|
|
|
|
|
|
|
|
immBegin(GPU_PRIM_LINES, sld->totsv * 2);
|
|
|
|
if (is_clamp) {
|
|
|
|
sv = sld->sv;
|
|
|
|
for (i = 0; i < sld->totsv; i++, sv++) {
|
|
|
|
immVertex3fv(shdr_pos, sv->co_orig_3d);
|
|
|
|
immVertex3fv(shdr_pos, sv->co_link_orig_3d[sv->co_link_curr]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sv = sld->sv;
|
|
|
|
for (i = 0; i < sld->totsv; i++, sv++) {
|
|
|
|
float a[3], b[3];
|
|
|
|
sub_v3_v3v3(a, sv->co_link_orig_3d[sv->co_link_curr], sv->co_orig_3d);
|
|
|
|
mul_v3_fl(a, 100.0f);
|
|
|
|
negate_v3_v3(b, a);
|
|
|
|
add_v3_v3(a, sv->co_orig_3d);
|
|
|
|
add_v3_v3(b, sv->co_orig_3d);
|
|
|
|
|
|
|
|
immVertex3fv(shdr_pos, a);
|
|
|
|
immVertex3fv(shdr_pos, b);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
immEnd();
|
|
|
|
|
|
|
|
GPU_point_size(ctrl_size);
|
|
|
|
|
|
|
|
immBegin(GPU_PRIM_POINTS, 1);
|
|
|
|
immVertex3fv(shdr_pos,
|
|
|
|
(slp->flipped && slp->use_even) ?
|
|
|
|
curr_sv->co_link_orig_3d[curr_sv->co_link_curr] :
|
|
|
|
curr_sv->co_orig_3d);
|
|
|
|
immEnd();
|
|
|
|
|
|
|
|
immUnbindProgram();
|
|
|
|
|
|
|
|
/* direction from active vertex! */
|
2023-08-02 20:00:47 +02:00
|
|
|
if (!compare_v2v2(t->mval, t->mouse.imval, FLT_EPSILON)) {
|
2020-02-14 12:42:17 +01:00
|
|
|
float zfac;
|
|
|
|
float co_orig_3d[3];
|
|
|
|
float co_dest_3d[3];
|
|
|
|
|
2023-08-02 20:00:47 +02:00
|
|
|
float2 xy_delta = t->mval - t->mouse.imval;
|
2020-02-14 12:42:17 +01:00
|
|
|
|
2022-10-24 14:16:37 +02:00
|
|
|
mul_v3_m4v3(co_orig_3d,
|
|
|
|
TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world,
|
|
|
|
curr_sv->co_orig_3d);
|
2023-07-13 17:59:52 +02:00
|
|
|
zfac = ED_view3d_calc_zfac(static_cast<const RegionView3D *>(t->region->regiondata),
|
|
|
|
co_orig_3d);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
2022-03-01 00:56:28 +01:00
|
|
|
ED_view3d_win_to_delta(t->region, xy_delta, zfac, co_dest_3d);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
2022-11-02 14:41:49 +01:00
|
|
|
invert_m4_m4(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->world_to_object,
|
2022-10-24 14:16:37 +02:00
|
|
|
TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world);
|
2022-11-02 14:41:49 +01:00
|
|
|
mul_mat3_m4_v3(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->world_to_object, co_dest_3d);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
add_v3_v3(co_dest_3d, curr_sv->co_orig_3d);
|
|
|
|
|
|
|
|
GPU_line_width(1.0f);
|
|
|
|
|
|
|
|
immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
|
|
|
|
|
|
|
|
float viewport_size[4];
|
|
|
|
GPU_viewport_size_get_f(viewport_size);
|
|
|
|
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
|
|
|
|
|
|
|
|
immUniform1i("colors_len", 0); /* "simple" mode */
|
|
|
|
immUniformColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
|
|
|
immUniform1f("dash_width", 6.0f);
|
2022-12-08 21:07:28 +01:00
|
|
|
immUniform1f("udash_factor", 0.5f);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
immBegin(GPU_PRIM_LINES, 2);
|
|
|
|
immVertex3fv(shdr_pos, curr_sv->co_orig_3d);
|
|
|
|
immVertex3fv(shdr_pos, co_dest_3d);
|
|
|
|
immEnd();
|
|
|
|
|
|
|
|
immUnbindProgram();
|
|
|
|
}
|
|
|
|
|
|
|
|
GPU_matrix_pop();
|
|
|
|
|
2020-08-20 16:38:34 +02:00
|
|
|
GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
|
2020-02-14 12:42:17 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-03 15:29:16 +01:00
|
|
|
static void vert_slide_apply_elem(const TransDataVertSlideVert *sv,
|
|
|
|
const float perc,
|
|
|
|
const bool use_even,
|
|
|
|
const bool use_flip,
|
|
|
|
float r_co[3])
|
|
|
|
{
|
|
|
|
if (use_even == false) {
|
|
|
|
interp_v3_v3v3(r_co, sv->co_orig_3d, sv->co_link_orig_3d[sv->co_link_curr], perc);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
float dir[3];
|
|
|
|
sub_v3_v3v3(dir, sv->co_link_orig_3d[sv->co_link_curr], sv->co_orig_3d);
|
|
|
|
float edge_len = normalize_v3(dir);
|
|
|
|
if (edge_len > FLT_EPSILON) {
|
|
|
|
if (use_flip) {
|
|
|
|
madd_v3_v3v3fl(r_co, sv->co_link_orig_3d[sv->co_link_curr], dir, -perc);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
madd_v3_v3v3fl(r_co, sv->co_orig_3d, dir, perc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
copy_v3_v3(r_co, sv->co_orig_3d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 19:53:23 +02:00
|
|
|
static void doVertSlide(TransInfo *t, float perc)
|
2020-02-14 12:42:17 +01:00
|
|
|
{
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideParams *slp = static_cast<VertSlideParams *>(t->custom.mode.data);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
slp->perc = perc;
|
|
|
|
|
2023-02-03 15:29:16 +01:00
|
|
|
const bool use_even = slp->use_even;
|
|
|
|
|
2020-02-14 12:42:17 +01:00
|
|
|
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideData *sld = static_cast<VertSlideData *>(tc->custom.mode.data);
|
|
|
|
if (sld == nullptr) {
|
2020-07-14 14:30:54 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2023-02-03 15:29:16 +01:00
|
|
|
float tperc = perc;
|
|
|
|
if (use_even) {
|
2020-02-14 12:42:17 +01:00
|
|
|
TransDataVertSlideVert *sv_curr = &sld->sv[sld->curr_sv_index];
|
|
|
|
const float edge_len_curr = len_v3v3(sv_curr->co_orig_3d,
|
|
|
|
sv_curr->co_link_orig_3d[sv_curr->co_link_curr]);
|
2023-02-03 15:29:16 +01:00
|
|
|
tperc *= edge_len_curr;
|
|
|
|
}
|
2020-02-14 12:42:17 +01:00
|
|
|
|
2023-02-03 15:29:16 +01:00
|
|
|
TransDataVertSlideVert *sv = sld->sv;
|
|
|
|
for (int i = 0; i < sld->totsv; i++, sv++) {
|
|
|
|
vert_slide_apply_elem(sv, tperc, use_even, slp->flipped, sv->v->co);
|
2020-02-14 12:42:17 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-22 14:07:51 +02:00
|
|
|
static void vert_slide_snap_apply(TransInfo *t, float *value)
|
|
|
|
{
|
|
|
|
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_OK(t);
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideData *sld = static_cast<VertSlideData *>(tc->custom.mode.data);
|
2020-06-22 14:07:51 +02:00
|
|
|
TransDataVertSlideVert *sv = &sld->sv[sld->curr_sv_index];
|
|
|
|
|
|
|
|
float snap_point[3], co_orig_3d[3], co_curr_3d[3], dvec[3];
|
|
|
|
copy_v3_v3(co_orig_3d, sv->co_orig_3d);
|
|
|
|
copy_v3_v3(co_curr_3d, sv->co_link_orig_3d[sv->co_link_curr]);
|
|
|
|
if (tc->use_local_mat) {
|
|
|
|
mul_m4_v3(tc->mat, co_orig_3d);
|
|
|
|
mul_m4_v3(tc->mat, co_curr_3d);
|
|
|
|
}
|
|
|
|
|
|
|
|
getSnapPoint(t, dvec);
|
2023-01-12 14:16:25 +01:00
|
|
|
sub_v3_v3(dvec, t->tsnap.snap_source);
|
2023-06-23 20:36:57 +02:00
|
|
|
if (t->tsnap.target_type & (SCE_SNAP_TO_EDGE | SCE_SNAP_TO_FACE)) {
|
2020-07-01 22:17:05 +02:00
|
|
|
float co_dir[3];
|
|
|
|
sub_v3_v3v3(co_dir, co_curr_3d, co_orig_3d);
|
|
|
|
normalize_v3(co_dir);
|
2023-06-23 20:36:57 +02:00
|
|
|
if (t->tsnap.target_type & SCE_SNAP_TO_EDGE) {
|
2020-07-01 22:17:05 +02:00
|
|
|
transform_constraint_snap_axis_to_edge(t, co_dir, dvec);
|
2020-06-22 14:07:51 +02:00
|
|
|
}
|
|
|
|
else {
|
2020-07-01 22:17:05 +02:00
|
|
|
transform_constraint_snap_axis_to_face(t, co_dir, dvec);
|
2020-06-22 14:07:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
add_v3_v3v3(snap_point, co_orig_3d, dvec);
|
|
|
|
*value = line_point_factor_v3(snap_point, co_orig_3d, co_curr_3d);
|
|
|
|
}
|
|
|
|
|
2023-08-02 20:03:58 +02:00
|
|
|
static void applyVertSlide(TransInfo *t)
|
2020-02-14 12:42:17 +01:00
|
|
|
{
|
|
|
|
char str[UI_MAX_DRAW_STR];
|
|
|
|
size_t ofs = 0;
|
|
|
|
float final;
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideParams *slp = static_cast<VertSlideParams *>(t->custom.mode.data);
|
2020-02-14 12:42:17 +01:00
|
|
|
const bool flipped = slp->flipped;
|
|
|
|
const bool use_even = slp->use_even;
|
|
|
|
const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
|
|
|
|
const bool is_constrained = !(is_clamp == false || hasNumInput(&t->num));
|
|
|
|
|
2021-12-08 18:20:03 +01:00
|
|
|
final = t->values[0] + t->values_modal_offset[0];
|
2020-02-14 12:42:17 +01:00
|
|
|
|
2023-01-10 03:45:12 +01:00
|
|
|
transform_snap_mixed_apply(t, &final);
|
2020-08-31 15:14:40 +02:00
|
|
|
if (!validSnap(t)) {
|
|
|
|
transform_snap_increment(t, &final);
|
|
|
|
}
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
/* only do this so out of range values are not displayed */
|
|
|
|
if (is_constrained) {
|
|
|
|
CLAMP(final, 0.0f, 1.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
applyNumInput(&t->num, &final);
|
|
|
|
|
|
|
|
t->values_final[0] = final;
|
|
|
|
|
|
|
|
/* header string */
|
2020-07-22 08:21:33 +02:00
|
|
|
ofs += BLI_strncpy_rlen(str + ofs, TIP_("Vertex Slide: "), sizeof(str) - ofs);
|
2020-02-14 12:42:17 +01:00
|
|
|
if (hasNumInput(&t->num)) {
|
|
|
|
char c[NUM_STR_REP_LEN];
|
|
|
|
outputNumInput(&(t->num), c, &t->scene->unit);
|
|
|
|
ofs += BLI_strncpy_rlen(str + ofs, &c[0], sizeof(str) - ofs);
|
|
|
|
}
|
|
|
|
else {
|
2021-05-27 09:16:08 +02:00
|
|
|
ofs += BLI_snprintf_rlen(str + ofs, sizeof(str) - ofs, "%.4f ", final);
|
2020-02-14 12:42:17 +01:00
|
|
|
}
|
2021-05-27 09:16:08 +02:00
|
|
|
ofs += BLI_snprintf_rlen(
|
2020-02-14 12:42:17 +01:00
|
|
|
str + ofs, sizeof(str) - ofs, TIP_("(E)ven: %s, "), WM_bool_as_string(use_even));
|
|
|
|
if (use_even) {
|
2021-05-27 09:16:08 +02:00
|
|
|
ofs += BLI_snprintf_rlen(
|
2020-02-14 12:42:17 +01:00
|
|
|
str + ofs, sizeof(str) - ofs, TIP_("(F)lipped: %s, "), WM_bool_as_string(flipped));
|
|
|
|
}
|
2021-05-27 09:16:08 +02:00
|
|
|
ofs += BLI_snprintf_rlen(
|
2020-02-14 12:42:17 +01:00
|
|
|
str + ofs, sizeof(str) - ofs, TIP_("Alt or (C)lamp: %s"), WM_bool_as_string(is_clamp));
|
|
|
|
/* done with header string */
|
|
|
|
|
|
|
|
/* do stuff here */
|
|
|
|
doVertSlide(t, final);
|
|
|
|
|
2023-07-27 04:04:18 +02:00
|
|
|
recalc_data(t);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
2020-04-03 13:25:03 +02:00
|
|
|
ED_area_status_text(t->area, str);
|
2020-02-14 12:42:17 +01:00
|
|
|
}
|
|
|
|
|
2023-06-04 10:46:04 +02:00
|
|
|
static void vert_slide_transform_matrix_fn(TransInfo *t, float mat_xform[4][4])
|
Transform: new feature to edit the 'Snap Base'
This commit implements a new modifier key (`B`) for the transform
operators.
This new key allows changing the 'Snap Base' of a transform by snapping
it to a defined point in the scene.
Ref #66424
# Implementation Details
- This feature is only available in the 3D View.
- This feature is only available for the transform modes:
- `Move`,
- `Rotate`,
- `Scale`,
- `Vert Slide` and
- `Edge Slide`.
- The `Snap Base Edit` is enabled while we are transforming and we
press the key `B`
- The `Snap Base Edit` is confirmed when we press any of the keys:
`B`, `LMB`, `Enter`
- During um operation, if no snap target is set for an element in the
scene (Vertex, Edge...), the snap targets to geometry Vertex, Edge,
Face, Center of Edge and Perpendicular of Edge are set automatically.
- Constraint or similar modal features are not available during the
`Snap Base Edit` mode.
- Text input is not available during the `Snap Base Edit` mode.
- A prone snap base point is indicated with an small cursor drawing.
Pull Request: https://projects.blender.org/blender/blender/pulls/104443
2023-06-03 04:18:49 +02:00
|
|
|
{
|
|
|
|
float delta[3], orig_co[3], final_co[3];
|
|
|
|
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideParams *slp = static_cast<VertSlideParams *>(t->custom.mode.data);
|
Transform: new feature to edit the 'Snap Base'
This commit implements a new modifier key (`B`) for the transform
operators.
This new key allows changing the 'Snap Base' of a transform by snapping
it to a defined point in the scene.
Ref #66424
# Implementation Details
- This feature is only available in the 3D View.
- This feature is only available for the transform modes:
- `Move`,
- `Rotate`,
- `Scale`,
- `Vert Slide` and
- `Edge Slide`.
- The `Snap Base Edit` is enabled while we are transforming and we
press the key `B`
- The `Snap Base Edit` is confirmed when we press any of the keys:
`B`, `LMB`, `Enter`
- During um operation, if no snap target is set for an element in the
scene (Vertex, Edge...), the snap targets to geometry Vertex, Edge,
Face, Center of Edge and Perpendicular of Edge are set automatically.
- Constraint or similar modal features are not available during the
`Snap Base Edit` mode.
- Text input is not available during the `Snap Base Edit` mode.
- A prone snap base point is indicated with an small cursor drawing.
Pull Request: https://projects.blender.org/blender/blender/pulls/104443
2023-06-03 04:18:49 +02:00
|
|
|
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_OK(t);
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideData *sld_active = static_cast<VertSlideData *>(tc->custom.mode.data);
|
Transform: new feature to edit the 'Snap Base'
This commit implements a new modifier key (`B`) for the transform
operators.
This new key allows changing the 'Snap Base' of a transform by snapping
it to a defined point in the scene.
Ref #66424
# Implementation Details
- This feature is only available in the 3D View.
- This feature is only available for the transform modes:
- `Move`,
- `Rotate`,
- `Scale`,
- `Vert Slide` and
- `Edge Slide`.
- The `Snap Base Edit` is enabled while we are transforming and we
press the key `B`
- The `Snap Base Edit` is confirmed when we press any of the keys:
`B`, `LMB`, `Enter`
- During um operation, if no snap target is set for an element in the
scene (Vertex, Edge...), the snap targets to geometry Vertex, Edge,
Face, Center of Edge and Perpendicular of Edge are set automatically.
- Constraint or similar modal features are not available during the
`Snap Base Edit` mode.
- Text input is not available during the `Snap Base Edit` mode.
- A prone snap base point is indicated with an small cursor drawing.
Pull Request: https://projects.blender.org/blender/blender/pulls/104443
2023-06-03 04:18:49 +02:00
|
|
|
TransDataVertSlideVert *sv_active = &sld_active->sv[sld_active->curr_sv_index];
|
|
|
|
|
|
|
|
copy_v3_v3(orig_co, sv_active->co_orig_3d);
|
|
|
|
|
|
|
|
float tperc = t->values_final[0];
|
|
|
|
if (slp->use_even) {
|
|
|
|
const float edge_len_curr = len_v3v3(sv_active->co_orig_3d,
|
|
|
|
sv_active->co_link_orig_3d[sv_active->co_link_curr]);
|
|
|
|
tperc *= edge_len_curr;
|
|
|
|
}
|
|
|
|
|
|
|
|
vert_slide_apply_elem(sv_active, tperc, slp->use_even, slp->flipped, final_co);
|
|
|
|
|
|
|
|
if (tc->use_local_mat) {
|
|
|
|
mul_m4_v3(tc->mat, orig_co);
|
|
|
|
mul_m4_v3(tc->mat, final_co);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub_v3_v3v3(delta, final_co, orig_co);
|
|
|
|
add_v3_v3(mat_xform[3], delta);
|
|
|
|
}
|
|
|
|
|
2023-06-02 14:42:27 +02:00
|
|
|
static void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp)
|
2020-02-14 12:42:17 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
t->mode = TFM_VERT_SLIDE;
|
|
|
|
|
|
|
|
{
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideParams *slp = static_cast<VertSlideParams *>(MEM_callocN(sizeof(*slp), __func__));
|
2020-02-14 12:42:17 +01:00
|
|
|
slp->use_even = use_even;
|
|
|
|
slp->flipped = flipped;
|
|
|
|
slp->perc = 0.0f;
|
|
|
|
|
|
|
|
if (!use_clamp) {
|
|
|
|
t->flag |= T_ALT_TRANSFORM;
|
|
|
|
}
|
|
|
|
|
|
|
|
t->custom.mode.data = slp;
|
|
|
|
t->custom.mode.use_free = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ok = false;
|
|
|
|
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
2020-06-15 14:53:10 +02:00
|
|
|
VertSlideData *sld = createVertSlideVerts(t, tc);
|
2020-02-14 12:42:17 +01:00
|
|
|
if (sld) {
|
2020-06-15 14:53:10 +02:00
|
|
|
tc->custom.mode.data = sld;
|
2020-02-14 12:42:17 +01:00
|
|
|
tc->custom.mode.free_cb = freeVertSlideVerts;
|
2020-06-15 14:53:10 +02:00
|
|
|
ok = true;
|
2020-02-14 12:42:17 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ok == false) {
|
|
|
|
t->state = TRANS_CANCEL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-06-15 14:53:10 +02:00
|
|
|
calcVertSlideMouseActiveVert(t, t->mval);
|
|
|
|
calcVertSlideMouseActiveEdges(t, t->mval);
|
2020-02-14 12:42:17 +01:00
|
|
|
|
|
|
|
/* set custom point first if you want value to be initialized by init */
|
|
|
|
calcVertSlideCustomPoints(t);
|
|
|
|
initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
|
|
|
|
|
|
|
|
t->idx_max = 0;
|
|
|
|
t->num.idx_max = 0;
|
2020-10-08 14:45:45 +02:00
|
|
|
t->snap[0] = 0.1f;
|
|
|
|
t->snap[1] = t->snap[0] * 0.1f;
|
2020-02-14 12:42:17 +01:00
|
|
|
|
2020-10-08 14:45:45 +02:00
|
|
|
copy_v3_fl(t->num.val_inc, t->snap[0]);
|
2020-02-14 12:42:17 +01:00
|
|
|
t->num.unit_sys = t->scene->unit.system;
|
|
|
|
t->num.unit_type[0] = B_UNIT_NONE;
|
|
|
|
}
|
|
|
|
|
2023-06-02 14:42:27 +02:00
|
|
|
static void initVertSlide(TransInfo *t, wmOperator *op)
|
2020-02-14 12:42:17 +01:00
|
|
|
{
|
2023-06-02 14:42:27 +02:00
|
|
|
bool use_even = false;
|
|
|
|
bool flipped = false;
|
|
|
|
bool use_clamp = true;
|
|
|
|
if (op) {
|
|
|
|
use_even = RNA_boolean_get(op->ptr, "use_even");
|
|
|
|
flipped = RNA_boolean_get(op->ptr, "flipped");
|
|
|
|
use_clamp = RNA_boolean_get(op->ptr, "use_clamp");
|
|
|
|
}
|
|
|
|
initVertSlide_ex(t, use_even, flipped, use_clamp);
|
2020-02-14 12:42:17 +01:00
|
|
|
}
|
2021-12-14 05:49:31 +01:00
|
|
|
|
2020-02-14 12:42:17 +01:00
|
|
|
/** \} */
|
2022-08-26 18:17:30 +02:00
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/** \name Mouse Input Utilities
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
void transform_mode_vert_slide_reproject_input(TransInfo *t)
|
|
|
|
{
|
|
|
|
if (t->spacetype == SPACE_VIEW3D) {
|
2023-07-13 17:59:52 +02:00
|
|
|
RegionView3D *rv3d = static_cast<RegionView3D *>(t->region->regiondata);
|
2022-08-26 18:17:30 +02:00
|
|
|
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
2023-07-13 17:59:52 +02:00
|
|
|
VertSlideData *sld = static_cast<VertSlideData *>(tc->custom.mode.data);
|
2022-08-26 18:17:30 +02:00
|
|
|
ED_view3d_ob_project_mat_get(rv3d, tc->obedit, sld->proj_mat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vert_slide_update_input(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \} */
|
2023-06-02 14:42:27 +02:00
|
|
|
|
|
|
|
TransModeInfo TransMode_vertslide = {
|
2023-07-03 17:30:56 +02:00
|
|
|
/*flags*/ T_NO_CONSTRAINT,
|
2023-06-02 14:42:27 +02:00
|
|
|
/*init_fn*/ initVertSlide,
|
|
|
|
/*transform_fn*/ applyVertSlide,
|
Transform: new feature to edit the 'Snap Base'
This commit implements a new modifier key (`B`) for the transform
operators.
This new key allows changing the 'Snap Base' of a transform by snapping
it to a defined point in the scene.
Ref #66424
# Implementation Details
- This feature is only available in the 3D View.
- This feature is only available for the transform modes:
- `Move`,
- `Rotate`,
- `Scale`,
- `Vert Slide` and
- `Edge Slide`.
- The `Snap Base Edit` is enabled while we are transforming and we
press the key `B`
- The `Snap Base Edit` is confirmed when we press any of the keys:
`B`, `LMB`, `Enter`
- During um operation, if no snap target is set for an element in the
scene (Vertex, Edge...), the snap targets to geometry Vertex, Edge,
Face, Center of Edge and Perpendicular of Edge are set automatically.
- Constraint or similar modal features are not available during the
`Snap Base Edit` mode.
- Text input is not available during the `Snap Base Edit` mode.
- A prone snap base point is indicated with an small cursor drawing.
Pull Request: https://projects.blender.org/blender/blender/pulls/104443
2023-06-03 04:18:49 +02:00
|
|
|
/*transform_matrix_fn*/ vert_slide_transform_matrix_fn,
|
2023-06-02 14:42:27 +02:00
|
|
|
/*handle_event_fn*/ handleEventVertSlide,
|
|
|
|
/*snap_distance_fn*/ transform_snap_distance_len_squared_fn,
|
|
|
|
/*snap_apply_fn*/ vert_slide_snap_apply,
|
|
|
|
/*draw_fn*/ drawVertSlide,
|
|
|
|
};
|