79 float gridf, imat[3][3], bmat[3][3], vec[3];
88 for (
Object *obedit : objects) {
106 copy_m3_m4(bmat, obedit->object_to_world().ptr());
113 add_v3_v3(vec, obedit->object_to_world().location());
114 vec[0] = gridf *
floorf(0.5f + vec[0] / gridf);
115 vec[1] = gridf *
floorf(0.5f + vec[1] / gridf);
116 vec[2] = gridf *
floorf(0.5f + vec[2] / gridf);
117 sub_v3_v3(vec, obedit->object_to_world().location());
130 for (
Object *ob_eval : objects_eval) {
134 invert_m4_m4(ob_eval->runtime->world_to_object.ptr(), ob_eval->object_to_world().ptr());
145 mul_m4_v3(ob_eval->object_to_world().ptr(), nLoc);
146 vec[0] = gridf *
floorf(0.5f + nLoc[0] / gridf);
147 vec[1] = gridf *
floorf(0.5f + nLoc[1] / gridf);
148 vec[2] = gridf *
floorf(0.5f + nLoc[2] / gridf);
150 mul_m4_v3(ob_eval->world_to_object().ptr(), vec);
158 pchan->
loc[0] = vec[0];
161 pchan->
loc[1] = vec[1];
164 pchan->
loc[2] = vec[2];
187 const bool use_transform_skip_children = (scene->toolsettings->transform_flag &
189 const bool use_transform_data_origin = (scene->toolsettings->transform_flag &
199 objects_eval.
append(ob_eval);
205 if (use_transform_skip_children) {
209 for (
Object *ob_eval : objects_eval) {
213 xcs = object::xform_skip_child_container_create();
214 object::xform_skip_child_container_item_ensure_from_array(
215 xcs, scene, view_layer, objects.data(), objects.size());
217 if (use_transform_data_origin) {
219 xds = object::data_xform_container_create();
226 for (
Object *ob_eval : objects_eval) {
228 vec[0] = -ob_eval->object_to_world().location()[0] +
229 gridf *
floorf(0.5f + ob_eval->object_to_world().location()[0] / gridf);
230 vec[1] = -ob_eval->object_to_world().location()[1] +
231 gridf *
floorf(0.5f + ob_eval->object_to_world().location()[1] / gridf);
232 vec[2] = -ob_eval->object_to_world().location()[2] +
233 gridf *
floorf(0.5f + ob_eval->object_to_world().location()[2] / gridf);
236 float originmat[3][3];
243 ob->
loc[0] = ob_eval->loc[0] + vec[0];
246 ob->
loc[1] = ob_eval->loc[1] + vec[1];
249 ob->
loc[2] = ob_eval->loc[2] + vec[2];
255 if (use_transform_data_origin) {
256 object::data_xform_container_item_ensure(xds, ob);
262 if (use_transform_skip_children) {
263 object::object_xform_skip_child_container_update_all(xcs, bmain,
depsgraph);
264 object::object_xform_skip_child_container_destroy(xcs);
266 if (use_transform_data_origin) {
267 object::data_xform_container_update_all(xds, bmain,
depsgraph);
268 object::data_xform_container_destroy(xds);
280 ot->
name =
"Snap Selection to Grid";
281 ot->
description =
"Snap selected item(s) to their nearest grid division";
282 ot->
idname =
"VIEW3D_OT_snap_selected_to_grid";
309 const float snap_target_global[3],
310 const bool use_offset,
311 const int pivot_point,
312 const bool use_toolsettings)
321 float imat[3][3], bmat[3][3];
322 float center_global[3];
323 float offset_global[3];
333 sub_v3_v3v3(offset_global, snap_target_global, center_global);
337 float snap_target_local[3];
340 scene, view_layer, v3d);
341 for (
const int ob_index : objects.index_range()) {
342 obedit = objects[ob_index];
361 copy_m3_m4(bmat, obedit->object_to_world().ptr());
365 sub_v3_v3v3(snap_target_local, snap_target_global, obedit->object_to_world().location());
369 float offset_local[3];
394 for (
Object *ob : objects) {
396 float snap_target_local[3];
398 invert_m4_m4(ob->runtime->world_to_object.ptr(), ob->object_to_world().ptr());
399 mul_v3_m4v3(snap_target_local, ob->world_to_object().ptr(), snap_target_global);
411 pchan->bone->flag &= ~BONE_TRANSFORM;
418 ((pchan->bone->parent &&
422 float cursor_pose[3];
425 mul_v3_m4v3(cursor_pose, ob->object_to_world().ptr(), pchan->pose_mat[3]);
428 mul_m4_v3(ob->world_to_object().ptr(), cursor_pose);
436 if (use_toolsettings) {
438 pchan->loc[0] = cursor_pose[0];
441 pchan->loc[1] = cursor_pose[1];
444 pchan->loc[2] = cursor_pose[2];
457 pchan->bone->flag &= ~BONE_TRANSFORM;
472 ob =
static_cast<Object *
>(ob->id.next))
474 ob->flag &= ~OB_DONE;
488 const bool use_transform_skip_children = use_toolsettings &&
489 (scene->toolsettings->transform_flag &
491 const bool use_transform_data_origin = use_toolsettings &&
492 (scene->toolsettings->transform_flag &
497 if (use_transform_skip_children) {
499 xcs = object::xform_skip_child_container_create();
500 object::xform_skip_child_container_item_ensure_from_array(
501 xcs, scene, view_layer, objects.data(), objects.size());
503 if (use_transform_data_origin) {
505 xds = object::data_xform_container_create();
509 for (
Object *ob : objects) {
510 object::data_xform_container_item_ensure(xds, ob);
518 for (
Object *ob : objects) {
523 float cursor_parent[3];
526 add_v3_v3v3(cursor_parent, ob->object_to_world().location(), offset_global);
529 copy_v3_v3(cursor_parent, snap_target_global);
532 sub_v3_v3(cursor_parent, ob->object_to_world().location());
535 float originmat[3][3], parentmat[4][4];
546 if (use_toolsettings) {
548 ob->loc[0] += cursor_parent[0];
551 ob->loc[1] += cursor_parent[1];
554 ob->loc[2] += cursor_parent[2];
567 if (use_transform_skip_children) {
568 object::object_xform_skip_child_container_update_all(xcs, bmain,
depsgraph);
569 object::object_xform_skip_child_container_destroy(xcs);
571 if (use_transform_data_origin) {
572 object::data_xform_container_update_all(xds, bmain,
depsgraph);
573 object::data_xform_container_destroy(xds);
584 const float snap_target_global[3],
585 const int pivot_point)
589 const bool use_offset =
true;
592 const bool use_toolsettings =
false;
594 C, op, snap_target_global, use_offset, pivot_point, use_toolsettings);
609 const float *snap_target_global = scene->cursor.location;
610 const int pivot_point = scene->toolsettings->transform_pivot_point;
621 ot->
name =
"Snap Selection to Cursor";
623 ot->
idname =
"VIEW3D_OT_snap_selected_to_cursor";
637 "If the selection should be snapped as a whole or by each object center");
649 float snap_target_global[3];
665 ot->
name =
"Snap Selection to Active";
666 ot->
description =
"Snap selected item(s) to the active item";
667 ot->
idname =
"VIEW3D_OT_snap_selected_to_active";
692 curs = scene->cursor.location;
694 curs[0] = gridf *
floorf(0.5f + curs[0] / gridf);
695 curs[1] = gridf *
floorf(0.5f + curs[1] / gridf);
696 curs[2] = gridf *
floorf(0.5f + curs[2] / gridf);
707 ot->
name =
"Snap Cursor to Grid";
708 ot->
description =
"Snap 3D cursor to the nearest grid division";
709 ot->
idname =
"VIEW3D_OT_snap_cursor_to_grid";
733 float min[3], max[3], mat[4][4],
pos[3], cammat[4][4];
741 copy_m4_m4(cammat, ob->object_to_world().ptr());
757 tracking, tracking_object, scene->r.cfra, imat);
787 float bmat[3][3], vec[3],
min[3], max[3], centroid[3];
797 for (
const int ob_index : objects.index_range()) {
798 obedit = objects[ob_index];
816 copy_m3_m4(bmat, obedit_eval->object_to_world().ptr());
822 add_v3_v3(vec, obedit_eval->object_to_world().location());
840 mul_m4_v3(obact_eval->object_to_world().ptr(), vec);
850 copy_v3_v3(vec, ob_eval->object_to_world().location());
885 const int pivot_point = scene->toolsettings->transform_pivot_point;
898 ot->
name =
"Snap Cursor to Selected";
899 ot->
description =
"Snap 3D cursor to the middle of the selected item(s)";
900 ot->
idname =
"VIEW3D_OT_snap_cursor_to_selected";
947 ot->
name =
"Snap Cursor to Active";
949 ot->
idname =
"VIEW3D_OT_snap_cursor_to_active";
981 ot->
name =
"Snap Cursor to World Origin";
983 ot->
idname =
"VIEW3D_OT_snap_cursor_to_center";
1005 if (mask.is_empty()) {
1006 return std::nullopt;
1008 return threading::parallel_reduce(
1013 mask.slice(range).foreach_index([&](const int i) {
1014 math::min_max(math::transform_point(transform, positions[i]), init.min, init.max);
1027 float centroid[3], vec[3], bmat[3][3];
1031 float ob_min[3], ob_max[3];
1037 obedit->object_to_world().ptr(),
1050 IndexMaskMemory memory;
1051 const IndexMask mask = curves::retrieve_selected_points(curves, memory);
1054 bke::crazyspace::get_evaluated_curves_deformation(obedit, ob_orig);
1057 obedit->object_to_world(), deformation.positions, mask);
1059 if (curves_bounds) {
1070 std::optional<Bounds<float3>> grease_pencil_bounds = std::nullopt;
1073 greasepencil::retrieve_editable_drawings(*scene, grease_pencil);
1076 if (curves.points_num() == 0) {
1080 IndexMaskMemory memory;
1081 const IndexMask points = greasepencil::retrieve_editable_and_selected_points(
1082 ob_orig, info.drawing, info.layer_index, memory);
1083 if (points.is_empty()) {
1088 bke::crazyspace::get_evaluated_grease_pencil_drawing_deformation(
1089 obedit, ob_orig, info.layer_index, info.frame_number);
1092 const float4x4 layer_to_world = layer.to_world_space(*obedit);
1094 grease_pencil_bounds = bounds::merge(
1095 grease_pencil_bounds,
1099 if (grease_pencil_bounds) {
1115 copy_m3_m4(bmat, obedit->object_to_world().ptr());
1121 add_v3_v3(vec, obedit->object_to_world().location());
Functions and classes to work with Actions.
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
bool ANIM_bonecoll_is_visible_pchan(const bArmature *armature, const bPoseChannel *pchan)
Functions to insert, delete or modify keyframes.
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void BKE_armature_loc_pose_to_bone(bPoseChannel *pchan, const float inloc[3], float outloc[3])
bool BKE_armature_bone_flag_test_recursive(const Bone *bone, int flag)
#define PBONE_VISIBLE(arm, bone)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Object * CTX_data_edit_object(const bContext *C)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
#define FOREACH_SELECTED_EDITABLE_OBJECT_END
#define FOREACH_SELECTED_OBJECT_BEGIN(_view_layer, _v3d, _instance)
#define FOREACH_SELECTED_EDITABLE_OBJECT_BEGIN(_view_layer, _v3d, _instance)
#define FOREACH_SELECTED_OBJECT_END
blender::Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode_unique_data(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
bool BKE_mball_minmax_ex(const MetaBall *mb, float min[3], float max[3], const float obmat[4][4], short flag)
General operations, lookup, etc. for blender objects.
bool BKE_object_flag_test_recursive(const Object *ob, short flag)
MovieClip * BKE_object_movieclip_get(Scene *scene, const Object *ob, bool use_default)
void BKE_object_get_parent_matrix(const Object *ob, Object *par, float r_parentmat[4][4])
void BKE_object_where_is_calc_ex(Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3])
blender::Vector< Object * > BKE_object_pose_array_get(const Scene *scene, ViewLayer *view_layer, View3D *v3d)
void BKE_report(ReportList *reports, eReportType type, const char *message)
void BKE_scene_graph_evaluated_ensure(Depsgraph *depsgraph, Main *bmain)
void BKE_tracking_get_camera_object_matrix(const struct Object *camera_object, float mat[4][4])
#define TRACK_SELECTED(track)
void BKE_tracking_camera_get_reconstructed_interpolate(struct MovieTracking *tracking, struct MovieTrackingObject *tracking_object, float framenr, float mat[4][4])
#define LISTBASE_FOREACH(type, var, list)
void mul_m3_v3(const float M[3][3], float r[3])
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void copy_m3_m4(float m1[3][3], const float m2[4][4])
bool invert_m3_m3(float inverse[3][3], const float mat[3][3])
void mul_m4_v3(const float M[4][4], float r[3])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
bool invert_m4(float mat[4][4])
void mul_m3_m4m4(float R[3][3], const float A[4][4], const float B[4][4])
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
#define INIT_MINMAX(min, max)
void DEG_id_tag_update(ID *id, unsigned int flags)
ViewLayer * DEG_get_evaluated_view_layer(const Depsgraph *graph)
Object * DEG_get_original_object(Object *object)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
Object is a sort of wrapper for general info.
#define OBPOSE_FROM_OBACT(ob)
@ SCE_XFORM_SKIP_CHILDREN
#define OBEDIT_FROM_OBACT(ob)
@ V3D_AROUND_CENTER_BOUNDS
@ V3D_SHOW_RECONSTRUCTION
#define ANIM_KS_LOCATION_ID
bool ED_operator_view3d_active(bContext *C)
bool ED_operator_region_view3d_active(bContext *C)
bool ED_transverts_check_obedit(const Object *obedit)
void ED_transverts_create_from_obedit(TransVertStore *tvs, const Object *obedit, int mode)
void ED_transverts_free(TransVertStore *tvs)
void ED_transverts_update_obedit(TransVertStore *tvs, Object *obedit)
float ED_view3d_grid_view_scale(const Scene *scene, const View3D *v3d, const ARegion *region, const char **r_grid_unit)
Read Guarded memory(de)allocation.
void ANIM_deselect_keys_in_animation_editors(bContext *C)
void append(const T &value)
local_group_size(16, 16) .push_constant(Type b
const Depsgraph * depsgraph
KeyingSet * ANIM_get_keyingset_for_autokeying(const Scene *scene, const char *transformKSName)
void autokeyframe_object(bContext *C, Scene *scene, Object *ob, Span< RNAPath > rna_paths)
bool is_autokey_on(const Scene *scene)
bool autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *pchan, KeyingSet *ks)
bool calc_active_center(Object *ob, bool select_only, float r_center[3])
bool shape_key_report_if_locked(const Object *obedit, ReportList *reports)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
static MatBase identity()
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
struct ReportList * reports
static int snap_curs_to_center_exec(bContext *C, wmOperator *)
static int snap_curs_to_grid_exec(bContext *C, wmOperator *)
void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot)
bool ED_view3d_snap_selected_to_location(bContext *C, wmOperator *op, const float snap_target_global[3], const int pivot_point)
static void bundle_midpoint(Scene *scene, Object *ob, float r_vec[3])
static bool snap_selected_to_location(bContext *C, wmOperator *op, const float snap_target_global[3], const bool use_offset, const int pivot_point, const bool use_toolsettings)
static bool snap_curs_to_sel_ex(bContext *C, const int pivot_point, float r_cursor[3])
void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
static int snap_selected_to_active_exec(bContext *C, wmOperator *op)
void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot)
static int snap_curs_to_sel_exec(bContext *C, wmOperator *)
static int snap_sel_to_grid_exec(bContext *C, wmOperator *op)
bool ED_view3d_minmax_verts(const Scene *scene, Object *obedit, float r_min[3], float r_max[3])
static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3])
static int snap_selected_to_cursor_exec(bContext *C, wmOperator *op)
static std::optional< blender::Bounds< blender::float3 > > bounds_min_max_with_transform(const blender::float4x4 &transform, const blender::Span< blender::float3 > positions, const blender::IndexMask &mask)
void VIEW3D_OT_snap_selected_to_active(wmOperatorType *ot)
void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
static int snap_curs_to_active_exec(bContext *C, wmOperator *)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)