Blender V4.3
transform_snap_object_curve.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
9#include "BLI_math_matrix.hh"
10
11#include "DNA_curve_types.h"
12
13#include "BKE_bvhutils.hh"
14#include "BKE_curve.hh"
15#include "BKE_object.hh"
16
18
20
23
24eSnapMode snapCurve(SnapObjectContext *sctx, const Object *ob_eval, const float4x4 &obmat)
25{
26 bool has_snap = false;
27
28 /* Only vertex snapping mode (eg control points and handles) supported for now). */
29 if ((sctx->runtime.snap_to_flag & SCE_SNAP_TO_POINT) == 0) {
30 return SCE_SNAP_TO_NONE;
31 }
32
33 Curve *cu = static_cast<Curve *>(ob_eval->data);
34
35 SnapData nearest2d(sctx, obmat);
36
37 const bool use_obedit = BKE_object_is_in_editmode(ob_eval);
38
39 if (use_obedit == false) {
40 /* Test BoundBox. */
41 std::optional<blender::Bounds<blender::float3>> bounds = BKE_curve_minmax(cu, true);
42 if (bounds && !nearest2d.snap_boundbox(bounds->min, bounds->max)) {
43 return SCE_SNAP_TO_NONE;
44 }
45 }
46
47 nearest2d.clip_planes_enable(sctx, ob_eval, true);
48
49 bool skip_selected = (sctx->runtime.params.snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED) !=
50 0;
51
52 LISTBASE_FOREACH (Nurb *, nu, (use_obedit ? &cu->editnurb->nurbs : &cu->nurb)) {
53 if (nu->bezt) {
54 for (int u : blender::IndexRange(nu->pntsu)) {
55 if (use_obedit) {
56 if (nu->bezt[u].hide) {
57 /* Skip hidden. */
58 continue;
59 }
60
61 bool is_selected = (nu->bezt[u].f2 & SELECT) != 0;
62 if (is_selected && skip_selected) {
63 continue;
64 }
65
66 /* Don't snap if handle is selected (moving),
67 * or if it is aligning to a moving handle. */
68 bool is_selected_h1 = (nu->bezt[u].f1 & SELECT) != 0;
69 bool is_selected_h2 = (nu->bezt[u].f3 & SELECT) != 0;
70 bool is_autoalign_h1 = (nu->bezt[u].h1 & HD_ALIGN) != 0;
71 bool is_autoalign_h2 = (nu->bezt[u].h2 & HD_ALIGN) != 0;
72 if (!skip_selected || !(is_selected_h1 || (is_autoalign_h1 && is_selected_h2))) {
73 has_snap |= nearest2d.snap_point(nu->bezt[u].vec[0]);
74 }
75
76 if (!skip_selected || !(is_selected_h2 || (is_autoalign_h2 && is_selected_h1))) {
77 has_snap |= nearest2d.snap_point(nu->bezt[u].vec[2]);
78 }
79 }
80 has_snap |= nearest2d.snap_point(nu->bezt[u].vec[1]);
81 }
82 }
83 else if (nu->bp) {
84 for (int u : blender::IndexRange(nu->pntsu * nu->pntsv)) {
85 if (use_obedit) {
86 if (nu->bp[u].hide) {
87 /* Skip hidden. */
88 continue;
89 }
90
91 bool is_selected = (nu->bp[u].f1 & SELECT) != 0;
92 if (is_selected && skip_selected) {
93 continue;
94 }
95 }
96 has_snap |= nearest2d.snap_point(nu->bp[u].vec);
97 }
98 }
99 }
100 if (has_snap) {
101 nearest2d.register_result(sctx, ob_eval, &cu->id);
102 return SCE_SNAP_TO_POINT;
103 }
104 return SCE_SNAP_TO_NONE;
105}
std::optional< blender::Bounds< blender::float3 > > BKE_curve_minmax(const Curve *cu, bool use_radius)
Definition curve.cc:5104
General operations, lookup, etc. for blender objects.
bool BKE_object_is_in_editmode(const Object *ob)
#define LISTBASE_FOREACH(type, var, list)
@ HD_ALIGN
@ SCE_SNAP_TARGET_NOT_SELECTED
@ SCE_SNAP_TO_POINT
@ SCE_SNAP_TO_NONE
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition btDbvt.cpp:299
void clip_planes_enable(SnapObjectContext *sctx, const Object *ob_eval, bool skip_occlusion_plane=false)
bool snap_point(const blender::float3 &co, int index=-1)
static void register_result(SnapObjectContext *sctx, const Object *ob_eval, const ID *id_eval, const blender::float4x4 &obmat, BVHTreeNearest *r_nearest)
bool snap_boundbox(const blender::float3 &min, const blender::float3 &max)
#define SELECT
EditNurb * editnurb
ListBase nurb
ListBase nurbs
struct SnapObjectContext::@589 runtime
eSnapMode snapCurve(SnapObjectContext *sctx, const Object *ob_eval, const float4x4 &obmat)