Files
test/source/blender/editors/include/ED_armature.hh
2024-04-04 11:26:28 +11:00

344 lines
13 KiB
C++

/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup editors
*/
#pragma once
#include "BLI_compiler_attrs.h"
#include "BLI_listbase.h"
#include "BLI_span.hh"
struct Base;
struct Bone;
struct Depsgraph;
struct EditBone;
struct GPUSelectResult;
struct ListBase;
struct Main;
struct Mesh;
struct MeshDeformModifierData;
struct Object;
struct ReportList;
struct Scene;
struct SelectPick_Params;
struct UndoType;
struct View3D;
struct ViewLayer;
struct bArmature;
struct bContext;
struct bPoseChannel;
struct wmKeyConfig;
struct wmOperator;
#define BONESEL_ROOT (1u << 29)
#define BONESEL_TIP (1u << 30)
#define BONESEL_BONE (1u << 31)
#define BONESEL_ANY (BONESEL_TIP | BONESEL_ROOT | BONESEL_BONE)
/* useful macros, be sure to #include "ANIM_bone_collections.hh". */
#define EBONE_VISIBLE(arm, ebone) ANIM_bone_is_visible_editbone(arm, ebone)
#define EBONE_SELECTABLE(arm, ebone) \
(EBONE_VISIBLE(arm, ebone) && !((ebone)->flag & BONE_UNSELECTABLE))
#define EBONE_EDITABLE(ebone) \
(CHECK_TYPE_INLINE(ebone, EditBone *), \
(((ebone)->flag & BONE_SELECTED) && !((ebone)->flag & BONE_EDITMODE_LOCKED)))
/* Used in `armature_select.cc` and `pose_select.cc`. */
#define BONE_SELECT_PARENT 0
#define BONE_SELECT_CHILD 1
/* `armature_add.cc` */
/**
* Default bone add, returns it selected, but without tail set.
*
* \note should be used everywhere, now it allocates bones still locally in functions.
*/
EditBone *ED_armature_ebone_add(bArmature *arm, const char *name);
EditBone *ED_armature_ebone_add_primitive(Object *obedit_arm, float length, bool view_aligned);
void ED_armature_ebone_copy(EditBone *dest, const EditBone *source);
/**
* Get current armature from the context, including properties editor pinning.
*/
bArmature *ED_armature_context(const bContext *C);
/**
* Adjust bone roll to align Z axis with vector `align_axis` is in local space and is normalized.
*/
float ED_armature_ebone_roll_to_vector(const EditBone *bone,
const float align_axis[3],
bool axis_only);
/**
* \param centermode: 0 == do center, 1 == center new, 2 == center cursor.
*
* \note Exported for use in `editors/object/`.
*/
void ED_armature_origin_set(
Main *bmain, Object *ob, const float cursor[3], int centermode, int around);
/**
* See #BKE_armature_transform for object-mode transform.
*/
void ED_armature_edit_transform(bArmature *arm, const float mat[4][4], bool do_props);
void ED_armature_transform(bArmature *arm, const float mat[4][4], bool do_props);
/* `armature_naming.cc` */
/**
* Ensure the bone name is unique.
* If bone is already in list, pass it as argument to ignore it.
*/
void ED_armature_ebone_unique_name(ListBase *ebones, char *name, EditBone *bone);
/**
* Bone Rename (called by UI for renaming a bone).
* Seems messy, but that's what you get with not using pointers but channel names :).
* \warning make sure the original bone was not renamed yet!
*/
void ED_armature_bone_rename(Main *bmain,
bArmature *arm,
const char *oldnamep,
const char *newnamep);
/**
* Renames (by flipping) all selected bones at once.
*
* This way if we are flipping related bones (e.g., Bone.L, Bone.R) at the same time
* all the bones are safely renamed, without conflicting with each other.
*
* \param arm: Armature the bones belong to
* \param bones_names: List of bone conflict elements (#LinkData pointing to names).
* \param do_strip_numbers: if set, try to get rid of dot-numbers at end of bone names.
*/
void ED_armature_bones_flip_names(Main *bmain,
bArmature *arm,
ListBase *bones_names,
bool do_strip_numbers);
/* `armature_ops.cc` */
void ED_operatortypes_armature();
void ED_operatormacros_armature();
void ED_keymap_armature(wmKeyConfig *keyconf);
/* `armature_relations.cc` */
/**
* Join armature exec is exported for use in object->join objects operator.
*/
int ED_armature_join_objects_exec(bContext *C, wmOperator *op);
/* `armature_select.cc` */
Base *ED_armature_base_and_ebone_from_select_buffer(blender::Span<Base *> bases,
unsigned int select_id,
EditBone **r_ebone);
Object *ED_armature_object_and_ebone_from_select_buffer(blender::Span<Object *> objects,
unsigned int select_id,
EditBone **r_ebone);
Base *ED_armature_base_and_pchan_from_select_buffer(blender::Span<Base *> bases,
unsigned int select_id,
bPoseChannel **r_pchan);
/**
* For callers that don't need the pose channel.
*/
Base *ED_armature_base_and_bone_from_select_buffer(blender::Span<Base *> bases,
unsigned int select_id,
Bone **r_bone);
bool ED_armature_edit_deselect_all(Object *obedit);
bool ED_armature_edit_deselect_all_visible(Object *obedit);
bool ED_armature_edit_deselect_all_multi_ex(blender::Span<Base *> bases);
bool ED_armature_edit_deselect_all_visible_multi_ex(blender::Span<Base *> bases);
bool ED_armature_edit_deselect_all_visible_multi(bContext *C);
/**
* \return True when pick finds an element or the selection changed.
*/
bool ED_armature_edit_select_pick_bone(
bContext *C, Base *basact, EditBone *ebone, int selmask, const SelectPick_Params *params);
/**
* Bone selection picking for armature edit-mode in the view3d.
*/
bool ED_armature_edit_select_pick(bContext *C, const int mval[2], const SelectPick_Params *params);
/**
* Perform a selection operation on elements which have been 'touched',
* use for lasso & border select but can be used elsewhere too.
*
* Tagging is done via #EditBone.temp.i using: #BONESEL_ROOT, #BONESEL_TIP, #BONESEL_BONE
* And optionally ignoring end-points using the #BONESEL_ROOT, #BONESEL_TIP right shifted 16 bits.
* (used when the values are clipped outside the view).
*
* \param sel_op: #eSelectOp type.
*
* \note Visibility checks must be done by the caller.
*/
bool ED_armature_edit_select_op_from_tagged(bArmature *arm, int sel_op);
/* `armature_skinning.cc` */
#define ARM_GROUPS_NAME 1
#define ARM_GROUPS_ENVELOPE 2
#define ARM_GROUPS_AUTO 3
void ED_object_vgroup_calc_from_armature(ReportList *reports,
Depsgraph *depsgraph,
Scene *scene,
Object *ob,
Object *par,
int mode,
bool mirror);
/* `editarmature_undo.cc` */
/** Export for ED_undo_sys. */
void ED_armature_undosys_type(UndoType *ut);
/* `armature_utils.cc` */
/** Sync selection to parent for connected children. */
void ED_armature_edit_sync_selection(ListBase *edbo);
void ED_armature_edit_validate_active(bArmature *arm);
/**
* \param clear_connected: When false caller is responsible for keeping the flag in a valid state.
*/
void ED_armature_ebone_remove_ex(bArmature *arm, EditBone *exBone, bool clear_connected);
void ED_armature_ebone_remove(bArmature *arm, EditBone *exBone);
bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebone_child);
/**
* Finds the first parent shared by \a ebone_child
*
* \param ebone_child: Children bones to search
* \param ebone_child_tot: Size of the ebone_child array
* \return The shared parent or NULL.
*/
EditBone *ED_armature_ebone_find_shared_parent(EditBone *ebone_child[],
unsigned int ebone_child_tot);
void ED_armature_ebone_to_mat3(EditBone *ebone, float r_mat[3][3]);
void ED_armature_ebone_to_mat4(EditBone *ebone, float r_mat[4][4]);
void ED_armature_ebone_from_mat3(EditBone *ebone, const float mat[3][3]);
void ED_armature_ebone_from_mat4(EditBone *ebone, const float mat[4][4]);
/**
* Return a pointer to the bone of the given name
*/
EditBone *ED_armature_ebone_find_name(const ListBase *edbo, const char *name);
/**
* \see #BKE_pose_channel_get_mirrored (pose-mode, matching function)
*/
EditBone *ED_armature_ebone_get_mirrored(const ListBase *edbo, EditBone *ebo);
void ED_armature_ebone_transform_mirror_update(bArmature *arm, EditBone *ebo, bool check_select);
/**
* If edit-bone (partial) selected, copy data.
* context; edit-mode armature, with mirror editing enabled.
*/
void ED_armature_edit_transform_mirror_update(Object *obedit);
/** Put edit-mode back in Object. */
void ED_armature_from_edit(Main *bmain, bArmature *arm);
/** Put armature in edit-mode. */
void ED_armature_to_edit(bArmature *arm);
void ED_armature_edit_free(bArmature *arm);
void ED_armature_ebone_listbase_temp_clear(ListBase *lb);
/**
* Free list of bones and their properties.
*/
void ED_armature_ebone_listbase_free(ListBase *lb, bool do_id_user);
void ED_armature_ebone_listbase_copy(ListBase *lb_dst, ListBase *lb_src, bool do_id_user);
int ED_armature_ebone_selectflag_get(const EditBone *ebone);
void ED_armature_ebone_selectflag_set(EditBone *ebone, int flag);
void ED_armature_ebone_select_set(EditBone *ebone, bool select);
void ED_armature_ebone_selectflag_enable(EditBone *ebone, int flag);
void ED_armature_ebone_selectflag_disable(EditBone *ebone, int flag);
/* `pose_edit.cc` */
Object *ED_pose_object_from_context(bContext *C);
bool ED_object_posemode_exit_ex(Main *bmain, Object *ob);
bool ED_object_posemode_exit(bContext *C, Object *ob);
/** This function is used to process the necessary updates for. */
bool ED_object_posemode_enter_ex(Main *bmain, Object *ob);
bool ED_object_posemode_enter(bContext *C, Object *ob);
/** Corresponds to #eAnimvizCalcRange. */
enum ePosePathCalcRange {
POSE_PATH_CALC_RANGE_CURRENT_FRAME,
POSE_PATH_CALC_RANGE_CHANGED,
POSE_PATH_CALC_RANGE_FULL,
};
/**
* For the object with pose/action: update paths for those that have got them
* This should selectively update paths that exist...
*
* To be called from various tools that do incremental updates.
*/
void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, ePosePathCalcRange range);
/* `pose_select.cc` */
/**
* \return True when pick finds an element or the selection changed.
*/
bool ED_armature_pose_select_pick_bone(const Scene *scene,
ViewLayer *view_layer,
View3D *v3d,
Object *ob,
Bone *bone,
const SelectPick_Params *params)
ATTR_NONNULL(1, 2, 3, 4, 6);
/**
* Called for mode-less pose selection.
* assumes the active object is still on old situation.
*
* \return True when pick finds an element or the selection changed.
*/
bool ED_armature_pose_select_pick_with_buffer(const Scene *scene,
ViewLayer *view_layer,
View3D *v3d,
Base *base,
const GPUSelectResult *hit_results,
int hits,
const SelectPick_Params *params,
bool do_nearest) ATTR_NONNULL(1, 2, 3, 4, 5, 7);
/**
* While in weight-paint mode, a single pose may be active as well.
* While not common, it's possible we have multiple armatures deforming a mesh.
*
* This function de-selects all other objects, and selects the new base.
* It can't be set to the active object because we need
* to keep this set to the weight paint object.
*/
void ED_armature_pose_select_in_wpaint_mode(const Scene *scene,
ViewLayer *view_layer,
Base *base_select);
bool ED_pose_deselect_all_multi_ex(blender::Span<Base *> bases,
int select_mode,
bool ignore_visibility);
bool ED_pose_deselect_all_multi(bContext *C, int select_mode, bool ignore_visibility);
/**
* 'select_mode' is usual SEL_SELECT/SEL_DESELECT/SEL_TOGGLE/SEL_INVERT.
* When true, 'ignore_visibility' makes this func also affect invisible bones
* (hidden or on hidden layers).
*/
bool ED_pose_deselect_all(Object *ob, int select_mode, bool ignore_visibility);
void ED_pose_bone_select_tag_update(Object *ob);
/**
* Utility method for changing the selection status of a bone.
* change_active determines whether to change the active bone of the armature when selecting pose
* channels. It is false during range selection otherwise true.
*/
void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select, bool change_active);
/* `meshlaplacian.cc` */
void ED_mesh_deform_bind_callback(Object *object,
MeshDeformModifierData *mmd,
Mesh *cagemesh,
float *vertexcos,
int verts_num,
float cagemat[4][4]);