diff options
Diffstat (limited to 'source/blender/editors/transform')
30 files changed, 285 insertions, 260 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 34e5b78c48f..ad6ab625438 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1594,9 +1594,9 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) RNA_enum_set(op->ptr, "snap_target", t->tsnap.source_select); eSnapTargetSelect target = t->tsnap.target_select; - RNA_boolean_set(op->ptr, "use_snap_self", (target & SCE_SNAP_TARGET_NOT_ACTIVE) != 0); - RNA_boolean_set(op->ptr, "use_snap_edit", (target & SCE_SNAP_TARGET_NOT_EDITED) != 0); - RNA_boolean_set(op->ptr, "use_snap_nonedit", (target & SCE_SNAP_TARGET_NOT_NONEDITED) != 0); + RNA_boolean_set(op->ptr, "use_snap_self", (target & SCE_SNAP_TARGET_NOT_ACTIVE) == 0); + RNA_boolean_set(op->ptr, "use_snap_edit", (target & SCE_SNAP_TARGET_NOT_EDITED) == 0); + RNA_boolean_set(op->ptr, "use_snap_nonedit", (target & SCE_SNAP_TARGET_NOT_NONEDITED) == 0); RNA_boolean_set( op->ptr, "use_snap_selectable", (target & SCE_SNAP_TARGET_ONLY_SELECTABLE) != 0); } @@ -1721,13 +1721,18 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) } } -static void initSnapSpatial(TransInfo *t, float r_snap[2], float r_snap_y[2]) +static void initSnapSpatial(TransInfo *t, float r_snap[3], float *r_snap_precision) { + /* Default values. */ + r_snap[0] = r_snap[1] = 1.0f; + r_snap[2] = 0.0f; + *r_snap_precision = 0.1f; + if (t->spacetype == SPACE_VIEW3D) { if (t->region->regiondata) { View3D *v3d = t->area->spacedata.first; - r_snap[0] = ED_view3d_grid_view_scale(t->scene, v3d, t->region, NULL) * 1.0f; - r_snap[1] = r_snap[0] * 0.1f; + r_snap[0] = r_snap[1] = r_snap[2] = ED_view3d_grid_view_scale( + t->scene, v3d, t->region, NULL); } } else if (t->spacetype == SPACE_IMAGE) { @@ -1741,24 +1746,16 @@ static void initSnapSpatial(TransInfo *t, float r_snap[2], float r_snap_y[2]) ED_space_image_grid_steps(sima, grid_steps_x, grid_steps_y, grid_size); /* Snapping value based on what type of grid is used (adaptive-subdividing or custom-grid). */ r_snap[0] = ED_space_image_increment_snap_value(grid_size, grid_steps_x, zoom_factor); - r_snap[1] = r_snap[0] / 2.0f; - r_snap_y[0] = ED_space_image_increment_snap_value(grid_size, grid_steps_y, zoom_factor); - r_snap_y[1] = r_snap_y[0] / 2.0f; + r_snap[1] = ED_space_image_increment_snap_value(grid_size, grid_steps_y, zoom_factor); + *r_snap_precision = 0.5f; } else if (t->spacetype == SPACE_CLIP) { - r_snap[0] = 0.125f; - r_snap[1] = 0.0625f; + r_snap[0] = r_snap[1] = 0.125f; + *r_snap_precision = 0.5f; } else if (t->spacetype == SPACE_NODE) { r_snap[0] = r_snap[1] = ED_node_grid_size(); } - else if (t->spacetype == SPACE_GRAPH) { - r_snap[0] = 1.0; - r_snap[1] = 0.1f; - } - else { - r_snap[0] = r_snap[1] = 1.0f; - } } bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event, int mode) @@ -1898,7 +1895,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve initSnapping(t, op); /* Initialize snapping data AFTER mode flags */ - initSnapSpatial(t, t->snap_spatial_x, t->snap_spatial_y); + initSnapSpatial(t, t->snap_spatial, &t->snap_spatial_precision); /* EVIL! posemode code can switch translation to rotate when 1 bone is selected. * will be removed (ton) */ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 95686f12fe2..1e260ecd292 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -469,7 +469,8 @@ typedef struct TransDataContainer { /** * Store matrix, this avoids having to have duplicate check all over - * Typically: 'obedit->obmat' or 'poseobj->obmat', but may be used elsewhere too. + * Typically: 'obedit->object_to_world' or 'poseobj->object_to_world', but may be used elsewhere + * too. */ bool use_local_mat; @@ -555,9 +556,12 @@ typedef struct TransInfo { /** Snapping Gears. */ float snap[2]; /** Spatial snapping gears(even when rotating, scaling... etc). */ - float snap_spatial_x[2]; - /** Spatial snapping in the Y coordinate, for non-uniform grid in UV Editor. */ - float snap_spatial_y[2]; + float snap_spatial[3]; + /** + * Precision factor that is multiplied to snap_spatial when precision + * modifier is enabled for snap to grid or incremental snap. + */ + float snap_spatial_precision; /** Mouse side of the current frame, 'L', 'R' or 'B' */ char frame_side; diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index fa56456d8e7..7abf0e5c00c 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -404,9 +404,11 @@ static void applyAxisConstraintVec(const TransInfo *t, } } + /* Fallback for when axes are aligned. */ + mul_m3_v3(t->con.pmtx, out); + if (is_snap_to_point) { - /* With snap points, a projection is alright, no adjustments needed. */ - mul_m3_v3(t->con.pmtx, out); + /* Pass. With snap points, a projection is alright, no adjustments needed. */ } else { const int dims = getConstraintSpaceDimension(t); @@ -422,14 +424,9 @@ static void applyAxisConstraintVec(const TransInfo *t, /* Disabled, as it has not proven to be really useful. (See T82386). */ // constraint_snap_plane_to_face(t, plane, out); } - else { + else if (!isPlaneProjectionViewAligned(t, plane)) { /* View alignment correction. */ - if (!isPlaneProjectionViewAligned(t, plane)) { - planeProjection(t, plane, in, out); - } - else { - mul_m3_v3(t->con.pmtx, out); - } + planeProjection(t, plane, in, out); } } } diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index 7a68ee1bfbf..a5b2442f11c 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -981,7 +981,7 @@ static void init_TransDataContainers(TransInfo *t, if (tc->use_local_mat) { BLI_assert((t->flag & T_2D_EDIT) == 0); - copy_m4_m4(tc->mat, objects[i]->obmat); + copy_m4_m4(tc->mat, objects[i]->object_to_world); copy_m3_m4(tc->mat3, tc->mat); /* for non-invertible scale matrices, invert_m4_m4_fallback() * can still provide a valid pivot */ @@ -1235,8 +1235,8 @@ void transform_convert_clip_mirror_modifier_apply(TransDataContainer *tc) if (mmd->mirror_ob) { float obinv[4][4]; - invert_m4_m4(obinv, mmd->mirror_ob->obmat); - mul_m4_m4m4(mtx, obinv, ob->obmat); + invert_m4_m4(obinv, mmd->mirror_ob->object_to_world); + mul_m4_m4m4(mtx, obinv, ob->object_to_world); invert_m4_m4(imtx, mtx); } diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h index 8466fd88e1d..4798d666d70 100644 --- a/source/blender/editors/transform/transform_convert.h +++ b/source/blender/editors/transform/transform_convert.h @@ -226,8 +226,6 @@ void transform_convert_mesh_crazyspace_transdata_set(const float mtx[3][3], struct TransData *r_td); void transform_convert_mesh_crazyspace_free(struct TransMeshDataCrazySpace *r_crazyspace_data); -void special_aftertrans_update__mesh(bContext *C, TransInfo *t); - /* transform_convert_mesh_edge.c */ extern TransConvertTypeInfo TransConvertType_MeshEdge; diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index 4b79625fa66..2e37f6b7c34 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -306,8 +306,9 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) * just make things obey standard rotation locks too */ if (data->rootbone == 0) { for (bPoseChannel *pchan_iter = pchan; pchan_iter; pchan_iter = pchan_iter->parent) { - /* here, we set ik-settings for bone from pchan->protectflag */ - /* XXX: careful with quats/axis-angle rotations where we're locking 4d components. */ + /* Here, we set IK-settings for bone from `pchan->protectflag`. */ + /* XXX: careful with quaternion/axis-angle rotations + * where we're locking 4d components. */ if (pchan_iter->protectflag & OB_LOCK_ROTX) { pchan_iter->ikflag |= BONE_IK_NO_XDOF_TEMP; } @@ -592,7 +593,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr td->ext->rotOrder = pchan->rotmode; /* proper way to get parent transform + own transform + constraints transform */ - copy_m3_m4(omat, ob->obmat); + copy_m3_m4(omat, ob->object_to_world); /* New code, using "generic" BKE_bone_parent_transform_calc_from_pchan(). */ { @@ -954,7 +955,7 @@ static void createTransArmatureVerts(bContext *UNUSED(C), TransInfo *t) bool mirror = ((arm->flag & ARM_MIRROR_EDIT) != 0); BoneInitData *bid = tc->custom.type.data; - copy_m3_m4(mtx, tc->obedit->obmat); + copy_m3_m4(mtx, tc->obedit->object_to_world); pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransEditBone"); diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c index 404b1293208..13ba28ec3d0 100644 --- a/source/blender/editors/transform/transform_convert_curve.c +++ b/source/blender/editors/transform/transform_convert_curve.c @@ -174,7 +174,7 @@ static void createTransCurveVerts(bContext *UNUSED(C), TransInfo *t) transform_mode_use_local_origins(t)); float mtx[3][3], smtx[3][3]; - copy_m3_m4(mtx, tc->obedit->obmat); + copy_m3_m4(mtx, tc->obedit->object_to_world); pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); TransData *td = tc->data; diff --git a/source/blender/editors/transform/transform_convert_lattice.c b/source/blender/editors/transform/transform_convert_lattice.c index b77538dc249..e9b3401974b 100644 --- a/source/blender/editors/transform/transform_convert_lattice.c +++ b/source/blender/editors/transform/transform_convert_lattice.c @@ -66,7 +66,7 @@ static void createTransLatticeVerts(bContext *UNUSED(C), TransInfo *t) } tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Lattice EditMode)"); - copy_m3_m4(mtx, tc->obedit->obmat); + copy_m3_m4(mtx, tc->obedit->object_to_world); pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); td = tc->data; diff --git a/source/blender/editors/transform/transform_convert_mball.c b/source/blender/editors/transform/transform_convert_mball.c index 7ae93524d0b..c90052e9e8c 100644 --- a/source/blender/editors/transform/transform_convert_mball.c +++ b/source/blender/editors/transform/transform_convert_mball.c @@ -61,7 +61,7 @@ static void createTransMBallVerts(bContext *UNUSED(C), TransInfo *t) tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "MetaElement_TransExtension"); - copy_m3_m4(mtx, tc->obedit->obmat); + copy_m3_m4(mtx, tc->obedit->object_to_world); pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); for (ml = mb->editelems->first; ml; ml = ml->next) { diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index af7982f862a..3192b1b6786 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -1527,7 +1527,7 @@ static void createTransEditVerts(bContext *UNUSED(C), TransInfo *t) em, calc_single_islands, calc_island_center, calc_island_axismtx, &island_data); } - copy_m3_m4(mtx, tc->obedit->obmat); + copy_m3_m4(mtx, tc->obedit->object_to_world); /* we use a pseudo-inverse so that when one of the axes is scaled to 0, * matrix inversion still works and we can still moving along the other */ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); @@ -2068,7 +2068,7 @@ static void recalcData_mesh(TransInfo *t) /** \name Special After Transform Mesh * \{ */ -void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t) +static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t) { const bool is_canceling = (t->state == TRANS_CANCEL); const bool use_automerge = !is_canceling && (t->flag & (T_AUTOMERGE | T_AUTOSPLIT)) != 0; diff --git a/source/blender/editors/transform/transform_convert_mesh_edge.c b/source/blender/editors/transform/transform_convert_mesh_edge.c index 7f26029850b..fd62b199345 100644 --- a/source/blender/editors/transform/transform_convert_mesh_edge.c +++ b/source/blender/editors/transform/transform_convert_mesh_edge.c @@ -62,7 +62,7 @@ static void createTransEdge(bContext *UNUSED(C), TransInfo *t) td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransCrease"); - copy_m3_m4(mtx, tc->obedit->obmat); + copy_m3_m4(mtx, tc->obedit->object_to_world); pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); /* create data we need */ @@ -125,5 +125,5 @@ TransConvertTypeInfo TransConvertType_MeshEdge = { /* flags */ T_EDIT, /* createTransData */ createTransEdge, /* recalcData */ recalcData_mesh_edge, - /* special_aftertrans_update */ special_aftertrans_update__mesh, + /* special_aftertrans_update */ NULL, }; diff --git a/source/blender/editors/transform/transform_convert_mesh_skin.c b/source/blender/editors/transform/transform_convert_mesh_skin.c index 376e559181e..cb6108a4c45 100644 --- a/source/blender/editors/transform/transform_convert_mesh_skin.c +++ b/source/blender/editors/transform/transform_convert_mesh_skin.c @@ -130,7 +130,7 @@ static void createTransMeshSkin(bContext *UNUSED(C), TransInfo *t) em, calc_single_islands, calc_island_center, calc_island_axismtx, &island_data); } - copy_m3_m4(mtx, tc->obedit->obmat); + copy_m3_m4(mtx, tc->obedit->object_to_world); /* we use a pseudo-inverse so that when one of the axes is scaled to 0, * matrix inversion still works and we can still moving along the other */ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); diff --git a/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c b/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c index 59836180166..d253261f458 100644 --- a/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c +++ b/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c @@ -131,7 +131,7 @@ static void createTransMeshVertCData(bContext *UNUSED(C), TransInfo *t) em, calc_single_islands, calc_island_center, calc_island_axismtx, &island_data); } - copy_m3_m4(mtx, tc->obedit->obmat); + copy_m3_m4(mtx, tc->obedit->object_to_world); /* we use a pseudo-inverse so that when one of the axes is scaled to 0, * matrix inversion still works and we can still moving along the other */ pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c index af5a51cbff6..830094ebe83 100644 --- a/source/blender/editors/transform/transform_convert_nla.c +++ b/source/blender/editors/transform/transform_convert_nla.c @@ -60,9 +60,9 @@ typedef struct TransDataNla { * \{ */ /** - * \brief Applies a translation to the given NlaStrip. - * \param strip_rna_ptr The RNA pointer of the NLA strip to modify. - * \param transdata The transformation info structure. + * \brief Applies a translation to the given #NlaStrip. + * \param strip_rna_ptr: The RNA pointer of the NLA strip to modify. + * \param transdata: The transformation info structure. */ static void applyTransformNLA_translation(PointerRNA *strip_rna_ptr, const TransDataNla *transdata) { diff --git a/source/blender/editors/transform/transform_convert_node.cc b/source/blender/editors/transform/transform_convert_node.cc index eb5eb822d69..6ab0e1fe701 100644 --- a/source/blender/editors/transform/transform_convert_node.cc +++ b/source/blender/editors/transform/transform_convert_node.cc @@ -155,9 +155,52 @@ static void createTransNodeData(bContext * /*C*/, TransInfo *t) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Node Transform Creation +/** \name Flush Transform Nodes * \{ */ +static void node_snap_grid_apply(TransInfo *t) +{ + int i; + + if (!(activeSnap(t) && (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) { + return; + } + + float grid_size[2]; + copy_v2_v2(grid_size, t->snap_spatial); + if (t->modifiers & MOD_PRECISION) { + mul_v2_fl(grid_size, t->snap_spatial_precision); + } + + /* Early exit on unusable grid size. */ + if (is_zero_v2(grid_size)) { + return; + } + + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + TransData *td; + + for (i = 0, td = tc->data; i < tc->data_len; i++, td++) { + float iloc[2], loc[2], tvec[2]; + if (td->flag & TD_SKIP) { + continue; + } + + if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) { + continue; + } + + copy_v2_v2(iloc, td->loc); + + loc[0] = roundf(iloc[0] / grid_size[0]) * grid_size[0]; + loc[1] = roundf(iloc[1] / grid_size[1]) * grid_size[1]; + + sub_v2_v2v2(tvec, loc, iloc); + add_v2_v2(td->loc, tvec); + } + } +} + static void flushTransNodes(TransInfo *t) { using namespace blender::ed; @@ -191,7 +234,7 @@ static void flushTransNodes(TransInfo *t) } FOREACH_TRANS_DATA_CONTAINER (t, tc) { - applyGridAbsolute(t); + node_snap_grid_apply(t); /* flush to 2d vector from internally used 3d vector */ for (int i = 0; i < tc->data_len; i++) { diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c index 0dcfd7206ad..55f7cd9b23d 100644 --- a/source/blender/editors/transform/transform_convert_object.c +++ b/source/blender/editors/transform/transform_convert_object.c @@ -158,14 +158,14 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) copy_qt_qt(td->ext->oquat, ob->quat); } /* update object's loc/rot to get current rigid body transform */ - mat4_to_loc_rot_size(ob->loc, rot, scale, ob->obmat); + mat4_to_loc_rot_size(ob->loc, rot, scale, ob->object_to_world); sub_v3_v3(ob->loc, ob->dloc); BKE_object_mat3_to_rot(ob, rot, false); /* drot is already corrected here */ } } /* axismtx has the real orientation */ - transform_orientations_create_from_axis(td->axismtx, UNPACK3(ob->obmat)); + transform_orientations_create_from_axis(td->axismtx, UNPACK3(ob->object_to_world)); if (t->orient_type_mask & (1 << V3D_ORIENT_GIMBAL)) { if (!gimbal_axis_object(ob, td->ext->axismtx_gimbal)) { copy_m3_m3(td->ext->axismtx_gimbal, td->axismtx); @@ -192,7 +192,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) * More proper solution would be to make a shallow copy of the object and * evaluate that, and access matrix of that evaluated copy of the object. * Might be more tricky than it sounds, if some logic later on accesses the - * object matrix via td->ob->obmat. */ + * object matrix via td->ob->object_to_world. */ Object *object_eval = DEG_get_evaluated_object(t->depsgraph, ob); if (skip_invert == false && constinv == false) { object_eval->transflag |= OB_NO_CONSTRAINTS; /* BKE_object_where_is_calc checks this */ @@ -208,7 +208,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) } /* Copy newly evaluated fields to the original object, similar to how * active dependency graph will do it. */ - copy_m4_m4(ob->obmat, object_eval->obmat); + copy_m4_m4(ob->object_to_world, object_eval->object_to_world); /* Only copy negative scale flag, this is the only flag which is modified by * the BKE_object_where_is_calc(). The rest of the flags we need to keep, * otherwise we might lose dupli flags (see T61787). */ @@ -258,9 +258,9 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) copy_v3_v3(td->ext->isize, ob->scale); copy_v3_v3(td->ext->dscale, ob->dscale); - copy_v3_v3(td->center, ob->obmat[3]); + copy_v3_v3(td->center, ob->object_to_world[3]); - copy_m4_m4(td->ext->obmat, ob->obmat); + copy_m4_m4(td->ext->obmat, ob->object_to_world); /* is there a need to set the global<->data space conversion matrices? */ if (ob->parent || constinv) { @@ -271,7 +271,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) * done, as it doesn't work well. */ BKE_object_to_mat3(ob, obmtx); - copy_m3_m4(totmat, ob->obmat); + copy_m3_m4(totmat, ob->object_to_world); /* If the object scale is zero on any axis, this might result in a zero matrix. * In this case, the transformation would not do anything, see: T50103. */ diff --git a/source/blender/editors/transform/transform_convert_object_texspace.c b/source/blender/editors/transform/transform_convert_object_texspace.c index 839bf6b77b3..b4c1c134d49 100644 --- a/source/blender/editors/transform/transform_convert_object_texspace.c +++ b/source/blender/editors/transform/transform_convert_object_texspace.c @@ -67,8 +67,8 @@ static void createTransTexspace(bContext *UNUSED(C), TransInfo *t) td->flag = TD_SELECTED; td->ob = ob; - copy_m3_m4(td->mtx, ob->obmat); - copy_m3_m4(td->axismtx, ob->obmat); + copy_m3_m4(td->mtx, ob->object_to_world); + copy_m3_m4(td->axismtx, ob->object_to_world); normalize_m3(td->axismtx); pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); diff --git a/source/blender/editors/transform/transform_convert_particle.c b/source/blender/editors/transform/transform_convert_particle.c index 3e056b6a048..f212f042773 100644 --- a/source/blender/editors/transform/transform_convert_particle.c +++ b/source/blender/editors/transform/transform_convert_particle.c @@ -95,7 +95,7 @@ static void createTransParticleVerts(bContext *UNUSED(C), TransInfo *t) unit_m4(mat); - invert_m4_m4(ob->imat, ob->obmat); + invert_m4_m4(ob->imat, ob->object_to_world); for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) { TransData *head, *tail; diff --git a/source/blender/editors/transform/transform_convert_sculpt.c b/source/blender/editors/transform/transform_convert_sculpt.c index f4f2e2a1c6e..cdbf497c584 100644 --- a/source/blender/editors/transform/transform_convert_sculpt.c +++ b/source/blender/editors/transform/transform_convert_sculpt.c @@ -49,7 +49,7 @@ static void createTransSculpt(bContext *C, TransInfo *t) td->flag = TD_SELECTED; copy_v3_v3(td->center, ss->pivot_pos); - mul_m4_v3(ob->obmat, td->center); + mul_m4_v3(ob->object_to_world, td->center); td->ob = ob; td->loc = ss->pivot_pos; @@ -60,16 +60,16 @@ static void createTransSculpt(bContext *C, TransInfo *t) } float obmat_inv[3][3]; - copy_m3_m4(obmat_inv, ob->obmat); + copy_m3_m4(obmat_inv, ob->object_to_world); invert_m3(obmat_inv); td->ext->rot = NULL; td->ext->rotAxis = NULL; td->ext->rotAngle = NULL; td->ext->quat = ss->pivot_rot; - copy_m4_m4(td->ext->obmat, ob->obmat); + copy_m4_m4(td->ext->obmat, ob->object_to_world); copy_m3_m3(td->ext->l_smtx, obmat_inv); - copy_m3_m4(td->ext->r_mtx, ob->obmat); + copy_m3_m4(td->ext->r_mtx, ob->object_to_world); copy_m3_m3(td->ext->r_smtx, obmat_inv); copy_qt_qt(td->ext->iquat, ss->pivot_rot); @@ -83,8 +83,8 @@ static void createTransSculpt(bContext *C, TransInfo *t) copy_v3_v3(td->ext->isize, ss->init_pivot_scale); copy_m3_m3(td->smtx, obmat_inv); - copy_m3_m4(td->mtx, ob->obmat); - copy_m3_m4(td->axismtx, ob->obmat); + copy_m3_m4(td->mtx, ob->object_to_world); + copy_m3_m4(td->axismtx, ob->object_to_world); BLI_assert(!(t->options & CTX_PAINT_CURVE)); ED_sculpt_init_transform(C, ob, t->mval, t->undo_name); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 301eac4536e..e1f93bf881b 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1063,7 +1063,7 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]) } if (tc->obedit) { if (ED_object_calc_active_center_for_editmode(tc->obedit, select_only, r_center)) { - mul_m4_v3(tc->obedit->obmat, r_center); + mul_m4_v3(tc->obedit->object_to_world, r_center); return true; } } @@ -1071,7 +1071,7 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]) BKE_view_layer_synced_ensure(t->scene, t->view_layer); Object *ob = BKE_view_layer_active_object_get(t->view_layer); if (ED_object_calc_active_center_for_posemode(ob, select_only, r_center)) { - mul_m4_v3(ob->obmat, r_center); + mul_m4_v3(ob->object_to_world, r_center); return true; } } @@ -1088,7 +1088,7 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]) BKE_view_layer_synced_ensure(t->scene, t->view_layer); Base *base = BKE_view_layer_active_base_get(t->view_layer); if (base && ((!select_only) || ((base->flag & BASE_SELECTED) != 0))) { - copy_v3_v3(r_center, base->object->obmat[3]); + copy_v3_v3(r_center, base->object->object_to_world[3]); return true; } } diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index f3d17559a63..2be210d24e7 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -581,12 +581,12 @@ bool gimbal_axis_pose(Object *ob, const bPoseChannel *pchan, float gmat[3][3]) mul_m3_m3m3(mat, parent_mat, tmat); /* needed if object transformation isn't identity */ - copy_m3_m4(obmat, ob->obmat); + copy_m3_m4(obmat, ob->object_to_world); mul_m3_m3m3(gmat, obmat, mat); } else { /* needed if object transformation isn't identity */ - copy_m3_m4(obmat, ob->obmat); + copy_m3_m4(obmat, ob->object_to_world); mul_m3_m3m3(gmat, obmat, tmat); } @@ -608,7 +608,7 @@ bool gimbal_axis_object(Object *ob, float gmat[3][3]) if (ob->parent) { float parent_mat[3][3]; - copy_m3_m4(parent_mat, ob->parent->obmat); + copy_m3_m4(parent_mat, ob->parent->object_to_world); normalize_m3(parent_mat); mul_m3_m3m3(gmat, parent_mat, gmat); } @@ -675,14 +675,14 @@ int ED_transform_calc_gizmo_stats(const bContext *C, copy_m3_m4(tbounds->axis, rv3d->twmat); if (params->use_local_axis && (ob && ob->mode & (OB_MODE_EDIT | OB_MODE_POSE))) { float diff_mat[3][3]; - copy_m3_m4(diff_mat, ob->obmat); + copy_m3_m4(diff_mat, ob->object_to_world); normalize_m3(diff_mat); invert_m3(diff_mat); mul_m3_m3m3(tbounds->axis, tbounds->axis, diff_mat); normalize_m3(tbounds->axis); tbounds->use_matrix_space = true; - copy_m4_m4(tbounds->matrix_space, ob->obmat); + copy_m4_m4(tbounds->matrix_space, ob->object_to_world); } if (is_gp_edit) { @@ -751,7 +751,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, #define FOREACH_EDIT_OBJECT_BEGIN(ob_iter, use_mat_local) \ { \ - invert_m4_m4(obedit->imat, obedit->obmat); \ + invert_m4_m4(obedit->imat, obedit->object_to_world); \ uint objects_len = 0; \ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode( \ scene, view_layer, CTX_wm_view3d(C), &objects_len); \ @@ -780,7 +780,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, float mat_local[4][4]; if (use_mat_local) { - mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat); + mul_m4_m4m4(mat_local, obedit->imat, ob_iter->object_to_world); } BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { @@ -800,7 +800,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, float mat_local[4][4]; if (use_mat_local) { - mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat); + mul_m4_m4m4(mat_local, obedit->imat, ob_iter->object_to_world); } LISTBASE_FOREACH (EditBone *, ebo, arm->edbo) { if (EBONE_VISIBLE(arm, ebo)) { @@ -833,7 +833,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, float mat_local[4][4]; if (use_mat_local) { - mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat); + mul_m4_m4m4(mat_local, obedit->imat, ob_iter->object_to_world); } nu = nurbs->first; @@ -893,7 +893,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, float mat_local[4][4]; if (use_mat_local) { - mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat); + mul_m4_m4m4(mat_local, obedit->imat, ob_iter->object_to_world); } LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) { @@ -913,7 +913,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, float mat_local[4][4]; if (use_mat_local) { - mul_m4_m4m4(mat_local, obedit->imat, ob_iter->obmat); + mul_m4_m4m4(mat_local, obedit->imat, ob_iter->object_to_world); } while (a--) { @@ -933,13 +933,13 @@ int ED_transform_calc_gizmo_stats(const bContext *C, /* selection center */ if (totsel) { mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */ - mul_m4_v3(obedit->obmat, tbounds->center); - mul_m4_v3(obedit->obmat, tbounds->min); - mul_m4_v3(obedit->obmat, tbounds->max); + mul_m4_v3(obedit->object_to_world, tbounds->center); + mul_m4_v3(obedit->object_to_world, tbounds->min); + mul_m4_v3(obedit->object_to_world, tbounds->max); } } else if (ob && (ob->mode & OB_MODE_POSE)) { - invert_m4_m4(ob->imat, ob->obmat); + invert_m4_m4(ob->imat, ob->object_to_world); uint objects_len = 0; Object **objects = BKE_object_pose_array_get(scene, view_layer, v3d, &objects_len); @@ -954,7 +954,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, float mat_local[4][4]; if (use_mat_local) { - mul_m4_m4m4(mat_local, ob->imat, ob_iter->obmat); + mul_m4_m4m4(mat_local, ob->imat, ob_iter->object_to_world); } /* Use channels to get stats. */ @@ -971,18 +971,18 @@ int ED_transform_calc_gizmo_stats(const bContext *C, if (totsel) { mul_v3_fl(tbounds->center, 1.0f / (float)totsel); /* centroid! */ - mul_m4_v3(ob->obmat, tbounds->center); - mul_m4_v3(ob->obmat, tbounds->min); - mul_m4_v3(ob->obmat, tbounds->max); + mul_m4_v3(ob->object_to_world, tbounds->center); + mul_m4_v3(ob->object_to_world, tbounds->min); + mul_m4_v3(ob->object_to_world, tbounds->max); } } else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) { if (ob->mode & OB_MODE_SCULPT) { totsel = 1; - calc_tw_center_with_matrix(tbounds, ob->sculpt->pivot_pos, false, ob->obmat); - mul_m4_v3(ob->obmat, tbounds->center); - mul_m4_v3(ob->obmat, tbounds->min); - mul_m4_v3(ob->obmat, tbounds->max); + calc_tw_center_with_matrix(tbounds, ob->sculpt->pivot_pos, false, ob->object_to_world); + mul_m4_v3(ob->object_to_world, tbounds->center); + mul_m4_v3(ob->object_to_world, tbounds->min); + mul_m4_v3(ob->object_to_world, tbounds->max); } } else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) { @@ -1037,12 +1037,12 @@ int ED_transform_calc_gizmo_stats(const bContext *C, } if (params->use_only_center || (bb == NULL)) { - calc_tw_center(tbounds, base->object->obmat[3]); + calc_tw_center(tbounds, base->object->object_to_world[3]); } else { for (uint j = 0; j < 8; j++) { float co[3]; - mul_v3_m4v3(co, base->object->obmat, bb->vec[j]); + mul_v3_m4v3(co, base->object->object_to_world, bb->vec[j]); calc_tw_center(tbounds, co); } } diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c index 2eaeaf92c86..aeceedf0690 100644 --- a/source/blender/editors/transform/transform_mode.c +++ b/source/blender/editors/transform/transform_mode.c @@ -1041,7 +1041,7 @@ void ElementResize(const TransInfo *t, if (t->options & CTX_POSE_BONE) { /* Without this, the resulting location of scaled bones aren't correct, * especially noticeable scaling root or disconnected bones around the cursor, see T92515. */ - mul_mat3_m4_v3(tc->poseobj->obmat, vec); + mul_mat3_m4_v3(tc->poseobj->object_to_world, vec); } mul_m3_v3(td->smtx, vec); } diff --git a/source/blender/editors/transform/transform_mode_curveshrinkfatten.c b/source/blender/editors/transform/transform_mode_curveshrinkfatten.c index f7f9e14b8ac..0b87b45679a 100644 --- a/source/blender/editors/transform/transform_mode_curveshrinkfatten.c +++ b/source/blender/editors/transform/transform_mode_curveshrinkfatten.c @@ -8,6 +8,7 @@ #include <stdlib.h> #include "BLI_math.h" +#include "BLI_math_bits.h" #include "BLI_string.h" #include "BKE_context.h" @@ -62,7 +63,14 @@ static void applyCurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) } if (td->val) { - *td->val = td->ival * ratio; + if (td->ival == 0.0f && ratio > 1.0f) { + /* Allow Shrink/Fatten for zero radius. */ + *td->val = (ratio - 1.0f) * uint_as_float(POINTER_AS_UINT(t->custom.mode.data)); + } + else { + *td->val = td->ival * ratio; + } + /* apply PET */ *td->val = interpf(*td->val, td->ival, td->factor); CLAMP_MIN(*td->val, 0.0f); @@ -92,6 +100,18 @@ void initCurveShrinkFatten(TransInfo *t) t->num.unit_type[0] = B_UNIT_NONE; t->flag |= T_NO_CONSTRAINT; + + float scale_factor = 0.0f; + if (((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW) && + (t->data_len_all == 1)) || + (t->data_len_all == 3 && TRANS_DATA_CONTAINER_FIRST_OK(t)->data[0].val == NULL)) { + /* For cases where only one point on the curve is being transformed and the radius of that + * point is zero, use the factor to multiply the offset of the ratio and allow scaling. + * Note that for bezier curves, 3 TransData equals 1 point in most cases. */ + RegionView3D *rv3d = t->region->regiondata; + scale_factor = rv3d->pixsize * t->mouse.factor * t->zfac; + } + t->custom.mode.data = POINTER_FROM_UINT(float_as_uint(scale_factor)); } /** \} */ diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index 5baf06006d9..5cdb4d3bf61 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -1149,7 +1149,7 @@ void drawEdgeSlide(TransInfo *t) GPU_blend(GPU_BLEND_ALPHA); GPU_matrix_push(); - GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat); + GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index 91388ecd661..59d34c3918b 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -170,7 +170,7 @@ static void transdata_elem_translate_fn(void *__restrict iter_data_v, /** \} */ /* -------------------------------------------------------------------- */ -/** \name Transform (Translation) +/** \name Transform (Translation) Header * \{ */ static void translate_dist_to_str(char *r_str, @@ -341,6 +341,96 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_ } } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Transform (Translation) Snapping + * \{ */ + +static void translate_snap_target_grid_ensure(TransInfo *t) +{ + /* Only need to calculate once. */ + if ((t->tsnap.status & TARGET_GRID_INIT) == 0) { + if (t->data_type == &TransConvertType_Cursor3D) { + /* Use a fallback when transforming the cursor. + * In this case the center is _not_ derived from the cursor which is being transformed. */ + copy_v3_v3(t->tsnap.snapTargetGrid, TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->data->iloc); + } + else if (t->around == V3D_AROUND_CURSOR) { + /* Use a fallback for cursor selection, + * this isn't useful as a global center for absolute grid snapping + * since its not based on the position of the selection. */ + tranform_snap_target_median_calc(t, t->tsnap.snapTargetGrid); + } + else { + copy_v3_v3(t->tsnap.snapTargetGrid, t->center_global); + } + t->tsnap.status |= TARGET_GRID_INIT; + } +} + +static void translate_snap_grid_apply(TransInfo *t, + const int max_index, + const float grid_dist[3], + const float loc[3], + float r_out[3]) +{ + BLI_assert(max_index <= 2); + translate_snap_target_grid_ensure(t); + const float *center_global = t->tsnap.snapTargetGrid; + const float *asp = t->aspect; + + float in[3]; + if (t->con.mode & CON_APPLY) { + BLI_assert(t->tsnap.snapElem == SCE_SNAP_MODE_NONE); + t->con.applyVec(t, NULL, NULL, loc, in); + } + else { + copy_v3_v3(in, loc); + } + + for (int i = 0; i <= max_index; i++) { + const float iter_fac = grid_dist[i] * asp[i]; + r_out[i] = iter_fac * roundf((in[i] + center_global[i]) / iter_fac) - center_global[i]; + } +} + +static bool translate_snap_grid(TransInfo *t, float *val) +{ + if (!activeSnap(t)) { + return false; + } + + if (!(t->tsnap.mode & SCE_SNAP_MODE_GRID) || validSnap(t)) { + /* Don't do grid snapping if there is a valid snap point. */ + return false; + } + + /* Don't do grid snapping if not in 3D viewport or UV editor */ + if (!ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) { + return false; + } + + if (t->mode != TFM_TRANSLATION) { + return false; + } + + float grid_dist[3]; + copy_v3_v3(grid_dist, t->snap_spatial); + if (t->modifiers & MOD_PRECISION) { + mul_v3_fl(grid_dist, t->snap_spatial_precision); + } + + /* Early bailing out if no need to snap */ + if (is_zero_v3(grid_dist)) { + return false; + } + + translate_snap_grid_apply(t, t->idx_max, grid_dist, val, val); + t->tsnap.snapElem = SCE_SNAP_MODE_GRID; + return true; +} + static void ApplySnapTranslation(TransInfo *t, float vec[3]) { float point[3]; @@ -372,6 +462,12 @@ static void ApplySnapTranslation(TransInfo *t, float vec[3]) } } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Transform (Translation) + * \{ */ + static void applyTranslationValue(TransInfo *t, const float vec[3]) { struct TranslateCustomData *custom_data = t->custom.mode.data; @@ -514,7 +610,7 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2])) t->tsnap.snapElem = SCE_SNAP_MODE_NONE; applySnappingAsGroup(t, global_dir); - transform_snap_grid(t, global_dir); + translate_snap_grid(t, global_dir); if (t->con.mode & CON_APPLY) { float in[3]; @@ -590,7 +686,8 @@ void initTranslation(TransInfo *t) t->num.flag = 0; t->num.idx_max = t->idx_max; - copy_v2_v2(t->snap, t->snap_spatial_x); + t->snap[0] = t->snap_spatial[0]; + t->snap[1] = t->snap_spatial[0] * t->snap_spatial_precision; copy_v3_fl(t->num.val_inc, t->snap[0]); t->num.unit_sys = t->scene->unit.system; diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c index d7c4d862b23..cc1ea188fbc 100644 --- a/source/blender/editors/transform/transform_mode_vert_slide.c +++ b/source/blender/editors/transform/transform_mode_vert_slide.c @@ -167,7 +167,7 @@ static void calcVertSlideMouseActiveEdges(struct TransInfo *t, const int mval[2] float dir_dot; sub_v3_v3v3(tdir, sv->co_orig_3d, sv->co_link_orig_3d[j]); - mul_mat3_m4_v3(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat, tdir); + mul_mat3_m4_v3(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world, tdir); project_plane_v3_v3v3(tdir, tdir, t->viewinv[2]); normalize_v3(tdir); @@ -382,7 +382,7 @@ void drawVertSlide(TransInfo *t) GPU_blend(GPU_BLEND_ALPHA); GPU_matrix_push(); - GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat); + GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world); GPU_line_width(line_size); @@ -437,14 +437,15 @@ void drawVertSlide(TransInfo *t) xy_delta[0] = t->mval[0] - t->mouse.imval[0]; xy_delta[1] = t->mval[1] - t->mouse.imval[1]; - mul_v3_m4v3( - co_orig_3d, TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat, curr_sv->co_orig_3d); + mul_v3_m4v3(co_orig_3d, + TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world, + curr_sv->co_orig_3d); zfac = ED_view3d_calc_zfac(t->region->regiondata, co_orig_3d); ED_view3d_win_to_delta(t->region, xy_delta, zfac, co_dest_3d); invert_m4_m4(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->imat, - TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat); + TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->object_to_world); mul_mat3_m4_v3(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->imat, co_dest_3d); add_v3_v3(co_dest_3d, curr_sv->co_orig_3d); diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 212df5978e4..66fee01f864 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -126,7 +126,7 @@ static TransformOrientation *createObjectSpace(bContext *C, ob = base->object; - copy_m3_m4(mat, ob->obmat); + copy_m3_m4(mat, ob->object_to_world); normalize_m3(mat); /* use object name if no name is given */ @@ -532,7 +532,7 @@ short ED_transform_calc_orientation_from_type_ex(const Scene *scene, ED_getTransformOrientationMatrix(scene, view_layer, v3d, ob, obedit, pivot_point, r_mat); } else { - transform_orientations_create_from_axis(r_mat, UNPACK3(ob->obmat)); + transform_orientations_create_from_axis(r_mat, UNPACK3(ob->object_to_world)); } break; } @@ -764,7 +764,7 @@ int getTransformOrientation_ex(const Scene *scene, float imat[3][3], mat[3][3]; /* we need the transpose of the inverse for a normal... */ - copy_m3_m4(imat, ob->obmat); + copy_m3_m4(imat, ob->object_to_world); invert_m3_m3(mat, imat); transpose_m3(mat); @@ -1192,8 +1192,8 @@ int getTransformOrientation_ex(const Scene *scene, if (result == ORIENTATION_EDGE) { float tvec[3]; - mul_mat3_m4_v3(ob->obmat, normal); - mul_mat3_m4_v3(ob->obmat, plane); + mul_mat3_m4_v3(ob->object_to_world, normal); + mul_mat3_m4_v3(ob->object_to_world, plane); /* align normal to edge direction (so normal is perpendicular to the plane). * 'ORIENTATION_EDGE' will do the other way around. @@ -1235,7 +1235,7 @@ int getTransformOrientation_ex(const Scene *scene, /* use for both active & all */ if (ok) { /* we need the transpose of the inverse for a normal... */ - copy_m3_m4(imat, ob->obmat); + copy_m3_m4(imat, ob->object_to_world); invert_m3_m3(mat, imat); transpose_m3(mat); @@ -1267,8 +1267,8 @@ int getTransformOrientation_ex(const Scene *scene, } if (ok) { - copy_v3_v3(normal, ob->obmat[2]); - copy_v3_v3(plane, ob->obmat[1]); + copy_v3_v3(normal, ob->object_to_world[2]); + copy_v3_v3(plane, ob->object_to_world[1]); } } result = ORIENTATION_NORMAL; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 553202b5798..11cb57dc911 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -372,7 +372,7 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td } else if (t->options & CTX_OBJECT) { BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob); - copy_v3_v3(iloc, td->ob->obmat[3]); + copy_v3_v3(iloc, td->ob->object_to_world[3]); } if (ED_view3d_project_float_global(t->region, iloc, mval_fl, V3D_PROJ_TEST_NOP) != @@ -444,7 +444,7 @@ static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td } else if (t->options & CTX_OBJECT) { BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob); - copy_v3_v3(init_loc, td->ob->obmat[3]); + copy_v3_v3(init_loc, td->ob->object_to_world[3]); } eSnapMode hit = ED_transform_snap_object_project_view3d( @@ -511,56 +511,6 @@ void applySnappingIndividual(TransInfo *t) } } -void applyGridAbsolute(TransInfo *t) -{ - int i; - - if (!(activeSnap(t) && (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) { - return; - } - - float grid_size_x = (t->modifiers & MOD_PRECISION) ? t->snap_spatial_x[1] : t->snap_spatial_x[0]; - float grid_size_y = (t->modifiers & MOD_PRECISION) ? t->snap_spatial_y[1] : t->snap_spatial_y[0]; - float grid_size_z = grid_size_x; - - /* Early exit on unusable grid size. */ - if (grid_size_x == 0.0f || grid_size_y == 0.0f || grid_size_z == 0.0f) { - return; - } - - FOREACH_TRANS_DATA_CONTAINER (t, tc) { - TransData *td; - - for (i = 0, td = tc->data; i < tc->data_len; i++, td++) { - float iloc[3], loc[3], tvec[3]; - if (td->flag & TD_SKIP) { - continue; - } - - if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) { - continue; - } - - copy_v3_v3(iloc, td->loc); - if (tc->use_local_mat) { - mul_m4_v3(tc->mat, iloc); - } - else if (t->options & CTX_OBJECT) { - BKE_object_eval_transform_all(t->depsgraph, t->scene, td->ob); - copy_v3_v3(iloc, td->ob->obmat[3]); - } - - loc[0] = roundf(iloc[0] / grid_size_x) * grid_size_x; - loc[1] = roundf(iloc[1] / grid_size_y) * grid_size_y; - loc[2] = roundf(iloc[2] / grid_size_z) * grid_size_z; - - sub_v3_v3v3(tvec, loc, iloc); - mul_m3_v3(td->smtx, tvec); - add_v3_v3(td->loc, tvec); - } - } -} - void applySnappingAsGroup(TransInfo *t, float *vec) { if (!activeSnap_SnappingAsGroup(t)) { @@ -1187,7 +1137,7 @@ static void snap_calc_sequencer_fn(TransInfo *t, float *UNUSED(vec)) /** \name Target * \{ */ -static void snap_target_median_impl(TransInfo *t, float r_median[3]) +void tranform_snap_target_median_calc(const TransInfo *t, float r_median[3]) { int i_accum = 0; @@ -1223,28 +1173,6 @@ static void snap_target_median_impl(TransInfo *t, float r_median[3]) // TargetSnapOffset(t, NULL); } -static void snap_target_grid_ensure(TransInfo *t) -{ - /* Only need to calculate once. */ - if ((t->tsnap.status & TARGET_GRID_INIT) == 0) { - if (t->data_type == &TransConvertType_Cursor3D) { - /* Use a fallback when transforming the cursor. - * In this case the center is _not_ derived from the cursor which is being transformed. */ - copy_v3_v3(t->tsnap.snapTargetGrid, TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->data->iloc); - } - else if (t->around == V3D_AROUND_CURSOR) { - /* Use a fallback for cursor selection, - * this isn't useful as a global center for absolute grid snapping - * since its not based on the position of the selection. */ - snap_target_median_impl(t, t->tsnap.snapTargetGrid); - } - else { - copy_v3_v3(t->tsnap.snapTargetGrid, t->center_global); - } - t->tsnap.status |= TARGET_GRID_INIT; - } -} - static void TargetSnapOffset(TransInfo *t, TransData *td) { if (t->spacetype == SPACE_NODE && td != NULL) { @@ -1316,7 +1244,7 @@ static void TargetSnapMedian(TransInfo *t) { /* Only need to calculate once. */ if ((t->tsnap.status & TARGET_INIT) == 0) { - snap_target_median_impl(t, t->tsnap.snapTarget); + tranform_snap_target_median_calc(t, t->tsnap.snapTarget); t->tsnap.status |= TARGET_INIT; } } @@ -1654,66 +1582,6 @@ bool snapNodesTransform( /** \name snap Grid * \{ */ -static void snap_grid_apply(TransInfo *t, - const int max_index, - const float grid_dist_x, - const float grid_dist_y, - const float loc[3], - float r_out[3]) -{ - BLI_assert(max_index <= 2); - snap_target_grid_ensure(t); - const float *center_global = t->tsnap.snapTargetGrid; - const float *asp = t->aspect; - - float in[3]; - if (t->con.mode & CON_APPLY) { - BLI_assert(t->tsnap.snapElem == SCE_SNAP_MODE_NONE); - t->con.applyVec(t, NULL, NULL, loc, in); - } - else { - copy_v3_v3(in, loc); - } - - for (int i = 0; i <= max_index; i++) { - const float iter_fac = ((i == 1) ? grid_dist_y : grid_dist_x) * asp[i]; - r_out[i] = iter_fac * roundf((in[i] + center_global[i]) / iter_fac) - center_global[i]; - } -} - -bool transform_snap_grid(TransInfo *t, float *val) -{ - if (!activeSnap(t)) { - return false; - } - - if (!(t->tsnap.mode & SCE_SNAP_MODE_GRID) || validSnap(t)) { - /* Don't do grid snapping if there is a valid snap point. */ - return false; - } - - /* Don't do grid snapping if not in 3D viewport or UV editor */ - if (!ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) { - return false; - } - - if (t->mode != TFM_TRANSLATION) { - return false; - } - - float grid_dist_x = (t->modifiers & MOD_PRECISION) ? t->snap_spatial_x[1] : t->snap_spatial_x[0]; - float grid_dist_y = (t->modifiers & MOD_PRECISION) ? t->snap_spatial_y[1] : t->snap_spatial_y[0]; - - /* Early bailing out if no need to snap */ - if (grid_dist_x == 0.0f || grid_dist_y == 0.0f) { - return false; - } - - snap_grid_apply(t, t->idx_max, grid_dist_x, grid_dist_y, val, val); - t->tsnap.snapElem = SCE_SNAP_MODE_GRID; - return true; -} - static void snap_increment_apply_ex(const TransInfo *UNUSED(t), const int max_index, const float increment_val, diff --git a/source/blender/editors/transform/transform_snap.h b/source/blender/editors/transform/transform_snap.h index 2b78c554ad8..16d9062e978 100644 --- a/source/blender/editors/transform/transform_snap.h +++ b/source/blender/editors/transform/transform_snap.h @@ -38,10 +38,10 @@ bool snapNodesTransform(struct TransInfo *t, bool transformModeUseSnap(const TransInfo *t); +void tranform_snap_target_median_calc(const TransInfo *t, float r_median[3]); bool transform_snap_increment_ex(const TransInfo *t, bool use_local_space, float *r_val); bool transform_snap_increment(const TransInfo *t, float *val); float transform_snap_increment_get(const TransInfo *t); -bool transform_snap_grid(TransInfo *t, float *val); bool activeSnap(const TransInfo *t); bool activeSnap_SnappingIndividual(const TransInfo *t); @@ -52,7 +52,6 @@ bool validSnap(const TransInfo *t); void initSnapping(struct TransInfo *t, struct wmOperator *op); void freeSnapping(struct TransInfo *t); void applySnappingIndividual(TransInfo *t); -void applyGridAbsolute(TransInfo *t); void applySnappingAsGroup(TransInfo *t, float *vec); void resetSnapping(TransInfo *t); eRedrawFlag handleSnapping(TransInfo *t, const struct wmEvent *event); diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index 7971e1ca9af..24d76a50117 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -565,7 +565,7 @@ static void iter_snap_objects(SnapObjectContext *sctx, free_object_duplilist(lb); } - sob_callback(sctx, params, obj_eval, obj_eval->obmat, is_object_active, data); + sob_callback(sctx, params, obj_eval, obj_eval->object_to_world, is_object_active, data); } } @@ -1145,7 +1145,7 @@ static void raycast_obj_fn(SnapObjectContext *sctx, * \param r_index: Hit index or -1 when no valid index is found. * (currently only set to the polygon index when using `snap_to == SCE_SNAP_MODE_FACE_RAYCAST`). * \param r_ob: Hit object. - * \param r_obmat: Object matrix (may not be #Object.obmat with dupli-instances). + * \param r_obmat: Object matrix (may not be #Object.object_to_world with dupli-instances). * \param r_hit_list: List of #SnapObjectHitDepth (caller must free). */ static bool raycastObjects(SnapObjectContext *sctx, @@ -1483,7 +1483,7 @@ static void nearest_world_object_fn(SnapObjectContext *sctx, * \param r_no: Normal of nearest point on target surface. * \param r_index: Index of nearest polygon on target surface. * \param r_ob: Nearest target object. - * \param r_obmat: Nearest target matrix (may not be #Object.obmat with dupli-instances). + * \param r_obmat: Nearest target matrix (may not be #Object.object_to_world with dupli-instances). */ static bool nearestWorldObjects(SnapObjectContext *sctx, const struct SnapObjectParams *params, @@ -3177,7 +3177,7 @@ static void snap_obj_fn(SnapObjectContext *sctx, * \param r_index: Hit index or -1 when no valid index is found. * (currently only set to the polygon index when using `snap_to == SCE_SNAP_MODE_FACE_RAYCAST`). * \param r_ob: Hit object. - * \param r_obmat: Object matrix (may not be #Object.obmat with dupli-instances). + * \param r_obmat: Object matrix (may not be #Object.object_to_world with dupli-instances). */ static eSnapMode snapObjectsRay(SnapObjectContext *sctx, const SnapObjectParams *params, |