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:
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r--source/blender/editors/transform/transform.c24
-rw-r--r--source/blender/editors/transform/transform.h3
-rw-r--r--source/blender/editors/transform/transform_constraints.c9
-rw-r--r--source/blender/editors/transform/transform_conversions.c170
-rw-r--r--source/blender/editors/transform/transform_generics.c22
-rw-r--r--source/blender/editors/transform/transform_ops.c3
-rw-r--r--source/blender/editors/transform/transform_snap.c30
-rw-r--r--source/blender/editors/transform/transform_snap_object.c105
8 files changed, 233 insertions, 133 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index fb1543c5deb..366dcc4dc21 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1717,9 +1717,10 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
projectFloatViewEx(t, vecrot, cent, V3D_PROJ_TEST_CLIP_ZERO);
- gpuMatrixBegin3D_legacy(); /* TODO(merwin): finish the 2D matrix API & use here */
+ gpuPushMatrix();
unsigned pos = add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
+ UNUSED_VARS(pos); /* silence warning */
BLI_assert(pos == POS_INDEX);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1824,7 +1825,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
}
immUnbindProgram();
- gpuMatrixEnd();
+ gpuPopMatrix();
}
}
@@ -2191,7 +2192,14 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
calculateCenter(t);
if (event) {
- initMouseInput(t, &t->mouse, t->center2d, event->mval, event->shift);
+ /* Initialize accurate transform to settings requested by keymap. */
+ bool use_accurate = false;
+ if ((prop = RNA_struct_find_property(op->ptr, "use_accurate")) && RNA_property_is_set(op->ptr, prop)) {
+ if (RNA_property_boolean_get(op->ptr, prop)) {
+ use_accurate = true;
+ }
+ }
+ initMouseInput(t, &t->mouse, t->center2d, event->mval, use_accurate);
}
switch (mode) {
@@ -6841,8 +6849,7 @@ static void drawEdgeSlide(TransInfo *t)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- gpuMatrixBegin3D_legacy();
-
+ gpuPushMatrix();
gpuMultMatrix3D(t->obedit->obmat);
unsigned pos = add_attrib(immVertexFormat(), "pos", COMP_F32, 3, KEEP_FLOAT);
@@ -6930,7 +6937,7 @@ static void drawEdgeSlide(TransInfo *t)
immUnbindProgram();
- gpuMatrixEnd();
+ gpuPopMatrix();
glDisable(GL_BLEND);
@@ -7454,8 +7461,7 @@ static void drawVertSlide(TransInfo *t)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- gpuMatrixBegin3D_legacy();
-
+ gpuPushMatrix();
gpuMultMatrix3D(t->obedit->obmat);
glLineWidth(line_size);
@@ -7534,7 +7540,7 @@ static void drawVertSlide(TransInfo *t)
immUnbindProgram();
- gpuMatrixEnd();
+ gpuPopMatrix();
if (v3d && v3d->zbuf)
glEnable(GL_DEPTH_TEST);
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 31af54c030b..a292b27e2b3 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -50,6 +50,7 @@ struct Object;
struct View3D;
struct ScrArea;
struct Scene;
+struct SceneLayer;
struct bConstraint;
struct wmKeyMap;
struct wmKeyConfig;
@@ -644,7 +645,7 @@ bool transdata_check_local_islands(TransInfo *t, short around);
int count_set_pose_transflags(int *out_mode, short around, struct Object *ob);
/* auto-keying stuff used by special_aftertrans_update */
-void autokeyframe_ob_cb_func(struct bContext *C, struct Scene *scene, struct View3D *v3d, struct Object *ob, int tmode);
+void autokeyframe_ob_cb_func(struct bContext *C, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct Object *ob, int tmode);
void autokeyframe_pose_cb_func(struct bContext *C, struct Scene *scene, struct View3D *v3d, struct Object *ob, int tmode, short targetless_ik);
/*********************** Constraints *****************************/
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index d123d9eb3c1..5936f215c62 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -43,6 +43,7 @@
#include "BIF_glutil.h"
#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -778,13 +779,13 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
unit_m4(imat);
}
- glPushMatrix();
+ gpuPushMatrix();
if (t->spacetype == SPACE_VIEW3D) {
/* pass */
}
else if (t->spacetype == SPACE_IMAGE) {
- glScalef(1.0f / t->aspect[0], 1.0f / t->aspect[1], 1.0f);
+ gpuScale2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]);
}
else if (ELEM(t->spacetype, SPACE_IPO, SPACE_ACTION)) {
/* only scale y */
@@ -794,7 +795,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
float ysize = BLI_rctf_size_y(datamask);
float xmask = BLI_rcti_size_x(mask);
float ymask = BLI_rcti_size_y(mask);
- glScalef(1.0f, (ysize / xsize) * (xmask / ymask), 1.0f);
+ gpuScale2f(1.0f, (ysize / xsize) * (xmask / ymask));
}
depth_test_enabled = glIsEnabled(GL_DEPTH_TEST);
@@ -815,7 +816,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
if (depth_test_enabled)
glEnable(GL_DEPTH_TEST);
- glPopMatrix();
+ gpuPopMatrix();
}
}
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index b68b3365e46..c09434a3bc9 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -286,13 +286,13 @@ static void set_prop_dist(TransInfo *t, const bool with_dist)
static void createTransTexspace(TransInfo *t)
{
- Scene *scene = t->scene;
+ SceneLayer *sl = t->sl;
TransData *td;
Object *ob;
ID *id;
short *texflag;
- ob = OBACT;
+ ob = OBACT_NEW;
if (ob == NULL) { // Shouldn't logically happen, but still...
t->total = 0;
@@ -1800,7 +1800,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
Base *base = CTX_data_active_base(C);
Object *ob = CTX_data_active_object(C);
ParticleEditSettings *pset = PE_settings(t->scene);
- PTCacheEdit *edit = PE_get_current(t->scene, ob);
+ PTCacheEdit *edit = PE_get_current(t->scene, t->sl, ob);
ParticleSystem *psys = NULL;
ParticleSystemModifierData *psmd = NULL;
PTCacheEditPoint *point;
@@ -1917,8 +1917,9 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
void flushTransParticles(TransInfo *t)
{
Scene *scene = t->scene;
- Object *ob = OBACT;
- PTCacheEdit *edit = PE_get_current(scene, ob);
+ SceneLayer *sl = t->sl;
+ Object *ob = OBACT_NEW;
+ PTCacheEdit *edit = PE_get_current(scene, sl, ob);
ParticleSystem *psys = edit->psys;
ParticleSystemModifierData *psmd = NULL;
PTCacheEditPoint *point;
@@ -1957,14 +1958,17 @@ void flushTransParticles(TransInfo *t)
point->flag |= PEP_EDIT_RECALC;
}
- PE_update_object(scene, OBACT, 1);
+ PE_update_object(scene, sl, OBACT_NEW, 1);
}
/* ********************* mesh ****************** */
-static bool bmesh_test_dist_add(BMVert *v, BMVert *v_other,
- float *dists, const float *dists_prev,
- float mtx[3][3])
+static bool bmesh_test_dist_add(
+ BMVert *v, BMVert *v_other,
+ float *dists, const float *dists_prev,
+ /* optionally track original index */
+ int *index, const int *index_prev,
+ float mtx[3][3])
{
if ((BM_elem_flag_test(v_other, BM_ELEM_SELECT) == 0) &&
(BM_elem_flag_test(v_other, BM_ELEM_HIDDEN) == 0))
@@ -1979,6 +1983,9 @@ static bool bmesh_test_dist_add(BMVert *v, BMVert *v_other,
dist_other = dists_prev[i] + len_v3(vec);
if (dist_other < dists[i_other]) {
dists[i_other] = dist_other;
+ if (index != NULL) {
+ index[i_other] = index_prev[i];
+ }
return true;
}
}
@@ -1986,11 +1993,13 @@ static bool bmesh_test_dist_add(BMVert *v, BMVert *v_other,
return false;
}
-static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float *dists)
+/**
+ * \parm mtx: Measure disatnce in this space.
+ * \parm dists: Store the closest connected distance to selected vertices.
+ * \parm index: Optionally store the original index we're measuring the distance to (can be NULL).
+ */
+static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float *dists, int *index)
{
- /* need to be very careful of feedback loops here, store previous dist's to avoid feedback */
- float *dists_prev = MEM_mallocN(bm->totvert * sizeof(float), __func__);
-
BLI_LINKSTACK_DECLARE(queue, BMVert *);
/* any BM_ELEM_TAG'd vertex is in 'queue_next', so we don't add in twice */
@@ -2011,17 +2020,27 @@ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float
if (BM_elem_flag_test(v, BM_ELEM_SELECT) == 0 || BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
dist = FLT_MAX;
+ if (index != NULL) {
+ index[i] = i;
+ }
}
else {
BLI_LINKSTACK_PUSH(queue, v);
dist = 0.0f;
+ if (index != NULL) {
+ index[i] = i;
+ }
}
- dists[i] = dists_prev[i] = dist;
+ dists[i] = dist;
}
bm->elem_index_dirty &= ~BM_VERT;
}
+ /* need to be very careful of feedback loops here, store previous dist's to avoid feedback */
+ float *dists_prev = MEM_dupallocN(dists);
+ int *index_prev = MEM_dupallocN(index); /* may be NULL */
+
do {
BMVert *v;
LinkNode *lnk;
@@ -2050,7 +2069,7 @@ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float
/* edge distance */
{
BMVert *v_other = BM_edge_other_vert(e_iter, v);
- if (bmesh_test_dist_add(v, v_other, dists, dists_prev, mtx)) {
+ if (bmesh_test_dist_add(v, v_other, dists, dists_prev, index, index_prev, mtx)) {
if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
BM_elem_flag_enable(v_other, BM_ELEM_TAG);
BLI_LINKSTACK_PUSH(queue_next, v_other);
@@ -2075,7 +2094,7 @@ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float
(BM_elem_flag_test(l_iter_radial->f, BM_ELEM_HIDDEN) == 0))
{
BMVert *v_other = l_iter_radial->next->next->v;
- if (bmesh_test_dist_add(v, v_other, dists, dists_prev, mtx)) {
+ if (bmesh_test_dist_add(v, v_other, dists, dists_prev, index, index_prev, mtx)) {
if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
BM_elem_flag_enable(v_other, BM_ELEM_TAG);
BLI_LINKSTACK_PUSH(queue_next, v_other);
@@ -2099,6 +2118,9 @@ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float
/* keep in sync, avoid having to do full memcpy each iteration */
dists_prev[i] = dists[i];
+ if (index != NULL) {
+ index_prev[i] = index[i];
+ }
}
BLI_LINKSTACK_SWAP(queue, queue_next);
@@ -2112,9 +2134,14 @@ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float
BLI_LINKSTACK_FREE(queue_next);
MEM_freeN(dists_prev);
+ if (index_prev != NULL) {
+ MEM_freeN(index_prev);
+ }
}
-static struct TransIslandData *editmesh_islands_info_calc(BMEditMesh *em, int *r_island_tot, int **r_island_vert_map)
+static struct TransIslandData *editmesh_islands_info_calc(
+ BMEditMesh *em, int *r_island_tot, int **r_island_vert_map,
+ bool calc_single_islands)
{
BMesh *bm = em->bm;
struct TransIslandData *trans_islands;
@@ -2226,6 +2253,42 @@ static struct TransIslandData *editmesh_islands_info_calc(BMEditMesh *em, int *r
MEM_freeN(groups_array);
MEM_freeN(group_index);
+ /* for PET we need islands of 1 so connected vertices can use it with V3D_AROUND_LOCAL_ORIGINS */
+ if (calc_single_islands) {
+ BMIter viter;
+ BMVert *v;
+ int group_tot_single = 0;
+
+ BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
+ group_tot_single += 1;
+ }
+ }
+
+ if (group_tot_single != 0) {
+ trans_islands = MEM_reallocN(trans_islands, group_tot + group_tot_single);
+
+ BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
+ struct TransIslandData *v_island = &trans_islands[group_tot];
+ vert_map[i] = group_tot;
+
+ copy_v3_v3(v_island->co, v->co);
+
+ if (is_zero_v3(v->no) != 0.0f) {
+ axis_dominant_v3_to_m3(v_island->axismtx, v->no);
+ invert_m3(v_island->axismtx);
+ }
+ else {
+ unit_m3(v_island->axismtx);
+ }
+
+ group_tot += 1;
+ }
+ }
+ }
+ }
+
*r_island_tot = group_tot;
*r_island_vert_map = vert_map;
@@ -2325,6 +2388,11 @@ static void createTransEditVerts(TransInfo *t)
int island_info_tot;
int *island_vert_map = NULL;
+ const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS) && (t->mode != TFM_TRANSLATION);
+ /* Original index of our connected vertex when connected distances are calculated.
+ * Optional, allocate if needed. */
+ int *dists_index = NULL;
+
if (t->flag & T_MIRROR) {
EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology);
mirror = 1;
@@ -2356,8 +2424,12 @@ static void createTransEditVerts(TransInfo *t)
t->total = count;
/* allocating scratch arrays */
- if (prop_mode & T_PROP_CONNECTED)
- dists = MEM_mallocN(em->bm->totvert * sizeof(float), "scratch nears");
+ if (prop_mode & T_PROP_CONNECTED) {
+ dists = MEM_mallocN(em->bm->totvert * sizeof(float), __func__);
+ if (is_island_center) {
+ dists_index = MEM_mallocN(em->bm->totvert * sizeof(int), __func__);
+ }
+ }
}
else {
t->total = bm->totvertsel;
@@ -2379,7 +2451,7 @@ static void createTransEditVerts(TransInfo *t)
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
if (prop_mode & T_PROP_CONNECTED) {
- editmesh_set_connectivity_distance(em->bm, mtx, dists);
+ editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index);
}
/* Only in case of rotation and resize, we want the elements of the edited
@@ -2387,8 +2459,14 @@ static void createTransEditVerts(TransInfo *t)
*
* TODO: use island_info to detect the closest point when the "Snap Target"
* in Blender UI is "Closest" */
- if ((t->around == V3D_AROUND_LOCAL_ORIGINS) && (t->mode != TFM_TRANSLATION)) {
- island_info = editmesh_islands_info_calc(em, &island_info_tot, &island_vert_map);
+ if (is_island_center) {
+ /* In this specific case, near-by vertices will need to know the island of the nearest connected vertex. */
+ const bool calc_single_islands = (
+ (prop_mode & T_PROP_CONNECTED) &&
+ (t->around == V3D_AROUND_LOCAL_ORIGINS) &&
+ (em->selectmode & SCE_SELECT_VERTEX));
+
+ island_info = editmesh_islands_info_calc(em, &island_info_tot, &island_vert_map, calc_single_islands);
}
/* detect CrazySpace [tm] */
@@ -2438,10 +2516,16 @@ static void createTransEditVerts(TransInfo *t)
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- struct TransIslandData *v_island = (island_info && island_vert_map[a] != -1) ?
- &island_info[island_vert_map[a]] : NULL;
+ struct TransIslandData *v_island = NULL;
float *bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) : NULL;
+ if (island_info) {
+ const int connected_index = (dists_index && dists_index[a] != -1) ? dists_index[a] : a;
+ v_island = (island_vert_map[connected_index] != -1) ?
+ &island_info[island_vert_map[connected_index]] : NULL;
+ }
+
+
VertsToTransData(t, tob, tx, em, eve, bweight, v_island);
if (tx)
tx++;
@@ -2520,6 +2604,8 @@ cleanup:
MEM_freeN(defmats);
if (dists)
MEM_freeN(dists);
+ if (dists_index)
+ MEM_freeN(dists_index);
if (t->flag & T_MIRROR) {
EDBM_verts_mirror_cache_end(em);
@@ -5523,7 +5609,7 @@ static void clear_trans_object_base_flags(TransInfo *t)
* tmode: should be a transform mode
*/
// NOTE: context may not always be available, so must check before using it as it's a luxury for a few cases
-void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob, int tmode)
+void autokeyframe_ob_cb_func(bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, Object *ob, int tmode)
{
ID *id = &ob->id;
FCurve *fcu;
@@ -5572,7 +5658,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob,
}
else if (ELEM(tmode, TFM_ROTATION, TFM_TRACKBALL)) {
if (v3d->around == V3D_AROUND_ACTIVE) {
- if (ob != OBACT)
+ if (ob != OBACT_NEW)
do_loc = true;
}
else if (v3d->around == V3D_AROUND_CURSOR)
@@ -5583,7 +5669,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob,
}
else if (tmode == TFM_RESIZE) {
if (v3d->around == V3D_AROUND_ACTIVE) {
- if (ob != OBACT)
+ if (ob != OBACT_NEW)
do_loc = true;
}
else if (v3d->around == V3D_AROUND_CURSOR)
@@ -6302,10 +6388,10 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
else if (t->options & CTX_PAINT_CURVE) {
/* pass */
}
- else if ((t->scene->basact) &&
- (ob = t->scene->basact->object) &&
+ else if ((t->sl->basact) &&
+ (ob = t->sl->basact->object) &&
(ob->mode & OB_MODE_PARTICLE_EDIT) &&
- PE_get_current(t->scene, ob))
+ PE_get_current(t->scene, t->sl, ob))
{
/* do nothing */
}
@@ -6346,7 +6432,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
/* Set autokey if necessary */
if (!canceled) {
- autokeyframe_ob_cb_func(C, t->scene, (View3D *)t->view, ob, t->mode);
+ autokeyframe_ob_cb_func(C, t->scene, t->sl, (View3D *)t->view, ob, t->mode);
}
/* restore rigid body transform */
@@ -6381,8 +6467,6 @@ int special_transform_moving(TransInfo *t)
static void createTransObject(bContext *C, TransInfo *t)
{
- Scene *scene = t->scene;
-
TransData *td = NULL;
TransDataExtension *tx;
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
@@ -6432,15 +6516,16 @@ static void createTransObject(bContext *C, TransInfo *t)
CTX_DATA_END;
if (is_prop_edit) {
- View3D *v3d = t->view;
- BaseLegacy *base;
+ SceneLayer *sl = t->sl;
+ Base *base;
- for (base = scene->base.first; base; base = base->next) {
+ for (base = sl->object_bases.first; base; base = base->next) {
Object *ob = base->object;
/* if base is not selected, not a parent of selection or not a child of selection and it is editable */
- if ((ob->flag & (SELECT | BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 &&
- BASE_EDITABLE_BGMODE(v3d, scene, base))
+ if ((ob->flag & (BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 &&
+ (base->flag & BASE_SELECTED) == 0 &&
+ BASE_EDITABLE_BGMODE_NEW(base))
{
td->protectflag = ob->protectflag;
td->ext = tx;
@@ -8021,7 +8106,12 @@ void createTransData(bContext *C, TransInfo *t)
if (t->data && t->flag & T_PROP_EDIT) {
if (ELEM(t->obedit->type, OB_CURVE, OB_MESH)) {
sort_trans_data(t); // makes selected become first in array
- set_prop_dist(t, 0);
+ if ((t->obedit->type == OB_MESH) && (t->flag & T_PROP_CONNECTED)) {
+ /* already calculated by editmesh_set_connectivity_distance */
+ }
+ else {
+ set_prop_dist(t, 0);
+ }
sort_trans_data_dist(t);
}
else {
@@ -8057,7 +8147,7 @@ void createTransData(bContext *C, TransInfo *t)
}
}
- else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_start_edit(PE_get_current(scene, ob))) {
+ else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_start_edit(PE_get_current(scene, sl, ob))) {
createTransParticleVerts(C, t);
t->flag |= T_POINTS;
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 2c10ee61466..6da0631ffa3 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -63,6 +63,7 @@
#include "RNA_access.h"
#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "BIK_api.h"
@@ -325,6 +326,7 @@ static void recalcData_actedit(TransInfo *t)
/* initialize relevant anim-context 'context' data from TransInfo data */
/* NOTE: sync this with the code in ANIM_animdata_get_context() */
ac.scene = t->scene;
+ ac.scene_layer = t->sl;
ac.obact = OBACT_NEW;
ac.sa = t->sa;
ac.ar = t->ar;
@@ -374,6 +376,7 @@ static void recalcData_graphedit(TransInfo *t)
/* initialize relevant anim-context 'context' data from TransInfo data */
/* NOTE: sync this with the code in ANIM_animdata_get_context() */
ac.scene = t->scene;
+ ac.scene_layer = t->sl;
ac.obact = OBACT_NEW;
ac.sa = t->sa;
ac.ar = t->ar;
@@ -708,7 +711,7 @@ static void recalcData_spaceclip(TransInfo *t)
/* helper for recalcData() - for object transforms, typically in the 3D view */
static void recalcData_objects(TransInfo *t)
{
- BaseLegacy *base = t->scene->basact;
+ Base *base = t->sl->basact;
if (t->obedit) {
if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) {
@@ -895,7 +898,7 @@ static void recalcData_objects(TransInfo *t)
else
BKE_pose_where_is(t->scene, ob);
}
- else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, base->object)) {
+ else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) && PE_get_current(t->scene, t->sl, base->object)) {
if (t->state != TRANS_CANCEL) {
applyProject(t);
}
@@ -925,7 +928,7 @@ static void recalcData_objects(TransInfo *t)
// TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
animrecord_check_state(t->scene, &ob->id, t->animtimer);
- autokeyframe_ob_cb_func(t->context, t->scene, (View3D *)t->view, ob, t->mode);
+ autokeyframe_ob_cb_func(t->context, t->scene, t->sl, (View3D *)t->view, ob, t->mode);
}
/* sets recalc flags fully, instead of flushing existing ones
@@ -1031,11 +1034,10 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis
if (t->spacetype == SPACE_VIEW3D) {
View3D *v3d = t->view;
- glPushMatrix();
-
- //if (t->obedit) glLoadMatrixf(t->obedit->obmat); // sets opengl viewing
-
-
+ gpuPushMatrix();
+
+ // if (t->obedit) gpuLoadMatrix3D(t->obedit->obmat); // sets opengl viewing
+
copy_v3_v3(v3, dir);
mul_v3_fl(v3, v3d->far);
@@ -1062,7 +1064,7 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis
immUnbindProgram();
- glPopMatrix();
+ gpuPopMatrix();
}
}
@@ -1785,7 +1787,7 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
}
}
else if (t->options & CTX_PAINT_CURVE) {
- Paint *p = BKE_paint_get_active(t->scene);
+ Paint *p = BKE_paint_get_active(t->scene, t->sl);
Brush *br = p->brush;
PaintCurve *pc = br->paint_curve;
copy_v3_v3(r_center, pc->points[pc->add_index - 1].bez.vec[1]);
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index fed1b2f5676..1be477fb998 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -569,6 +569,9 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
// Add confirm method all the time. At the end because it's not really that important and should be hidden only in log, not in keymap edit
/*prop =*/ RNA_def_boolean(ot->srna, "release_confirm", 0, "Confirm on Release", "Always confirm operation when releasing button");
//RNA_def_property_flag(prop, PROP_HIDDEN);
+
+ prop = RNA_def_boolean(ot->srna, "use_accurate", 0, "Accurate", "Use accurate transformation");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
prop = RNA_def_boolean(ot->srna, "draw_helplines", 1, "Draw Helplines", "");
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index bd640463da2..8f37b35c6f0 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -206,35 +206,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
else if (t->spacetype == SPACE_IMAGE) {
if (validSnap(t)) {
/* This will not draw, and Im nor sure why - campbell */
-#if 0
- float xuser_asp, yuser_asp;
- int wi, hi;
- float w, h;
-
- calc_image_view(G.sima, 'f'); // float
- myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
- glLoadIdentity();
-
- ED_space_image_get_aspect(t->sa->spacedata.first, &xuser_aspx, &yuser_asp);
- ED_space_image_width(t->sa->spacedata.first, &wi, &hi);
- w = (((float)wi) / IMG_SIZE_FALLBACK) * G.sima->zoom * xuser_asp;
- h = (((float)hi) / IMG_SIZE_FALLBACK) * G.sima->zoom * yuser_asp;
-
- cpack(0xFFFFFF);
- glTranslate2fv(t->tsnap.snapPoint);
-
- //glRectf(0, 0, 1, 1);
-
- setlinestyle(0);
- cpack(0x0);
- fdrawline(-0.020 / w, 0, -0.1 / w, 0);
- fdrawline(0.1 / w, 0, 0.020 / w, 0);
- fdrawline(0, -0.020 / h, 0, -0.1 / h);
- fdrawline(0, 0.1 / h, 0, 0.020 / h);
-
- glTranslatef(-t->tsnap.snapPoint[0], -t->tsnap.snapPoint[1], 0.0f);
- setlinestyle(0);
-#endif
+ /* TODO: see 2.7x for non-working code */
}
}
else if (t->spacetype == SPACE_NODE) {
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index 2e95b67d508..587a62d017d 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -87,6 +87,8 @@ typedef struct SnapObjectData {
typedef struct SnapObjectData_Mesh {
SnapObjectData sd;
BVHTreeFromMesh *bvh_trees[3];
+ MPoly *mpoly;
+ bool poly_allocated;
} SnapObjectData_Mesh;
@@ -934,9 +936,10 @@ static bool snapEmpty(
float tmp_co[3];
copy_v3_v3(tmp_co, obmat[3]);
if (test_projected_vert_dist(
- snapdata->depth_range, snapdata->mval, tmp_co,
- snapdata->pmat, snapdata->win_half, is_persp, &dist_px_sq,
- r_loc)) {
+ snapdata->depth_range, snapdata->mval, tmp_co,
+ snapdata->pmat, snapdata->win_half, is_persp, &dist_px_sq,
+ r_loc))
+ {
*dist_px = sqrtf(dist_px_sq);
*ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir);
retval = true;
@@ -1051,7 +1054,6 @@ static int dm_looptri_to_poly_index(DerivedMesh *dm, const MLoopTri *lt)
static bool snapDerivedMesh(
SnapObjectContext *sctx, SnapData *snapdata,
Object *ob, DerivedMesh *dm, float obmat[4][4], const unsigned int ob_index,
- bool do_bb,
/* read/write args */
float *ray_depth, float *dist_px,
/* return args */
@@ -1112,39 +1114,30 @@ static bool snapDerivedMesh(
copy_v3_v3(ray_org_local, snapdata->ray_origin);
mul_m4_v3(imat, ray_org_local);
- if (do_bb) {
- BoundBox *bb = BKE_object_boundbox_get(ob);
-
- if (bb) {
- BoundBox bb_temp;
-
- /* We cannot afford a bounding box with some null dimension, which may happen in some cases...
- * Threshold is rather high, but seems to be needed to get good behavior, see T46099. */
- bb = BKE_boundbox_ensure_minimum_dimensions(bb, &bb_temp, 1e-1f);
-
- /* In vertex and edges you need to get the pixel distance from ray to BoundBox, see T46816. */
- if (ELEM(snapdata->snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) {
- float dist_px_sq = dist_squared_to_projected_aabb_simple(
- lpmat, snapdata->win_half, ray_min_dist, snapdata->mval,
- ray_org_local, ray_normal_local, bb->vec[0], bb->vec[6]);
- if (dist_px_sq > SQUARE(*dist_px))
- {
- return retval;
- }
+ /* Test BoundBox */
+ BoundBox *bb = BKE_object_boundbox_get(ob);
+ if (bb) {
+ /* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */
+ if (ELEM(snapdata->snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) {
+ float dist_px_sq = dist_squared_to_projected_aabb_simple(
+ lpmat, snapdata->win_half, ray_min_dist, snapdata->mval,
+ ray_org_local, ray_normal_local, bb->vec[0], bb->vec[6]);
+ if (dist_px_sq > SQUARE(*dist_px)) {
+ return retval;
}
- else {
- /* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
- if (!isect_ray_aabb_v3_simple(
- ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], NULL, NULL))
- {
- return retval;
- }
+ }
+ else {
+ /* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
+ if (!isect_ray_aabb_v3_simple(
+ ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], NULL, NULL))
+ {
+ return retval;
}
- /* was local_depth, see: T47838 */
- len_diff = dist_aabb_to_plane(bb->vec[0], bb->vec[6], ray_start_local, ray_normal_local);
- if (len_diff < 0) len_diff = 0.0f;
- need_ray_start_correction_init = false;
}
+ /* was local_depth, see: T47838 */
+ len_diff = dist_aabb_to_plane(bb->vec[0], bb->vec[6], ray_start_local, ray_normal_local);
+ if (len_diff < 0) len_diff = 0.0f;
+ need_ray_start_correction_init = false;
}
SnapObjectData_Mesh *sod = NULL;
@@ -1182,6 +1175,29 @@ static bool snapDerivedMesh(
if (treedata->cached && !bvhcache_has_tree(dm->bvhCache, treedata->tree)) {
free_bvhtree_from_mesh(treedata);
}
+ else {
+ if (!treedata->vert_allocated) {
+ treedata->vert = DM_get_vert_array(dm, &treedata->vert_allocated);
+ }
+ if ((tree_index == 1) && !treedata->edge_allocated) {
+ treedata->edge = DM_get_edge_array(dm, &treedata->vert_allocated);
+ }
+ if (tree_index == 2) {
+ if (!treedata->loop_allocated) {
+ treedata->loop = DM_get_loop_array(dm, &treedata->loop_allocated);
+ }
+ if (!treedata->looptri_allocated) {
+ if (!sod->poly_allocated) {
+ sod->mpoly = DM_get_poly_array(dm, &sod->poly_allocated);
+ }
+ treedata->looptri = DM_get_looptri_array(
+ dm, treedata->vert,
+ sod->mpoly, dm->getNumPolys(dm),
+ treedata->loop, dm->getNumLoops(dm),
+ &treedata->looptri_allocated);
+ }
+ }
+ }
}
}
@@ -1295,10 +1311,17 @@ static bool snapDerivedMesh(
}
/* SCE_SNAP_MODE_VERTEX or SCE_SNAP_MODE_EDGE */
else {
+
+ /* Warning: the depth_max is currently being used only in perspective view.
+ * It is not correct to limit the maximum depth for elements obtained with nearest
+ * since this limitation depends on the normal and the size of the occlusion face.
+ * And more... ray_depth is being confused with Z-depth here... (varies only the precision) */
+ const float ray_depth_max_global = *ray_depth + snapdata->depth_range[0];
+
Nearest2dUserData neasrest2d = {
.dist_px_sq = SQUARE(*dist_px),
.r_axis_closest = {1.0f, 1.0f, 1.0f},
- .depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]},
+ .depth_range = {snapdata->depth_range[0], ray_depth_max_global},
.userdata = treedata,
.get_edge_verts = (Nearest2DGetEdgeVertsCallback)get_dm_edge_verts,
.copy_vert_no = (Nearest2DCopyVertNoCallback)copy_dm_vert_no,
@@ -1650,7 +1673,6 @@ static bool snapObject(
}
retval = snapDerivedMesh(
sctx, snapdata, ob, dm, obmat, ob_index,
- true,
ray_depth, dist_px,
r_loc, r_no,
r_index, r_hit_list);
@@ -1858,6 +1880,9 @@ static void snap_object_data_free(void *sod_v)
free_bvhtree_from_mesh(sod->bvh_trees[i]);
}
}
+ if (sod->poly_allocated) {
+ MEM_freeN(sod->mpoly);
+ }
break;
}
case SNAP_EDIT_MESH:
@@ -2053,10 +2078,10 @@ static bool transform_snap_context_project_view3d_mixed_impl(
for (int i = 0; i < 3; i++) {
if (snap_to_flag & (1 << i)) {
if (ED_transform_snap_object_project_view3d(
- sctx,
- elem_type[i], params,
- mval, dist_px, &ray_depth,
- r_co, r_no))
+ sctx,
+ elem_type[i], params,
+ mval, dist_px, &ray_depth,
+ r_co, r_no))
{
is_hit = true;
break;