2023-05-31 16:19:06 +02:00
|
|
|
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup edobj
|
2011-02-27 20:29:51 +00:00
|
|
|
*/
|
|
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <cstring>
|
2022-04-03 12:54:42 -05:00
|
|
|
#include <numeric>
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
|
2009-11-23 11:58:30 +00:00
|
|
|
#include "DNA_anim_types.h"
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
#include "DNA_armature_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_collection_types.h"
|
2024-09-13 11:08:37 +02:00
|
|
|
#include "DNA_grease_pencil_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_lattice_types.h"
|
|
|
|
|
#include "DNA_light_types.h"
|
2012-02-19 22:17:30 +00:00
|
|
|
#include "DNA_mesh_types.h"
|
2012-02-26 08:55:31 +00:00
|
|
|
#include "DNA_meta_types.h"
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
#include "DNA_object_types.h"
|
2023-01-02 10:49:57 -05:00
|
|
|
#include "DNA_pointcloud_types.h"
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
#include "BLI_array.hh"
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
#include "BLI_listbase.h"
|
Cleanup: reduce amount of math-related includes
Using ClangBuildAnalyzer on the whole Blender build, it was pointing
out that BLI_math.h is the heaviest "header hub" (i.e. non tiny file
that is included a lot).
However, there's very little (actually zero) source files in Blender
that need "all the math" (base, colors, vectors, matrices,
quaternions, intersection, interpolation, statistics, solvers and
time). A common use case is source files needing just vectors, or
just vectors & matrices, or just colors etc. Actually, 181 files
were including the whole math thing without needing it at all.
This change removes BLI_math.h completely, and instead in all the
places that need it, includes BLI_math_vector.h or BLI_math_color.h
and so on.
Change from that:
- BLI_math_color.h was included 1399 times -> now 408 (took 114.0sec
to parse -> now 36.3sec)
- BLI_simd.h 1403 -> 418 (109.7sec -> 34.9sec).
Full rebuild of Blender (Apple M1, Xcode, RelWithDebInfo) is not
affected much (342sec -> 334sec). Most of benefit would be when
someone's changing BLI_simd.h or BLI_math_color.h or similar files,
that now there's 3x fewer files result in a recompile.
Pull Request #110944
2023-08-09 11:39:20 +03:00
|
|
|
#include "BLI_math_geom.h"
|
|
|
|
|
#include "BLI_math_matrix.h"
|
2023-02-06 21:25:45 +01:00
|
|
|
#include "BLI_math_matrix.hh"
|
Cleanup: reduce amount of math-related includes
Using ClangBuildAnalyzer on the whole Blender build, it was pointing
out that BLI_math.h is the heaviest "header hub" (i.e. non tiny file
that is included a lot).
However, there's very little (actually zero) source files in Blender
that need "all the math" (base, colors, vectors, matrices,
quaternions, intersection, interpolation, statistics, solvers and
time). A common use case is source files needing just vectors, or
just vectors & matrices, or just colors etc. Actually, 181 files
were including the whole math thing without needing it at all.
This change removes BLI_math.h completely, and instead in all the
places that need it, includes BLI_math_vector.h or BLI_math_color.h
and so on.
Change from that:
- BLI_math_color.h was included 1399 times -> now 408 (took 114.0sec
to parse -> now 36.3sec)
- BLI_simd.h 1403 -> 418 (109.7sec -> 34.9sec).
Full rebuild of Blender (Apple M1, Xcode, RelWithDebInfo) is not
affected much (342sec -> 334sec). Most of benefit would be when
someone's changing BLI_simd.h or BLI_math_color.h or similar files,
that now there's 3x fewer files result in a recompile.
Pull Request #110944
2023-08-09 11:39:20 +03:00
|
|
|
#include "BLI_math_rotation.h"
|
2023-02-08 11:15:00 -05:00
|
|
|
#include "BLI_task.hh"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2022-03-18 15:50:46 -05:00
|
|
|
#include "BLI_vector.hh"
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
|
2023-11-16 11:41:55 +01:00
|
|
|
#include "BKE_armature.hh"
|
|
|
|
|
#include "BKE_context.hh"
|
|
|
|
|
#include "BKE_curve.hh"
|
2022-04-03 12:54:42 -05:00
|
|
|
#include "BKE_curves.hh"
|
2023-11-16 11:41:55 +01:00
|
|
|
#include "BKE_editmesh.hh"
|
2023-03-13 10:42:51 +01:00
|
|
|
#include "BKE_gpencil_legacy.h"
|
2024-09-13 11:08:37 +02:00
|
|
|
#include "BKE_grease_pencil.hh"
|
2024-01-20 19:17:36 +01:00
|
|
|
#include "BKE_idtype.hh"
|
2023-11-16 11:41:55 +01:00
|
|
|
#include "BKE_lattice.hh"
|
2024-01-23 15:18:09 -05:00
|
|
|
#include "BKE_layer.hh"
|
2024-01-15 12:44:04 -05:00
|
|
|
#include "BKE_lib_id.hh"
|
2025-02-07 17:47:16 +01:00
|
|
|
#include "BKE_library.hh"
|
2023-12-01 19:43:16 +01:00
|
|
|
#include "BKE_main.hh"
|
2024-01-24 11:33:47 -05:00
|
|
|
#include "BKE_mball.hh"
|
2023-03-12 22:29:15 +01:00
|
|
|
#include "BKE_mesh.hh"
|
2023-08-02 22:14:18 +02:00
|
|
|
#include "BKE_multires.hh"
|
2023-10-09 23:41:53 +02:00
|
|
|
#include "BKE_object.hh"
|
2024-02-10 18:34:29 +01:00
|
|
|
#include "BKE_report.hh"
|
2024-02-10 19:16:25 +01:00
|
|
|
#include "BKE_scene.hh"
|
2013-05-13 13:37:05 +00:00
|
|
|
#include "BKE_tracking.h"
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
|
2024-02-24 01:32:53 +01:00
|
|
|
#include "BLT_translation.hh"
|
|
|
|
|
|
2023-09-22 03:18:17 +02:00
|
|
|
#include "DEG_depsgraph.hh"
|
|
|
|
|
#include "DEG_depsgraph_query.hh"
|
2017-06-08 10:14:53 +02:00
|
|
|
|
2023-08-10 22:40:27 +02:00
|
|
|
#include "RNA_access.hh"
|
|
|
|
|
#include "RNA_define.hh"
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
|
2024-02-24 01:32:53 +01:00
|
|
|
#include "UI_interface.hh"
|
|
|
|
|
|
2023-08-04 23:11:22 +02:00
|
|
|
#include "WM_api.hh"
|
|
|
|
|
#include "WM_types.hh"
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
|
2024-07-18 14:48:00 +02:00
|
|
|
#include "ANIM_action.hh"
|
2023-10-12 15:44:58 +02:00
|
|
|
#include "ANIM_keyframing.hh"
|
2024-11-15 10:51:41 +01:00
|
|
|
#include "ANIM_keyingsets.hh"
|
2023-10-12 15:44:58 +02:00
|
|
|
|
2024-07-18 14:48:00 +02:00
|
|
|
#include "ED_anim_api.hh"
|
2023-08-05 02:57:52 +02:00
|
|
|
#include "ED_armature.hh"
|
|
|
|
|
#include "ED_keyframing.hh"
|
|
|
|
|
#include "ED_mesh.hh"
|
|
|
|
|
#include "ED_object.hh"
|
2023-08-04 23:11:22 +02:00
|
|
|
#include "ED_screen.hh"
|
2023-08-05 02:57:52 +02:00
|
|
|
#include "ED_view3d.hh"
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2025-04-21 16:12:56 +02:00
|
|
|
#include "RNA_access.hh"
|
|
|
|
|
#include "RNA_prototypes.hh"
|
|
|
|
|
|
2024-03-26 20:34:48 -04:00
|
|
|
#include "object_intern.hh"
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
|
2024-03-28 01:30:38 +01:00
|
|
|
namespace blender::ed::object {
|
2022-03-18 15:50:46 -05:00
|
|
|
|
2019-08-22 04:56:18 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Clear Transformation Utilities
|
|
|
|
|
* \{ */
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
|
2011-01-26 09:27:43 +00:00
|
|
|
/* clear location of object */
|
2016-07-09 11:52:09 +12:00
|
|
|
static void object_clear_loc(Object *ob, const bool clear_delta)
|
2011-01-26 09:27:43 +00:00
|
|
|
{
|
|
|
|
|
/* clear location if not locked */
|
2016-07-09 11:52:09 +12:00
|
|
|
if ((ob->protectflag & OB_LOCK_LOCX) == 0) {
|
|
|
|
|
ob->loc[0] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->dloc[0] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-09 11:52:09 +12:00
|
|
|
}
|
|
|
|
|
if ((ob->protectflag & OB_LOCK_LOCY) == 0) {
|
|
|
|
|
ob->loc[1] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->dloc[1] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-09 11:52:09 +12:00
|
|
|
}
|
|
|
|
|
if ((ob->protectflag & OB_LOCK_LOCZ) == 0) {
|
|
|
|
|
ob->loc[2] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->dloc[2] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-09 11:52:09 +12:00
|
|
|
}
|
2011-01-26 09:27:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* clear rotation of object */
|
2016-07-09 11:52:09 +12:00
|
|
|
static void object_clear_rot(Object *ob, const bool clear_delta)
|
2011-01-26 09:27:43 +00:00
|
|
|
{
|
|
|
|
|
/* clear rotations that aren't locked */
|
2012-04-28 15:42:27 +00:00
|
|
|
if (ob->protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) {
|
2011-01-26 09:27:43 +00:00
|
|
|
if (ob->protectflag & OB_LOCK_ROT4D) {
|
|
|
|
|
/* perform clamping on a component by component basis */
|
|
|
|
|
if (ob->rotmode == ROT_MODE_AXISANGLE) {
|
2016-07-09 11:52:09 +12:00
|
|
|
if ((ob->protectflag & OB_LOCK_ROTW) == 0) {
|
|
|
|
|
ob->rotAngle = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->drotAngle = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-09 11:52:09 +12:00
|
|
|
}
|
|
|
|
|
if ((ob->protectflag & OB_LOCK_ROTX) == 0) {
|
|
|
|
|
ob->rotAxis[0] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->drotAxis[0] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-09 11:52:09 +12:00
|
|
|
}
|
|
|
|
|
if ((ob->protectflag & OB_LOCK_ROTY) == 0) {
|
|
|
|
|
ob->rotAxis[1] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->drotAxis[1] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-09 11:52:09 +12:00
|
|
|
}
|
|
|
|
|
if ((ob->protectflag & OB_LOCK_ROTZ) == 0) {
|
|
|
|
|
ob->rotAxis[2] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->drotAxis[2] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-09 11:52:09 +12:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 00:18:34 +10:00
|
|
|
/* Check validity of axis - axis should never be 0,0,0
|
|
|
|
|
* (if so, then we make it rotate about y). */
|
2019-04-22 09:19:45 +10:00
|
|
|
if (IS_EQF(ob->rotAxis[0], ob->rotAxis[1]) && IS_EQF(ob->rotAxis[1], ob->rotAxis[2])) {
|
2011-01-26 09:27:43 +00:00
|
|
|
ob->rotAxis[1] = 1.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-09 11:52:09 +12:00
|
|
|
if (IS_EQF(ob->drotAxis[0], ob->drotAxis[1]) && IS_EQF(ob->drotAxis[1], ob->drotAxis[2]) &&
|
2019-04-22 09:19:45 +10:00
|
|
|
clear_delta)
|
|
|
|
|
{
|
2012-04-28 15:42:27 +00:00
|
|
|
ob->drotAxis[1] = 1.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2011-01-26 09:27:43 +00:00
|
|
|
}
|
|
|
|
|
else if (ob->rotmode == ROT_MODE_QUAT) {
|
2016-07-09 11:52:09 +12:00
|
|
|
if ((ob->protectflag & OB_LOCK_ROTW) == 0) {
|
|
|
|
|
ob->quat[0] = 1.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->dquat[0] = 1.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-09 11:52:09 +12:00
|
|
|
}
|
2016-07-11 08:45:00 +10:00
|
|
|
if ((ob->protectflag & OB_LOCK_ROTX) == 0) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->quat[1] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->dquat[1] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-11 08:45:00 +10:00
|
|
|
}
|
|
|
|
|
if ((ob->protectflag & OB_LOCK_ROTY) == 0) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->quat[2] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->dquat[2] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-11 08:45:00 +10:00
|
|
|
}
|
|
|
|
|
if ((ob->protectflag & OB_LOCK_ROTZ) == 0) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->quat[3] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->dquat[3] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-11 08:45:00 +10:00
|
|
|
}
|
2012-07-06 23:56:59 +00:00
|
|
|
/* TODO: does this quat need normalizing now? */
|
2011-01-26 09:27:43 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* the flag may have been set for the other modes, so just ignore the extra flag... */
|
2016-07-09 11:52:09 +12:00
|
|
|
if ((ob->protectflag & OB_LOCK_ROTX) == 0) {
|
|
|
|
|
ob->rot[0] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->drot[0] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-09 11:52:09 +12:00
|
|
|
}
|
|
|
|
|
if ((ob->protectflag & OB_LOCK_ROTY) == 0) {
|
|
|
|
|
ob->rot[1] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->drot[1] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2016-07-09 11:52:09 +12:00
|
|
|
}
|
|
|
|
|
if ((ob->protectflag & OB_LOCK_ROTZ) == 0) {
|
|
|
|
|
ob->rot[2] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->drot[2] = 0.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2011-01-26 09:27:43 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2011-01-26 09:27:43 +00:00
|
|
|
else {
|
|
|
|
|
/* perform clamping using euler form (3-components) */
|
2012-07-06 23:56:59 +00:00
|
|
|
/* FIXME: deltas are not handled for these cases yet... */
|
2011-01-26 09:27:43 +00:00
|
|
|
float eul[3], oldeul[3], quat1[4] = {0};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-01-26 09:27:43 +00:00
|
|
|
if (ob->rotmode == ROT_MODE_QUAT) {
|
2011-11-06 16:34:44 +00:00
|
|
|
copy_qt_qt(quat1, ob->quat);
|
2011-01-26 09:27:43 +00:00
|
|
|
quat_to_eul(oldeul, ob->quat);
|
|
|
|
|
}
|
|
|
|
|
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
|
|
|
|
|
axis_angle_to_eulO(oldeul, EULER_ORDER_DEFAULT, ob->rotAxis, ob->rotAngle);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
copy_v3_v3(oldeul, ob->rot);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-04-28 15:42:27 +00:00
|
|
|
eul[0] = eul[1] = eul[2] = 0.0f;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:19:45 +10:00
|
|
|
if (ob->protectflag & OB_LOCK_ROTX) {
|
2012-04-28 15:42:27 +00:00
|
|
|
eul[0] = oldeul[0];
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
|
|
|
|
if (ob->protectflag & OB_LOCK_ROTY) {
|
2012-04-28 15:42:27 +00:00
|
|
|
eul[1] = oldeul[1];
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
|
|
|
|
if (ob->protectflag & OB_LOCK_ROTZ) {
|
2012-04-28 15:42:27 +00:00
|
|
|
eul[2] = oldeul[2];
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-01-26 09:27:43 +00:00
|
|
|
if (ob->rotmode == ROT_MODE_QUAT) {
|
|
|
|
|
eul_to_quat(ob->quat, eul);
|
|
|
|
|
/* quaternions flip w sign to accumulate rotations correctly */
|
2012-04-28 15:42:27 +00:00
|
|
|
if ((quat1[0] < 0.0f && ob->quat[0] > 0.0f) || (quat1[0] > 0.0f && ob->quat[0] < 0.0f)) {
|
2011-01-26 09:27:43 +00:00
|
|
|
mul_qt_fl(ob->quat, -1.0f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
|
2012-04-28 15:42:27 +00:00
|
|
|
eulO_to_axis_angle(ob->rotAxis, &ob->rotAngle, eul, EULER_ORDER_DEFAULT);
|
2011-01-26 09:27:43 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
copy_v3_v3(ob->rot, eul);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2011-01-26 09:27:43 +00:00
|
|
|
}
|
2012-04-28 15:42:27 +00:00
|
|
|
} /* Duplicated in source/blender/editors/armature/editarmature.c */
|
2012-10-21 05:46:41 +00:00
|
|
|
else {
|
2011-01-26 09:27:43 +00:00
|
|
|
if (ob->rotmode == ROT_MODE_QUAT) {
|
2011-02-02 00:40:55 +00:00
|
|
|
unit_qt(ob->quat);
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
unit_qt(ob->dquat);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2011-01-26 09:27:43 +00:00
|
|
|
}
|
|
|
|
|
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
|
2011-02-02 00:40:55 +00:00
|
|
|
unit_axis_angle(ob->rotAxis, &ob->rotAngle);
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
unit_axis_angle(ob->drotAxis, &ob->drotAngle);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2011-01-26 09:27:43 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2011-02-02 00:40:55 +00:00
|
|
|
zero_v3(ob->rot);
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
zero_v3(ob->drot);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2011-01-26 09:27:43 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* clear scale of object */
|
2016-07-09 11:52:09 +12:00
|
|
|
static void object_clear_scale(Object *ob, const bool clear_delta)
|
2011-01-26 09:27:43 +00:00
|
|
|
{
|
|
|
|
|
/* clear scale factors which are not locked */
|
2012-04-28 15:42:27 +00:00
|
|
|
if ((ob->protectflag & OB_LOCK_SCALEX) == 0) {
|
2019-02-18 15:43:06 +11:00
|
|
|
ob->scale[0] = 1.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->dscale[0] = 1.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2011-01-26 09:27:43 +00:00
|
|
|
}
|
2012-04-28 15:42:27 +00:00
|
|
|
if ((ob->protectflag & OB_LOCK_SCALEY) == 0) {
|
2019-02-18 15:43:06 +11:00
|
|
|
ob->scale[1] = 1.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->dscale[1] = 1.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2011-01-26 09:27:43 +00:00
|
|
|
}
|
2012-04-28 15:42:27 +00:00
|
|
|
if ((ob->protectflag & OB_LOCK_SCALEZ) == 0) {
|
2019-02-18 15:43:06 +11:00
|
|
|
ob->scale[2] = 1.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
if (clear_delta) {
|
2016-07-09 11:52:09 +12:00
|
|
|
ob->dscale[2] = 1.0f;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2011-01-26 09:27:43 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* generic exec for clear-transform operators */
|
2025-03-20 21:11:06 +00:00
|
|
|
static wmOperatorStatus object_clear_transform_generic_exec(bContext *C,
|
|
|
|
|
wmOperator *op,
|
|
|
|
|
void (*clear_func)(Object *,
|
|
|
|
|
const bool),
|
|
|
|
|
const char default_ksName[])
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
{
|
2019-12-21 13:12:30 +11:00
|
|
|
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
|
|
|
|
Main *bmain = CTX_data_main(C);
|
2012-04-28 15:42:27 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-02-01 13:34:27 +11:00
|
|
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
2022-03-18 15:50:46 -05:00
|
|
|
/* May be null. */
|
2020-02-01 13:34:27 +11:00
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2011-01-26 09:27:43 +00:00
|
|
|
KeyingSet *ks;
|
2016-07-09 11:52:09 +12:00
|
|
|
const bool clear_delta = RNA_boolean_get(op->ptr, "clear_delta");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
BLI_assert(!ELEM(nullptr, clear_func, default_ksName));
|
2020-02-01 13:34:27 +11:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
Vector<Object *> objects;
|
|
|
|
|
FOREACH_SELECTED_EDITABLE_OBJECT_BEGIN (view_layer, v3d, ob) {
|
|
|
|
|
objects.append(ob);
|
2020-02-01 13:34:27 +11:00
|
|
|
}
|
2022-03-18 15:50:46 -05:00
|
|
|
FOREACH_SELECTED_EDITABLE_OBJECT_END;
|
2020-02-01 13:34:27 +11:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
if (objects.is_empty()) {
|
2011-01-26 09:27:43 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-21 13:12:30 +11:00
|
|
|
/* Support transforming the object data. */
|
2020-02-01 13:34:27 +11:00
|
|
|
const bool use_transform_skip_children = (scene->toolsettings->transform_flag &
|
|
|
|
|
SCE_XFORM_SKIP_CHILDREN);
|
2019-12-21 13:12:30 +11:00
|
|
|
const bool use_transform_data_origin = (scene->toolsettings->transform_flag &
|
|
|
|
|
SCE_XFORM_DATA_ORIGIN);
|
2023-06-03 08:36:28 +10:00
|
|
|
XFormObjectSkipChild_Container *xcs = nullptr;
|
|
|
|
|
XFormObjectData_Container *xds = nullptr;
|
2019-12-21 13:12:30 +11:00
|
|
|
|
2020-02-01 13:34:27 +11:00
|
|
|
if (use_transform_skip_children) {
|
|
|
|
|
BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
|
2024-03-28 01:30:38 +01:00
|
|
|
xcs = xform_skip_child_container_create();
|
|
|
|
|
xform_skip_child_container_item_ensure_from_array(
|
2022-09-14 21:30:20 +02:00
|
|
|
xcs, scene, view_layer, objects.data(), objects.size());
|
2020-02-01 13:34:27 +11:00
|
|
|
}
|
2019-12-21 13:12:30 +11:00
|
|
|
if (use_transform_data_origin) {
|
|
|
|
|
BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
|
2024-03-28 01:30:38 +01:00
|
|
|
xds = data_xform_container_create();
|
2019-12-21 13:12:30 +11:00
|
|
|
}
|
|
|
|
|
|
2010-09-30 11:56:39 +00:00
|
|
|
/* get KeyingSet to use */
|
2024-11-15 10:51:41 +01:00
|
|
|
ks = blender::animrig::get_keyingset_for_autokeying(scene, default_ksName);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-07-18 14:48:00 +02:00
|
|
|
if (blender::animrig::is_autokey_on(scene)) {
|
|
|
|
|
ANIM_deselect_keys_in_animation_editors(C);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
for (Object *ob : objects) {
|
2019-12-21 13:12:30 +11:00
|
|
|
if (use_transform_data_origin) {
|
2024-03-28 01:30:38 +01:00
|
|
|
data_xform_container_item_ensure(xds, ob);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2019-12-21 13:12:30 +11:00
|
|
|
|
|
|
|
|
/* run provided clearing function */
|
|
|
|
|
clear_func(ob, clear_delta);
|
|
|
|
|
|
2024-03-28 01:30:38 +01:00
|
|
|
animrig::autokeyframe_object(C, scene, ob, ks);
|
2019-12-21 13:12:30 +11:00
|
|
|
|
|
|
|
|
/* tag for updates */
|
|
|
|
|
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2020-02-01 13:34:27 +11:00
|
|
|
|
|
|
|
|
if (use_transform_skip_children) {
|
2024-03-28 01:30:38 +01:00
|
|
|
object_xform_skip_child_container_update_all(xcs, bmain, depsgraph);
|
|
|
|
|
object_xform_skip_child_container_destroy(xcs);
|
2020-02-01 13:34:27 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-21 13:12:30 +11:00
|
|
|
if (use_transform_data_origin) {
|
2024-03-28 01:30:38 +01:00
|
|
|
data_xform_container_update_all(xds, bmain, depsgraph);
|
|
|
|
|
data_xform_container_destroy(xds);
|
2019-12-21 13:12:30 +11:00
|
|
|
}
|
|
|
|
|
|
2009-12-13 11:49:17 +00:00
|
|
|
/* this is needed so children are also updated */
|
2022-03-18 15:50:46 -05:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, nullptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-22 04:56:18 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Clear Location Operator
|
|
|
|
|
* \{ */
|
2011-01-26 09:27:43 +00:00
|
|
|
|
2025-03-20 21:11:06 +00:00
|
|
|
static wmOperatorStatus object_location_clear_exec(bContext *C, wmOperator *op)
|
2011-01-26 09:27:43 +00:00
|
|
|
{
|
2011-10-23 05:08:02 +00:00
|
|
|
return object_clear_transform_generic_exec(C, op, object_clear_loc, ANIM_KS_LOCATION_ID);
|
2011-01-26 09:27:43 +00:00
|
|
|
}
|
|
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
void OBJECT_OT_location_clear(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Clear Location";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Clear the object's location";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "OBJECT_OT_location_clear";
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-05-17 09:18:03 +10:00
|
|
|
/* API callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = object_location_clear_exec;
|
|
|
|
|
ot->poll = ED_operator_scene_editable;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* flags */
|
2012-04-28 15:42:27 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-07-09 11:52:09 +12:00
|
|
|
/* properties */
|
|
|
|
|
ot->prop = RNA_def_boolean(
|
|
|
|
|
ot->srna,
|
|
|
|
|
"clear_delta",
|
|
|
|
|
false,
|
|
|
|
|
"Clear Delta",
|
|
|
|
|
"Clear delta location in addition to clearing the normal location transform");
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
|
|
|
|
|
2019-08-22 04:56:18 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Clear Rotation Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2025-03-20 21:11:06 +00:00
|
|
|
static wmOperatorStatus object_rotation_clear_exec(bContext *C, wmOperator *op)
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
{
|
2011-10-23 05:08:02 +00:00
|
|
|
return object_clear_transform_generic_exec(C, op, object_clear_rot, ANIM_KS_ROTATION_ID);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBJECT_OT_rotation_clear(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Clear Rotation";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Clear the object's rotation";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "OBJECT_OT_rotation_clear";
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-05-17 09:18:03 +10:00
|
|
|
/* API callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = object_rotation_clear_exec;
|
|
|
|
|
ot->poll = ED_operator_scene_editable;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* flags */
|
2012-04-28 15:42:27 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-07-09 11:52:09 +12:00
|
|
|
/* properties */
|
|
|
|
|
ot->prop = RNA_def_boolean(
|
|
|
|
|
ot->srna,
|
|
|
|
|
"clear_delta",
|
|
|
|
|
false,
|
|
|
|
|
"Clear Delta",
|
|
|
|
|
"Clear delta rotation in addition to clearing the normal rotation transform");
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
|
|
|
|
|
2019-08-22 04:56:18 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Clear Scale Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2025-03-20 21:11:06 +00:00
|
|
|
static wmOperatorStatus object_scale_clear_exec(bContext *C, wmOperator *op)
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
{
|
2011-10-23 05:08:02 +00:00
|
|
|
return object_clear_transform_generic_exec(C, op, object_clear_scale, ANIM_KS_SCALING_ID);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBJECT_OT_scale_clear(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Clear Scale";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Clear the object's scale";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "OBJECT_OT_scale_clear";
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-05-17 09:18:03 +10:00
|
|
|
/* API callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = object_scale_clear_exec;
|
|
|
|
|
ot->poll = ED_operator_scene_editable;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* flags */
|
2012-04-28 15:42:27 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-07-09 11:52:09 +12:00
|
|
|
/* properties */
|
|
|
|
|
ot->prop = RNA_def_boolean(
|
|
|
|
|
ot->srna,
|
|
|
|
|
"clear_delta",
|
|
|
|
|
false,
|
|
|
|
|
"Clear Delta",
|
|
|
|
|
"Clear delta scale in addition to clearing the normal scale transform");
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
|
|
|
|
|
2019-08-22 04:56:18 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Clear Origin Operator
|
|
|
|
|
* \{ */
|
2011-01-26 09:27:43 +00:00
|
|
|
|
2025-03-20 21:11:06 +00:00
|
|
|
static wmOperatorStatus object_origin_clear_exec(bContext *C, wmOperator * /*op*/)
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
{
|
2011-01-26 10:25:15 +00:00
|
|
|
float *v1, *v3;
|
|
|
|
|
float mat[3][3];
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
|
2012-04-30 16:22:40 +00:00
|
|
|
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
|
2011-01-26 10:25:15 +00:00
|
|
|
if (ob->parent) {
|
|
|
|
|
/* vectors pointed to by v1 and v3 will get modified */
|
2012-04-28 15:42:27 +00:00
|
|
|
v1 = ob->loc;
|
|
|
|
|
v3 = ob->parentinv[3];
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_m3_m4(mat, ob->parentinv);
|
2010-07-23 23:48:21 +00:00
|
|
|
negate_v3_v3(v3, v1);
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_m3_v3(mat, v3);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2011-08-12 18:06:05 +00:00
|
|
|
|
2018-12-06 17:52:37 +01:00
|
|
|
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
|
|
|
|
CTX_DATA_END;
|
|
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, nullptr);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBJECT_OT_origin_clear(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Clear Origin";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Clear the object's origin";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "OBJECT_OT_origin_clear";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2025-05-17 09:18:03 +10:00
|
|
|
/* API callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = object_origin_clear_exec;
|
|
|
|
|
ot->poll = ED_operator_scene_editable;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* flags */
|
2012-04-28 15:42:27 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
|
|
|
|
|
2019-08-22 04:56:18 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Apply Transformation Operator
|
|
|
|
|
* \{ */
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
|
|
|
|
|
/* use this when the loc/size/rot of the parent has changed but the children
|
2012-05-16 23:37:23 +00:00
|
|
|
* should stay in the same place, e.g. for apply-size-rot or object center */
|
2019-06-19 12:15:10 +02:00
|
|
|
static void ignore_parent_tx(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
{
|
2019-07-08 12:23:24 +02:00
|
|
|
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* a change was made, adjust the children to compensate */
|
2022-03-18 15:50:46 -05:00
|
|
|
LISTBASE_FOREACH (Object *, ob_child, &bmain->objects) {
|
2012-03-24 06:38:07 +00:00
|
|
|
if (ob_child->parent == ob) {
|
2025-05-02 15:08:29 +02:00
|
|
|
Object *ob_child_eval = DEG_get_evaluated(depsgraph, ob_child);
|
2024-02-14 16:14:49 +01:00
|
|
|
BKE_object_apply_mat4(ob_child_eval, ob_child_eval->object_to_world().ptr(), true, false);
|
2024-02-28 15:06:02 +01:00
|
|
|
invert_m4_m4(ob_child->parentinv,
|
|
|
|
|
BKE_object_calc_parent(depsgraph, scene, ob_child_eval).ptr());
|
2019-05-29 15:33:45 +02:00
|
|
|
/* Copy result of BKE_object_apply_mat4(). */
|
|
|
|
|
BKE_object_transform_copy(ob_child, ob_child_eval);
|
2019-07-08 12:23:24 +02:00
|
|
|
/* Make sure evaluated object is in a consistent state with the original one.
|
|
|
|
|
* It might be needed for applying transform on its children. */
|
|
|
|
|
copy_m4_m4(ob_child_eval->parentinv, ob_child->parentinv);
|
|
|
|
|
BKE_object_eval_transform_all(depsgraph, scene_eval, ob_child_eval);
|
2019-07-03 16:03:17 +02:00
|
|
|
/* Tag for update.
|
|
|
|
|
* This is because parent matrix did change, so in theory the child object might now be
|
|
|
|
|
* evaluated to a different location in another editing context. */
|
|
|
|
|
DEG_id_tag_update(&ob_child->id, ID_RECALC_TRANSFORM);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-19 14:12:34 +02:00
|
|
|
static void append_sorted_object_parent_hierarchy(Object *root_object,
|
|
|
|
|
Object *object,
|
|
|
|
|
Object **sorted_objects,
|
|
|
|
|
int *object_index)
|
|
|
|
|
{
|
2022-03-18 15:50:46 -05:00
|
|
|
if (!ELEM(object->parent, nullptr, root_object)) {
|
2019-06-19 14:12:34 +02:00
|
|
|
append_sorted_object_parent_hierarchy(
|
|
|
|
|
root_object, object->parent, sorted_objects, object_index);
|
|
|
|
|
}
|
2024-08-07 12:12:17 +02:00
|
|
|
if (object->id.tag & ID_TAG_DOIT) {
|
2019-06-19 14:12:34 +02:00
|
|
|
sorted_objects[*object_index] = object;
|
|
|
|
|
(*object_index)++;
|
2024-08-07 12:12:17 +02:00
|
|
|
object->id.tag &= ~ID_TAG_DOIT;
|
2019-06-19 14:12:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
static Array<Object *> sorted_selected_editable_objects(bContext *C)
|
2019-06-19 14:12:34 +02:00
|
|
|
{
|
|
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
|
|
|
|
|
|
/* Count all objects, but also tag all the selected ones. */
|
2024-08-07 12:12:17 +02:00
|
|
|
BKE_main_id_tag_all(bmain, ID_TAG_DOIT, false);
|
2024-07-23 15:49:28 +10:00
|
|
|
int objects_num = 0;
|
2019-06-19 14:12:34 +02:00
|
|
|
CTX_DATA_BEGIN (C, Object *, object, selected_editable_objects) {
|
2024-08-07 12:12:17 +02:00
|
|
|
object->id.tag |= ID_TAG_DOIT;
|
2024-07-23 15:49:28 +10:00
|
|
|
objects_num++;
|
2019-06-19 14:12:34 +02:00
|
|
|
}
|
|
|
|
|
CTX_DATA_END;
|
2024-07-23 15:49:28 +10:00
|
|
|
if (objects_num == 0) {
|
2022-03-18 15:50:46 -05:00
|
|
|
return {};
|
2019-06-19 14:12:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Append all the objects. */
|
2024-07-23 15:49:28 +10:00
|
|
|
Array<Object *> sorted_objects(objects_num);
|
2019-06-19 14:12:34 +02:00
|
|
|
int object_index = 0;
|
|
|
|
|
CTX_DATA_BEGIN (C, Object *, object, selected_editable_objects) {
|
2024-08-07 12:12:17 +02:00
|
|
|
if ((object->id.tag & ID_TAG_DOIT) == 0) {
|
2019-06-19 14:12:34 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
2022-03-18 15:50:46 -05:00
|
|
|
append_sorted_object_parent_hierarchy(object, object, sorted_objects.data(), &object_index);
|
2019-06-19 14:12:34 +02:00
|
|
|
}
|
|
|
|
|
CTX_DATA_END;
|
|
|
|
|
|
|
|
|
|
return sorted_objects;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-30 11:07:29 +02:00
|
|
|
/**
|
|
|
|
|
* Check if we need and can handle the special multiuser case.
|
|
|
|
|
*/
|
|
|
|
|
static bool apply_objects_internal_can_multiuser(bContext *C)
|
|
|
|
|
{
|
|
|
|
|
Object *obact = CTX_data_active_object(C);
|
|
|
|
|
|
2022-04-15 11:59:02 -05:00
|
|
|
if (ELEM(nullptr, obact, obact->data)) {
|
2022-03-30 11:07:29 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ID_REAL_USERS(obact->data) == 1) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool all_objects_same_data = true;
|
|
|
|
|
bool obact_selected = false;
|
|
|
|
|
|
|
|
|
|
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
|
|
|
|
|
if (ob->data != obact->data) {
|
|
|
|
|
all_objects_same_data = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ob == obact) {
|
|
|
|
|
obact_selected = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
CTX_DATA_END;
|
|
|
|
|
|
|
|
|
|
return all_objects_same_data && obact_selected;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2022-03-30 12:23:39 +02:00
|
|
|
* Check if the current selection need to be made into single user.
|
2022-03-30 11:07:29 +02:00
|
|
|
*
|
|
|
|
|
* It assumes that all selected objects share the same object data.
|
|
|
|
|
*/
|
|
|
|
|
static bool apply_objects_internal_need_single_user(bContext *C)
|
|
|
|
|
{
|
|
|
|
|
Object *ob = CTX_data_active_object(C);
|
|
|
|
|
BLI_assert(apply_objects_internal_can_multiuser(C));
|
|
|
|
|
|
|
|
|
|
/* Counting the number of objects is valid since it's known the
|
|
|
|
|
* selection is only made up of users of the active objects data. */
|
|
|
|
|
return (ID_REAL_USERS(ob->data) > CTX_DATA_COUNT(C, selected_editable_objects));
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-28 01:30:38 +01:00
|
|
|
static void transform_positions(MutableSpan<float3> positions, const float4x4 &matrix)
|
2023-01-02 10:49:57 -05:00
|
|
|
{
|
|
|
|
|
threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) {
|
|
|
|
|
for (float3 &position : positions.slice(range)) {
|
2023-02-06 21:25:45 +01:00
|
|
|
position = math::transform_point(matrix, position);
|
2023-01-02 10:49:57 -05:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-20 21:11:06 +00:00
|
|
|
static wmOperatorStatus apply_objects_internal(bContext *C,
|
|
|
|
|
ReportList *reports,
|
|
|
|
|
bool apply_loc,
|
|
|
|
|
bool apply_rot,
|
|
|
|
|
bool apply_scale,
|
|
|
|
|
bool do_props,
|
|
|
|
|
bool do_single_user)
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
{
|
2012-04-28 15:42:27 +00:00
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2019-07-25 16:36:22 +02:00
|
|
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
2012-10-12 14:35:10 +00:00
|
|
|
float rsmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale;
|
2013-11-26 06:39:14 +11:00
|
|
|
bool changed = true;
|
2022-03-30 12:23:39 +02:00
|
|
|
bool const do_multi_user = apply_objects_internal_can_multiuser(C);
|
2022-03-30 11:07:29 +02:00
|
|
|
float obact_invmat[4][4], obact_parent[4][4], obact_parentinv[4][4];
|
|
|
|
|
|
2022-03-30 12:23:39 +02:00
|
|
|
/* Only used when do_multi_user is set. */
|
2022-04-04 15:42:37 +10:00
|
|
|
Object *obact = nullptr;
|
2022-03-30 11:07:29 +02:00
|
|
|
bool make_single_user = false;
|
|
|
|
|
|
|
|
|
|
if (do_multi_user) {
|
|
|
|
|
obact = CTX_data_active_object(C);
|
2024-02-14 16:14:49 +01:00
|
|
|
invert_m4_m4(obact_invmat, obact->object_to_world().ptr());
|
2022-03-30 11:07:29 +02:00
|
|
|
|
2024-02-28 15:06:02 +01:00
|
|
|
copy_m4_m4(obact_parent, BKE_object_calc_parent(depsgraph, scene, obact).ptr());
|
2022-03-30 11:07:29 +02:00
|
|
|
copy_m4_m4(obact_parentinv, obact->parentinv);
|
|
|
|
|
|
|
|
|
|
if (apply_objects_internal_need_single_user(C)) {
|
|
|
|
|
if (do_single_user) {
|
|
|
|
|
make_single_user = true;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ID *obact_data = static_cast<ID *>(obact->data);
|
|
|
|
|
BKE_reportf(reports,
|
|
|
|
|
RPT_ERROR,
|
2022-04-04 15:42:37 +10:00
|
|
|
R"(Cannot apply to a multi user: Object "%s", %s "%s", aborting)",
|
2022-03-30 11:07:29 +02:00
|
|
|
obact->id.name + 2,
|
|
|
|
|
BKE_idtype_idcode_to_name(GS(obact_data->name)),
|
|
|
|
|
obact_data->name + 2);
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* first check if we can execute */
|
2012-04-30 16:22:40 +00:00
|
|
|
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
|
2018-07-31 10:22:19 +02:00
|
|
|
if (ELEM(ob->type,
|
|
|
|
|
OB_MESH,
|
|
|
|
|
OB_ARMATURE,
|
|
|
|
|
OB_LATTICE,
|
|
|
|
|
OB_MBALL,
|
2022-02-18 09:50:29 -06:00
|
|
|
OB_CURVES_LEGACY,
|
2018-07-31 10:22:19 +02:00
|
|
|
OB_SURF,
|
|
|
|
|
OB_FONT,
|
2023-01-02 10:49:57 -05:00
|
|
|
OB_CURVES,
|
2024-09-13 11:08:37 +02:00
|
|
|
OB_POINTCLOUD,
|
|
|
|
|
OB_GREASE_PENCIL))
|
2023-01-02 10:49:57 -05:00
|
|
|
{
|
2022-03-18 15:50:46 -05:00
|
|
|
ID *obdata = static_cast<ID *>(ob->data);
|
2022-03-30 11:07:29 +02:00
|
|
|
if (!do_multi_user && ID_REAL_USERS(obdata) > 1) {
|
2013-09-18 22:45:14 +00:00
|
|
|
BKE_reportf(reports,
|
|
|
|
|
RPT_ERROR,
|
2022-03-18 15:50:46 -05:00
|
|
|
R"(Cannot apply to a multi user: Object "%s", %s "%s", aborting)",
|
2013-09-18 22:45:14 +00:00
|
|
|
ob->id.name + 2,
|
2020-03-19 19:37:00 +01:00
|
|
|
BKE_idtype_idcode_to_name(GS(obdata->name)),
|
2013-09-18 22:45:14 +00:00
|
|
|
obdata->name + 2);
|
2013-11-26 06:39:14 +11:00
|
|
|
changed = false;
|
2012-03-20 23:09:28 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-05-16 14:53:09 +02:00
|
|
|
if (!ID_IS_EDITABLE(obdata) || ID_IS_OVERRIDE_LIBRARY(obdata)) {
|
2013-09-18 22:45:14 +00:00
|
|
|
BKE_reportf(reports,
|
|
|
|
|
RPT_ERROR,
|
2022-03-28 17:34:36 +02:00
|
|
|
R"(Cannot apply to library or override data: Object "%s", %s "%s", aborting)",
|
2013-09-18 22:45:14 +00:00
|
|
|
ob->id.name + 2,
|
2020-03-19 19:37:00 +01:00
|
|
|
BKE_idtype_idcode_to_name(GS(obdata->name)),
|
2013-09-18 22:45:14 +00:00
|
|
|
obdata->name + 2);
|
2013-11-26 06:39:14 +11:00
|
|
|
changed = false;
|
2013-02-11 10:56:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-02-18 09:50:29 -06:00
|
|
|
if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
|
2022-03-18 15:50:46 -05:00
|
|
|
ID *obdata = static_cast<ID *>(ob->data);
|
|
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-02-18 09:50:29 -06:00
|
|
|
if (((ob->type == OB_CURVES_LEGACY) && !(cu->flag & CU_3D)) && (apply_rot || apply_loc)) {
|
2013-09-18 22:45:14 +00:00
|
|
|
BKE_reportf(
|
|
|
|
|
reports,
|
|
|
|
|
RPT_ERROR,
|
2022-03-18 15:50:46 -05:00
|
|
|
R"(Rotation/Location can't apply to a 2D curve: Object "%s", %s "%s", aborting)",
|
2013-09-18 22:45:14 +00:00
|
|
|
ob->id.name + 2,
|
2020-03-19 19:37:00 +01:00
|
|
|
BKE_idtype_idcode_to_name(GS(obdata->name)),
|
2013-09-18 22:45:14 +00:00
|
|
|
obdata->name + 2);
|
2013-11-26 06:39:14 +11:00
|
|
|
changed = false;
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2015-10-12 12:34:17 +11:00
|
|
|
if (cu->key) {
|
|
|
|
|
BKE_reportf(reports,
|
|
|
|
|
RPT_ERROR,
|
2022-03-18 15:50:46 -05:00
|
|
|
R"(Can't apply to a curve with shape-keys: Object "%s", %s "%s", aborting)",
|
2015-10-12 12:34:17 +11:00
|
|
|
ob->id.name + 2,
|
2020-03-19 19:37:00 +01:00
|
|
|
BKE_idtype_idcode_to_name(GS(obdata->name)),
|
2015-10-12 12:34:17 +11:00
|
|
|
obdata->name + 2);
|
|
|
|
|
changed = false;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-31 10:22:19 +02:00
|
|
|
if (ob->type == OB_FONT) {
|
|
|
|
|
if (apply_rot || apply_loc) {
|
2022-12-01 15:21:59 -06:00
|
|
|
BKE_reportf(reports,
|
|
|
|
|
RPT_ERROR,
|
2022-12-09 15:41:05 -06:00
|
|
|
"Text objects can only have their scale applied: \"%s\"",
|
2022-12-01 15:21:59 -06:00
|
|
|
ob->id.name + 2);
|
2018-07-31 10:22:19 +02:00
|
|
|
changed = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
if (ob->type == OB_LAMP) {
|
2022-03-18 15:50:46 -05:00
|
|
|
Light *la = static_cast<Light *>(ob->data);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
if (la->type == LA_AREA) {
|
2013-11-26 06:39:14 +11:00
|
|
|
if (apply_rot || apply_loc) {
|
2018-07-31 10:22:19 +02:00
|
|
|
BKE_reportf(reports,
|
2012-05-20 11:06:46 +00:00
|
|
|
RPT_ERROR,
|
|
|
|
|
"Area Lights can only have scale applied: \"%s\"",
|
|
|
|
|
ob->id.name + 2);
|
2013-11-26 06:39:14 +11:00
|
|
|
changed = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-04-30 16:22:40 +00:00
|
|
|
CTX_DATA_END;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:19:45 +10:00
|
|
|
if (!changed) {
|
2012-05-05 14:03:12 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-05 14:03:12 +00:00
|
|
|
changed = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* now execute */
|
2022-03-30 11:07:29 +02:00
|
|
|
|
|
|
|
|
if (make_single_user) {
|
|
|
|
|
/* Make single user. */
|
2024-03-28 01:30:38 +01:00
|
|
|
single_obdata_user_make(bmain, scene, obact);
|
2022-03-30 11:07:29 +02:00
|
|
|
BKE_main_id_newptr_and_tag_clear(bmain);
|
2022-04-04 15:42:37 +10:00
|
|
|
WM_event_add_notifier(C, NC_WINDOW, nullptr);
|
2022-03-30 11:07:29 +02:00
|
|
|
DEG_relations_tag_update(bmain);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
Array<Object *> objects = sorted_selected_editable_objects(C);
|
|
|
|
|
if (objects.is_empty()) {
|
2019-06-19 14:12:34 +02:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-30 06:16:38 +02:00
|
|
|
bool has_non_invertable_matrix = false;
|
|
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
for (Object *ob : objects) {
|
2010-10-14 02:05:37 +00:00
|
|
|
/* calculate rotation/scale matrix */
|
2019-04-22 09:19:45 +10:00
|
|
|
if (apply_scale && apply_rot) {
|
2014-04-01 11:34:00 +11:00
|
|
|
BKE_object_to_mat3(ob, rsmat);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
|
|
|
|
else if (apply_scale) {
|
2012-05-05 14:03:12 +00:00
|
|
|
BKE_object_scale_to_mat3(ob, rsmat);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
else if (apply_rot) {
|
2012-10-12 14:35:10 +00:00
|
|
|
float tmat[3][3], timat[3][3];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* simple rotation matrix */
|
|
|
|
|
BKE_object_rot_to_mat3(ob, rsmat, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* correct for scale, note mul_m3_m3m3 has swapped args! */
|
2012-05-05 14:03:12 +00:00
|
|
|
BKE_object_scale_to_mat3(ob, tmat);
|
2025-04-30 06:16:38 +02:00
|
|
|
if (!invert_m3_m3(timat, tmat)) {
|
|
|
|
|
BKE_reportf(reports,
|
|
|
|
|
RPT_WARNING,
|
|
|
|
|
"%s \"%s\" %s",
|
|
|
|
|
RPT_("Object"),
|
|
|
|
|
ob->id.name + 2,
|
|
|
|
|
RPT_("have non-invertable transformation matrix, not applying transform."));
|
|
|
|
|
has_non_invertable_matrix = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2010-10-14 02:05:37 +00:00
|
|
|
mul_m3_m3m3(rsmat, timat, rsmat);
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_m3_m3m3(rsmat, rsmat, tmat);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-04-22 09:19:45 +10:00
|
|
|
else {
|
2009-11-10 20:43:45 +00:00
|
|
|
unit_m3(rsmat);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_m4_m3(mat, rsmat);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* calculate translation */
|
2012-04-28 15:42:27 +00:00
|
|
|
if (apply_loc) {
|
2022-06-27 10:37:09 -03:00
|
|
|
add_v3_v3v3(mat[3], ob->loc, ob->dloc);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-08-11 16:20:30 +00:00
|
|
|
if (!(apply_scale && apply_rot)) {
|
2018-04-06 12:07:27 +02:00
|
|
|
float tmat[3][3];
|
|
|
|
|
/* correct for scale and rotation that is still applied */
|
|
|
|
|
BKE_object_to_mat3(ob, obmat);
|
|
|
|
|
invert_m3_m3(iobmat, obmat);
|
|
|
|
|
mul_m3_m3m3(tmat, rsmat, iobmat);
|
2010-10-14 02:05:37 +00:00
|
|
|
mul_m3_v3(tmat, mat[3]);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* apply to object data */
|
2022-03-30 11:07:29 +02:00
|
|
|
if (do_multi_user && ob != obact) {
|
|
|
|
|
/* Don't apply, just set the new object data, the correct
|
|
|
|
|
* transformations will happen later. */
|
|
|
|
|
id_us_min((ID *)ob->data);
|
|
|
|
|
ob->data = obact->data;
|
|
|
|
|
id_us_plus((ID *)ob->data);
|
|
|
|
|
}
|
|
|
|
|
else if (ob->type == OB_MESH) {
|
2023-12-08 16:40:06 -05:00
|
|
|
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:19:45 +10:00
|
|
|
if (apply_scale) {
|
2018-06-06 15:50:24 +02:00
|
|
|
multiresModifier_scale_disp(depsgraph, scene, ob);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-06 15:50:24 +02:00
|
|
|
/* adjust data */
|
2025-03-28 11:36:39 -04:00
|
|
|
bke::mesh_transform(*mesh, float4x4(mat), true);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2012-03-20 23:09:28 +00:00
|
|
|
else if (ob->type == OB_ARMATURE) {
|
2022-03-18 15:50:46 -05:00
|
|
|
bArmature *arm = static_cast<bArmature *>(ob->data);
|
2019-08-23 11:53:45 +10:00
|
|
|
BKE_armature_transform(arm, mat, do_props);
|
2012-03-20 23:09:28 +00:00
|
|
|
}
|
2013-02-11 10:56:21 +00:00
|
|
|
else if (ob->type == OB_LATTICE) {
|
2022-03-18 15:50:46 -05:00
|
|
|
Lattice *lt = static_cast<Lattice *>(ob->data);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-11 22:16:44 +10:00
|
|
|
BKE_lattice_transform(lt, mat, true);
|
2013-02-11 10:56:21 +00:00
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
else if (ob->type == OB_MBALL) {
|
2022-03-18 15:50:46 -05:00
|
|
|
MetaBall *mb = static_cast<MetaBall *>(ob->data);
|
2017-08-11 22:16:44 +10:00
|
|
|
BKE_mball_transform(mb, mat, do_props);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2022-02-18 09:50:29 -06:00
|
|
|
else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
|
2022-03-18 15:50:46 -05:00
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
2015-10-12 12:34:17 +11:00
|
|
|
scale = mat3_to_scale(rsmat);
|
|
|
|
|
BKE_curve_transform_ex(cu, mat, true, do_props, scale);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2015-10-12 12:34:17 +11:00
|
|
|
else if (ob->type == OB_FONT) {
|
2022-03-18 15:50:46 -05:00
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-10-12 12:34:17 +11:00
|
|
|
scale = mat3_to_scale(rsmat);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-09 18:41:07 +02:00
|
|
|
for (int i = 0; i < cu->totbox; i++) {
|
2015-10-12 12:34:17 +11:00
|
|
|
TextBox *tb = &cu->tb[i];
|
2017-08-06 19:47:25 +10:00
|
|
|
tb->x *= scale;
|
2015-10-12 12:34:17 +11:00
|
|
|
tb->y *= scale;
|
|
|
|
|
tb->w *= scale;
|
|
|
|
|
tb->h *= scale;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-11 22:16:44 +10:00
|
|
|
if (do_props) {
|
|
|
|
|
cu->fsize *= scale;
|
|
|
|
|
}
|
2015-10-12 12:34:17 +11:00
|
|
|
}
|
2022-04-03 12:54:42 -05:00
|
|
|
else if (ob->type == OB_CURVES) {
|
|
|
|
|
Curves &curves = *static_cast<Curves *>(ob->data);
|
2023-02-06 21:25:45 +01:00
|
|
|
curves.geometry.wrap().transform(float4x4(mat));
|
2023-01-31 18:45:34 +01:00
|
|
|
curves.geometry.wrap().calculate_bezier_auto_handles();
|
2022-04-03 12:54:42 -05:00
|
|
|
}
|
2024-09-13 11:08:37 +02:00
|
|
|
else if (ob->type == OB_GREASE_PENCIL) {
|
|
|
|
|
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
|
|
|
|
|
|
|
|
|
|
const float scalef = mat4_to_scale(mat);
|
|
|
|
|
|
|
|
|
|
for (const int layer_i : grease_pencil.layers().index_range()) {
|
2024-09-23 13:54:02 +02:00
|
|
|
bke::greasepencil::Layer &layer = grease_pencil.layer(layer_i);
|
2024-09-13 11:08:37 +02:00
|
|
|
const float4x4 layer_to_object = layer.to_object_space(*ob);
|
|
|
|
|
const float4x4 object_to_layer = math::invert(layer_to_object);
|
|
|
|
|
const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.frames();
|
|
|
|
|
frames.foreach_item(
|
|
|
|
|
[&](bke::greasepencil::FramesMapKeyT /*key*/, GreasePencilFrame frame) {
|
|
|
|
|
GreasePencilDrawingBase *base = grease_pencil.drawing(frame.drawing_index);
|
|
|
|
|
if (base->type != GP_DRAWING) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
bke::greasepencil::Drawing &drawing =
|
|
|
|
|
reinterpret_cast<GreasePencilDrawing *>(base)->wrap();
|
|
|
|
|
bke::CurvesGeometry &curves = drawing.strokes_for_write();
|
|
|
|
|
MutableSpan<float> radii = drawing.radii_for_write();
|
|
|
|
|
threading::parallel_for(radii.index_range(), 8192, [&](const IndexRange range) {
|
|
|
|
|
for (const int i : range) {
|
|
|
|
|
radii[i] *= scalef;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
curves.transform(object_to_layer * float4x4(mat) * layer_to_object);
|
|
|
|
|
curves.calculate_bezier_auto_handles();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-02 10:49:57 -05:00
|
|
|
else if (ob->type == OB_POINTCLOUD) {
|
|
|
|
|
PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data);
|
2023-12-20 13:16:41 -05:00
|
|
|
transform_positions(pointcloud.positions_for_write(), float4x4(mat));
|
|
|
|
|
pointcloud.tag_positions_changed();
|
2023-01-02 10:49:57 -05:00
|
|
|
}
|
2013-05-13 13:37:05 +00:00
|
|
|
else if (ob->type == OB_CAMERA) {
|
2013-09-09 11:37:37 +00:00
|
|
|
MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-05-13 13:37:05 +00:00
|
|
|
/* applying scale on camera actually scales clip's reconstruction.
|
|
|
|
|
* of there's clip assigned to camera nothing to do actually.
|
|
|
|
|
*/
|
2019-04-22 09:19:45 +10:00
|
|
|
if (!clip) {
|
2013-05-13 13:37:05 +00:00
|
|
|
continue;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:19:45 +10:00
|
|
|
if (apply_scale) {
|
2019-02-18 15:43:06 +11:00
|
|
|
BKE_tracking_reconstruction_scale(&clip->tracking, ob->scale);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2013-05-13 13:37:05 +00:00
|
|
|
}
|
2013-09-02 22:57:22 +00:00
|
|
|
else if (ob->type == OB_EMPTY) {
|
2018-06-04 09:31:30 +02:00
|
|
|
/* It's possible for empties too, even though they don't
|
2013-09-02 22:57:22 +00:00
|
|
|
* really have obdata, since we can simply apply the maximum
|
|
|
|
|
* scaling to the empty's drawsize.
|
|
|
|
|
*
|
|
|
|
|
* Core Assumptions:
|
2018-06-04 09:31:30 +02:00
|
|
|
* 1) Most scaled empties have uniform scaling
|
2013-09-02 22:57:22 +00:00
|
|
|
* (i.e. for visibility reasons), AND/OR
|
|
|
|
|
* 2) Preserving non-uniform scaling is not that important,
|
|
|
|
|
* and is something that many users would be willing to
|
|
|
|
|
* sacrifice for having an easy way to do this.
|
|
|
|
|
*/
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-03-27 08:09:04 +01:00
|
|
|
if (apply_scale) {
|
2019-02-18 15:43:06 +11:00
|
|
|
float max_scale = max_fff(fabsf(ob->scale[0]), fabsf(ob->scale[1]), fabsf(ob->scale[2]));
|
2014-05-05 15:41:08 +10:00
|
|
|
ob->empty_drawsize *= max_scale;
|
2013-09-02 22:57:22 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-04-30 22:05:03 +02:00
|
|
|
else if (ob->type == OB_LAMP) {
|
2022-03-18 15:50:46 -05:00
|
|
|
Light *la = static_cast<Light *>(ob->data);
|
2018-04-30 22:05:03 +02:00
|
|
|
if (la->type != LA_AREA) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-04-30 22:05:03 +02:00
|
|
|
bool keeps_aspect_ratio = compare_ff_relative(rsmat[0][0], rsmat[1][1], FLT_EPSILON, 64);
|
|
|
|
|
if ((la->area_shape == LA_AREA_SQUARE) && !keeps_aspect_ratio) {
|
|
|
|
|
la->area_shape = LA_AREA_RECT;
|
|
|
|
|
la->area_sizey = la->area_size;
|
|
|
|
|
}
|
Cycles/Eevee: Implement disk and ellipse shapes for area lamps
The implementation is pretty straightforward.
In Cycles, sampling the shapes is currently done w.r.t. area instead of solid angle.
There is a paper on solid angle sampling for disks [1], but the described algorithm is based on
simply sampling the enclosing square and rejecting samples outside of the disk, which is not exactly
great for Cycles' RNG (we'd need to setup a LCG for the repeated sampling) and for GPU divergence.
Even worse, the algorithm is only defined for disks. For ellipses, the basic idea still works, but a
way to analytically calculate the solid angle is required. This is technically possible [2], but the
calculation is extremely complex and still requires a lookup table for the Heuman Lambda function.
Therefore, I've decided to not implement that for now, we could still look into it later on.
In Eevee, the code uses the existing ltc_evaluate_disk to implement the lighting calculations.
[1]: "Solid Angle Sampling of Disk and Cylinder Lights"
[2]: "Analytical solution for the solid angle subtended at any point by an ellipse via a point source radiation vector potential"
Reviewers: sergey, brecht, fclem
Differential Revision: https://developer.blender.org/D3171
2018-05-24 03:50:16 +02:00
|
|
|
else if ((la->area_shape == LA_AREA_DISK) && !keeps_aspect_ratio) {
|
|
|
|
|
la->area_shape = LA_AREA_ELLIPSE;
|
|
|
|
|
la->area_sizey = la->area_size;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-04-30 22:05:03 +02:00
|
|
|
la->area_size *= rsmat[0][0];
|
|
|
|
|
la->area_sizey *= rsmat[1][1];
|
|
|
|
|
la->area_sizez *= rsmat[2][2];
|
2024-10-15 20:24:32 +02:00
|
|
|
|
|
|
|
|
/* Explicit tagging is required for Lamp ID because, unlike Geometry IDs like Mesh,
|
|
|
|
|
* it is not covered by the `ID_RECALC_GEOMETRY` flag applied to the object at the end
|
|
|
|
|
* of this loop. */
|
|
|
|
|
DEG_id_tag_update(&la->id, ID_RECALC_PARAMETERS);
|
2018-04-30 22:05:03 +02:00
|
|
|
}
|
2013-05-13 13:37:05 +00:00
|
|
|
else {
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
continue;
|
2013-05-13 13:37:05 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-30 11:07:29 +02:00
|
|
|
if (do_multi_user && ob != obact) {
|
|
|
|
|
float _obmat[4][4], _iobmat[4][4];
|
|
|
|
|
float _mat[4][4];
|
|
|
|
|
|
2024-02-14 16:14:49 +01:00
|
|
|
copy_m4_m4(_obmat, ob->object_to_world().ptr());
|
2022-03-30 11:07:29 +02:00
|
|
|
invert_m4_m4(_iobmat, _obmat);
|
|
|
|
|
|
|
|
|
|
copy_m4_m4(_mat, _obmat);
|
|
|
|
|
mul_m4_m4_post(_mat, obact_invmat);
|
|
|
|
|
mul_m4_m4_post(_mat, obact_parent);
|
|
|
|
|
mul_m4_m4_post(_mat, obact_parentinv);
|
|
|
|
|
|
|
|
|
|
if (apply_loc && apply_scale && apply_rot) {
|
|
|
|
|
BKE_object_apply_mat4(ob, _mat, false, true);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2024-03-28 01:30:38 +01:00
|
|
|
Object ob_temp = dna::shallow_copy(*ob);
|
2022-03-30 11:07:29 +02:00
|
|
|
BKE_object_apply_mat4(&ob_temp, _mat, false, true);
|
|
|
|
|
|
|
|
|
|
if (apply_loc) {
|
|
|
|
|
copy_v3_v3(ob->loc, ob_temp.loc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (apply_scale) {
|
|
|
|
|
copy_v3_v3(ob->scale, ob_temp.scale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (apply_rot) {
|
|
|
|
|
copy_v4_v4(ob->quat, ob_temp.quat);
|
|
|
|
|
copy_v3_v3(ob->rot, ob_temp.rot);
|
|
|
|
|
copy_v3_v3(ob->rotAxis, ob_temp.rotAxis);
|
|
|
|
|
ob->rotAngle = ob_temp.rotAngle;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2022-03-30 11:07:29 +02:00
|
|
|
else {
|
|
|
|
|
if (apply_loc) {
|
|
|
|
|
zero_v3(ob->loc);
|
2022-06-27 10:37:09 -03:00
|
|
|
zero_v3(ob->dloc);
|
2022-03-30 11:07:29 +02:00
|
|
|
}
|
|
|
|
|
if (apply_scale) {
|
2022-06-27 10:37:09 -03:00
|
|
|
copy_v3_fl(ob->scale, 1.0f);
|
|
|
|
|
copy_v3_fl(ob->dscale, 1.0f);
|
2022-03-30 11:07:29 +02:00
|
|
|
}
|
|
|
|
|
if (apply_rot) {
|
|
|
|
|
zero_v3(ob->rot);
|
2022-06-27 10:37:09 -03:00
|
|
|
zero_v3(ob->drot);
|
2022-03-30 11:07:29 +02:00
|
|
|
unit_qt(ob->quat);
|
2022-08-24 17:19:31 +10:00
|
|
|
unit_qt(ob->dquat);
|
2022-03-30 11:07:29 +02:00
|
|
|
unit_axis_angle(ob->rotAxis, &ob->rotAngle);
|
2022-08-24 17:19:31 +10:00
|
|
|
unit_axis_angle(ob->drotAxis, &ob->drotAngle);
|
2022-03-30 11:07:29 +02:00
|
|
|
}
|
2009-11-22 06:19:30 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-05-02 15:08:29 +02:00
|
|
|
Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
|
2019-05-29 15:33:45 +02:00
|
|
|
BKE_object_transform_copy(ob_eval, ob);
|
|
|
|
|
|
|
|
|
|
BKE_object_where_is_calc(depsgraph, scene, ob_eval);
|
2012-04-28 15:42:27 +00:00
|
|
|
if (ob->type == OB_ARMATURE) {
|
2019-05-29 15:33:45 +02:00
|
|
|
/* needed for bone parents */
|
2022-03-18 15:50:46 -05:00
|
|
|
BKE_armature_copy_bone_transforms(static_cast<bArmature *>(ob_eval->data),
|
|
|
|
|
static_cast<bArmature *>(ob->data));
|
2019-05-29 15:33:45 +02:00
|
|
|
BKE_pose_where_is(depsgraph, scene, ob_eval);
|
2011-04-20 04:11:12 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-19 12:15:10 +02:00
|
|
|
ignore_parent_tx(bmain, depsgraph, scene, ob);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-12-06 17:52:37 +01:00
|
|
|
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-11-26 06:39:14 +11:00
|
|
|
changed = true;
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2019-06-19 14:12:34 +02:00
|
|
|
|
2013-11-26 06:39:14 +11:00
|
|
|
if (!changed) {
|
2013-08-28 04:17:48 +00:00
|
|
|
BKE_report(reports, RPT_WARNING, "Objects have no data to transform");
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2013-08-28 04:17:48 +00:00
|
|
|
}
|
2025-04-30 06:16:38 +02:00
|
|
|
if (has_non_invertable_matrix) {
|
|
|
|
|
BKE_report(reports, RPT_WARNING, "Failed to apply rotation to some of the objects");
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, nullptr);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-20 21:11:06 +00:00
|
|
|
static wmOperatorStatus visual_transform_apply_exec(bContext *C, wmOperator * /*op*/)
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
{
|
2012-04-28 15:42:27 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2019-07-25 16:36:22 +02:00
|
|
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
2013-11-26 06:39:14 +11:00
|
|
|
bool changed = false;
|
2017-07-21 11:53:13 +02:00
|
|
|
|
2012-04-30 16:22:40 +00:00
|
|
|
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
|
2025-05-02 15:08:29 +02:00
|
|
|
Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
|
2019-06-04 15:17:23 +02:00
|
|
|
BKE_object_where_is_calc(depsgraph, scene, ob_eval);
|
2024-02-14 16:14:49 +01:00
|
|
|
BKE_object_apply_mat4(ob_eval, ob_eval->object_to_world().ptr(), true, true);
|
2019-06-04 15:17:23 +02:00
|
|
|
BKE_object_transform_copy(ob, ob_eval);
|
2010-11-08 22:32:28 +00:00
|
|
|
|
|
|
|
|
/* update for any children that may get moved */
|
2018-12-06 17:52:37 +01:00
|
|
|
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2013-11-26 06:39:14 +11:00
|
|
|
changed = true;
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
|
|
|
|
CTX_DATA_END;
|
|
|
|
|
|
2019-04-22 09:19:45 +10:00
|
|
|
if (!changed) {
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, nullptr);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBJECT_OT_visual_transform_apply(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Apply Visual Transform";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Apply the object's visual transformation to its data";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "OBJECT_OT_visual_transform_apply";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2025-05-17 09:18:03 +10:00
|
|
|
/* API callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = visual_transform_apply_exec;
|
|
|
|
|
ot->poll = ED_operator_scene_editable;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* flags */
|
2012-04-28 15:42:27 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-20 21:11:06 +00:00
|
|
|
static wmOperatorStatus object_transform_apply_exec(bContext *C, wmOperator *op)
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
{
|
2014-04-11 11:25:41 +10:00
|
|
|
const bool loc = RNA_boolean_get(op->ptr, "location");
|
|
|
|
|
const bool rot = RNA_boolean_get(op->ptr, "rotation");
|
|
|
|
|
const bool sca = RNA_boolean_get(op->ptr, "scale");
|
2017-08-11 22:16:44 +10:00
|
|
|
const bool do_props = RNA_boolean_get(op->ptr, "properties");
|
2022-03-30 11:07:29 +02:00
|
|
|
const bool do_single_user = RNA_boolean_get(op->ptr, "isolate_users");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (loc || rot || sca) {
|
2022-03-30 11:07:29 +02:00
|
|
|
return apply_objects_internal(C, op->reports, loc, rot, sca, do_props, do_single_user);
|
2011-05-03 07:09:02 +00:00
|
|
|
}
|
2020-07-03 15:42:22 +02:00
|
|
|
/* allow for redo */
|
|
|
|
|
return OPERATOR_FINISHED;
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
|
|
|
|
|
2025-03-20 21:11:06 +00:00
|
|
|
static wmOperatorStatus object_transform_apply_invoke(bContext *C,
|
|
|
|
|
wmOperator *op,
|
|
|
|
|
const wmEvent * /*event*/)
|
2022-03-30 11:07:29 +02:00
|
|
|
{
|
2024-03-28 01:30:38 +01:00
|
|
|
Object *ob = context_active_object(C);
|
2022-03-30 11:07:29 +02:00
|
|
|
|
|
|
|
|
bool can_handle_multiuser = apply_objects_internal_can_multiuser(C);
|
|
|
|
|
bool need_single_user = can_handle_multiuser && apply_objects_internal_need_single_user(C);
|
|
|
|
|
|
2022-05-18 15:30:49 +10:00
|
|
|
if ((ob != nullptr) && (ob->data != nullptr) && need_single_user) {
|
2022-03-30 11:07:29 +02:00
|
|
|
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "isolate_users");
|
|
|
|
|
if (!RNA_property_is_set(op->ptr, prop)) {
|
|
|
|
|
RNA_property_boolean_set(op->ptr, prop, true);
|
|
|
|
|
}
|
|
|
|
|
if (RNA_property_boolean_get(op->ptr, prop)) {
|
2024-02-24 01:32:53 +01:00
|
|
|
return WM_operator_confirm_ex(C,
|
|
|
|
|
op,
|
|
|
|
|
IFACE_("Apply Object Transformations"),
|
|
|
|
|
IFACE_("Warning: Multiple objects share the same data.\nMake "
|
|
|
|
|
"single user and then apply transformations?"),
|
|
|
|
|
IFACE_("Apply"),
|
|
|
|
|
ALERT_ICON_WARNING,
|
|
|
|
|
false);
|
2022-03-30 11:07:29 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return object_transform_apply_exec(C, op);
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-03 07:09:02 +00:00
|
|
|
void OBJECT_OT_transform_apply(wmOperatorType *ot)
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Apply Object Transform";
|
2011-05-03 07:09:02 +00:00
|
|
|
ot->description = "Apply the object's transformation to its data";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "OBJECT_OT_transform_apply";
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-05-17 09:18:03 +10:00
|
|
|
/* API callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = object_transform_apply_exec;
|
2022-03-30 11:07:29 +02:00
|
|
|
ot->invoke = object_transform_apply_invoke;
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = ED_operator_objectmode;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* flags */
|
2012-04-28 15:42:27 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-21 13:43:16 +01:00
|
|
|
RNA_def_boolean(ot->srna, "location", true, "Location", "");
|
|
|
|
|
RNA_def_boolean(ot->srna, "rotation", true, "Rotation", "");
|
|
|
|
|
RNA_def_boolean(ot->srna, "scale", true, "Scale", "");
|
2017-08-11 22:16:44 +10:00
|
|
|
RNA_def_boolean(ot->srna,
|
|
|
|
|
"properties",
|
|
|
|
|
true,
|
|
|
|
|
"Apply Properties",
|
|
|
|
|
"Modify properties such as curve vertex radius, font size and bone envelope");
|
2022-03-30 11:07:29 +02:00
|
|
|
PropertyRNA *prop = RNA_def_boolean(ot->srna,
|
|
|
|
|
"isolate_users",
|
|
|
|
|
false,
|
|
|
|
|
"Isolate Multi User Data",
|
|
|
|
|
"Create new object-data users if needed");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
|
|
|
|
|
2022-04-24 13:33:14 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Apply Parent Inverse Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2025-03-20 21:11:06 +00:00
|
|
|
static wmOperatorStatus object_parent_inverse_apply_exec(bContext *C, wmOperator * /*op*/)
|
Object: Set Parent (Keep Transform Without Inverse)
**Relevant to Artists:** This patch adds an option to the Parenting
menu, `Object (Keep Transform Without Inverse)`, and Apply menu, `Parent
Inverse`. The operators preserve the child's world transform without
using the parent inverse matrix. Effectively, we set the child's origin
to the parent. When the child has an identity local transform, then the
child is world-space aligned with its parent (scale excluded).
**Technical:** In both cases, the hidden parent inverse matrix is
generally set to identity (cleared or "not used") as long as the parent
has no shear. If the parent has shear, then this matrix will not be
entirely cleared. It will contain shear to counter the parent's shear.
This is required, otherwise the object's local matrix cannot be properly
decomposed into location, rotation and scale, and thus cannot preserve
the world transform.
If the child's world transform has shear, then its world transform is
not preserved. This is currently not supported for consistency in the
handling of shear during the other parenting ops: Parent (Keep
Transform), Clear [Parent] and Keep Transform. If it should work, then
another patch should add the support for all of them.
Reviewed By: sybren, RiggingDojo
Differential Revision: https://developer.blender.org/D14581
2022-04-14 18:16:23 -04:00
|
|
|
{
|
|
|
|
|
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
|
2022-04-15 11:59:02 -05:00
|
|
|
if (ob->parent == nullptr) {
|
Object: Set Parent (Keep Transform Without Inverse)
**Relevant to Artists:** This patch adds an option to the Parenting
menu, `Object (Keep Transform Without Inverse)`, and Apply menu, `Parent
Inverse`. The operators preserve the child's world transform without
using the parent inverse matrix. Effectively, we set the child's origin
to the parent. When the child has an identity local transform, then the
child is world-space aligned with its parent (scale excluded).
**Technical:** In both cases, the hidden parent inverse matrix is
generally set to identity (cleared or "not used") as long as the parent
has no shear. If the parent has shear, then this matrix will not be
entirely cleared. It will contain shear to counter the parent's shear.
This is required, otherwise the object's local matrix cannot be properly
decomposed into location, rotation and scale, and thus cannot preserve
the world transform.
If the child's world transform has shear, then its world transform is
not preserved. This is currently not supported for consistency in the
handling of shear during the other parenting ops: Parent (Keep
Transform), Clear [Parent] and Keep Transform. If it should work, then
another patch should add the support for all of them.
Reviewed By: sybren, RiggingDojo
Differential Revision: https://developer.blender.org/D14581
2022-04-14 18:16:23 -04:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
|
|
|
|
|
BKE_object_apply_parent_inverse(ob);
|
|
|
|
|
}
|
|
|
|
|
CTX_DATA_END;
|
|
|
|
|
|
2022-04-15 11:59:02 -05:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, nullptr);
|
Object: Set Parent (Keep Transform Without Inverse)
**Relevant to Artists:** This patch adds an option to the Parenting
menu, `Object (Keep Transform Without Inverse)`, and Apply menu, `Parent
Inverse`. The operators preserve the child's world transform without
using the parent inverse matrix. Effectively, we set the child's origin
to the parent. When the child has an identity local transform, then the
child is world-space aligned with its parent (scale excluded).
**Technical:** In both cases, the hidden parent inverse matrix is
generally set to identity (cleared or "not used") as long as the parent
has no shear. If the parent has shear, then this matrix will not be
entirely cleared. It will contain shear to counter the parent's shear.
This is required, otherwise the object's local matrix cannot be properly
decomposed into location, rotation and scale, and thus cannot preserve
the world transform.
If the child's world transform has shear, then its world transform is
not preserved. This is currently not supported for consistency in the
handling of shear during the other parenting ops: Parent (Keep
Transform), Clear [Parent] and Keep Transform. If it should work, then
another patch should add the support for all of them.
Reviewed By: sybren, RiggingDojo
Differential Revision: https://developer.blender.org/D14581
2022-04-14 18:16:23 -04:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBJECT_OT_parent_inverse_apply(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Apply Parent Inverse";
|
2022-04-19 20:40:41 -04:00
|
|
|
ot->description = "Apply the object's parent inverse to its data";
|
Object: Set Parent (Keep Transform Without Inverse)
**Relevant to Artists:** This patch adds an option to the Parenting
menu, `Object (Keep Transform Without Inverse)`, and Apply menu, `Parent
Inverse`. The operators preserve the child's world transform without
using the parent inverse matrix. Effectively, we set the child's origin
to the parent. When the child has an identity local transform, then the
child is world-space aligned with its parent (scale excluded).
**Technical:** In both cases, the hidden parent inverse matrix is
generally set to identity (cleared or "not used") as long as the parent
has no shear. If the parent has shear, then this matrix will not be
entirely cleared. It will contain shear to counter the parent's shear.
This is required, otherwise the object's local matrix cannot be properly
decomposed into location, rotation and scale, and thus cannot preserve
the world transform.
If the child's world transform has shear, then its world transform is
not preserved. This is currently not supported for consistency in the
handling of shear during the other parenting ops: Parent (Keep
Transform), Clear [Parent] and Keep Transform. If it should work, then
another patch should add the support for all of them.
Reviewed By: sybren, RiggingDojo
Differential Revision: https://developer.blender.org/D14581
2022-04-14 18:16:23 -04:00
|
|
|
ot->idname = "OBJECT_OT_parent_inverse_apply";
|
|
|
|
|
|
2025-05-17 09:18:03 +10:00
|
|
|
/* API callbacks. */
|
Object: Set Parent (Keep Transform Without Inverse)
**Relevant to Artists:** This patch adds an option to the Parenting
menu, `Object (Keep Transform Without Inverse)`, and Apply menu, `Parent
Inverse`. The operators preserve the child's world transform without
using the parent inverse matrix. Effectively, we set the child's origin
to the parent. When the child has an identity local transform, then the
child is world-space aligned with its parent (scale excluded).
**Technical:** In both cases, the hidden parent inverse matrix is
generally set to identity (cleared or "not used") as long as the parent
has no shear. If the parent has shear, then this matrix will not be
entirely cleared. It will contain shear to counter the parent's shear.
This is required, otherwise the object's local matrix cannot be properly
decomposed into location, rotation and scale, and thus cannot preserve
the world transform.
If the child's world transform has shear, then its world transform is
not preserved. This is currently not supported for consistency in the
handling of shear during the other parenting ops: Parent (Keep
Transform), Clear [Parent] and Keep Transform. If it should work, then
another patch should add the support for all of them.
Reviewed By: sybren, RiggingDojo
Differential Revision: https://developer.blender.org/D14581
2022-04-14 18:16:23 -04:00
|
|
|
ot->exec = object_parent_inverse_apply_exec;
|
|
|
|
|
ot->poll = ED_operator_objectmode;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-22 04:56:18 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Set Object Center Operator
|
|
|
|
|
* \{ */
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
|
2010-08-01 11:00:36 +00:00
|
|
|
enum {
|
2012-04-28 15:42:27 +00:00
|
|
|
GEOMETRY_TO_ORIGIN = 0,
|
2010-08-01 11:00:36 +00:00
|
|
|
ORIGIN_TO_GEOMETRY,
|
2012-10-20 16:48:54 +00:00
|
|
|
ORIGIN_TO_CURSOR,
|
2017-08-21 15:06:07 +10:00
|
|
|
ORIGIN_TO_CENTER_OF_MASS_SURFACE,
|
|
|
|
|
ORIGIN_TO_CENTER_OF_MASS_VOLUME,
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
};
|
|
|
|
|
|
2024-03-28 01:30:38 +01:00
|
|
|
static float3 arithmetic_mean(const Span<float3> values)
|
2023-01-02 10:49:57 -05:00
|
|
|
{
|
|
|
|
|
if (values.is_empty()) {
|
|
|
|
|
return float3(0);
|
|
|
|
|
}
|
|
|
|
|
/* TODO: Use a method that avoids overflow. */
|
|
|
|
|
return std::accumulate(values.begin(), values.end(), float3(0)) / values.size();
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-28 01:30:38 +01:00
|
|
|
static void translate_positions(MutableSpan<float3> positions, const float3 &translation)
|
2023-01-02 10:49:57 -05:00
|
|
|
{
|
|
|
|
|
threading::parallel_for(positions.index_range(), 2048, [&](const IndexRange range) {
|
|
|
|
|
for (float3 &position : positions.slice(range)) {
|
|
|
|
|
position += translation;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-20 21:11:06 +00:00
|
|
|
static wmOperatorStatus object_origin_set_exec(bContext *C, wmOperator *op)
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
{
|
2012-04-28 15:42:27 +00:00
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2013-07-15 01:34:59 +00:00
|
|
|
Object *obact = CTX_data_active_object(C);
|
2012-04-28 15:42:27 +00:00
|
|
|
Object *obedit = CTX_data_edit_object(C);
|
2019-07-25 16:36:22 +02:00
|
|
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
2022-04-03 12:54:42 -05:00
|
|
|
float3 cent, cent_neg, centn;
|
2019-01-16 19:57:58 +11:00
|
|
|
const float *cursor = scene->cursor.location;
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
int centermode = RNA_enum_get(op->ptr, "type");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* keep track of what is changed */
|
2012-04-28 15:42:27 +00:00
|
|
|
int tot_change = 0, tot_lib_error = 0, tot_multiuser_arm_error = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-08-01 11:00:36 +00:00
|
|
|
if (obedit && centermode != GEOMETRY_TO_ORIGIN) {
|
2012-10-26 17:32:50 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed in edit mode");
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2010-07-31 10:58:10 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-16 18:32:09 +11:00
|
|
|
int around;
|
|
|
|
|
{
|
|
|
|
|
PropertyRNA *prop_center = RNA_struct_find_property(op->ptr, "center");
|
|
|
|
|
if (RNA_property_is_set(op->ptr, prop_center)) {
|
|
|
|
|
around = RNA_property_enum_get(op->ptr, prop_center);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CENTER_BOUNDS) {
|
|
|
|
|
around = V3D_AROUND_CENTER_BOUNDS;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
around = V3D_AROUND_CENTER_MEDIAN;
|
|
|
|
|
}
|
|
|
|
|
RNA_property_enum_set(op->ptr, prop_center, around);
|
|
|
|
|
}
|
2010-08-01 11:00:36 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-07-31 10:58:10 +00:00
|
|
|
zero_v3(cent);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (obedit) {
|
2012-04-28 15:42:27 +00:00
|
|
|
if (obedit->type == OB_MESH) {
|
2023-12-08 16:40:06 -05:00
|
|
|
Mesh *mesh = static_cast<Mesh *>(obedit->data);
|
2024-04-18 13:52:20 +02:00
|
|
|
BMEditMesh *em = mesh->runtime->edit_mesh.get();
|
2010-01-28 00:45:30 +00:00
|
|
|
BMVert *eve;
|
|
|
|
|
BMIter iter;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (centermode == ORIGIN_TO_CURSOR) {
|
2010-09-04 05:31:25 +00:00
|
|
|
copy_v3_v3(cent, cursor);
|
2024-02-14 16:14:49 +01:00
|
|
|
invert_m4_m4(obedit->runtime->world_to_object.ptr(), obedit->object_to_world().ptr());
|
|
|
|
|
mul_m4_v3(obedit->world_to_object().ptr(), cent);
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2020-06-23 18:31:10 +10:00
|
|
|
if (around == V3D_AROUND_CENTER_BOUNDS) {
|
2012-05-13 11:14:43 +00:00
|
|
|
float min[3], max[3];
|
|
|
|
|
INIT_MINMAX(min, max);
|
|
|
|
|
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
|
2012-05-13 11:05:52 +00:00
|
|
|
minmax_v3v3_v3(min, max, eve->co);
|
2010-09-04 05:31:25 +00:00
|
|
|
}
|
2012-05-13 11:14:43 +00:00
|
|
|
mid_v3_v3v3(cent, min, max);
|
2010-08-01 11:00:36 +00:00
|
|
|
}
|
2020-06-23 18:31:10 +10:00
|
|
|
else { /* #V3D_AROUND_CENTER_MEDIAN. */
|
|
|
|
|
if (em->bm->totvert) {
|
2022-09-25 18:33:28 +10:00
|
|
|
const float total_div = 1.0f / float(em->bm->totvert);
|
2020-06-23 18:31:10 +10:00
|
|
|
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
|
|
|
|
|
madd_v3_v3fl(cent, eve->co, total_div);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-04-19 13:47:58 +00:00
|
|
|
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
|
2010-08-01 11:00:36 +00:00
|
|
|
sub_v3_v3(eve->co, cent);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-27 04:46:52 +00:00
|
|
|
EDBM_mesh_normals_update(em);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
tot_change++;
|
2018-12-06 17:52:37 +01:00
|
|
|
DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
|
2012-04-28 15:42:27 +00:00
|
|
|
}
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
Array<Object *> objects = sorted_selected_editable_objects(C);
|
|
|
|
|
if (objects.is_empty()) {
|
2019-06-19 14:36:07 +02:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* reset flags */
|
2022-04-01 23:22:17 -05:00
|
|
|
for (const int object_index : objects.index_range()) {
|
2019-06-19 14:36:07 +02:00
|
|
|
Object *ob = objects[object_index];
|
2012-04-28 15:42:27 +00:00
|
|
|
ob->flag &= ~OB_DONE;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-07-15 01:34:59 +00:00
|
|
|
/* move active first */
|
2022-04-01 23:22:17 -05:00
|
|
|
if (ob == obact && objects.size() > 1) {
|
2022-03-18 15:50:46 -05:00
|
|
|
memmove(&objects[1], objects.data(), object_index * sizeof(Object *));
|
2019-06-19 14:36:07 +02:00
|
|
|
objects[0] = ob;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2013-07-15 01:34:59 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
LISTBASE_FOREACH (Object *, tob, &bmain->objects) {
|
2019-04-22 09:19:45 +10:00
|
|
|
if (tob->data) {
|
2024-08-07 12:12:17 +02:00
|
|
|
((ID *)tob->data)->tag &= ~ID_TAG_DOIT;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
|
|
|
|
if (tob->instance_collection) {
|
2024-08-07 12:12:17 +02:00
|
|
|
((ID *)tob->instance_collection)->tag &= ~ID_TAG_DOIT;
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
for (Object *ob : objects) {
|
2021-07-13 22:11:57 +10:00
|
|
|
if (ob->flag & OB_DONE) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
bool do_inverse_offset = false;
|
|
|
|
|
ob->flag |= OB_DONE;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
if (centermode == ORIGIN_TO_CURSOR) {
|
|
|
|
|
copy_v3_v3(cent, cursor);
|
2024-02-14 16:14:49 +01:00
|
|
|
invert_m4_m4(ob->runtime->world_to_object.ptr(), ob->object_to_world().ptr());
|
|
|
|
|
mul_m4_v3(ob->world_to_object().ptr(), cent);
|
2021-07-13 22:11:57 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
if (ob->data == nullptr) {
|
2022-03-23 12:15:50 +11:00
|
|
|
/* Special support for instanced collections. */
|
2021-07-13 22:11:57 +10:00
|
|
|
if ((ob->transflag & OB_DUPLICOLLECTION) && ob->instance_collection &&
|
2024-08-07 12:12:17 +02:00
|
|
|
(ob->instance_collection->id.tag & ID_TAG_DOIT) == 0)
|
2021-07-13 22:11:57 +10:00
|
|
|
{
|
2022-03-28 17:34:36 +02:00
|
|
|
if (!BKE_id_is_editable(bmain, &ob->instance_collection->id)) {
|
2021-07-13 22:11:57 +10:00
|
|
|
tot_lib_error++;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
else {
|
2021-07-13 13:01:28 +10:00
|
|
|
if (centermode == ORIGIN_TO_CURSOR) {
|
|
|
|
|
/* done */
|
|
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
else {
|
2024-12-20 19:09:20 -05:00
|
|
|
float3 min, max;
|
2021-07-13 22:11:57 +10:00
|
|
|
/* only bounds support */
|
|
|
|
|
INIT_MINMAX(min, max);
|
|
|
|
|
BKE_object_minmax_dupli(depsgraph, scene, ob, min, max, true);
|
|
|
|
|
mid_v3_v3v3(cent, min, max);
|
2024-02-14 16:14:49 +01:00
|
|
|
invert_m4_m4(ob->runtime->world_to_object.ptr(), ob->object_to_world().ptr());
|
|
|
|
|
mul_m4_v3(ob->world_to_object().ptr(), cent);
|
2021-07-13 13:01:28 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
add_v3_v3(ob->instance_collection->instance_offset, cent);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 13:01:28 +10:00
|
|
|
tot_change++;
|
2024-08-07 12:12:17 +02:00
|
|
|
ob->instance_collection->id.tag |= ID_TAG_DOIT;
|
2021-07-13 13:01:28 +10:00
|
|
|
do_inverse_offset = true;
|
|
|
|
|
}
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
}
|
2024-05-16 14:53:09 +02:00
|
|
|
else if (!ID_IS_EDITABLE(ob->data) || ID_IS_OVERRIDE_LIBRARY(ob->data)) {
|
2021-07-13 22:11:57 +10:00
|
|
|
tot_lib_error++;
|
|
|
|
|
}
|
|
|
|
|
else if (ob->type == OB_MESH) {
|
2022-03-18 15:50:46 -05:00
|
|
|
if (obedit == nullptr) {
|
2023-12-08 16:40:06 -05:00
|
|
|
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-22 04:56:18 +10:00
|
|
|
if (centermode == ORIGIN_TO_CURSOR) {
|
|
|
|
|
/* done */
|
2018-12-14 11:01:01 +11:00
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
else if (centermode == ORIGIN_TO_CENTER_OF_MASS_SURFACE) {
|
2023-12-08 16:40:06 -05:00
|
|
|
BKE_mesh_center_of_surface(mesh, cent);
|
2021-07-13 22:11:57 +10:00
|
|
|
}
|
|
|
|
|
else if (centermode == ORIGIN_TO_CENTER_OF_MASS_VOLUME) {
|
2023-12-08 16:40:06 -05:00
|
|
|
BKE_mesh_center_of_volume(mesh, cent);
|
2021-07-13 22:11:57 +10:00
|
|
|
}
|
2020-06-23 18:31:10 +10:00
|
|
|
else if (around == V3D_AROUND_CENTER_BOUNDS) {
|
2023-12-08 16:40:06 -05:00
|
|
|
if (const std::optional<Bounds<float3>> bounds = mesh->bounds_min_max()) {
|
2023-06-16 08:08:18 -04:00
|
|
|
cent = math::midpoint(bounds->min, bounds->max);
|
|
|
|
|
}
|
2018-12-14 11:01:01 +11:00
|
|
|
}
|
2020-06-23 18:31:10 +10:00
|
|
|
else { /* #V3D_AROUND_CENTER_MEDIAN. */
|
2023-12-08 16:40:06 -05:00
|
|
|
BKE_mesh_center_median(mesh, cent);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-08-01 11:00:36 +00:00
|
|
|
negate_v3_v3(cent_neg, cent);
|
2025-03-28 11:36:39 -04:00
|
|
|
bke::mesh_translate(*mesh, cent_neg, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-08-01 11:00:36 +00:00
|
|
|
tot_change++;
|
2024-08-07 12:12:17 +02:00
|
|
|
mesh->id.tag |= ID_TAG_DOIT;
|
2014-04-01 11:34:00 +11:00
|
|
|
do_inverse_offset = true;
|
2021-07-13 22:11:57 +10:00
|
|
|
}
|
|
|
|
|
}
|
2022-02-18 09:50:29 -06:00
|
|
|
else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
|
2022-03-18 15:50:46 -05:00
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
if (centermode == ORIGIN_TO_CURSOR) {
|
|
|
|
|
/* done */
|
|
|
|
|
}
|
|
|
|
|
else if (around == V3D_AROUND_CENTER_BOUNDS) {
|
2024-03-28 01:30:38 +01:00
|
|
|
if (std::optional<Bounds<float3>> bounds = BKE_curve_minmax(cu, true)) {
|
2023-11-27 16:14:49 +01:00
|
|
|
cent = math::midpoint(bounds->min, bounds->max);
|
|
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
}
|
|
|
|
|
else { /* #V3D_AROUND_CENTER_MEDIAN. */
|
|
|
|
|
BKE_curve_center_median(cu, cent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* don't allow Z change if curve is 2D */
|
2022-02-18 09:50:29 -06:00
|
|
|
if ((ob->type == OB_CURVES_LEGACY) && !(cu->flag & CU_3D)) {
|
2021-07-13 22:11:57 +10:00
|
|
|
cent[2] = 0.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
negate_v3_v3(cent_neg, cent);
|
2022-03-18 15:50:46 -05:00
|
|
|
BKE_curve_translate(cu, cent_neg, true);
|
2021-07-13 22:11:57 +10:00
|
|
|
|
|
|
|
|
tot_change++;
|
2024-08-07 12:12:17 +02:00
|
|
|
cu->id.tag |= ID_TAG_DOIT;
|
2021-07-13 22:11:57 +10:00
|
|
|
do_inverse_offset = true;
|
|
|
|
|
|
|
|
|
|
if (obedit) {
|
|
|
|
|
if (centermode == GEOMETRY_TO_ORIGIN) {
|
|
|
|
|
DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
break;
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
}
|
|
|
|
|
else if (ob->type == OB_FONT) {
|
|
|
|
|
/* Get from bounding-box. */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
2024-03-28 01:30:38 +01:00
|
|
|
std::optional<Bounds<float3>> bounds = BKE_curve_minmax(cu, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-11-27 16:14:49 +01:00
|
|
|
if (!bounds && (centermode != ORIGIN_TO_CURSOR)) {
|
2021-07-13 22:11:57 +10:00
|
|
|
/* Do nothing. */
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (centermode == ORIGIN_TO_CURSOR) {
|
|
|
|
|
/* Done. */
|
2010-08-01 11:00:36 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2021-07-13 22:11:57 +10:00
|
|
|
/* extra 0.5 is the height o above line */
|
2023-11-27 16:14:49 +01:00
|
|
|
cent = math::midpoint(bounds->min, bounds->max);
|
2021-07-13 22:11:57 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
cent[2] = 0.0f;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
cu->xof = cu->xof - cent[0];
|
|
|
|
|
cu->yof = cu->yof - cent[1];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
tot_change++;
|
2024-08-07 12:12:17 +02:00
|
|
|
cu->id.tag |= ID_TAG_DOIT;
|
2021-07-13 22:11:57 +10:00
|
|
|
do_inverse_offset = true;
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
}
|
|
|
|
|
else if (ob->type == OB_ARMATURE) {
|
2022-03-18 15:50:46 -05:00
|
|
|
bArmature *arm = static_cast<bArmature *>(ob->data);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
if (ID_REAL_USERS(arm) > 1) {
|
2012-03-03 16:31:46 +00:00
|
|
|
#if 0
|
2023-07-12 14:18:59 +02:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Cannot apply to a multi user armature");
|
|
|
|
|
return;
|
2012-03-03 16:31:46 +00:00
|
|
|
#endif
|
2021-07-13 22:11:57 +10:00
|
|
|
tot_multiuser_arm_error++;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Function to recenter armatures in editarmature.c
|
|
|
|
|
* Bone + object locations are handled there.
|
|
|
|
|
*/
|
|
|
|
|
ED_armature_origin_set(bmain, ob, cursor, centermode, around);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
tot_change++;
|
2024-08-07 12:12:17 +02:00
|
|
|
arm->id.tag |= ID_TAG_DOIT;
|
2023-09-25 16:56:17 +10:00
|
|
|
// do_inverse_offset = true; /* docenter_armature() handles this. */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-05-02 15:08:29 +02:00
|
|
|
Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
|
2021-07-13 22:11:57 +10:00
|
|
|
BKE_object_transform_copy(ob_eval, ob);
|
2022-03-18 15:50:46 -05:00
|
|
|
BKE_armature_copy_bone_transforms(static_cast<bArmature *>(ob_eval->data),
|
|
|
|
|
static_cast<bArmature *>(ob->data));
|
2021-07-13 22:11:57 +10:00
|
|
|
BKE_object_where_is_calc(depsgraph, scene, ob_eval);
|
|
|
|
|
BKE_pose_where_is(depsgraph, scene, ob_eval); /* needed for bone parents */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
ignore_parent_tx(bmain, depsgraph, scene, ob);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
if (obedit) {
|
|
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
}
|
|
|
|
|
else if (ob->type == OB_MBALL) {
|
2022-03-18 15:50:46 -05:00
|
|
|
MetaBall *mb = static_cast<MetaBall *>(ob->data);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
if (centermode == ORIGIN_TO_CURSOR) {
|
|
|
|
|
/* done */
|
|
|
|
|
}
|
|
|
|
|
else if (around == V3D_AROUND_CENTER_BOUNDS) {
|
|
|
|
|
BKE_mball_center_bounds(mb, cent);
|
|
|
|
|
}
|
|
|
|
|
else { /* #V3D_AROUND_CENTER_MEDIAN. */
|
|
|
|
|
BKE_mball_center_median(mb, cent);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
negate_v3_v3(cent_neg, cent);
|
|
|
|
|
BKE_mball_translate(mb, cent_neg);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
tot_change++;
|
2024-08-07 12:12:17 +02:00
|
|
|
mb->id.tag |= ID_TAG_DOIT;
|
2021-07-13 22:11:57 +10:00
|
|
|
do_inverse_offset = true;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
if (obedit) {
|
|
|
|
|
if (centermode == GEOMETRY_TO_ORIGIN) {
|
|
|
|
|
DEG_id_tag_update(&obedit->id, ID_RECALC_GEOMETRY);
|
2012-02-26 08:55:31 +00:00
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
}
|
|
|
|
|
else if (ob->type == OB_LATTICE) {
|
2022-03-18 15:50:46 -05:00
|
|
|
Lattice *lt = static_cast<Lattice *>(ob->data);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
if (centermode == ORIGIN_TO_CURSOR) {
|
|
|
|
|
/* done */
|
|
|
|
|
}
|
|
|
|
|
else if (around == V3D_AROUND_CENTER_BOUNDS) {
|
2024-03-28 01:30:38 +01:00
|
|
|
if (std::optional<Bounds<float3>> bounds = BKE_lattice_minmax(lt)) {
|
2023-11-27 16:14:49 +01:00
|
|
|
cent = math::midpoint(bounds->min, bounds->max);
|
|
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
}
|
|
|
|
|
else { /* #V3D_AROUND_CENTER_MEDIAN. */
|
|
|
|
|
BKE_lattice_center_median(lt, cent);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
negate_v3_v3(cent_neg, cent);
|
2022-03-18 15:50:46 -05:00
|
|
|
BKE_lattice_translate(lt, cent_neg, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
tot_change++;
|
2024-08-07 12:12:17 +02:00
|
|
|
lt->id.tag |= ID_TAG_DOIT;
|
2021-07-13 22:11:57 +10:00
|
|
|
do_inverse_offset = true;
|
|
|
|
|
}
|
2022-04-03 12:54:42 -05:00
|
|
|
else if (ob->type == OB_CURVES) {
|
|
|
|
|
Curves &curves_id = *static_cast<Curves *>(ob->data);
|
2023-01-31 18:45:34 +01:00
|
|
|
bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
2022-04-03 12:54:42 -05:00
|
|
|
if (ELEM(centermode, ORIGIN_TO_CENTER_OF_MASS_SURFACE, ORIGIN_TO_CENTER_OF_MASS_VOLUME) ||
|
|
|
|
|
!ELEM(around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEDIAN))
|
|
|
|
|
{
|
|
|
|
|
BKE_report(
|
|
|
|
|
op->reports, RPT_WARNING, "Curves Object does not support this set origin operation");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (curves.points_num() == 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (centermode == ORIGIN_TO_CURSOR) {
|
|
|
|
|
/* done */
|
|
|
|
|
}
|
|
|
|
|
else if (around == V3D_AROUND_CENTER_BOUNDS) {
|
2023-06-16 08:08:18 -04:00
|
|
|
const Bounds<float3> bounds = *curves.bounds_min_max();
|
|
|
|
|
cent = math::midpoint(bounds.min, bounds.max);
|
2022-04-03 12:54:42 -05:00
|
|
|
}
|
|
|
|
|
else if (around == V3D_AROUND_CENTER_MEDIAN) {
|
2023-10-23 19:37:18 +02:00
|
|
|
cent = arithmetic_mean(curves.positions());
|
2022-04-03 12:54:42 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tot_change++;
|
|
|
|
|
curves.translate(-cent);
|
2024-08-07 12:12:17 +02:00
|
|
|
curves_id.id.tag |= ID_TAG_DOIT;
|
2022-04-03 12:54:42 -05:00
|
|
|
do_inverse_offset = true;
|
|
|
|
|
}
|
2024-09-19 15:27:29 +02:00
|
|
|
else if (ob->type == OB_GREASE_PENCIL) {
|
|
|
|
|
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
|
|
|
|
|
if (ELEM(centermode, ORIGIN_TO_CENTER_OF_MASS_SURFACE, ORIGIN_TO_CENTER_OF_MASS_VOLUME) ||
|
|
|
|
|
!ELEM(around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEDIAN))
|
|
|
|
|
{
|
|
|
|
|
BKE_report(op->reports,
|
|
|
|
|
RPT_WARNING,
|
|
|
|
|
"Grease Pencil Object does not support this set origin operation");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (centermode == ORIGIN_TO_CURSOR) {
|
|
|
|
|
/* done */
|
|
|
|
|
}
|
|
|
|
|
else if (around == V3D_AROUND_CENTER_BOUNDS) {
|
|
|
|
|
const int current_frame = scene->r.cfra;
|
|
|
|
|
const Bounds<float3> bounds = *grease_pencil.bounds_min_max(current_frame);
|
|
|
|
|
cent = math::midpoint(bounds.min, bounds.max);
|
|
|
|
|
}
|
|
|
|
|
else if (around == V3D_AROUND_CENTER_MEDIAN) {
|
|
|
|
|
const int current_frame = scene->r.cfra;
|
|
|
|
|
float3 center = float3(0.0f);
|
|
|
|
|
int total_points = 0;
|
|
|
|
|
|
|
|
|
|
for (const int layer_i : grease_pencil.layers().index_range()) {
|
2024-09-23 13:54:02 +02:00
|
|
|
const bke::greasepencil::Layer &layer = grease_pencil.layer(layer_i);
|
2024-09-19 15:27:29 +02:00
|
|
|
const float4x4 layer_to_object = layer.local_transform();
|
|
|
|
|
if (!layer.is_visible()) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (const bke::greasepencil::Drawing *drawing = grease_pencil.get_drawing_at(
|
|
|
|
|
layer, current_frame))
|
|
|
|
|
{
|
|
|
|
|
const bke::CurvesGeometry &curves = drawing->strokes();
|
|
|
|
|
|
|
|
|
|
for (const int i : curves.points_range()) {
|
|
|
|
|
center += math::transform_point(layer_to_object, curves.positions()[i]);
|
|
|
|
|
}
|
|
|
|
|
total_points += curves.points_num();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (total_points != 0) {
|
|
|
|
|
cent = center / total_points;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tot_change++;
|
|
|
|
|
|
|
|
|
|
for (const int layer_i : grease_pencil.layers().index_range()) {
|
2024-09-23 13:54:02 +02:00
|
|
|
bke::greasepencil::Layer &layer = grease_pencil.layer(layer_i);
|
2024-09-19 15:27:29 +02:00
|
|
|
const float4x4 layer_to_object = layer.local_transform();
|
|
|
|
|
const float4x4 object_to_layer = math::invert(layer_to_object);
|
|
|
|
|
const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.frames();
|
|
|
|
|
frames.foreach_item(
|
|
|
|
|
[&](bke::greasepencil::FramesMapKeyT /*key*/, GreasePencilFrame frame) {
|
|
|
|
|
GreasePencilDrawingBase *base = grease_pencil.drawing(frame.drawing_index);
|
|
|
|
|
if (base->type != GP_DRAWING) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
bke::greasepencil::Drawing &drawing =
|
|
|
|
|
reinterpret_cast<GreasePencilDrawing *>(base)->wrap();
|
|
|
|
|
bke::CurvesGeometry &curves = drawing.strokes_for_write();
|
|
|
|
|
|
|
|
|
|
curves.translate(math::transform_direction(object_to_layer, -cent));
|
|
|
|
|
curves.calculate_bezier_auto_handles();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
grease_pencil.id.tag |= ID_TAG_DOIT;
|
|
|
|
|
do_inverse_offset = true;
|
|
|
|
|
}
|
2023-01-02 10:49:57 -05:00
|
|
|
else if (ob->type == OB_POINTCLOUD) {
|
|
|
|
|
PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data);
|
2023-12-20 13:16:41 -05:00
|
|
|
MutableSpan<float3> positions = pointcloud.positions_for_write();
|
2023-01-02 10:49:57 -05:00
|
|
|
if (ELEM(centermode, ORIGIN_TO_CENTER_OF_MASS_SURFACE, ORIGIN_TO_CENTER_OF_MASS_VOLUME) ||
|
|
|
|
|
!ELEM(around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEDIAN))
|
|
|
|
|
{
|
|
|
|
|
BKE_report(op->reports,
|
|
|
|
|
RPT_WARNING,
|
|
|
|
|
"Point cloud object does not support this set origin operation");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (centermode == ORIGIN_TO_CURSOR) {
|
|
|
|
|
/* Done. */
|
|
|
|
|
}
|
|
|
|
|
else if (around == V3D_AROUND_CENTER_BOUNDS) {
|
2023-06-16 08:08:18 -04:00
|
|
|
if (const std::optional<Bounds<float3>> bounds = pointcloud.bounds_min_max()) {
|
|
|
|
|
cent = math::midpoint(bounds->min, bounds->max);
|
2023-01-02 10:49:57 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (around == V3D_AROUND_CENTER_MEDIAN) {
|
2023-12-20 13:16:41 -05:00
|
|
|
cent = arithmetic_mean(positions);
|
2023-01-02 10:49:57 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tot_change++;
|
2023-12-20 13:16:41 -05:00
|
|
|
translate_positions(positions, -cent);
|
|
|
|
|
pointcloud.tag_positions_changed();
|
2024-08-07 12:12:17 +02:00
|
|
|
pointcloud.id.tag |= ID_TAG_DOIT;
|
2023-01-02 10:49:57 -05:00
|
|
|
do_inverse_offset = true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
/* offset other selected objects */
|
|
|
|
|
if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) {
|
|
|
|
|
float obmat[4][4];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
/* was the object data modified
|
|
|
|
|
* NOTE: the functions above must set 'cent'. */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
/* convert the offset to parent space */
|
|
|
|
|
BKE_object_to_mat4(ob, obmat);
|
|
|
|
|
mul_v3_mat3_m4v3(centn, obmat, cent); /* omit translation part */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
add_v3_v3(ob->loc, centn);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-05-02 15:08:29 +02:00
|
|
|
Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
|
2021-07-13 22:11:57 +10:00
|
|
|
BKE_object_transform_copy(ob_eval, ob);
|
|
|
|
|
BKE_object_where_is_calc(depsgraph, scene, ob_eval);
|
|
|
|
|
if (ob->type == OB_ARMATURE) {
|
|
|
|
|
/* needed for bone parents */
|
2022-03-18 15:50:46 -05:00
|
|
|
BKE_armature_copy_bone_transforms(static_cast<bArmature *>(ob_eval->data),
|
|
|
|
|
static_cast<bArmature *>(ob->data));
|
2021-07-13 22:11:57 +10:00
|
|
|
BKE_pose_where_is(depsgraph, scene, ob_eval);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-07-13 22:11:57 +10:00
|
|
|
ignore_parent_tx(bmain, depsgraph, scene, ob);
|
|
|
|
|
|
|
|
|
|
/* other users? */
|
|
|
|
|
// CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects)
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
|
|
/* use existing context looper */
|
2022-03-18 15:50:46 -05:00
|
|
|
for (Object *ob_other : objects) {
|
2021-07-13 22:11:57 +10:00
|
|
|
if ((ob_other->flag & OB_DONE) == 0 &&
|
|
|
|
|
((ob->data && (ob->data == ob_other->data)) ||
|
|
|
|
|
(ob->instance_collection == ob_other->instance_collection &&
|
|
|
|
|
(ob->transflag | ob_other->transflag) & OB_DUPLICOLLECTION)))
|
|
|
|
|
{
|
|
|
|
|
ob_other->flag |= OB_DONE;
|
|
|
|
|
DEG_id_tag_update(&ob_other->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
|
|
|
|
|
|
2024-02-14 16:14:49 +01:00
|
|
|
mul_v3_mat3_m4v3(
|
|
|
|
|
centn, ob_other->object_to_world().ptr(), cent); /* omit translation part */
|
2021-07-13 22:11:57 +10:00
|
|
|
add_v3_v3(ob_other->loc, centn);
|
|
|
|
|
|
2025-05-02 15:08:29 +02:00
|
|
|
Object *ob_other_eval = DEG_get_evaluated(depsgraph, ob_other);
|
2021-07-13 22:11:57 +10:00
|
|
|
BKE_object_transform_copy(ob_other_eval, ob_other);
|
|
|
|
|
BKE_object_where_is_calc(depsgraph, scene, ob_other_eval);
|
|
|
|
|
if (ob_other->type == OB_ARMATURE) {
|
|
|
|
|
/* needed for bone parents */
|
2022-03-18 15:50:46 -05:00
|
|
|
BKE_armature_copy_bone_transforms(static_cast<bArmature *>(ob_eval->data),
|
|
|
|
|
static_cast<bArmature *>(ob->data));
|
2021-07-13 22:11:57 +10:00
|
|
|
BKE_pose_where_is(depsgraph, scene, ob_other_eval);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
ignore_parent_tx(bmain, depsgraph, scene, ob_other);
|
2010-08-01 11:00:36 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2021-07-13 22:11:57 +10:00
|
|
|
// CTX_DATA_END;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2010-08-01 11:00:36 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
LISTBASE_FOREACH (Object *, tob, &bmain->objects) {
|
2024-08-07 12:12:17 +02:00
|
|
|
if (tob->data && (((ID *)tob->data)->tag & ID_TAG_DOIT)) {
|
2018-08-23 10:14:29 -03:00
|
|
|
BKE_object_batch_cache_dirty_tag(tob);
|
2018-12-06 17:52:37 +01:00
|
|
|
DEG_id_tag_update(&tob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2021-06-29 20:12:51 +10:00
|
|
|
/* Special support for dupli-groups. */
|
2024-08-07 12:12:17 +02:00
|
|
|
else if (tob->instance_collection && tob->instance_collection->id.tag & ID_TAG_DOIT) {
|
2019-05-27 11:33:15 +02:00
|
|
|
DEG_id_tag_update(&tob->id, ID_RECALC_TRANSFORM);
|
2024-02-19 15:54:08 +01:00
|
|
|
DEG_id_tag_update(&tob->instance_collection->id, ID_RECALC_SYNC_TO_EVAL);
|
2019-05-27 11:33:15 +02:00
|
|
|
}
|
2017-06-28 14:58:25 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
if (tot_change) {
|
2022-03-18 15:50:46 -05:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, nullptr);
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-07-20 10:41:08 +00:00
|
|
|
/* Warn if any errors occurred */
|
2012-04-28 15:42:27 +00:00
|
|
|
if (tot_lib_error + tot_multiuser_arm_error) {
|
2012-10-14 15:29:09 +00:00
|
|
|
BKE_reportf(op->reports,
|
|
|
|
|
RPT_WARNING,
|
|
|
|
|
"%i object(s) not centered, %i changed:",
|
|
|
|
|
tot_lib_error + tot_multiuser_arm_error,
|
|
|
|
|
tot_change);
|
2019-04-22 09:19:45 +10:00
|
|
|
if (tot_lib_error) {
|
2012-10-14 15:29:09 +00:00
|
|
|
BKE_reportf(op->reports, RPT_WARNING, "|%i linked library object(s)", tot_lib_error);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
|
|
|
|
if (tot_multiuser_arm_error) {
|
2012-04-28 15:42:27 +00:00
|
|
|
BKE_reportf(
|
|
|
|
|
op->reports, RPT_WARNING, "|%i multiuser armature object(s)", tot_multiuser_arm_error);
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2009-12-03 21:56:04 +00:00
|
|
|
void OBJECT_OT_origin_set(wmOperatorType *ot)
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
{
|
2017-10-18 15:07:26 +11:00
|
|
|
static const EnumPropertyItem prop_set_center_types[] = {
|
2010-08-01 11:00:36 +00:00
|
|
|
{GEOMETRY_TO_ORIGIN,
|
|
|
|
|
"GEOMETRY_ORIGIN",
|
|
|
|
|
0,
|
|
|
|
|
"Geometry to Origin",
|
|
|
|
|
"Move object geometry to object origin"},
|
2012-10-08 21:03:35 +00:00
|
|
|
{ORIGIN_TO_GEOMETRY,
|
|
|
|
|
"ORIGIN_GEOMETRY",
|
|
|
|
|
0,
|
|
|
|
|
"Origin to Geometry",
|
2017-08-21 15:06:07 +10:00
|
|
|
"Calculate the center of geometry based on the current pivot point (median, otherwise "
|
2020-12-24 13:11:22 -06:00
|
|
|
"bounding box)"},
|
2012-10-08 21:03:35 +00:00
|
|
|
{ORIGIN_TO_CURSOR,
|
|
|
|
|
"ORIGIN_CURSOR",
|
|
|
|
|
0,
|
|
|
|
|
"Origin to 3D Cursor",
|
2017-08-21 15:06:07 +10:00
|
|
|
"Move object origin to position of the 3D cursor"},
|
|
|
|
|
/* Intentional naming mismatch since some scripts refer to this. */
|
|
|
|
|
{ORIGIN_TO_CENTER_OF_MASS_SURFACE,
|
|
|
|
|
"ORIGIN_CENTER_OF_MASS",
|
|
|
|
|
0,
|
|
|
|
|
"Origin to Center of Mass (Surface)",
|
2017-08-21 15:24:40 +10:00
|
|
|
"Calculate the center of mass from the surface area"},
|
2017-08-21 15:06:07 +10:00
|
|
|
{ORIGIN_TO_CENTER_OF_MASS_VOLUME,
|
|
|
|
|
"ORIGIN_CENTER_OF_VOLUME",
|
|
|
|
|
0,
|
|
|
|
|
"Origin to Center of Mass (Volume)",
|
|
|
|
|
"Calculate the center of mass from the volume (must be manifold geometry with consistent "
|
|
|
|
|
"normals)"},
|
2022-03-18 15:50:46 -05:00
|
|
|
{0, nullptr, 0, nullptr, nullptr},
|
2010-08-01 11:00:36 +00:00
|
|
|
};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-10-18 15:07:26 +11:00
|
|
|
static const EnumPropertyItem prop_set_bounds_types[] = {
|
2018-12-14 11:01:01 +11:00
|
|
|
{V3D_AROUND_CENTER_MEDIAN, "MEDIAN", 0, "Median Center", ""},
|
2015-12-01 18:52:24 +11:00
|
|
|
{V3D_AROUND_CENTER_BOUNDS, "BOUNDS", 0, "Bounds Center", ""},
|
2022-03-18 15:50:46 -05:00
|
|
|
{0, nullptr, 0, nullptr, nullptr},
|
2010-08-01 11:00:36 +00:00
|
|
|
};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Set Origin";
|
2012-10-08 21:03:35 +00:00
|
|
|
ot->description =
|
|
|
|
|
"Set the object's origin, by either moving the data, or set to center of data, or use 3D "
|
|
|
|
|
"cursor";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "OBJECT_OT_origin_set";
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-05-17 09:18:03 +10:00
|
|
|
/* API callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = WM_menu_invoke;
|
|
|
|
|
ot->exec = object_origin_set_exec;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = ED_operator_scene_editable;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
/* flags */
|
2012-04-28 15:42:27 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->prop = RNA_def_enum(ot->srna, "type", prop_set_center_types, 0, "Type", "");
|
2018-12-14 11:01:01 +11:00
|
|
|
RNA_def_enum(ot->srna, "center", prop_set_bounds_types, V3D_AROUND_CENTER_MEDIAN, "Center", "");
|
2.5: Object module
* Split object_edit.c into multiple files:
object_add.c, object_edit.c, object_hook.c, object_relations.c,
object_select.c, object_transform.c.
* Rename files to have consistent object_ and mball_ prefix:
object_shapekey.c, object_lattice.c, object_vgroup.c, mball_edit.c.
* Added operators:
* vertex group menu and set active
* apply location, rotation, scale, visual transform (location is new)
* make local
* make vertex parent
* move to layer
* convert to curve/mesh (not finished yet)
* Many small fixes for marked issues, but still much code to be cleaned
up here...
2009-09-09 11:52:56 +00:00
|
|
|
}
|
2017-08-06 19:47:25 +10:00
|
|
|
|
2019-08-22 04:56:18 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Transform Axis Target
|
|
|
|
|
*
|
2019-07-07 15:38:41 +10:00
|
|
|
* Note this is an experimental operator to point lights/cameras at objects.
|
2017-08-06 19:47:25 +10:00
|
|
|
* We may re-work how this behaves based on user feedback.
|
|
|
|
|
* - campbell.
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2019-04-22 00:18:34 +10:00
|
|
|
/** When using multiple objects, apply their relative rotational offset to the active object. */
|
2017-08-06 19:47:25 +10:00
|
|
|
#define USE_RELATIVE_ROTATION
|
2019-04-22 00:18:34 +10:00
|
|
|
/** Disable overlays, ignoring user setting (light wire gets in the way). */
|
2018-12-18 20:33:16 +11:00
|
|
|
#define USE_RENDER_OVERRIDE
|
2019-11-25 01:14:39 +11:00
|
|
|
/**
|
|
|
|
|
* Calculate a depth if the cursor isn't already over a depth
|
|
|
|
|
* (not essential but feels buggy without).
|
|
|
|
|
*/
|
2018-12-18 22:30:21 +11:00
|
|
|
#define USE_FAKE_DEPTH_INIT
|
2017-08-06 19:47:25 +10:00
|
|
|
|
|
|
|
|
struct XFormAxisItem {
|
|
|
|
|
Object *ob;
|
|
|
|
|
float rot_mat[3][3];
|
|
|
|
|
void *obtfm;
|
|
|
|
|
float xform_dist;
|
2020-04-16 15:50:04 +10:00
|
|
|
bool is_z_flip;
|
2017-08-06 19:47:25 +10:00
|
|
|
|
|
|
|
|
#ifdef USE_RELATIVE_ROTATION
|
|
|
|
|
/* use when translating multiple */
|
|
|
|
|
float xform_rot_offset[3][3];
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct XFormAxisData {
|
|
|
|
|
ViewContext vc;
|
2021-06-21 16:25:53 -03:00
|
|
|
ViewDepths *depths;
|
2017-08-06 19:47:25 +10:00
|
|
|
struct {
|
|
|
|
|
float depth;
|
|
|
|
|
float normal[3];
|
|
|
|
|
bool is_depth_valid;
|
|
|
|
|
bool is_normal_valid;
|
|
|
|
|
} prev;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
Vector<XFormAxisItem> object_data;
|
2017-08-06 19:47:25 +10:00
|
|
|
bool is_translate;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
int init_event;
|
|
|
|
|
};
|
|
|
|
|
|
2018-12-18 22:30:21 +11:00
|
|
|
#ifdef USE_FAKE_DEPTH_INIT
|
2022-03-18 15:50:46 -05:00
|
|
|
static void object_transform_axis_target_calc_depth_init(XFormAxisData *xfd, const int mval[2])
|
2018-12-18 22:30:21 +11:00
|
|
|
{
|
|
|
|
|
float view_co_a[3], view_co_b[3];
|
2022-09-26 17:38:25 +10:00
|
|
|
const float2 mval_fl = {float(mval[0]), float(mval[1])};
|
2020-03-06 16:56:42 +01:00
|
|
|
ED_view3d_win_to_ray(xfd->vc.region, mval_fl, view_co_a, view_co_b);
|
2018-12-18 22:30:21 +11:00
|
|
|
add_v3_v3(view_co_b, view_co_a);
|
|
|
|
|
float center[3] = {0.0f};
|
|
|
|
|
int center_tot = 0;
|
2022-03-18 15:50:46 -05:00
|
|
|
for (XFormAxisItem &item : xfd->object_data) {
|
|
|
|
|
const Object *ob = item.ob;
|
2024-02-14 16:14:49 +01:00
|
|
|
const float *ob_co_a = ob->object_to_world().location();
|
2018-12-18 22:30:21 +11:00
|
|
|
float ob_co_b[3];
|
2024-02-14 16:14:49 +01:00
|
|
|
add_v3_v3v3(ob_co_b, ob->object_to_world().location(), ob->object_to_world().ptr()[2]);
|
2018-12-18 22:30:21 +11:00
|
|
|
float view_isect[3], ob_isect[3];
|
|
|
|
|
if (isect_line_line_v3(view_co_a, view_co_b, ob_co_a, ob_co_b, view_isect, ob_isect)) {
|
|
|
|
|
add_v3_v3(center, view_isect);
|
|
|
|
|
center_tot += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (center_tot) {
|
|
|
|
|
mul_v3_fl(center, 1.0f / center_tot);
|
|
|
|
|
float center_proj[3];
|
2021-06-01 12:49:20 +10:00
|
|
|
ED_view3d_project_v3(xfd->vc.region, center, center_proj);
|
2018-12-18 22:30:21 +11:00
|
|
|
xfd->prev.depth = center_proj[2];
|
|
|
|
|
xfd->prev.is_depth_valid = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif /* USE_FAKE_DEPTH_INIT */
|
|
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
static bool object_is_target_compat(const Object *ob)
|
|
|
|
|
{
|
|
|
|
|
if (ob->type == OB_LAMP) {
|
2022-03-18 15:50:46 -05:00
|
|
|
const Light *la = static_cast<Light *>(ob->data);
|
2018-11-14 11:44:05 +01:00
|
|
|
if (ELEM(la->type, LA_SUN, LA_SPOT, LA_AREA)) {
|
2017-08-06 19:47:25 +10:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-27 12:02:02 +11:00
|
|
|
/* We might want to enable this later, for now just lights. */
|
2017-08-06 19:47:25 +10:00
|
|
|
#if 0
|
|
|
|
|
else if (ob->type == OB_CAMERA) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void object_transform_axis_target_free_data(wmOperator *op)
|
|
|
|
|
{
|
2022-03-18 15:50:46 -05:00
|
|
|
XFormAxisData *xfd = static_cast<XFormAxisData *>(op->customdata);
|
2018-12-18 20:33:16 +11:00
|
|
|
|
|
|
|
|
#ifdef USE_RENDER_OVERRIDE
|
2021-06-21 16:25:53 -03:00
|
|
|
if (xfd->depths) {
|
|
|
|
|
ED_view3d_depths_free(xfd->depths);
|
2018-12-18 20:33:16 +11:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
for (XFormAxisItem &item : xfd->object_data) {
|
|
|
|
|
MEM_freeN(item.obtfm);
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
2022-03-18 15:50:46 -05:00
|
|
|
MEM_delete(xfd);
|
|
|
|
|
op->customdata = nullptr;
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* We may want to expose as alternative to: BKE_object_apply_rotation */
|
|
|
|
|
static void object_apply_rotation(Object *ob, const float rmat[3][3])
|
|
|
|
|
{
|
|
|
|
|
float size[3];
|
|
|
|
|
float loc[3];
|
|
|
|
|
float rmat4[4][4];
|
|
|
|
|
copy_m4_m3(rmat4, rmat);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-02-18 15:43:06 +11:00
|
|
|
copy_v3_v3(size, ob->scale);
|
2017-08-06 19:47:25 +10:00
|
|
|
copy_v3_v3(loc, ob->loc);
|
|
|
|
|
BKE_object_apply_mat4(ob, rmat4, true, true);
|
2019-02-18 15:43:06 +11:00
|
|
|
copy_v3_v3(ob->scale, size);
|
2017-08-06 19:47:25 +10:00
|
|
|
copy_v3_v3(ob->loc, loc);
|
|
|
|
|
}
|
|
|
|
|
/* We may want to extract this to: BKE_object_apply_location */
|
|
|
|
|
static void object_apply_location(Object *ob, const float loc[3])
|
|
|
|
|
{
|
|
|
|
|
/* quick but weak */
|
2024-03-28 01:30:38 +01:00
|
|
|
Object ob_prev = dna::shallow_copy(*ob);
|
2017-08-06 19:47:25 +10:00
|
|
|
float mat[4][4];
|
2024-02-14 16:14:49 +01:00
|
|
|
copy_m4_m4(mat, ob->object_to_world().ptr());
|
2017-08-06 19:47:25 +10:00
|
|
|
copy_v3_v3(mat[3], loc);
|
|
|
|
|
BKE_object_apply_mat4(ob, mat, true, true);
|
|
|
|
|
copy_v3_v3(mat[3], ob->loc);
|
2024-03-28 01:30:38 +01:00
|
|
|
*ob = dna::shallow_copy(ob_prev);
|
2017-08-06 19:47:25 +10:00
|
|
|
copy_v3_v3(ob->loc, mat[3]);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-23 18:25:29 +10:00
|
|
|
static bool object_orient_to_location(Object *ob,
|
2019-09-14 08:10:50 +10:00
|
|
|
const float rot_orig[3][3],
|
2017-08-06 19:47:25 +10:00
|
|
|
const float axis[3],
|
2020-04-16 15:50:04 +10:00
|
|
|
const float location[3],
|
|
|
|
|
const bool z_flip)
|
2017-08-06 19:47:25 +10:00
|
|
|
{
|
|
|
|
|
float delta[3];
|
2024-02-14 16:14:49 +01:00
|
|
|
sub_v3_v3v3(delta, ob->object_to_world().location(), location);
|
2017-08-06 19:47:25 +10:00
|
|
|
if (normalize_v3(delta) != 0.0f) {
|
2020-04-16 15:50:04 +10:00
|
|
|
if (z_flip) {
|
|
|
|
|
negate_v3(delta);
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
if (len_squared_v3v3(delta, axis) > FLT_EPSILON) {
|
|
|
|
|
float delta_rot[3][3];
|
|
|
|
|
float final_rot[3][3];
|
|
|
|
|
rotation_between_vecs_to_mat3(delta_rot, axis, delta);
|
|
|
|
|
|
|
|
|
|
mul_m3_m3m3(final_rot, delta_rot, rot_orig);
|
|
|
|
|
|
|
|
|
|
object_apply_rotation(ob, final_rot);
|
|
|
|
|
|
2020-04-23 18:25:29 +10:00
|
|
|
return true;
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
|
|
|
|
}
|
2020-04-23 18:25:29 +10:00
|
|
|
return false;
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void object_transform_axis_target_cancel(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2022-03-18 15:50:46 -05:00
|
|
|
XFormAxisData *xfd = static_cast<XFormAxisData *>(op->customdata);
|
|
|
|
|
for (XFormAxisItem &item : xfd->object_data) {
|
|
|
|
|
BKE_object_tfm_restore(item.ob, item.obtfm);
|
|
|
|
|
DEG_id_tag_update(&item.ob->id, ID_RECALC_TRANSFORM);
|
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item.ob);
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
object_transform_axis_target_free_data(op);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-20 21:11:06 +00:00
|
|
|
static wmOperatorStatus object_transform_axis_target_invoke(bContext *C,
|
|
|
|
|
wmOperator *op,
|
|
|
|
|
const wmEvent *event)
|
2017-08-06 19:47:25 +10:00
|
|
|
{
|
2019-09-18 17:19:07 +02:00
|
|
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
2023-10-17 10:34:59 +02:00
|
|
|
ViewContext vc = ED_view3d_viewcontext_init(C, depsgraph);
|
2017-08-06 19:47:25 +10:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
if (vc.obact == nullptr || !object_is_target_compat(vc.obact)) {
|
2017-08-06 19:47:25 +10:00
|
|
|
/* Falls back to texture space transform. */
|
|
|
|
|
return OPERATOR_PASS_THROUGH;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-12-18 20:33:16 +11:00
|
|
|
|
|
|
|
|
#ifdef USE_RENDER_OVERRIDE
|
|
|
|
|
int flag2_prev = vc.v3d->flag2;
|
2019-03-05 15:09:25 +11:00
|
|
|
vc.v3d->flag2 |= V3D_HIDE_OVERLAYS;
|
2018-12-18 20:33:16 +11:00
|
|
|
#endif
|
|
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
ViewDepths *depths = nullptr;
|
|
|
|
|
ED_view3d_depth_override(
|
2024-12-02 22:01:14 +11:00
|
|
|
vc.depsgraph, vc.region, vc.v3d, nullptr, V3D_DEPTH_NO_GPENCIL, false, &depths);
|
2017-08-06 19:47:25 +10:00
|
|
|
|
2018-12-18 20:33:16 +11:00
|
|
|
#ifdef USE_RENDER_OVERRIDE
|
|
|
|
|
vc.v3d->flag2 = flag2_prev;
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
if (depths == nullptr) {
|
2017-08-06 19:47:25 +10:00
|
|
|
BKE_report(op->reports, RPT_WARNING, "Unable to access depth buffer, using view plane");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
ED_region_tag_redraw(vc.region);
|
2017-08-06 19:47:25 +10:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
XFormAxisData *xfd = MEM_new<XFormAxisData>(__func__);
|
|
|
|
|
op->customdata = xfd;
|
2017-08-06 19:47:25 +10:00
|
|
|
|
|
|
|
|
/* Don't change this at runtime. */
|
|
|
|
|
xfd->vc = vc;
|
2021-06-21 16:25:53 -03:00
|
|
|
xfd->depths = depths;
|
2017-08-06 19:47:25 +10:00
|
|
|
xfd->vc.mval[0] = event->mval[0];
|
|
|
|
|
xfd->vc.mval[1] = event->mval[1];
|
|
|
|
|
|
|
|
|
|
xfd->prev.depth = 1.0f;
|
|
|
|
|
xfd->prev.is_depth_valid = false;
|
|
|
|
|
xfd->prev.is_normal_valid = false;
|
|
|
|
|
xfd->is_translate = false;
|
|
|
|
|
|
|
|
|
|
xfd->init_event = WM_userdef_event_type_from_keymap_type(event->type);
|
|
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
xfd->object_data.append({});
|
|
|
|
|
xfd->object_data.last().ob = xfd->vc.obact;
|
2017-08-06 19:47:25 +10:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
|
|
|
|
|
if ((ob != xfd->vc.obact) && object_is_target_compat(ob)) {
|
|
|
|
|
xfd->object_data.append({});
|
|
|
|
|
xfd->object_data.last().ob = ob;
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
|
|
|
|
}
|
2022-03-18 15:50:46 -05:00
|
|
|
CTX_DATA_END;
|
2017-08-06 19:47:25 +10:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
for (XFormAxisItem &item : xfd->object_data) {
|
|
|
|
|
item.obtfm = BKE_object_tfm_backup(item.ob);
|
|
|
|
|
BKE_object_rot_to_mat3(item.ob, item.rot_mat, true);
|
2020-04-16 15:50:04 +10:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
/* Detect negative scale matrix. */
|
|
|
|
|
float full_mat3[3][3];
|
|
|
|
|
BKE_object_to_mat3(item.ob, full_mat3);
|
|
|
|
|
item.is_z_flip = dot_v3v3(item.rot_mat[2], full_mat3[2]) < 0.0f;
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WM_event_add_modal_handler(C, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-20 21:11:06 +00:00
|
|
|
static wmOperatorStatus object_transform_axis_target_modal(bContext *C,
|
|
|
|
|
wmOperator *op,
|
|
|
|
|
const wmEvent *event)
|
2017-08-06 19:47:25 +10:00
|
|
|
{
|
2022-03-18 15:50:46 -05:00
|
|
|
XFormAxisData *xfd = static_cast<XFormAxisData *>(op->customdata);
|
2020-03-06 16:56:42 +01:00
|
|
|
ARegion *region = xfd->vc.region;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-02-04 21:17:14 +11:00
|
|
|
view3d_operator_needs_gpu(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-02-24 22:48:34 +11:00
|
|
|
const bool is_translate = event->modifier & KM_CTRL;
|
2017-08-06 19:47:25 +10:00
|
|
|
const bool is_translate_init = is_translate && (xfd->is_translate != is_translate);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
if (event->type == MOUSEMOVE || is_translate_init) {
|
2021-06-21 16:25:53 -03:00
|
|
|
const ViewDepths *depths = xfd->depths;
|
2022-09-25 18:33:28 +10:00
|
|
|
if (depths && (uint(event->mval[0]) < depths->w) && (uint(event->mval[1]) < depths->h)) {
|
2021-04-05 10:48:28 -03:00
|
|
|
float depth_fl = 1.0f;
|
|
|
|
|
ED_view3d_depth_read_cached(depths, event->mval, 0, &depth_fl);
|
2017-08-06 19:47:25 +10:00
|
|
|
float location_world[3];
|
2021-04-05 10:48:28 -03:00
|
|
|
if (depth_fl == 1.0f) {
|
2017-08-06 19:47:25 +10:00
|
|
|
if (xfd->prev.is_depth_valid) {
|
2021-04-05 10:48:28 -03:00
|
|
|
depth_fl = xfd->prev.depth;
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
|
|
|
|
}
|
2018-12-18 22:30:21 +11:00
|
|
|
|
|
|
|
|
#ifdef USE_FAKE_DEPTH_INIT
|
|
|
|
|
/* First time only. */
|
2021-04-05 10:48:28 -03:00
|
|
|
if (depth_fl == 1.0f) {
|
2018-12-18 22:30:21 +11:00
|
|
|
if (xfd->prev.is_depth_valid == false) {
|
|
|
|
|
object_transform_axis_target_calc_depth_init(xfd, event->mval);
|
|
|
|
|
if (xfd->prev.is_depth_valid) {
|
2021-04-05 10:48:28 -03:00
|
|
|
depth_fl = xfd->prev.depth;
|
2018-12-18 22:30:21 +11:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-09-25 20:27:46 +10:00
|
|
|
double depth = double(depth_fl);
|
2017-08-06 19:47:25 +10:00
|
|
|
if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) {
|
2021-04-05 10:48:28 -03:00
|
|
|
xfd->prev.depth = depth_fl;
|
2017-08-06 19:47:25 +10:00
|
|
|
xfd->prev.is_depth_valid = true;
|
2021-06-01 12:49:20 +10:00
|
|
|
if (ED_view3d_depth_unproject_v3(region, event->mval, depth, location_world)) {
|
2017-08-06 19:47:25 +10:00
|
|
|
if (is_translate) {
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
float normal[3];
|
|
|
|
|
bool normal_found = false;
|
2021-06-21 16:25:53 -03:00
|
|
|
if (ED_view3d_depth_read_cached_normal(region, depths, event->mval, normal)) {
|
2017-08-06 19:47:25 +10:00
|
|
|
normal_found = true;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
/* cheap attempt to smooth normals out a bit! */
|
2020-04-17 19:17:00 +10:00
|
|
|
const int ofs = 2;
|
|
|
|
|
for (int x = -ofs; x <= ofs; x += ofs / 2) {
|
|
|
|
|
for (int y = -ofs; y <= ofs; y += ofs / 2) {
|
2017-08-06 19:47:25 +10:00
|
|
|
if (x != 0 && y != 0) {
|
2020-08-07 22:36:11 +10:00
|
|
|
const int mval_ofs[2] = {event->mval[0] + x, event->mval[1] + y};
|
2017-08-06 19:47:25 +10:00
|
|
|
float n[3];
|
2021-06-21 16:25:53 -03:00
|
|
|
if (ED_view3d_depth_read_cached_normal(region, depths, mval_ofs, n)) {
|
2017-08-06 19:47:25 +10:00
|
|
|
add_v3_v3(normal, n);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
normalize_v3(normal);
|
|
|
|
|
}
|
|
|
|
|
else if (xfd->prev.is_normal_valid) {
|
|
|
|
|
copy_v3_v3(normal, xfd->prev.normal);
|
|
|
|
|
normal_found = true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-17 18:48:33 +10:00
|
|
|
{
|
2017-08-06 19:47:25 +10:00
|
|
|
#ifdef USE_RELATIVE_ROTATION
|
2022-03-18 15:50:46 -05:00
|
|
|
if (is_translate_init && xfd->object_data.size() > 1) {
|
2017-08-06 19:47:25 +10:00
|
|
|
float xform_rot_offset_inv_first[3][3];
|
2022-03-18 15:50:46 -05:00
|
|
|
for (const int i : xfd->object_data.index_range()) {
|
|
|
|
|
XFormAxisItem &item = xfd->object_data[i];
|
2024-02-14 16:14:49 +01:00
|
|
|
copy_m3_m4(item.xform_rot_offset, item.ob->object_to_world().ptr());
|
2022-03-18 15:50:46 -05:00
|
|
|
normalize_m3(item.xform_rot_offset);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
if (i == 0) {
|
|
|
|
|
invert_m3_m3(xform_rot_offset_inv_first, xfd->object_data[0].xform_rot_offset);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2022-03-18 15:50:46 -05:00
|
|
|
mul_m3_m3m3(
|
|
|
|
|
item.xform_rot_offset, item.xform_rot_offset, xform_rot_offset_inv_first);
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
for (const int i : xfd->object_data.index_range()) {
|
|
|
|
|
XFormAxisItem &item = xfd->object_data[i];
|
2017-08-06 19:47:25 +10:00
|
|
|
if (is_translate_init) {
|
|
|
|
|
float ob_axis[3];
|
2024-02-14 16:14:49 +01:00
|
|
|
item.xform_dist = len_v3v3(item.ob->object_to_world().location(),
|
|
|
|
|
location_world);
|
|
|
|
|
normalize_v3_v3(ob_axis, item.ob->object_to_world().ptr()[2]);
|
2017-08-06 19:47:25 +10:00
|
|
|
/* Scale to avoid adding distance when moving between surfaces. */
|
2020-04-17 18:48:33 +10:00
|
|
|
if (normal_found) {
|
|
|
|
|
float scale = fabsf(dot_v3v3(ob_axis, normal));
|
2022-03-18 15:50:46 -05:00
|
|
|
item.xform_dist *= scale;
|
2020-04-17 18:48:33 +10:00
|
|
|
}
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float target_normal[3];
|
2020-04-17 18:48:33 +10:00
|
|
|
|
|
|
|
|
if (normal_found) {
|
|
|
|
|
copy_v3_v3(target_normal, normal);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2024-02-14 16:14:49 +01:00
|
|
|
normalize_v3_v3(target_normal, item.ob->object_to_world().ptr()[2]);
|
2020-04-17 18:48:33 +10:00
|
|
|
}
|
2017-08-06 19:47:25 +10:00
|
|
|
|
|
|
|
|
#ifdef USE_RELATIVE_ROTATION
|
2020-04-17 18:48:33 +10:00
|
|
|
if (normal_found) {
|
|
|
|
|
if (i != 0) {
|
2022-03-18 15:50:46 -05:00
|
|
|
mul_m3_v3(item.xform_rot_offset, target_normal);
|
2020-04-17 18:48:33 +10:00
|
|
|
}
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
float loc[3];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
copy_v3_v3(loc, location_world);
|
2022-03-18 15:50:46 -05:00
|
|
|
madd_v3_v3fl(loc, target_normal, item.xform_dist);
|
|
|
|
|
object_apply_location(item.ob, loc);
|
2019-01-15 23:24:20 +11:00
|
|
|
/* so orient behaves as expected */
|
2024-02-14 16:14:49 +01:00
|
|
|
copy_v3_v3(item.ob->runtime->object_to_world.location(), loc);
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
object_orient_to_location(
|
2022-03-18 15:50:46 -05:00
|
|
|
item.ob, item.rot_mat, item.rot_mat[2], location_world, item.is_z_flip);
|
2020-04-23 18:25:29 +10:00
|
|
|
|
2022-03-18 15:50:46 -05:00
|
|
|
DEG_id_tag_update(&item.ob->id, ID_RECALC_TRANSFORM);
|
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item.ob);
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
2020-04-17 18:48:33 +10:00
|
|
|
if (normal_found) {
|
|
|
|
|
copy_v3_v3(xfd->prev.normal, normal);
|
|
|
|
|
xfd->prev.is_normal_valid = true;
|
|
|
|
|
}
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-08-06 19:47:25 +10:00
|
|
|
else {
|
2022-03-18 15:50:46 -05:00
|
|
|
for (XFormAxisItem &item : xfd->object_data) {
|
|
|
|
|
if (object_orient_to_location(
|
|
|
|
|
item.ob, item.rot_mat, item.rot_mat[2], location_world, item.is_z_flip))
|
|
|
|
|
{
|
|
|
|
|
DEG_id_tag_update(&item.ob->id, ID_RECALC_TRANSFORM);
|
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item.ob);
|
2020-04-23 18:25:29 +10:00
|
|
|
}
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
|
|
|
|
xfd->prev.is_normal_valid = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-08-06 19:47:25 +10:00
|
|
|
xfd->is_translate = is_translate;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
ED_region_tag_redraw(xfd->vc.region);
|
2017-08-06 19:47:25 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
bool is_finished = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-07-21 15:54:39 +10:00
|
|
|
if (ISMOUSE_BUTTON(xfd->init_event)) {
|
2017-08-06 19:47:25 +10:00
|
|
|
if ((event->type == xfd->init_event) && (event->val == KM_RELEASE)) {
|
|
|
|
|
is_finished = true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-08-06 19:47:25 +10:00
|
|
|
else {
|
2020-03-18 10:38:37 -06:00
|
|
|
if (ELEM(event->type, LEFTMOUSE, EVT_RETKEY, EVT_PADENTER)) {
|
2017-08-06 19:47:25 +10:00
|
|
|
is_finished = true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
if (is_finished) {
|
2025-04-21 16:12:56 +02:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
|
/* Perform auto-keying for rotational changes for all objects. */
|
|
|
|
|
for (XFormAxisItem &item : xfd->object_data) {
|
|
|
|
|
PointerRNA ptr = RNA_pointer_create_discrete(&item.ob->id, &RNA_Object, &item.ob->id);
|
|
|
|
|
const char *rotation_property = "rotation_euler";
|
|
|
|
|
switch (item.ob->rotmode) {
|
|
|
|
|
case ROT_MODE_QUAT:
|
|
|
|
|
rotation_property = "rotation_quaternion";
|
|
|
|
|
break;
|
|
|
|
|
case ROT_MODE_AXISANGLE:
|
|
|
|
|
rotation_property = "rotation_axis_angle";
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
PropertyRNA *prop = RNA_struct_find_property(&ptr, rotation_property);
|
|
|
|
|
animrig::autokeyframe_property(C, scene, &ptr, prop, -1, scene->r.cfra, true);
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
object_transform_axis_target_free_data(op);
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2020-07-03 15:42:22 +02:00
|
|
|
if (ELEM(event->type, EVT_ESCKEY, RIGHTMOUSE)) {
|
2017-08-06 19:47:25 +10:00
|
|
|
object_transform_axis_target_cancel(C, op);
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OBJECT_OT_transform_axis_target(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2018-06-27 14:41:53 +02:00
|
|
|
ot->name = "Interactive Light Track to Cursor";
|
|
|
|
|
ot->description = "Interactively point cameras and lights to a location (Ctrl translates)";
|
2017-08-06 19:47:25 +10:00
|
|
|
ot->idname = "OBJECT_OT_transform_axis_target";
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2025-05-17 09:18:03 +10:00
|
|
|
/* API callbacks. */
|
2017-08-06 19:47:25 +10:00
|
|
|
ot->invoke = object_transform_axis_target_invoke;
|
|
|
|
|
ot->cancel = object_transform_axis_target_cancel;
|
|
|
|
|
ot->modal = object_transform_axis_target_modal;
|
|
|
|
|
ot->poll = ED_operator_region_view3d_active;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-06 19:47:25 +10:00
|
|
|
/* flags */
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#undef USE_RELATIVE_ROTATION
|
|
|
|
|
|
|
|
|
|
/** \} */
|
2024-03-28 01:30:38 +01:00
|
|
|
|
|
|
|
|
} // namespace blender::ed::object
|