Blender V5.0
transform_snap_object_armature.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
10
11#include "BLI_listbase.h"
12
13#include "BKE_armature.hh"
14
15#include "ED_armature.hh"
17
18#include "ANIM_armature.hh"
19
21
22namespace blender::ed::transform {
23
25 const Object *ob_eval,
26 const float4x4 &obmat,
27 bool is_object_active)
28{
30
32 /* Currently only edge and vert. */
33 return retval;
34 }
35
36 bArmature *arm = static_cast<bArmature *>(ob_eval->data);
37
38 SnapData nearest2d(sctx, obmat);
39
40 nearest2d.clip_planes_enable(sctx, ob_eval);
41
42 const float *head_vec = nullptr, *tail_vec = nullptr;
43
44 const bool is_editmode = arm->edbo != nullptr;
45 const bool is_posemode = is_object_active && (ob_eval->mode & OB_MODE_POSE);
46 const bool skip_selected = (is_editmode || is_posemode) &&
49
50 if (arm->edbo) {
51 LISTBASE_FOREACH (EditBone *, eBone, arm->edbo) {
52 if (blender::animrig::bone_is_visible(arm, eBone)) {
53 const bool is_selected = (eBone->flag & (BONE_ROOTSEL | BONE_TIPSEL)) != 0;
54 if (is_selected && skip_selected) {
55 continue;
56 }
57
58 if (nearest2d.snap_edge(eBone->head, eBone->tail)) {
59 head_vec = eBone->head;
60 tail_vec = eBone->tail;
61 }
62 }
63 }
64 }
65 else if (ob_eval->pose && ob_eval->pose->chanbase.first) {
66 LISTBASE_FOREACH (bPoseChannel *, pchan, &ob_eval->pose->chanbase) {
67 if (!blender::animrig::bone_is_visible(arm, pchan)) {
68 /* Skip hidden bones. */
69 continue;
70 }
71
72 const bool is_selected = (pchan->flag & POSE_SELECTED) != 0;
73 if (is_selected && skip_selected) {
74 continue;
75 }
76
77 if (nearest2d.snap_edge(pchan->pose_head, pchan->pose_tail)) {
78 head_vec = pchan->pose_head;
79 tail_vec = pchan->pose_tail;
80 }
81 }
82 }
83
84 if (nearest2d.nearest_point.index != -2) {
85 retval = sctx->runtime.snap_to_flag & SCE_SNAP_TO_EDGE;
86 if (retval == SCE_SNAP_TO_NONE) {
87 nearest2d.nearest_point.index = -2;
88 }
89
91 float dist_px_sq_edge = nearest2d.nearest_point.dist_sq;
92 nearest2d.nearest_point.dist_sq = sctx->ret.dist_px_sq;
93 if (nearest2d.snap_point(head_vec) || nearest2d.snap_point(tail_vec)) {
95 }
96 else if (retval) {
97 nearest2d.nearest_point.dist_sq = dist_px_sq_edge;
98 }
99 }
100 }
101
102 if (retval) {
103 nearest2d.register_result(sctx, ob_eval, &arm->id);
104 }
105 return retval;
106}
107
108} // namespace blender::ed::transform
Functions to deal with Armatures.
#define LISTBASE_FOREACH(type, var, list)
@ POSE_SELECTED
@ BONE_ROOTSEL
@ BONE_TIPSEL
@ OB_MODE_POSE
@ SCE_SNAP_TARGET_NOT_SELECTED
@ SCE_SNAP_TO_EDGE
@ SCE_SNAP_TO_FACE
@ SCE_SNAP_TO_EDGE_ENDPOINT
@ SCE_SNAP_TO_NONE
void clip_planes_enable(SnapObjectContext *sctx, const Object *ob_eval, bool skip_occlusion_plane=false)
bool snap_edge(const float3 &va, const float3 &vb, int edge_index=-1)
bool snap_point(const float3 &co, int index=-1)
static void register_result(SnapObjectContext *sctx, const Object *ob_eval, const ID *id_eval, const float4x4 &obmat, BVHTreeNearest *r_nearest)
bool bone_is_visible(const bArmature *armature, const Bone *bone)
eSnapMode snapArmature(SnapObjectContext *sctx, const Object *ob_eval, const float4x4 &obmat, bool is_object_active)
MatBase< float, 4, 4 > float4x4
void * first
struct bPose * pose
ListBase * edbo
ListBase chanbase
struct blender::ed::transform::SnapObjectContext::@170374026073064374202114033260227063176045253050 runtime
struct blender::ed::transform::SnapObjectContext::Output ret